Updated to new theme of TeXt
@@ -1,143 +1,842 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!DOCTYPE html><html lang="en">
|
||||
<head><meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Page Not Found - Stop Talking, Start Doing</title>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Page Not Found « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
<link rel="canonical" href="http://localhost:4000/404.html"><link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="/feed.xml"><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//404.html">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
<meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml">
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<!-- end favicons snippet --><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css" ><!-- start custom head snippets -->
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
<!-- end custom head snippets -->
|
||||
<script>(function() {
|
||||
window.isArray = function(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
};
|
||||
window.isString = function(val) {
|
||||
return typeof val === 'string';
|
||||
};
|
||||
|
||||
window.hasEvent = function(event) {
|
||||
return 'on'.concat(event) in window.document;
|
||||
};
|
||||
|
||||
window.isOverallScroller = function(node) {
|
||||
return node === document.documentElement || node === document.body || node === window;
|
||||
};
|
||||
|
||||
window.isFormElement = function(node) {
|
||||
var tagName = node.tagName;
|
||||
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
||||
};
|
||||
|
||||
window.pageLoad = (function () {
|
||||
var loaded = false, cbs = [];
|
||||
window.addEventListener('load', function () {
|
||||
var i;
|
||||
loaded = true;
|
||||
if (cbs.length > 0) {
|
||||
for (i = 0; i < cbs.length; i++) {
|
||||
cbs[i]();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
return {
|
||||
then: function(cb) {
|
||||
cb && (loaded ? cb() : (cbs.push(cb)));
|
||||
}
|
||||
};
|
||||
})();
|
||||
})();
|
||||
(function() {
|
||||
window.throttle = function(func, wait) {
|
||||
var args, result, thisArg, timeoutId, lastCalled = 0;
|
||||
|
||||
function trailingCall() {
|
||||
lastCalled = new Date;
|
||||
timeoutId = null;
|
||||
result = func.apply(thisArg, args);
|
||||
}
|
||||
return function() {
|
||||
var now = new Date,
|
||||
remaining = wait - (now - lastCalled);
|
||||
|
||||
args = arguments;
|
||||
thisArg = this;
|
||||
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
lastCalled = now;
|
||||
result = func.apply(thisArg, args);
|
||||
} else if (!timeoutId) {
|
||||
timeoutId = setTimeout(trailingCall, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
})();
|
||||
(function() {
|
||||
var Set = (function() {
|
||||
var add = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (data[i] === item) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.size ++;
|
||||
data.push(item);
|
||||
return data;
|
||||
};
|
||||
|
||||
var Set = function(data) {
|
||||
this.size = 0;
|
||||
this._data = [];
|
||||
var i;
|
||||
if (data.length > 0) {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
add.call(this, data[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Set.prototype.add = add;
|
||||
Set.prototype.get = function(index) { return this._data[index]; };
|
||||
Set.prototype.has = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.get(i) === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Set.prototype.is = function(map) {
|
||||
if (map._data.length !== this._data.length) { return false; }
|
||||
var i, j, flag, tData = this._data, mData = map._data;
|
||||
for (i = 0; i < tData.length; i++) {
|
||||
for (flag = false, j = 0; j < mData.length; j++) {
|
||||
if (tData[i] === mData[j]) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Set.prototype.values = function() {
|
||||
return this._data;
|
||||
};
|
||||
return Set;
|
||||
})();
|
||||
|
||||
window.Lazyload = (function(doc) {
|
||||
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
||||
var createNode = function(name, attrs) {
|
||||
var node = doc.createElement(name), attr;
|
||||
for (attr in attrs) {
|
||||
if (attrs.hasOwnProperty(attr)) {
|
||||
node.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
var end = function(type, url) {
|
||||
var s, q, qi, cbs, i, j, cur, val, flag;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
s[url] = true;
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (cur.urls.has(url)) {
|
||||
qi = cur, val = qi.urls.values();
|
||||
qi && (cbs = qi.callbacks);
|
||||
for (flag = true, j = 0; j < val.length; j++) {
|
||||
cur = val[j];
|
||||
if (!s[cur]) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
if (flag && cbs && cbs.length > 0) {
|
||||
for (j = 0; j < cbs.length; j++) {
|
||||
cbs[j].call(context);
|
||||
}
|
||||
qi.load = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var load = function(type, urls, callback) {
|
||||
var s, q, qi, node, i, cur,
|
||||
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (_urls.is(cur.urls)) {
|
||||
qi = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = _urls.values();
|
||||
if (qi) {
|
||||
callback && (qi.load || qi.callbacks.push(callback));
|
||||
callback && (qi.load && callback());
|
||||
} else {
|
||||
q.push({
|
||||
urls: _urls,
|
||||
callbacks: callback ? [callback] : [],
|
||||
load: false
|
||||
});
|
||||
for (i = 0; i < val.length; i++) {
|
||||
node = null, url = val[i];
|
||||
if (s[url] === undefined) {
|
||||
(type === 'js' ) && (node = createNode('script', { src: url }));
|
||||
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
||||
if (node) {
|
||||
node.onload = (function(type, url) {
|
||||
return function() {
|
||||
end(type, url);
|
||||
};
|
||||
})(type, url);
|
||||
(doc.head || doc.body).appendChild(node);
|
||||
s[url] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
js: function(url, callback) {
|
||||
load('js', url, callback);
|
||||
},
|
||||
css: function(url, callback) {
|
||||
load('css', url, callback);
|
||||
}
|
||||
};
|
||||
})(this.document);
|
||||
})();
|
||||
</script><script>
|
||||
(function() {
|
||||
var TEXT_VARIABLES = {
|
||||
version: '2.2.6',
|
||||
sources: {
|
||||
font_awesome: 'https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css',
|
||||
jquery: 'https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js',
|
||||
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
||||
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
||||
gitalk: {
|
||||
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
||||
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
||||
},
|
||||
valine: 'https://unpkg.com/valine/dist/Valine.min.js',
|
||||
mathjax: 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML',
|
||||
mermaid: 'https://cdn.bootcss.com/mermaid/8.0.0-rc.8/mermaid.min.js'
|
||||
},
|
||||
site: {
|
||||
toc: {
|
||||
selectors: 'h1,h2,h3'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
search_js: '/assets/search.js'
|
||||
}
|
||||
};
|
||||
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div class="root" data-is-touch="false">
|
||||
<div class="layout--page js-page-root"><div class="page__main js-page-main page__viewport cell cell--auto">
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Page Not Found</h1>
|
||||
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
||||
<div class="header__title">
|
||||
<div class="header__brand"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<style type="text/css">
|
||||
.st0{fill:#515151;}
|
||||
</style>
|
||||
<path class="st0" d="M1.7,22.3c5.7-5.7,11.3-5.7,17,0c3.3-3.3,3.5-5.3,0.8-6c2.7,0.7,3.5-1.1,2.3-5.6s-3.3-5.2-6.3-2.1
|
||||
c3-3,2.3-5.2-2.1-6.3S7,1.8,7.7,4.6C7,1.8,5,2.1,1.7,5.3C7.3,11,7.3,16.7,1.7,22.3"/>
|
||||
</svg>
|
||||
<a title="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
" href="/">Stop Talking, Start Doing</a></div><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></div><nav class="navigation">
|
||||
<ul><li class="navigation__item"><a href="/archive.html">Archive</a></li><li class="navigation__item"><a href="/about.html">About</a></li><li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li></ul>
|
||||
</nav></div>
|
||||
</header>
|
||||
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
||||
|
||||
<article class="post-content">
|
||||
<p>Where am I and where should I go?</p>
|
||||
<div class="col-aside d-print-none js-col-aside"></div>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
<div class="col-main cell cell--auto"><!-- start custom main top snippet -->
|
||||
|
||||
<!-- end custom main top snippet -->
|
||||
<article itemscope itemtype="http://schema.org/WebPage"><div class="article__header"><header><h1>Page Not Found</h1></header></div><meta itemprop="headline" content="Page Not Found"><meta itemprop="author" content="Pengzhan Hao"/><div class="js-article-content"><p>Where am I and where should I go?</p>
|
||||
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
||||
|
||||
<!-- end custom main bottom snippet -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div></div></div><div class="page__footer d-print-none">
|
||||
<footer class="footer py-4 js-page-footer">
|
||||
<div class="main"><div itemscope itemtype="http://schema.org/Person">
|
||||
<meta itemprop="name" content="Pengzhan Hao"><meta itemprop="url" content="/"><div class="footer__author-links"><div class="author-links">
|
||||
<ul class="menu menu--nowrap menu--inline"><li title="Send me an Email.">
|
||||
<a class="button button--circle mail-button" itemprop="email" href="mailto:haopengzhan@gmail.com" target="_blank">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</a><li title="Follow me on Github.">
|
||||
<a class="button button--circle github-button" itemprop="sameAs" href="https://github.com/codersherlock" target="_blank">
|
||||
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="svgpath" data-index="path_0" fill="#272636" d="M0 525.2c0 223.6 143.3 413.7 343 483.5 26.9 6.8 22.8-12.4 22.8-25.4l0-88.7c-155.3 18.2-161.5-84.6-172-101.7-21.1-36-70.8-45.2-56-62.3 35.4-18.2 71.4 4.6 113.1 66.3 30.2 44.7 89.1 37.2 119 29.7 6.5-26.9 20.5-50.9 39.7-69.6C248.8 728.2 181.7 630 181.7 513.2c0-56.6 18.7-108.7 55.3-150.7-23.3-69.3 2.2-128.5 5.6-137.3 66.5-6 135.5 47.6 140.9 51.8 37.8-10.2 80.9-15.6 129.1-15.6 48.5 0 91.8 5.6 129.8 15.9 12.9-9.8 77-55.8 138.8-50.2 3.3 8.8 28.2 66.7 6.3 135 37.1 42.1 56 94.6 56 151.4 0 117-67.5 215.3-228.8 243.7 26.9 26.6 43.6 63.4 43.6 104.2l0 128.8c0.9 10.3 0 20.5 17.2 20.5C878.1 942.4 1024 750.9 1024 525.3c0-282.9-229.3-512-512-512C229.1 13.2 0 242.3 0 525.2L0 525.2z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</a>
|
||||
</li></ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="site-info mt-2">
|
||||
<div>© Stop Talking, Start Doing 2021,
|
||||
Powered by <a title="Jekyll is a simple, blog-aware, static site generator." href="http://jekyllrb.com/">Jekyll</a> & <a
|
||||
title="TeXt is a super customizable Jekyll theme." href="https://github.com/kitian616/jekyll-TeXt-theme">TeXt Theme</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div></div>
|
||||
</div><script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $body = $('body'), $window = $(window);
|
||||
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
||||
var activeCount = 0;
|
||||
function modal(options) {
|
||||
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
||||
var scrollTop;
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
visible = _options.initialVisible === undefined ? false : show;
|
||||
onChange = _options.onChange;
|
||||
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
||||
}
|
||||
function init() {
|
||||
setState(visible);
|
||||
}
|
||||
function setState(isShow) {
|
||||
if (isShow === visible) {
|
||||
return;
|
||||
}
|
||||
visible = isShow;
|
||||
if (visible) {
|
||||
activeCount++;
|
||||
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
||||
$root.addClass('modal--show');
|
||||
$pageMain.scrollTop(scrollTop);
|
||||
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
||||
$window.on('keyup', handleKeyup);
|
||||
} else {
|
||||
activeCount > 0 && activeCount--;
|
||||
$root.removeClass('modal--show');
|
||||
$window.scrollTop(scrollTop);
|
||||
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
||||
$window.off('keyup', handleKeyup);
|
||||
}
|
||||
onChange && onChange(visible);
|
||||
}
|
||||
function show() {
|
||||
setState(true);
|
||||
}
|
||||
function hide() {
|
||||
setState(false);
|
||||
}
|
||||
function handleKeyup(e) {
|
||||
// Char Code: 27 ESC
|
||||
if (e.which === 27) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
setOptions(options);
|
||||
init();
|
||||
return {
|
||||
show: show,
|
||||
hide: hide,
|
||||
$el: $root
|
||||
};
|
||||
}
|
||||
$.fn.modal = modal;
|
||||
});
|
||||
})();
|
||||
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
||||
(function () {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
// search panel
|
||||
var search = (window.search || (window.search = {}));
|
||||
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
||||
true : window.useDefaultSearchBox ;
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
var $searchModal = $('.js-page-search-modal');
|
||||
var $searchToggle = $('.js-search-toggle');
|
||||
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
||||
var modalVisible = false;
|
||||
search.searchModal = searchModal;
|
||||
|
||||
var $searchBox = null;
|
||||
var $searchInput = null;
|
||||
var $searchClear = null;
|
||||
|
||||
function getModalVisible() {
|
||||
return modalVisible;
|
||||
}
|
||||
search.getModalVisible = getModalVisible;
|
||||
|
||||
function handleModalChange(visible) {
|
||||
modalVisible = visible;
|
||||
if (visible) {
|
||||
search.onShow && search.onShow();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
||||
} else {
|
||||
search.onShow && search.onHide();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
||||
setTimeout(function() {
|
||||
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
||||
search.clear && search.clear();
|
||||
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
$searchToggle.on('click', function() {
|
||||
modalVisible ? searchModal.hide() : searchModal.show();
|
||||
});
|
||||
// Char Code: 83 S, 191 /
|
||||
$(window).on('keyup', function(e) {
|
||||
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
||||
modalVisible || searchModal.show();
|
||||
}
|
||||
});
|
||||
|
||||
if (useDefaultSearchBox) {
|
||||
$searchBox = $('.js-search-box');
|
||||
$searchInput = $searchBox.children('input');
|
||||
$searchClear = $searchBox.children('.js-icon-clear');
|
||||
search.getSearchInput = function() {
|
||||
return $searchInput.get(0);
|
||||
};
|
||||
search.getVal = function() {
|
||||
return $searchInput.val();
|
||||
};
|
||||
search.setVal = function(val) {
|
||||
$searchInput.val(val);
|
||||
};
|
||||
|
||||
$searchInput.on('focus', function() {
|
||||
$(this).addClass('focus');
|
||||
});
|
||||
$searchInput.on('blur', function() {
|
||||
$(this).removeClass('focus');
|
||||
});
|
||||
$searchInput.on('input', window.throttle(function() {
|
||||
var val = $(this).val();
|
||||
if (val === '' || typeof val !== 'string') {
|
||||
search.clear && search.clear();
|
||||
} else {
|
||||
$searchBox.addClass('not-empty');
|
||||
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
||||
}
|
||||
}, 400));
|
||||
$searchClear.on('click', function() {
|
||||
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
||||
search.clear && search.clear();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><div class="search search--dark">
|
||||
<div class="main">
|
||||
<div class="search__header">Search</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-box js-search-box">
|
||||
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
||||
<input type="text" />
|
||||
<div class="search-box__icon-clear js-icon-clear">
|
||||
<a><i class="fas fa-times"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
||||
Cancel</button>
|
||||
</div>
|
||||
<div class="search-result js-search-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var PAHTS = window.TEXT_VARIABLES.paths;
|
||||
window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
|
||||
var search = (window.search || (window.search = {}));
|
||||
var searchData = window.TEXT_SEARCH_DATA || {};
|
||||
|
||||
function memorize(f) {
|
||||
var cache = {};
|
||||
return function () {
|
||||
var key = Array.prototype.join.call(arguments, ',');
|
||||
if (key in cache) return cache[key];
|
||||
else return cache[key] = f.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/// search
|
||||
function searchByQuery(query) {
|
||||
var i, j, key, keys, cur, _title, result = {};
|
||||
keys = Object.keys(searchData);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (j = 0; j < searchData[key].length; j++) {
|
||||
cur = searchData[key][j], _title = cur.title;
|
||||
if ((result[key] === undefined || result[key] && result[key].length < 4 )
|
||||
&& _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
result[key].push(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var renderHeader = memorize(function(header) {
|
||||
return $('<p class="search-result__header">' + header + '</p>');
|
||||
});
|
||||
|
||||
var renderItem = function(index, title, url) {
|
||||
return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
|
||||
};
|
||||
|
||||
function render(data) {
|
||||
if (!data) { return null; }
|
||||
var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
|
||||
keys = Object.keys(data);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
$root.append(renderHeader(key));
|
||||
for (j = 0; j < data[key].length; j++) {
|
||||
cur = data[key][j];
|
||||
$root.append(renderItem(itemIndex++, cur.title, cur.url));
|
||||
}
|
||||
}
|
||||
return $root;
|
||||
}
|
||||
|
||||
// search box
|
||||
var $result = $('.js-search-result'), $resultItems;
|
||||
var lastActiveIndex, activeIndex;
|
||||
|
||||
function clear() {
|
||||
$result.html(null);
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
}
|
||||
function onInputNotEmpty(val) {
|
||||
$result.html(render(searchByQuery(val)));
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
$resultItems.eq(0).addClass('active');
|
||||
}
|
||||
|
||||
search.clear = clear;
|
||||
search.onInputNotEmpty = onInputNotEmpty;
|
||||
|
||||
function updateResultItems() {
|
||||
lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
|
||||
activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
|
||||
}
|
||||
|
||||
function moveActiveIndex(direction) {
|
||||
var itemsCount = $resultItems ? $resultItems.length : 0;
|
||||
if (itemsCount > 1) {
|
||||
lastActiveIndex = activeIndex;
|
||||
if (direction === 'up') {
|
||||
activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
|
||||
} else if (direction === 'down') {
|
||||
activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
|
||||
}
|
||||
updateResultItems();
|
||||
}
|
||||
}
|
||||
|
||||
// Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇
|
||||
$(window).on('keyup', function(e) {
|
||||
var modalVisible = search.getModalVisible && search.getModalVisible();
|
||||
if (modalVisible) {
|
||||
if (e.which === 38) {
|
||||
modalVisible && moveActiveIndex('up');
|
||||
} else if (e.which === 40) {
|
||||
modalVisible && moveActiveIndex('down');
|
||||
} else if (e.which === 13) {
|
||||
modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$result.on('mouseover', '.search-result__item > a', function() {
|
||||
var itemIndex = $(this).parent().data('index');
|
||||
itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div></div>
|
||||
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function scrollToAnchor(anchor, duration, callback) {
|
||||
var $root = this;
|
||||
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
||||
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
$.fn.scrollToAnchor = scrollToAnchor;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function affix(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
||||
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
||||
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
||||
hasInit = false, curState;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroll && (scroll = _options.scroll);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$scrollTarget = $(scrollTarget);
|
||||
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
||||
$scroll = $(scroll);
|
||||
}
|
||||
function preCalc() {
|
||||
top();
|
||||
rootHeight = $root.outerHeight();
|
||||
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
||||
rootLeft = $root.offset().left;
|
||||
}
|
||||
function calc(needPreCalc) {
|
||||
needPreCalc && preCalc();
|
||||
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
||||
rootBottomTop = scrollBottom - rootTop;
|
||||
}
|
||||
function top() {
|
||||
if (curState !== 'top') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: 0
|
||||
});
|
||||
curState = 'top';
|
||||
}
|
||||
}
|
||||
function fixed() {
|
||||
if (curState !== 'fixed') {
|
||||
$root.addClass('fixed').css({
|
||||
left: rootLeft + 'px',
|
||||
top: 0
|
||||
});
|
||||
curState = 'fixed';
|
||||
}
|
||||
}
|
||||
function bottom() {
|
||||
if (curState !== 'bottom') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: rootBottomTop + 'px'
|
||||
});
|
||||
curState = 'bottom';
|
||||
}
|
||||
}
|
||||
function setState() {
|
||||
var scrollTop = $scrollTarget.scrollTop();
|
||||
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
||||
fixed();
|
||||
} else if (scrollTop < rootTop) {
|
||||
top();
|
||||
} else {
|
||||
bottom();
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
if(!hasInit) {
|
||||
var interval, timeout;
|
||||
calc(true); setState();
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState();
|
||||
});
|
||||
$window.on('resize', function() {
|
||||
disabled || (calc(true), setState());
|
||||
});
|
||||
hasInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions,
|
||||
refresh: function() {
|
||||
calc(true, { animation: false }); setState();
|
||||
}
|
||||
};
|
||||
}
|
||||
$.fn.affix = affix;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function toc(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
||||
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
||||
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.selectors && (selectors = _options.selectors);
|
||||
_options.container && (container = _options.container);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroller && (scroller = _options.scroller);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$headings = $(container).find(selectors).filter('[id]');
|
||||
$scrollTarget = $(scrollTarget);
|
||||
$scroller = $(scroller);
|
||||
}
|
||||
function calc() {
|
||||
headingsPos = [];
|
||||
$headings.each(function() {
|
||||
headingsPos.push(Math.floor($(this).position().top));
|
||||
});
|
||||
}
|
||||
function setState(element, disabled) {
|
||||
var scrollTop = $scrollTarget.scrollTop(), i;
|
||||
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
||||
if (element) {
|
||||
$activeCur = element;
|
||||
} else {
|
||||
for (i = 0; i < headingsPos.length; i++) {
|
||||
if (scrollTop >= headingsPos[i]) {
|
||||
$activeCur = $tocLi.eq(i);
|
||||
} else {
|
||||
$activeCur || ($activeCur = $tocLi.eq(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$activeLast && $activeLast.removeClass('active');
|
||||
($activeLast = $activeCur).addClass('active');
|
||||
}
|
||||
function render() {
|
||||
if(!hasRendered) {
|
||||
$root.append($tocUl);
|
||||
$headings.each(function() {
|
||||
var $this = $(this);
|
||||
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
||||
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
||||
});
|
||||
$tocLi = $tocUl.children('li');
|
||||
$tocUl.on('click', 'a', function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
scrolling = true;
|
||||
setState($this.parent());
|
||||
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
||||
scrolling = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
hasRendered = true;
|
||||
}
|
||||
function init() {
|
||||
var interval, timeout;
|
||||
if(!hasInit) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState(null, scrolling);
|
||||
});
|
||||
$window.on('resize', window.throttle(function() {
|
||||
if (!disabled) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
}
|
||||
}, 100));
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions
|
||||
};
|
||||
}
|
||||
$.fn.toc = toc;
|
||||
});
|
||||
})();
|
||||
/*(function () {
|
||||
|
||||
})();*/
|
||||
</script>
|
||||
</div>
|
||||
<script>(function () {
|
||||
var $root = document.getElementsByClassName('root')[0];
|
||||
if (window.hasEvent('touchstart')) {
|
||||
$root.dataset.isTouch = true;
|
||||
document.addEventListener('touchstart', function(){}, false);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 laobubu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,46 +0,0 @@
|
||||
My Personal Blog
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
写点啥呢?感觉自己真是开坑狂魔。
|
||||
准备开三个新坑吧,除去现在还在更新的科研进度,接下来我要开两个新坑介绍自己的两个项目,以及一个摄影的图坑。
|
||||
@@ -0,0 +1,990 @@
|
||||
<!DOCTYPE html><html lang="en">
|
||||
<head><meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>About - Stop Talking, Start Doing</title>
|
||||
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
<link rel="canonical" href="http://localhost:4000/about.html"><link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="/feed.xml"><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico">
|
||||
|
||||
<meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<!-- end favicons snippet --><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css" ><!-- start custom head snippets -->
|
||||
|
||||
<!-- end custom head snippets -->
|
||||
<script>(function() {
|
||||
window.isArray = function(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
};
|
||||
window.isString = function(val) {
|
||||
return typeof val === 'string';
|
||||
};
|
||||
|
||||
window.hasEvent = function(event) {
|
||||
return 'on'.concat(event) in window.document;
|
||||
};
|
||||
|
||||
window.isOverallScroller = function(node) {
|
||||
return node === document.documentElement || node === document.body || node === window;
|
||||
};
|
||||
|
||||
window.isFormElement = function(node) {
|
||||
var tagName = node.tagName;
|
||||
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
||||
};
|
||||
|
||||
window.pageLoad = (function () {
|
||||
var loaded = false, cbs = [];
|
||||
window.addEventListener('load', function () {
|
||||
var i;
|
||||
loaded = true;
|
||||
if (cbs.length > 0) {
|
||||
for (i = 0; i < cbs.length; i++) {
|
||||
cbs[i]();
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
then: function(cb) {
|
||||
cb && (loaded ? cb() : (cbs.push(cb)));
|
||||
}
|
||||
};
|
||||
})();
|
||||
})();
|
||||
(function() {
|
||||
window.throttle = function(func, wait) {
|
||||
var args, result, thisArg, timeoutId, lastCalled = 0;
|
||||
|
||||
function trailingCall() {
|
||||
lastCalled = new Date;
|
||||
timeoutId = null;
|
||||
result = func.apply(thisArg, args);
|
||||
}
|
||||
return function() {
|
||||
var now = new Date,
|
||||
remaining = wait - (now - lastCalled);
|
||||
|
||||
args = arguments;
|
||||
thisArg = this;
|
||||
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
lastCalled = now;
|
||||
result = func.apply(thisArg, args);
|
||||
} else if (!timeoutId) {
|
||||
timeoutId = setTimeout(trailingCall, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
})();
|
||||
(function() {
|
||||
var Set = (function() {
|
||||
var add = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (data[i] === item) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.size ++;
|
||||
data.push(item);
|
||||
return data;
|
||||
};
|
||||
|
||||
var Set = function(data) {
|
||||
this.size = 0;
|
||||
this._data = [];
|
||||
var i;
|
||||
if (data.length > 0) {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
add.call(this, data[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Set.prototype.add = add;
|
||||
Set.prototype.get = function(index) { return this._data[index]; };
|
||||
Set.prototype.has = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.get(i) === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Set.prototype.is = function(map) {
|
||||
if (map._data.length !== this._data.length) { return false; }
|
||||
var i, j, flag, tData = this._data, mData = map._data;
|
||||
for (i = 0; i < tData.length; i++) {
|
||||
for (flag = false, j = 0; j < mData.length; j++) {
|
||||
if (tData[i] === mData[j]) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Set.prototype.values = function() {
|
||||
return this._data;
|
||||
};
|
||||
return Set;
|
||||
})();
|
||||
|
||||
window.Lazyload = (function(doc) {
|
||||
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
||||
var createNode = function(name, attrs) {
|
||||
var node = doc.createElement(name), attr;
|
||||
for (attr in attrs) {
|
||||
if (attrs.hasOwnProperty(attr)) {
|
||||
node.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
var end = function(type, url) {
|
||||
var s, q, qi, cbs, i, j, cur, val, flag;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
s[url] = true;
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (cur.urls.has(url)) {
|
||||
qi = cur, val = qi.urls.values();
|
||||
qi && (cbs = qi.callbacks);
|
||||
for (flag = true, j = 0; j < val.length; j++) {
|
||||
cur = val[j];
|
||||
if (!s[cur]) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
if (flag && cbs && cbs.length > 0) {
|
||||
for (j = 0; j < cbs.length; j++) {
|
||||
cbs[j].call(context);
|
||||
}
|
||||
qi.load = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var load = function(type, urls, callback) {
|
||||
var s, q, qi, node, i, cur,
|
||||
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (_urls.is(cur.urls)) {
|
||||
qi = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = _urls.values();
|
||||
if (qi) {
|
||||
callback && (qi.load || qi.callbacks.push(callback));
|
||||
callback && (qi.load && callback());
|
||||
} else {
|
||||
q.push({
|
||||
urls: _urls,
|
||||
callbacks: callback ? [callback] : [],
|
||||
load: false
|
||||
});
|
||||
for (i = 0; i < val.length; i++) {
|
||||
node = null, url = val[i];
|
||||
if (s[url] === undefined) {
|
||||
(type === 'js' ) && (node = createNode('script', { src: url }));
|
||||
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
||||
if (node) {
|
||||
node.onload = (function(type, url) {
|
||||
return function() {
|
||||
end(type, url);
|
||||
};
|
||||
})(type, url);
|
||||
(doc.head || doc.body).appendChild(node);
|
||||
s[url] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
js: function(url, callback) {
|
||||
load('js', url, callback);
|
||||
},
|
||||
css: function(url, callback) {
|
||||
load('css', url, callback);
|
||||
}
|
||||
};
|
||||
})(this.document);
|
||||
})();
|
||||
</script><script>
|
||||
(function() {
|
||||
var TEXT_VARIABLES = {
|
||||
version: '2.2.6',
|
||||
sources: {
|
||||
font_awesome: 'https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css',
|
||||
jquery: 'https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js',
|
||||
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
||||
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
||||
gitalk: {
|
||||
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
||||
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
||||
},
|
||||
valine: 'https://unpkg.com/valine/dist/Valine.min.js',
|
||||
mathjax: 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML',
|
||||
mermaid: 'https://cdn.bootcss.com/mermaid/8.0.0-rc.8/mermaid.min.js'
|
||||
},
|
||||
site: {
|
||||
toc: {
|
||||
selectors: 'h1,h2,h3'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
search_js: '/assets/search.js'
|
||||
}
|
||||
};
|
||||
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="root" data-is-touch="false">
|
||||
<div class="layout--page js-page-root"><div class="page__main js-page-main page__viewport cell cell--auto">
|
||||
|
||||
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
||||
<div class="header__title">
|
||||
<div class="header__brand"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<style type="text/css">
|
||||
.st0{fill:#515151;}
|
||||
</style>
|
||||
<path class="st0" d="M1.7,22.3c5.7-5.7,11.3-5.7,17,0c3.3-3.3,3.5-5.3,0.8-6c2.7,0.7,3.5-1.1,2.3-5.6s-3.3-5.2-6.3-2.1
|
||||
c3-3,2.3-5.2-2.1-6.3S7,1.8,7.7,4.6C7,1.8,5,2.1,1.7,5.3C7.3,11,7.3,16.7,1.7,22.3"/>
|
||||
</svg>
|
||||
<a title="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
" href="/">Stop Talking, Start Doing</a></div><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></div><nav class="navigation">
|
||||
<ul><li class="navigation__item"><a href="/archive.html">Archive</a></li><li class="navigation__item navigation__item--active"><a href="/about.html">About</a></li><li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li></ul>
|
||||
</nav></div>
|
||||
</header>
|
||||
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
||||
|
||||
<div class="col-aside d-print-none js-col-aside"></div>
|
||||
|
||||
<div class="col-main cell cell--auto"><!-- start custom main top snippet -->
|
||||
|
||||
<!-- end custom main top snippet -->
|
||||
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1>About</h1></header></div><meta itemprop="headline" content="About"><meta itemprop="author" content="Pengzhan Hao"/><div class="js-article-content"><div class="layout--article"><!-- start custom article top snippet -->
|
||||
|
||||
<!-- end custom article top snippet -->
|
||||
<div class="article__content" itemprop="articleBody"><h1 id="pengzhan-hao">Pengzhan Hao</h1>
|
||||
|
||||
<p><strong>Position:</strong> Research Assistant in MOSLab<br />
|
||||
<strong>Education:</strong> Doctoral Student of SUNY at Binghamton<br />
|
||||
<strong>Email:</strong> phao3 at binghamton dot edu<br />
|
||||
<strong>Address:</strong><br />
|
||||
MOSLab, H-6 Engineering Building<br />
|
||||
Binghamton University<br />
|
||||
4400 Vestal Parkway East<br />
|
||||
Binghamton, NY 13902</p>
|
||||
|
||||
<h2 id="education">Education</h2>
|
||||
|
||||
<ul>
|
||||
<li>2017.08 - Ph.D. in Computer Science, Binghamton University, NY, USA</li>
|
||||
<li>2015.08 - 2017.05 M.E in Computer Science, Binghamton University, NY, USA</li>
|
||||
<li>2011.08 - 2015.06 B.E in Software Engineering, Beihang University, Beijing, China</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="experience">Experience</h2>
|
||||
|
||||
<ul>
|
||||
<li>2016.10 - <strong><em>Research Assistant</em></strong> @ Mobile and Operating System Lab, Binghamton University
|
||||
<ul>
|
||||
<li>Advised by Professor <a href="https://buzhangy.github.io/">Yifan Zhang</a></li>
|
||||
<li>Edge-based distributed deep learning
|
||||
<ul>
|
||||
<li>Implemented a system for time-sensitive, edge-based distributed neural network training scenarios with state-of-the-art performance.</li>
|
||||
<li>Applied empirical experiments to show potential opportunities in Edge-based/Mobile-based distributed neural network training.</li>
|
||||
<li>Investigated heterogeneous-aware training tasks scheduling problem.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Edge Computing
|
||||
<ul>
|
||||
<li>Envision edge computing’s work-flow in end device performance(latency, traffic) improving.</li>
|
||||
<li>Applied empirical experiments on different edge computing work-flow and propose/implement related solutions.</li>
|
||||
<li>Design and implement an edge-based multi-tier system for decreasing bandwidth usage from endpoint mobile device.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>2013.10 - 2014.09 <strong><em>Research Intern</em></strong> @ Advanced computer application technology engineering Research Center, Ministry of Education, China
|
||||
<ul>
|
||||
<li>Analyzed real-time routing problem and reliable algorithm design</li>
|
||||
<li>Led and developed a routing system mostly backend server program</li>
|
||||
<li>Participated in vehicle internet research</li>
|
||||
<li>Supervised by Juhua Pu, Zhang Xiong, Related project: Urban Computing</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>2013.10 - 2014.01 <strong><em>Research Intern</em></strong> @ Institute of Software, Chinese Academy of Sciences, China
|
||||
<ul>
|
||||
<li>Analyzed mobile OS kernel and Localized portion with C language</li>
|
||||
<li>Supervised by Cangzhou Yuan</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="research-projects">Research projects</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/CoderSherlock/dlib-exper">EDDL: Edge-based distributed deep learning</a></li>
|
||||
<li><a href="https://github.com/bumoslab/EdgeCourier">Edge Courier: Edge-involved Cloud file synchronization service</a> <em>Original repository(private)</em></li>
|
||||
<li>Real time routing planner <em>Original repository(private)</em>
|
||||
<ul>
|
||||
<li><a href="https://github.com/CoderSherlock/Project-OSCF.git">Map preprocessing driver</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="publications">Publications</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>EDDL: A Distributed Deep Learning System for Resource-limited Edge Computing Environment.</strong>
|
||||
<strong>Pengzhan Hao</strong>, and Yifan Zhang
|
||||
The Sixth ACM/IEEE Symposium on Edge Computing (<strong>ACM/IEEE SEC</strong>)<br />
|
||||
San Jose, CA, USA, 2021.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2021-10/eta-infocom18.pdf">A Case for Web Service Bandwidth Reduction on Mobile Devices with Edge-hosted Personal Services</a></strong>
|
||||
Yongshu Bai, <strong>Pengzhan Hao</strong>, and Yifan Zhang
|
||||
The 37th IEEE International Conference on Computer Communications (<strong>IEEE INFOCOM</strong>)<br />
|
||||
Honolulu, HI, USA, 2018.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2018-02/a7-hao.pdf">EdgeCourier: An Edge-hosted Personal Service for Low-bandwidth Document Synchronization in Mobile Cloud Storage Services</a></strong> <strong>[<a href="/">slide</a>]</strong><br />
|
||||
<strong>Pengzhan Hao</strong>, Yongshu Bai, Xin Zhang, and Yifan Zhang<br />
|
||||
The 2nd ACM/IEEE Symposium on Edge Computing (<strong>ACM/IEEE SEC</strong>)<br />
|
||||
San Jose, CA, USA, 2017.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2017-07/p169-zhang.pdf">Poster: Securing Device Inputs for Smartphones Using Hypervisor Based Approach</a></strong><br />
|
||||
Xin Zhang, Yongshu Bai, <strong>Pengzhan Hao</strong>, and Yifan Zhang<br />
|
||||
The 15th ACM International Conference on Mobile Systems, Applications, and Services (<strong>ACM MobiSys</strong>)<br />
|
||||
Niagara Falls, NY, USA, 2017.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2017-07/p163-hao.pdf">Poster: EPS - Edge-hosted Personal Services for Mobile Users</a> [<a href="/static/2017-07/eps_poster.pdf">poster</a>]</strong><br />
|
||||
<strong>Pengzhan Hao</strong>, Yongshu Bai, Xin Zhang, and Yifan Zhang<br />
|
||||
The 15th ACM International Conference on Mobile Systems, Applications, and Services (<strong>ACM MobiSys</strong>)<br />
|
||||
Niagara Falls, NY, USA, 2017.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="teaching">Teaching</h2>
|
||||
|
||||
<ul>
|
||||
<li>Operating system (Graduate level)</li>
|
||||
<li>Operating system (Undergraduate level)</li>
|
||||
<li>Introduction to distributed system (Graduate level)</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="fun">Fun</h2>
|
||||
</div><div class="d-print-none"><footer class="article__footer"><!-- start custom article footer snippet -->
|
||||
|
||||
<!-- end custom article footer snippet -->
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
$(function() {
|
||||
var $this ,$scroll;
|
||||
var $articleContent = $('.js-article-content');
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
||||
$scroll = $(scroll);
|
||||
|
||||
$articleContent.find('.highlight').each(function() {
|
||||
$this = $(this);
|
||||
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
||||
});
|
||||
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
||||
$this = $(this);
|
||||
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
||||
});
|
||||
$articleContent.on('click', '.anchor', function() {
|
||||
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div></article><!-- start custom main bottom snippet -->
|
||||
|
||||
<!-- end custom main bottom snippet -->
|
||||
</div>
|
||||
</div></div></div><div class="page__footer d-print-none">
|
||||
<footer class="footer py-4 js-page-footer">
|
||||
<div class="main"><div itemscope itemtype="http://schema.org/Person">
|
||||
<meta itemprop="name" content="Pengzhan Hao"><meta itemprop="url" content="/"><div class="footer__author-links"><div class="author-links">
|
||||
<ul class="menu menu--nowrap menu--inline"><li title="Send me an Email.">
|
||||
<a class="button button--circle mail-button" itemprop="email" href="mailto:haopengzhan@gmail.com" target="_blank">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</a><li title="Follow me on Github.">
|
||||
<a class="button button--circle github-button" itemprop="sameAs" href="https://github.com/codersherlock" target="_blank">
|
||||
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="svgpath" data-index="path_0" fill="#272636" d="M0 525.2c0 223.6 143.3 413.7 343 483.5 26.9 6.8 22.8-12.4 22.8-25.4l0-88.7c-155.3 18.2-161.5-84.6-172-101.7-21.1-36-70.8-45.2-56-62.3 35.4-18.2 71.4 4.6 113.1 66.3 30.2 44.7 89.1 37.2 119 29.7 6.5-26.9 20.5-50.9 39.7-69.6C248.8 728.2 181.7 630 181.7 513.2c0-56.6 18.7-108.7 55.3-150.7-23.3-69.3 2.2-128.5 5.6-137.3 66.5-6 135.5 47.6 140.9 51.8 37.8-10.2 80.9-15.6 129.1-15.6 48.5 0 91.8 5.6 129.8 15.9 12.9-9.8 77-55.8 138.8-50.2 3.3 8.8 28.2 66.7 6.3 135 37.1 42.1 56 94.6 56 151.4 0 117-67.5 215.3-228.8 243.7 26.9 26.6 43.6 63.4 43.6 104.2l0 128.8c0.9 10.3 0 20.5 17.2 20.5C878.1 942.4 1024 750.9 1024 525.3c0-282.9-229.3-512-512-512C229.1 13.2 0 242.3 0 525.2L0 525.2z" />
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</li></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="site-info mt-2">
|
||||
<div>© Stop Talking, Start Doing 2021,
|
||||
Powered by <a title="Jekyll is a simple, blog-aware, static site generator." href="http://jekyllrb.com/">Jekyll</a> & <a
|
||||
title="TeXt is a super customizable Jekyll theme." href="https://github.com/kitian616/jekyll-TeXt-theme">TeXt Theme</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div></div>
|
||||
</div><script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $body = $('body'), $window = $(window);
|
||||
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
||||
var activeCount = 0;
|
||||
function modal(options) {
|
||||
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
||||
var scrollTop;
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
visible = _options.initialVisible === undefined ? false : show;
|
||||
onChange = _options.onChange;
|
||||
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
||||
}
|
||||
function init() {
|
||||
setState(visible);
|
||||
}
|
||||
function setState(isShow) {
|
||||
if (isShow === visible) {
|
||||
return;
|
||||
}
|
||||
visible = isShow;
|
||||
if (visible) {
|
||||
activeCount++;
|
||||
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
||||
$root.addClass('modal--show');
|
||||
$pageMain.scrollTop(scrollTop);
|
||||
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
||||
$window.on('keyup', handleKeyup);
|
||||
} else {
|
||||
activeCount > 0 && activeCount--;
|
||||
$root.removeClass('modal--show');
|
||||
$window.scrollTop(scrollTop);
|
||||
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
||||
$window.off('keyup', handleKeyup);
|
||||
}
|
||||
onChange && onChange(visible);
|
||||
}
|
||||
function show() {
|
||||
setState(true);
|
||||
}
|
||||
function hide() {
|
||||
setState(false);
|
||||
}
|
||||
function handleKeyup(e) {
|
||||
// Char Code: 27 ESC
|
||||
if (e.which === 27) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
setOptions(options);
|
||||
init();
|
||||
return {
|
||||
show: show,
|
||||
hide: hide,
|
||||
$el: $root
|
||||
};
|
||||
}
|
||||
$.fn.modal = modal;
|
||||
});
|
||||
})();
|
||||
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
||||
(function () {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
// search panel
|
||||
var search = (window.search || (window.search = {}));
|
||||
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
||||
true : window.useDefaultSearchBox ;
|
||||
|
||||
var $searchModal = $('.js-page-search-modal');
|
||||
var $searchToggle = $('.js-search-toggle');
|
||||
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
||||
var modalVisible = false;
|
||||
search.searchModal = searchModal;
|
||||
|
||||
var $searchBox = null;
|
||||
var $searchInput = null;
|
||||
var $searchClear = null;
|
||||
|
||||
function getModalVisible() {
|
||||
return modalVisible;
|
||||
}
|
||||
search.getModalVisible = getModalVisible;
|
||||
|
||||
function handleModalChange(visible) {
|
||||
modalVisible = visible;
|
||||
if (visible) {
|
||||
search.onShow && search.onShow();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
||||
} else {
|
||||
search.onShow && search.onHide();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
||||
setTimeout(function() {
|
||||
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
||||
search.clear && search.clear();
|
||||
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
$searchToggle.on('click', function() {
|
||||
modalVisible ? searchModal.hide() : searchModal.show();
|
||||
});
|
||||
// Char Code: 83 S, 191 /
|
||||
$(window).on('keyup', function(e) {
|
||||
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
||||
modalVisible || searchModal.show();
|
||||
}
|
||||
});
|
||||
|
||||
if (useDefaultSearchBox) {
|
||||
$searchBox = $('.js-search-box');
|
||||
$searchInput = $searchBox.children('input');
|
||||
$searchClear = $searchBox.children('.js-icon-clear');
|
||||
search.getSearchInput = function() {
|
||||
return $searchInput.get(0);
|
||||
};
|
||||
search.getVal = function() {
|
||||
return $searchInput.val();
|
||||
};
|
||||
search.setVal = function(val) {
|
||||
$searchInput.val(val);
|
||||
};
|
||||
|
||||
$searchInput.on('focus', function() {
|
||||
$(this).addClass('focus');
|
||||
});
|
||||
$searchInput.on('blur', function() {
|
||||
$(this).removeClass('focus');
|
||||
});
|
||||
$searchInput.on('input', window.throttle(function() {
|
||||
var val = $(this).val();
|
||||
if (val === '' || typeof val !== 'string') {
|
||||
search.clear && search.clear();
|
||||
} else {
|
||||
$searchBox.addClass('not-empty');
|
||||
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
||||
}
|
||||
}, 400));
|
||||
$searchClear.on('click', function() {
|
||||
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
||||
search.clear && search.clear();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><div class="search search--dark">
|
||||
<div class="main">
|
||||
<div class="search__header">Search</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-box js-search-box">
|
||||
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
||||
<input type="text" />
|
||||
<div class="search-box__icon-clear js-icon-clear">
|
||||
<a><i class="fas fa-times"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
||||
Cancel</button>
|
||||
</div>
|
||||
<div class="search-result js-search-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var PAHTS = window.TEXT_VARIABLES.paths;
|
||||
window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
|
||||
var search = (window.search || (window.search = {}));
|
||||
var searchData = window.TEXT_SEARCH_DATA || {};
|
||||
|
||||
function memorize(f) {
|
||||
var cache = {};
|
||||
return function () {
|
||||
var key = Array.prototype.join.call(arguments, ',');
|
||||
if (key in cache) return cache[key];
|
||||
else return cache[key] = f.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/// search
|
||||
function searchByQuery(query) {
|
||||
var i, j, key, keys, cur, _title, result = {};
|
||||
keys = Object.keys(searchData);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (j = 0; j < searchData[key].length; j++) {
|
||||
cur = searchData[key][j], _title = cur.title;
|
||||
if ((result[key] === undefined || result[key] && result[key].length < 4 )
|
||||
&& _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
result[key].push(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var renderHeader = memorize(function(header) {
|
||||
return $('<p class="search-result__header">' + header + '</p>');
|
||||
});
|
||||
|
||||
var renderItem = function(index, title, url) {
|
||||
return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
|
||||
};
|
||||
|
||||
function render(data) {
|
||||
if (!data) { return null; }
|
||||
var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
|
||||
keys = Object.keys(data);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
$root.append(renderHeader(key));
|
||||
for (j = 0; j < data[key].length; j++) {
|
||||
cur = data[key][j];
|
||||
$root.append(renderItem(itemIndex++, cur.title, cur.url));
|
||||
}
|
||||
}
|
||||
return $root;
|
||||
}
|
||||
|
||||
// search box
|
||||
var $result = $('.js-search-result'), $resultItems;
|
||||
var lastActiveIndex, activeIndex;
|
||||
|
||||
function clear() {
|
||||
$result.html(null);
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
}
|
||||
function onInputNotEmpty(val) {
|
||||
$result.html(render(searchByQuery(val)));
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
$resultItems.eq(0).addClass('active');
|
||||
}
|
||||
|
||||
search.clear = clear;
|
||||
search.onInputNotEmpty = onInputNotEmpty;
|
||||
|
||||
function updateResultItems() {
|
||||
lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
|
||||
activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
|
||||
}
|
||||
|
||||
function moveActiveIndex(direction) {
|
||||
var itemsCount = $resultItems ? $resultItems.length : 0;
|
||||
if (itemsCount > 1) {
|
||||
lastActiveIndex = activeIndex;
|
||||
if (direction === 'up') {
|
||||
activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
|
||||
} else if (direction === 'down') {
|
||||
activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
|
||||
}
|
||||
updateResultItems();
|
||||
}
|
||||
}
|
||||
|
||||
// Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇
|
||||
$(window).on('keyup', function(e) {
|
||||
var modalVisible = search.getModalVisible && search.getModalVisible();
|
||||
if (modalVisible) {
|
||||
if (e.which === 38) {
|
||||
modalVisible && moveActiveIndex('up');
|
||||
} else if (e.which === 40) {
|
||||
modalVisible && moveActiveIndex('down');
|
||||
} else if (e.which === 13) {
|
||||
modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$result.on('mouseover', '.search-result__item > a', function() {
|
||||
var itemIndex = $(this).parent().data('index');
|
||||
itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div></div>
|
||||
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function scrollToAnchor(anchor, duration, callback) {
|
||||
var $root = this;
|
||||
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
||||
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
$.fn.scrollToAnchor = scrollToAnchor;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function affix(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
||||
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
||||
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
||||
hasInit = false, curState;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroll && (scroll = _options.scroll);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$scrollTarget = $(scrollTarget);
|
||||
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
||||
$scroll = $(scroll);
|
||||
}
|
||||
function preCalc() {
|
||||
top();
|
||||
rootHeight = $root.outerHeight();
|
||||
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
||||
rootLeft = $root.offset().left;
|
||||
}
|
||||
function calc(needPreCalc) {
|
||||
needPreCalc && preCalc();
|
||||
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
||||
rootBottomTop = scrollBottom - rootTop;
|
||||
}
|
||||
function top() {
|
||||
if (curState !== 'top') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: 0
|
||||
});
|
||||
curState = 'top';
|
||||
}
|
||||
}
|
||||
function fixed() {
|
||||
if (curState !== 'fixed') {
|
||||
$root.addClass('fixed').css({
|
||||
left: rootLeft + 'px',
|
||||
top: 0
|
||||
});
|
||||
curState = 'fixed';
|
||||
}
|
||||
}
|
||||
function bottom() {
|
||||
if (curState !== 'bottom') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: rootBottomTop + 'px'
|
||||
});
|
||||
curState = 'bottom';
|
||||
}
|
||||
}
|
||||
function setState() {
|
||||
var scrollTop = $scrollTarget.scrollTop();
|
||||
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
||||
fixed();
|
||||
} else if (scrollTop < rootTop) {
|
||||
top();
|
||||
} else {
|
||||
bottom();
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
if(!hasInit) {
|
||||
var interval, timeout;
|
||||
calc(true); setState();
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState();
|
||||
});
|
||||
$window.on('resize', function() {
|
||||
disabled || (calc(true), setState());
|
||||
});
|
||||
hasInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions,
|
||||
refresh: function() {
|
||||
calc(true, { animation: false }); setState();
|
||||
}
|
||||
};
|
||||
}
|
||||
$.fn.affix = affix;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function toc(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
||||
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
||||
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.selectors && (selectors = _options.selectors);
|
||||
_options.container && (container = _options.container);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroller && (scroller = _options.scroller);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$headings = $(container).find(selectors).filter('[id]');
|
||||
$scrollTarget = $(scrollTarget);
|
||||
$scroller = $(scroller);
|
||||
}
|
||||
function calc() {
|
||||
headingsPos = [];
|
||||
$headings.each(function() {
|
||||
headingsPos.push(Math.floor($(this).position().top));
|
||||
});
|
||||
}
|
||||
function setState(element, disabled) {
|
||||
var scrollTop = $scrollTarget.scrollTop(), i;
|
||||
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
||||
if (element) {
|
||||
$activeCur = element;
|
||||
} else {
|
||||
for (i = 0; i < headingsPos.length; i++) {
|
||||
if (scrollTop >= headingsPos[i]) {
|
||||
$activeCur = $tocLi.eq(i);
|
||||
} else {
|
||||
$activeCur || ($activeCur = $tocLi.eq(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$activeLast && $activeLast.removeClass('active');
|
||||
($activeLast = $activeCur).addClass('active');
|
||||
}
|
||||
function render() {
|
||||
if(!hasRendered) {
|
||||
$root.append($tocUl);
|
||||
$headings.each(function() {
|
||||
var $this = $(this);
|
||||
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
||||
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
||||
});
|
||||
$tocLi = $tocUl.children('li');
|
||||
$tocUl.on('click', 'a', function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
scrolling = true;
|
||||
setState($this.parent());
|
||||
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
||||
scrolling = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
hasRendered = true;
|
||||
}
|
||||
function init() {
|
||||
var interval, timeout;
|
||||
if(!hasInit) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState(null, scrolling);
|
||||
});
|
||||
$window.on('resize', window.throttle(function() {
|
||||
if (!disabled) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
}
|
||||
}, 100));
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions
|
||||
};
|
||||
}
|
||||
$.fn.toc = toc;
|
||||
});
|
||||
})();
|
||||
/*(function () {
|
||||
|
||||
})();*/
|
||||
</script>
|
||||
</div>
|
||||
<script>(function () {
|
||||
var $root = document.getElementsByClassName('root')[0];
|
||||
if (window.hasEvent('touchstart')) {
|
||||
$root.dataset.isTouch = true;
|
||||
document.addEventListener('touchstart', function(){}, false);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>About « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//about/">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">About</h1>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<h1 id="pengzhan-hao">Pengzhan Hao</h1>
|
||||
|
||||
<p><strong>Position:</strong> Research Assistant in MOSLab<br />
|
||||
<strong>Education:</strong> Doctoral Student of SUNY at Binghamton<br />
|
||||
<strong>Email:</strong> phao3 at binghamton dot edu<br />
|
||||
<strong>Address:</strong><br />
|
||||
MOSLab, H-6 Engineering Building<br />
|
||||
Binghamton University<br />
|
||||
4400 Vestal Parkway East<br />
|
||||
Binghamton, NY 13902</p>
|
||||
|
||||
<h2 id="education">Education</h2>
|
||||
|
||||
<ul>
|
||||
<li>2017.08 - Ph.D. in Computer Science, Binghamton University, NY, USA</li>
|
||||
<li>2015.08 - 2017.05 M.E in Computer Science, Binghamton University, NY, USA</li>
|
||||
<li>2011.08 - 2015.06 B.E in Software Engineering, Beihang University, Beijing, China</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="experience">Experience</h2>
|
||||
|
||||
<ul>
|
||||
<li>2016.10 - <strong><em>Research Assistant</em></strong> @ Mobile and Operating System Lab, Binghamton University
|
||||
<ul>
|
||||
<li>Advised by Professor <a href="https://buzhangy.github.io/">Yifan Zhang</a></li>
|
||||
<li>Edge-based distributed deep learning
|
||||
<ul>
|
||||
<li>Implemented a system for time-sensitive, edge-based distributed neural network training scenarios with state-of-the-art performance.</li>
|
||||
<li>Applied empirical experiments to show potential opportunities in Edge-based/Mobile-based distributed neural network training.</li>
|
||||
<li>Investigated heterogeneous-aware training tasks scheduling problem.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Edge Computing
|
||||
<ul>
|
||||
<li>Envision edge computing’s work-flow in end device performance(latency, traffic) improving.</li>
|
||||
<li>Applied empirical experiments on different edge computing work-flow and propose/implement related solutions.</li>
|
||||
<li>Design and implement an edge-based multi-tier system for decreasing bandwidth usage from endpoint mobile device.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>2013.10 - 2014.09 <strong><em>Research Intern</em></strong> @ Advanced computer application technology engineering Research Center, Ministry of Education, China
|
||||
<ul>
|
||||
<li>Analyzed real-time routing problem and reliable algorithm design</li>
|
||||
<li>Led and developed a routing system mostly backend server program</li>
|
||||
<li>Participated in vehicle internet research</li>
|
||||
<li>Supervised by Juhua Pu, Zhang Xiong, Related project: Urban Computing</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>2013.10 - 2014.01 <strong><em>Research Intern</em></strong> @ Institute of Software, Chinese Academy of Sciences, China
|
||||
<ul>
|
||||
<li>Analyzed mobile OS kernel and Localized portion with C language</li>
|
||||
<li>Supervised by Cangzhou Yuan</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="research-projects">Research projects</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/CoderSherlock/dlib-exper">EDDL: Edge-based distributed deep learning</a></li>
|
||||
<li><a href="https://github.com/bumoslab/EdgeCourier">Edge Courier: Edge-involved Cloud file synchronization service</a> <em>Original repository(private)</em></li>
|
||||
<li>Real time routing planner <em>Original repository(private)</em>
|
||||
<ul>
|
||||
<li><a href="https://github.com/CoderSherlock/Project-OSCF.git">Map preprocessing driver</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="publications">Publications</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>EDDL: A Distributed Deep Learning System for Resource-limited Edge Computing Environment.</strong>
|
||||
<strong>Pengzhan Hao</strong>, and Yifan Zhang
|
||||
The Sixth ACM/IEEE Symposium on Edge Computing (<strong>ACM/IEEE SEC</strong>)<br />
|
||||
San Jose, CA, USA, 2021.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2021-10/eta-infocom18.pdf">A Case for Web Service Bandwidth Reduction on Mobile Devices with Edge-hosted Personal Services</a></strong>
|
||||
Yongshu Bai, <strong>Pengzhan Hao</strong>, and Yifan Zhang
|
||||
The 37th IEEE International Conference on Computer Communications (<strong>IEEE INFOCOM</strong>)<br />
|
||||
Honolulu, HI, USA, 2018.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2018-02/a7-hao.pdf">EdgeCourier: An Edge-hosted Personal Service for Low-bandwidth Document Synchronization in Mobile Cloud Storage Services</a></strong> <strong>[<a href="/">slide</a>]</strong><br />
|
||||
<strong>Pengzhan Hao</strong>, Yongshu Bai, Xin Zhang, and Yifan Zhang<br />
|
||||
The 2nd ACM/IEEE Symposium on Edge Computing (<strong>ACM/IEEE SEC</strong>)<br />
|
||||
San Jose, CA, USA, 2017.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2017-07/p169-zhang.pdf">Poster: Securing Device Inputs for Smartphones Using Hypervisor Based Approach</a></strong><br />
|
||||
Xin Zhang, Yongshu Bai, <strong>Pengzhan Hao</strong>, and Yifan Zhang<br />
|
||||
The 15th ACM International Conference on Mobile Systems, Applications, and Services (<strong>ACM MobiSys</strong>)<br />
|
||||
Niagara Falls, NY, USA, 2017.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong><a href="/static/2017-07/p163-hao.pdf">Poster: EPS - Edge-hosted Personal Services for Mobile Users</a> [<a href="/static/2017-07/eps_poster.pdf">poster</a>]</strong><br />
|
||||
<strong>Pengzhan Hao</strong>, Yongshu Bai, Xin Zhang, and Yifan Zhang<br />
|
||||
The 15th ACM International Conference on Mobile Systems, Applications, and Services (<strong>ACM MobiSys</strong>)<br />
|
||||
Niagara Falls, NY, USA, 2017.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="teaching">Teaching</h2>
|
||||
|
||||
<ul>
|
||||
<li>Operating system (Graduate level)</li>
|
||||
<li>Operating system (Undergraduate level)</li>
|
||||
<li>Introduction to distributed system (Graduate level)</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="fun">Fun</h2>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,185 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Using charles proxy to monitor mobile SSL traffics « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="In this blog, I will generally talk about how to use proper tools to monitor SSL traffics of a mobile devices. Currently, I only can dealing with those SSL t...">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/charles-is-not-a-good-tool">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Using charles proxy to monitor mobile SSL traffics</h1>
|
||||
<p class="post-meta">Oct 27, 2016</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<p>In this blog, I will generally talk about how to use proper tools to monitor SSL traffics of a mobile devices. Currently, I only can dealing with those SSL traffics which use an obviously certification. Some applications may not using system root cert or they doesn’t provide us a method to modify their own certs. For these situation, I still didn’t find a good solutions for it. But I’ll keep updating this if I get one.<br />
|
||||
My current solution is using AP to forward all SSL traffic to a proxy, <a href="https://www.charlesproxy.com/">charles proxy</a> is my first choice (Prof asked). It’s a non-free software which still update new versions now. So mainly, I’ll talk about how to charles SSL proxy.</p>
|
||||
|
||||
<h3 id="preparations">Preparations</h3>
|
||||
<ul>
|
||||
<li>Monitor device situation: Linux Machine with wireless adapter</li>
|
||||
<li>Download the newest version(4.0.1) of charles</li>
|
||||
<li>Target android devices with root privilege</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="install-charles-and-configuration">Install Charles and Configuration</h3>
|
||||
|
||||
<ul>
|
||||
<li>You have to install charles first. After downloading the charles proxy, you have to unzip it and configure some basic settings.</li>
|
||||
</ul>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># open charles first</span>
|
||||
./bin/charles
|
||||
</code></pre></div></div>
|
||||
<ul>
|
||||
<li>Save charles’ private key and public key</li>
|
||||
</ul>
|
||||
|
||||
<p>In Help -> SSL Proxying -> Export Charles Root Certificate and Private Key, enter a password and save the public and private key in *.p12 format.<br />
|
||||
You also need to save charles Root Certificate, it also contains in the same menu. For convience, save it as *.pem format.</p>
|
||||
|
||||
<ul>
|
||||
<li>Set Proxy and SSL Proxy</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,233 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>EDDL: How do we train neural networks on limited edge devices - PART 1 « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="This post introduces our previous milestone in project “Edge trainer”, as the paper “EDDL: A Distributed Deep Learning System for Resource-limited Edge Compu...">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/eddl-how-do-we-train-on-limited-edge-devices">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">EDDL: How do we train neural networks on limited edge devices - PART 1</h1>
|
||||
<p class="post-meta">Oct 13, 2021</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<p>This post introduces our previous milestone in project “Edge trainer”, as the paper “EDDL: A Distributed Deep Learning System for Resource-limited Edge Computing Environment.” was published.
|
||||
As the first part of the introductions, I focus only on the motivation and summary of our works.
|
||||
More details in design and implementation can be found in late posts.</p>
|
||||
|
||||
<p><img src="/static/2021-10/edgelearn-1.png" height="250" /></p>
|
||||
|
||||
<h2 id="why-do-we-need-training-on-edge">Why do we need training on edge?</h2>
|
||||
|
||||
<p>Cloud is not trustworthy anymore. More and more facts supports that breach on cloud happens frequently than before.
|
||||
Nowadays, with more generated personal sensitive data has been uploaded to the cloud center, tech company know better to someones than user themselves.</p>
|
||||
|
||||
<p>Researchers, no matter in industry on academia, are working in a way that still learning from users’ data but also keeping raw sensitive data under users’ control.
|
||||
Many publications already showed feasibility of only sharing after-trained model instead of raw data.
|
||||
One recent popular study on this is google’s <a href="https://ai.googleblog.com/2017/04/federated-learning-collaborative.html">federated learning</a>.</p>
|
||||
|
||||
<p>During investigated this problem, we found that let end user train their own data is safe, but sacrifice efficiency.
|
||||
Since one end device has limited resources, training time and power consumption can be disappointing.
|
||||
We believe there must have a leverage between privacy and efficiency in some target scenarios.</p>
|
||||
|
||||
<p>Fortunately, we observed that users who belongs to the same campus, plant, firm and community always share similar interests.
|
||||
Therefore, these co-located users have similar demands in using AI-involved routines.
|
||||
Also, co-located users are easily targeted by same type of threats, such as ransomware to financial practitioners.</p>
|
||||
|
||||
<p>Think about this, sending features of a new malware app to cloud services in order to train a neural networks used by antivirus program.
|
||||
This process may takes long time and small amount of samples may not be recognized by the global neural networks model.
|
||||
With a customized local model trained and deployed on the edge can successfully counter the problem.
|
||||
With edge training as a supplement of cloud training can achieve better response time and let the whole system more flexible.</p>
|
||||
|
||||
<h2 id="why-training-on-edge-is-hard">Why training on edge is hard?</h2>
|
||||
|
||||
<p>Since all co-located users’ device can be used for an edge training, issues and challenges occur as deploying this distributed system.</p>
|
||||
|
||||
<p>The first challenge is <strong>struggling workers</strong>.
|
||||
Training devices are heterogeneity, from limited IoT camera to high-end media center with powerful GPU.
|
||||
They are not designed to do machine learnings.
|
||||
So, a good edge-based distributed learning framework must can handle variety speeds in training tasks.</p>
|
||||
|
||||
<p>The second challenge is how to <strong>scale up</strong> clusters.
|
||||
In a campus, thousands and more devices may contribute computing resources to the same training tasks.
|
||||
However, these devices may located in far not matter in physical or in network topology.
|
||||
How can we well use them well, without struggled with endless transmission time remains a challenge.</p>
|
||||
|
||||
<p>The third issue is frequently <strong>joining and exiting</strong> of devices.
|
||||
We can’t rely on each devices to faithfully working on training tasks rather than their original workload.
|
||||
Smartly schedule work balance and handle join/exit issues also need under consideration.</p>
|
||||
|
||||
<h2 id="our-proposal">Our proposal</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>Dynamic training data distribution and runtime profiler</p>
|
||||
|
||||
<p>We design a dynamic training data distribution mechanism that helps to both the first and the third challenges.
|
||||
Preprocessing data can be transmitted without leakage of raw sensitive information.
|
||||
This can helps with struggling workers who can train small batches in order to upload parameters with a similar training time.
|
||||
Also, for extremely slow devices, join and exit of devices cases, dynamic data distribution and profiler can helps with keep global training parameters from polluted and staleness.</p>
|
||||
|
||||
<p>To counter heterogeneity’s, more approaches were applied in our later research.
|
||||
More details were introduced to runtime profiler in the later works.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Asynchronous and synchronous aggregation enabled</p>
|
||||
|
||||
<p>In our findings, asynchronous and synchronous parameter update have their pros and cons.
|
||||
Keeping sync all the time leads struggling worker issue unsolvable.
|
||||
However, async’s harm to accuracy and convergence time also need attentions.
|
||||
To carefully chose between these two update policies at the runtime is what we proposed to make use of their own advantages.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Leader role splitting</p>
|
||||
|
||||
<p>The idea is to let worker devices with higher bandwidth taking leader role during training.
|
||||
Parameter updating does not require much computation but only need bandwidth.
|
||||
Devices with sufficient bandwidth can also work as virtual leader devices.
|
||||
This approach helps with minimize physical devices we used and more leaders can further scale up workers limits.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,316 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="Let’s generate a word cloud like this. Don’t understand the language is not a big deal.If your written language is based on latin alphabet(or other language ...">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/generate-word-cloud-with-chinese-fenci">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</h1>
|
||||
<p class="post-meta">Sep 15, 2020</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<p>Let’s generate a word cloud like this.
|
||||
Don’t understand the language is not a big deal.
|
||||
If your written language is based on latin alphabet(or other language has space between words), skip tokenization.</p>
|
||||
|
||||
<p><img src="/static/2020-09/2020-06-28.png" height="250" /></p>
|
||||
|
||||
<h2 id="background">Background</h2>
|
||||
|
||||
<p>Recently, I set up a web-based RSS client for retrieving and organizing everyday news. I used <a href="https://tt-rss.org/">TinyTinyRSS</a>, or as ttrss, a popular RSS client which friendly to docker. Thanks to developer <a href="https://ttrss.henry.wang/#about">HenryQW</a>, a well-written Nginx-based docker configuration is already available in docker hub. With more feeds were added, I found some feeds does not need to be checked everyday. Thus I was thinking to create a script to automatically list all keywords appears in a last period and generate a heat map kind figure of it.</p>
|
||||
|
||||
<p>Before you go further, I’ll tell you all my settings to give readers a general overview.</p>
|
||||
|
||||
<p>My first step is to read all text-based information from TTRSS’s PostgreSQL database. With information, I used a Chinese-NLP library, <a href="https://github.com/fxsjy/jieba">jieba</a>, to extract all keyword with their occurrences frequency. By using <a href="https://github.com/amueller/word_cloud">WordCloud</a>, a python library, word cloud figure is generated and present. More details will be discussed in later sections.</p>
|
||||
|
||||
<h2 id="get-rss-feeds-text">Get RSS feeds’ text</h2>
|
||||
|
||||
<p>My first thought is generating a keyword heat map for economy news of a last week. Since this blog post are more skewed to Chinese tokenization and draw the word cloud figure. I’ll leave my code here just in case. The SQL connector I used is <a href="https://pypi.org/project/psycopg2/">psycopg2</a>, an easy-use PostgreSQL library.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">dbe</span> <span class="o">=</span> <span class="n">psycopg2</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span>
|
||||
<span class="n">host</span><span class="o">=</span><span class="n">DB_HOST</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">DB_PORT</span><span class="p">,</span> <span class="n">database</span><span class="o">=</span><span class="n">DB_NAME</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">DB_USER</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="n">DB_PASS</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">get_1w_of_feed_byid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">:</span>
|
||||
<span class="n">cur</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">dbe</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span>
|
||||
<span class="n">cur</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'SELECT content FROM public.ttrss_entries </span><span class="se">\
|
||||
</span><span class="s"> where date_updated > now() - interval </span><span class="se">\'</span><span class="s">1 week</span><span class="se">\'</span><span class="s"> AND id in ( </span><span class="se">\
|
||||
</span><span class="s"> select int_id from DB_TABLE_NAME </span><span class="se">\
|
||||
</span><span class="s"> where feed_id='</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span> <span class="o">+</span> <span class="s">' </span><span class="se">\
|
||||
</span><span class="s"> ) </span><span class="se">\
|
||||
</span><span class="s"> ORDER BY id ASC '</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">rows</span> <span class="o">=</span> <span class="n">cur</span><span class="p">.</span><span class="n">fetchall</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">rows</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>Most arguments are intuitive and easy to understand. The only exception is argument of function <em>get_1w_of_feed_byid</em>. This <strong>id</strong> is the feed index of my subscriptions.</p>
|
||||
|
||||
<h2 id="tokenize-with-frequency">Tokenize with frequency</h2>
|
||||
|
||||
<p>Two popular tokenization library were used, and I chose <a href="https://github.com/fxsjy/jieba">jieba</a> after a few comparison. Before cutting the sentence, we first need to remove all punctuation marks.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">remove_biaodian</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="n">punct</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">u''':!),.:;?]}¢'"、。〉》」』】〕〗〞︰︱︳﹐、﹒
|
||||
﹔﹕﹖﹗﹚﹜﹞!),.:;?|}︴︶︸︺︼︾﹀﹂﹄﹏、~¢
|
||||
々‖•·ˇˉ―--′’”([{£¥'"‵〈《「『【〔〖([{£¥〝︵︷︹︻
|
||||
︽︿﹁﹃﹙﹛﹝({“‘-—_…'''</span><span class="p">)</span>
|
||||
<span class="n">ret</span> <span class="o">=</span> <span class="s">""</span>
|
||||
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">punct</span><span class="p">:</span>
|
||||
<span class="n">ret</span> <span class="o">+=</span> <span class="s">''</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">ret</span> <span class="o">+=</span> <span class="n">x</span>
|
||||
<span class="k">return</span> <span class="n">ret</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>After we have an all characters string, we can call jieba. By using the function <em>jieba.posseg.cut</em> with or without paddle, we can have a word list and their “part of speech”. As you can see in the following code, I also did two more works.</p>
|
||||
|
||||
<p>First, in the if statement, I only kept all nouns with some categories. Category abbreviation such as “nr” and “ns” represent different “part of speech”, I attached with categories I used in the following table. For more details you can find in this <a href="https://github.com/fxsjy/jieba">link</a>.</p>
|
||||
|
||||
<p>The second work is only keeping words with length longer than 2 characters. In Chinese, there’s no space between words such as Latin writing systems. Since then, some single-character-words such as conjunction words are easy to be misrecognized as specialty-noun. And this misrecognition will cause more single-character being regarded as specialty-noun. I am not able to improve NLP method, so I used a easy way to fix this by removing any words less than 2 characters.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">jieba.posseg</span> <span class="k">as</span> <span class="n">pseg</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">get_noun_jieba</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">:</span>
|
||||
<span class="n">content</span> <span class="o">=</span> <span class="n">remove_biaodian</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
|
||||
<span class="n">words</span> <span class="o">=</span> <span class="n">pseg</span><span class="p">.</span><span class="n">cut</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="c1"># Invoking jieba.posseg.cut function
|
||||
</span>
|
||||
<span class="n">ret</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">word</span><span class="p">,</span> <span class="n">flag</span> <span class="ow">in</span> <span class="n">words</span><span class="p">:</span>
|
||||
<span class="c1"># print(word, flag)
|
||||
</span> <span class="k">if</span> <span class="n">flag</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'nr'</span><span class="p">,</span> <span class="s">'ns'</span><span class="p">,</span> <span class="s">'nt'</span><span class="p">,</span> <span class="s">'nw'</span><span class="p">,</span> <span class="s">'nz'</span><span class="p">,</span> <span class="s">'PER'</span><span class="p">,</span> <span class="s">'ORG'</span><span class="p">,</span> <span class="s">'x'</span><span class="p">]:</span> <span class="c1"># LOC
|
||||
</span> <span class="n">ret</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="n">remove_biaodian</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">ret</span> <span class="k">if</span> <span class="n">i</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">!=</span> <span class="s">""</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">remove_biaodian</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">strip</span><span class="p">()))</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">]</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<ul>
|
||||
<li>Word category names and abbreviations</li>
|
||||
</ul>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Abbreviation</th>
|
||||
<th>Category name/ Part of speech</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>nr</td>
|
||||
<td>People name noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ns</td>
|
||||
<td>Location name noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nt</td>
|
||||
<td>Organization name noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nw</td>
|
||||
<td>Arts work noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nz</td>
|
||||
<td>Other noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PER</td>
|
||||
<td>People name noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ORG</td>
|
||||
<td>Location name noun</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td>Non-morpheme word</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>With all words extracted, we can easily calculate their frequencies. After this, we can using the following line of code to print a sorted result to verify correctness.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">noun</span> <span class="o">=</span> <span class="n">seg</span><span class="p">.</span><span class="n">get_noun_jieba</span><span class="p">(</span><span class="n">test_content</span><span class="p">)</span>
|
||||
<span class="c1"># ... Calculate frequency of above word list ...
|
||||
</span><span class="k">print</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">a_dict</span><span class="p">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<h2 id="draw-word-cloud">Draw word cloud</h2>
|
||||
|
||||
<p>With a keyword and frequency dictionary(data structure), we can just call built-in functions from wordcloud library to generate the figure.</p>
|
||||
|
||||
<p>First we need to initialize an instance of wordcloud class. As you can see in my code, I set it with 6 parameters. Width and Height of the canvas, maximum amount of words used to generate the figure, the font of words, background color and margin between any two words.</p>
|
||||
|
||||
<p>After having the instance, we call function <em>generate_from_frequencies</em> and pass keyword dictionary to it. The return value of this function is an bitmap image, which we can use <a href="https://matplotlib.org/">matplotlib</a> to plot it to your screen.</p>
|
||||
|
||||
<p>I tested my plot on ubuntu-subsystem on Windows 10, unfortunately matplotlib under subsystem depends on x11 window manager and its not default available on windows. We need to install an x11 manager to support. <a href="https://sourceforge.net/projects/xming/">Xming</a> is the one I used.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">wordcloud</span> <span class="kn">import</span> <span class="n">WordCloud</span>
|
||||
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
|
||||
|
||||
<span class="n">font_path</span> <span class="o">=</span> <span class="s">"./font/haipai.ttf"</span>
|
||||
<span class="n">output_path</span> <span class="o">=</span> <span class="s">"./font/out.png"</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">show_figure_with_frequency</span><span class="p">(</span><span class="n">keywords</span><span class="p">:</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="n">wc</span> <span class="o">=</span> <span class="n">WordCloud</span><span class="p">(</span><span class="n">width</span><span class="o">=</span><span class="mi">828</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">1792</span><span class="p">,</span> <span class="n">max_words</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">font_path</span><span class="o">=</span><span class="n">font_path</span><span class="p">,</span>
|
||||
<span class="n">background_color</span><span class="o">=</span><span class="s">"white"</span><span class="p">,</span> <span class="n">margin</span><span class="o">=</span><span class="mi">1</span><span class="p">).</span><span class="n">generate_from_frequencies</span><span class="p">(</span><span class="n">keywords</span><span class="p">)</span>
|
||||
<span class="n">plt</span><span class="p">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">wc</span><span class="p">)</span>
|
||||
<span class="n">plt</span><span class="p">.</span><span class="n">axis</span><span class="p">(</span><span class="s">'off'</span><span class="p">)</span>
|
||||
<span class="n">plt</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>If everything work fine, a word cloud figure will show up in a new window. My version looks like this.</p>
|
||||
|
||||
<p><img src="/static/2020-09/2020-06-28.png" height="150" /></p>
|
||||
|
||||
<p>This generated word cloud figure reflects the most popular economy news’ keyword in the week started 06-28-2020. Two largest words in the figure are “新冠” and “新冠病毒”, both means “Covid-19” (This figure was in the week of the second covid spur in Beijing, China). The size of the image fits my phone screen and I can use an app to automatic sync it to my phone’s wallpaper. However, in this image, too many location nouns are presented. This will be something I can make progress on in the future.</p>
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,157 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Stop Talking is the worst title of one blog « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/hello">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Stop Talking is the worst title of one blog</h1>
|
||||
<p class="post-meta">Oct 26, 2016</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,231 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Xv6 introduction « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching...">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/intro-xv6">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Xv6 introduction</h1>
|
||||
<p class="post-meta">Jul 28, 2017</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<p>In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes.
|
||||
Understand system call and know how to implement a simple one will be coved as the first half.
|
||||
In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb.</p>
|
||||
|
||||
<h2 id="xv6-systemcall">Xv6 Systemcall</h2>
|
||||
|
||||
<p>To invoke a system call, we have to first define a user mode function to be the interface of the kernel instruction in file <em>user.h</em>.</p>
|
||||
|
||||
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">function</span> <span class="p">(</span><span class="kt">void</span><span class="p">);</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>This interface-like function will then pass the function name, in this case function, to <em>usys.S</em>. When using user mode function in programs, <em>usys.S</em> will generate a reference to SYS_function and push system call number of this function into %eax. After that, system can know from <em>syscall.c</em> and determining whether this system call is available. We must define same name system function and add it into <em>syscall.h</em> and <em>syscall.c</em>.</p>
|
||||
|
||||
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define SYS_function ## // ## is the system call number
|
||||
</span><span class="p">[</span><span class="n">SYS_function</span><span class="p">]</span> <span class="n">sys_function</span> <span class="c1">// real system function name</span>
|
||||
<span class="k">extern</span> <span class="kt">int</span> <span class="nf">sys_function</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="c1">// real system function declaration</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>After adding these sentences to syscall files, we can implement real function in specific place where you want to make the function works well.</p>
|
||||
|
||||
<p>Sometimes, we need to pass variables among system calls. In this case, variables’ values are not necessary and even can’t be pass directly into system_function. When invoke a system call function, all variables of this system call will be pushed into current process’ stack. In file <em>syscall.c</em>, multiple functions are provided to get these variables from the process. I won’t waste time on explaining how to use these functions especially when elegant and detailed comments were written in source codes. However, I will explain concepts and how process organized and works in xv6 in future articles.</p>
|
||||
|
||||
<h2 id="debug-xv6-with-gdb">Debug xv6 with gdb</h2>
|
||||
|
||||
<p>Please make sure that you have used gdb before.
|
||||
If you never used gdb, you may write a simple 50-100 lines c code and practice how to use gdb first.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://sourceware.org/gdb/current/onlinedocs/gdb/">GDB Manual</a></li>
|
||||
<li><a href="https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf">GDB cheatsheet (pdf)</a></li>
|
||||
</ul>
|
||||
|
||||
<p>To make sure xv6 gdb enabled, please check if <em>.gdbinit.tmpl</em> file exist.
|
||||
This file is used for generate <em>.gdbinit</em> file which you can late consider it as a configuration for gdb.</p>
|
||||
|
||||
<p>Before running the xv6 instance in QEMU, one more thing you need to know is that using gdb to debug xv6 must be attached remotely.
|
||||
This is because xv6 was running within QEMU, and emulator is virtually gapped from the host device.
|
||||
Later when you start debugging, QEMU will open a gdb server to let gdb client connect to.</p>
|
||||
|
||||
<p>Once you want to start, using following command to compile and run xv6</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>make qemu-nox-gdb
|
||||
<span class="k">***</span> Now run <span class="s1">'gdb'</span><span class="nb">.</span>
|
||||
qemu-system-i386 <span class="nt">-nographic</span> <span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>fs.img,index<span class="o">=</span>1,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>xv6.img,index<span class="o">=</span>0,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="nt">-smp</span> 2 7
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>At this moment, it feels xv6 was stuck, this is because QEMU is ready to be connected by the gdb client.
|
||||
You may use the <em>.gdbinit</em> to automatically finish this remote connection by simple typein following command in another terminal.</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gdb <span class="nt">-x</span> .gdbinit
|
||||
GNU gdb <span class="o">(</span>Debian 8.2.1-2+b3<span class="o">)</span> 8.2.1
|
||||
|
||||
...
|
||||
|
||||
The target architecture is assumed to be i8086
|
||||
<span class="o">[</span>f000:fff0] 0xffff0: ljmp <span class="nv">$0x3630</span>,<span class="nv">$0xf000e05b</span>
|
||||
0x0000fff0 <span class="k">in</span> ?? <span class="o">()</span>
|
||||
+ symbol-file kernel
|
||||
warning: A handler <span class="k">for </span>the OS ABI <span class="s2">"GNU/Linux"</span> is not built into this configuration
|
||||
of GDB. Attempting to <span class="k">continue </span>with the default i8086 settings.
|
||||
|
||||
<span class="o">(</span>gdb<span class="o">)</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>Now within this gdb client shell, type ‘c’ to continue the xv6, and you will see xv6 start execution in the first terminal.</p>
|
||||
|
||||
<p>At this moment, you may add breakpoints to your code to see if your code is correctly implemented or not.</p>
|
||||
|
||||
<p><strong>One more thing</strong>, if you open <em>.gdbinit</em> file, you’ll find that it by default connect to a localhost target.
|
||||
If you are working on some other environment that target and client were not placed in the same device, change the localhost to ip address correspondingly.
|
||||
Using ssh may connect to different physical devices under same domain name, this is because load balancer were used. To check ip address, search command <em>ip</em>.</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target remote localhost:28467
|
||||
<span class="c"># target remote [ip-addr]:28467</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,266 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Some of my previews experiment works: 2016 « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="This blog contains only some basic record of my works. For some details, I will write a unique blog just for some specific topics.">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//archivers/some-of-my-previews-exper-work">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">Some of my previews experiment works: 2016</h1>
|
||||
<p class="post-meta">Oct 28, 2016</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<p>This blog contains only some basic record of my works. For some details, I will write a unique blog just for some specific topics.</p>
|
||||
|
||||
<h1 id="2016-10">2016-10</h1>
|
||||
|
||||
<h2 id="time-experiment-of-rsync">Time Experiment of rsync</h2>
|
||||
|
||||
<p>Patch is based on rsync with version 3.1.2. [<a href="https://download.samba.org/pub/rsync/rsync-3.1.2.tar.gz">Rsync</a>|<a href="/static/2016-10/rsync/rsync-3.1.2-time.patch">Patch</a>]</p>
|
||||
|
||||
<h3 id="how-to-collect-data">How to collect data</h3>
|
||||
|
||||
<p>Basically, everything of transmission time and computation time will be output with overall time will be printed on the console.
|
||||
But we also need some bash script to collect data through different size of random size and with different modification through them.</p>
|
||||
|
||||
<ul>
|
||||
<li>Start from 8K to 64M, modify at beginning, [<a href="/static/2016-10/rsync/small2Big_change_at_begin.sh">Bash script</a>]</li>
|
||||
<li>Start from 8K to 64M, modify at last, [<a href="/static/2016-10/rsync/small2Big_change_at_last.sh">Bash script</a>]</li>
|
||||
<li>Start from 8K to 64M, modify at random place with a (slow) python script, [<a href="/static/2016-10/rsync/small2Big_change_at_anyplace.sh">Bash script</a>|<a href="/static/2016-10/rsync/addbyte.py">Python program</a>]</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="time-experiment-of-seafile">Time Experiment of seafile</h2>
|
||||
|
||||
<p>Patch is based on seafile 5.1.4. You can find the release from <a href="https://github.com/haiwen/seafile/releases">seafile official repo</a>. You may follow official compile instructions from <a href="https://manual.seafile.com/build_seafile/linux.html">here</a>. [<a href="">Patch <strong>no longer avaiable, new version at following sections</strong></a>]</p>
|
||||
|
||||
<h3 id="how-to-collect-data-1">How to collect data</h3>
|
||||
|
||||
<p>We also need everything be done using scripting. But this time I only design added some distance between two increasing files’ sizes.</p>
|
||||
|
||||
<ul>
|
||||
<li>Start from 8K to 16M, 4 times increasing, modify at beginning/ at 1024 different places with python script. [<a href="/static/2016-11/seafile/trans.sh">Bash Script</a>|<a href="/static/2016-11/seafile/addbyte.py">Python program</a>]</li>
|
||||
<li>After using this auto testing script, everything of output will be marked in log files of seafile, which located in <strong>~/.ccnet/log/seafile.log</strong></li>
|
||||
<li>We need to use this simple awk code and vim operation to extract data.</li>
|
||||
</ul>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># CDC: content defined chucks</span>
|
||||
<span class="c"># HUT: Http upload traffic</span>
|
||||
<span class="c"># ALL: overall time of one commit & upload</span>
|
||||
<span class="nb">awk</span> <span class="s1">'/CDC|HUT|ALL/ {print $4,$5}'</span> ~/.ccnet/log/seafile.log <span class="o">></span> results.stat
|
||||
</code></pre></div></div>
|
||||
|
||||
<h3 id="install-seafile-on-odroid-xu">Install Seafile on odroid xu</h3>
|
||||
|
||||
<p>Due to failure of my cross-compile to seafile on android. I used develop board as a replacement experiment platform for ARM-seafile testing. I used a <a href="http://www.hardkernel.com/main/products/prdt_info.php?g_code=G137510300620">odroid xu</a> as hardware standard. Because all I need is an ARM platform, only an ARM-Ubuntu is enough for me. But develop prototype on a board is much fun than coding, I won’t address much this time. But I’ll start a blog telling some really cool stuff I made for a strange aim.</p>
|
||||
|
||||
<p>To install a ubuntu with GUI is my all preparation work. I found to way to do this.</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="http://www.armhf.com/boards/odroid-xu/">armhf</a> is a website for arm-based ubuntu. It has a detailed instruction to follow at <a href="http://www.armhf.com/boards/odroid-xu/odroid-sd-install/">here</a>. They also provide ubuntu 12.04/ 14.04 and debian 7.5 to choose. But unfortunately odroid xu’s hdmi output doesn’t supported by ubuntu native firmware. So install ubuntu-desktop might can’t be boot up for video output.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Burn images is much easy to install a pre-complied ubuntu system. I found this on odroid xu’s forum, which contains xubuntu image [<a href="http://odroid.in/ubuntu_14.04lts/ubuntu-14.04lts-xubuntu-odroid-xu-20140714.img.xz">download</a>] for odroid xu. With this image, you just need to use dd command to write whole system mirror into sdcard.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># If .img end with xz, use this command to uncompress first</span>
|
||||
unxz ubuntu-14.04lts-xubuntu-odroid-xu-20140714.img.xz
|
||||
<span class="c"># Burn image into SD-card</span>
|
||||
<span class="nb">sudo dd </span><span class="k">if</span><span class="o">=</span>ubuntu-14.04lts-xubuntu-odroid-xu-20140714.img <span class="nv">of</span><span class="o">=</span>/dev/sdb <span class="nv">bs</span><span class="o">=</span>1M <span class="nv">conv</span><span class="o">=</span>fsync
|
||||
<span class="nb">sync</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<h1 id="2016-11">2016-11</h1>
|
||||
|
||||
<h2 id="android-kernel">Android Kernel</h2>
|
||||
|
||||
<h3 id="how-to-build-an-android-kernel">How to build an Android Kernel?</h3>
|
||||
|
||||
<p>Generally, I won’t tell anything in this parts, just mark some related links, and point out some mistakes or error solutions.</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="http://source.android.com/source/building-kernels.html#figuring-out-which-kernel-to-build">Google Official Guide</a>
|
||||
– If you don’t have AOSP sources, you have to download prebuilt toolchains which recommended in this guide might not be correct. Use following links to choose your fitting tools.
|
||||
— <a href="https://android.googlesource.com/?format=HTML">ASOP git root</a>, under sub class “/platform/prebuilts/gcc”</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://softwarebakery.com/building-the-android-kernel-on-linux">Packing and Flashing a Boot.img</a> <strong>[highly recommend]</strong></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="2016-12">2016-12</h1>
|
||||
|
||||
<h2 id="android-kernel-1">Android Kernel</h2>
|
||||
|
||||
<h3 id="how-to-compile-with-ftrace">How to compile with ftrace?</h3>
|
||||
|
||||
<p>If we want to debug under android, ftrace is a great tool for working. But, ftrace is not available in android if we used default configure file. Android kernel configuration is in <strong>arch/arm64/kernel/configs</strong>. We need to add few lines under that.</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CONFIG_STRICT_MEMORY_RWX</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_FUNCTION_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_FUNCTION_GRAPH_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_DYNAMIC_FTRACE</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_PERSISTENT_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_IRQSOFF_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_PREEMPT_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_SCHED_TRACER</span><span class="o">=</span>y
|
||||
<span class="nv">CONFIG_STACK_TRACER</span><span class="o">=</span>y
|
||||
</code></pre></div></div>
|
||||
|
||||
<h3 id="how-to-extract-android-images-dump-an-image">How to extract android images: Dump an image</h3>
|
||||
|
||||
<p>If we want to hold a rooted status after flashing boot, we need to extract an image from android devices. We can first use following command to find which blocks belongs to. According to some references, <a href="http://forum.xda-developers.com/showthread.php?t=2450045">this article</a> provide three ways to dump an image, I picked one for easy using.</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>adb shell
|
||||
<span class="nb">ls</span> <span class="nt">-al</span> /dev/block/platform/<span class="nv">$SOME</span><span class="se">\_</span>DEVICE../../by-name <span class="c"># {Partitions} -> {Device Block}</span>
|
||||
|
||||
<span class="c"># dump file</span>
|
||||
su
|
||||
<span class="nb">dd </span><span class="k">if</span><span class="o">=</span>/dev/block/mmcblk0p37 <span class="nv">of</span><span class="o">=</span>/sdcard/boot.img
|
||||
</code></pre></div></div>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<div class="post-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = 'codersherlockblog'; // required: replace example with your forum shortname
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="assets/mstile-150x150.png"/>
|
||||
<TileColor>#b91d47</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 655 B |
|
After Width: | Height: | Size: 931 B |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<style type="text/css">
|
||||
.st0{fill:#515151;}
|
||||
</style>
|
||||
<path class="st0" d="M1.7,22.3c5.7-5.7,11.3-5.7,17,0c3.3-3.3,3.5-5.3,0.8-6c2.7,0.7,3.5-1.1,2.3-5.6s-3.3-5.2-6.3-2.1
|
||||
c3-3,2.3-5.2-2.1-6.3S7,1.8,7.7,4.6C7,1.8,5,2.1,1.7,5.3C7.3,11,7.3,16.7,1.7,22.3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 423 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2735 6469 c-98 -14 -126 -21 -178 -38 -188 -66 -289 -166 -332 -327
|
||||
-15 -58 -22 -232 -11 -284 3 -14 8 -41 11 -60 5 -32 4 -31 -10 10 -31 86 -104
|
||||
227 -143 277 -51 64 -127 119 -199 144 -69 25 -189 31 -255 13 -27 -7 -48 -11
|
||||
-48 -9 0 2 -33 -8 -72 -22 -193 -67 -452 -232 -702 -446 -27 -23 -60 -51 -73
|
||||
-62 -14 -11 -70 -63 -126 -116 l-101 -96 66 -69 c90 -94 114 -121 178 -194 30
|
||||
-35 60 -68 66 -74 5 -6 53 -65 105 -131 374 -471 603 -905 724 -1370 33 -127
|
||||
37 -148 56 -270 24 -157 33 -457 17 -620 -54 -579 -307 -1149 -767 -1729 -98
|
||||
-125 -114 -144 -196 -235 -54 -59 -60 -66 -120 -132 l-40 -44 50 46 c76 71
|
||||
104 96 175 158 36 31 70 61 76 66 14 13 72 60 154 125 36 28 73 57 83 65 9 8
|
||||
21 15 26 15 5 0 11 3 13 8 14 34 381 264 578 362 167 84 435 191 518 206 13 3
|
||||
42 11 65 18 23 8 56 17 72 20 17 4 41 9 55 12 81 16 185 33 245 39 39 4 81 8
|
||||
95 11 32 5 334 5 380 -1 19 -2 58 -7 86 -10 29 -3 62 -8 75 -10 13 -3 44 -8
|
||||
69 -11 25 -3 53 -8 62 -10 10 -3 29 -7 42 -10 113 -20 342 -93 501 -159 112
|
||||
-46 346 -164 406 -205 24 -16 48 -30 52 -30 20 0 346 -230 487 -343 173 -139
|
||||
259 -215 403 -355 l99 -96 102 104 c55 58 128 136 161 174 33 37 65 73 70 80
|
||||
32 36 129 163 181 236 301 423 344 745 130 953 -63 61 -216 145 -326 180 -8 2
|
||||
-1 2 15 0 284 -42 449 -5 574 129 105 111 163 330 155 588 -3 110 -13 245 -19
|
||||
275 -5 23 -14 82 -21 140 -3 22 -14 81 -24 130 -11 50 -21 101 -24 115 -6 36
|
||||
-75 311 -85 340 -5 14 -19 59 -31 100 -24 82 -74 227 -95 275 -7 17 -26 62
|
||||
-43 100 -147 339 -345 550 -573 610 -263 70 -586 -69 -944 -404 -57 -54 -54
|
||||
-41 5 19 35 35 140 171 186 240 109 162 183 332 199 455 7 51 8 158 2 185 -2
|
||||
8 -7 33 -12 55 -28 141 -168 324 -330 430 -47 31 -213 125 -221 125 -2 0 -32
|
||||
13 -66 29 -134 61 -322 122 -543 178 -33 8 -67 16 -75 18 -25 7 -303 65 -330
|
||||
70 -14 2 -45 7 -70 10 -25 3 -70 10 -100 15 -30 5 -80 12 -110 16 -79 9 -396
|
||||
12 -455 3z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1 @@
|
||||
window.TEXT_SEARCH_DATA={'posts':[{'title':"Stop Talking is the worst title of one blog",'url':"/posts/welcome-to-my-blog"},{'title':"Using charles proxy to monitor mobile SSL traffics",'url':"/posts/charles-is-not-a-good-tool"},{'title':"Some of my previews experiment works: 2016",'url':"/posts/some-of-my-previews-exper-work"},{'title':"Xv6 introduction",'url':"/posts/intro-xv6"},{'title':"Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries",'url':"/posts/generate-word-cloud-with-chinese-fenci"},{'title':"EDDL: How do we train neural networks on limited edge devices - PART 1",'url':"/posts/eddl-how-do-we-train-on-limited-edge-devices"}]};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "TeXt Theme",
|
||||
"short_name": "TeXt Theme",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Category « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//category/">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="home">
|
||||
<h1 class="page-heading">Category</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2 class="category" id="Network">NETWORK</h2>
|
||||
<ul>
|
||||
|
||||
<li><span>Oct 27, 2016</span> » <a href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 class="category" id="Nonsense">NONSENSE</h2>
|
||||
<ul>
|
||||
|
||||
<li><span>Oct 26, 2016</span> » <a href="/archivers/hello">Stop Talking is the worst title of one blog</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 class="category" id="Research">RESEARCH</h2>
|
||||
<ul>
|
||||
|
||||
<li><span>Oct 13, 2021</span> » <a href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><span>Oct 28, 2016</span> » <a href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 class="category" id="visualization">VISUALIZATION</h2>
|
||||
<ul>
|
||||
|
||||
<li><span>Sep 15, 2020</span> » <a href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 class="category" id="xv6">XV6</h2>
|
||||
<ul>
|
||||
|
||||
<li><span>Jul 28, 2017</span> » <a href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,296 +0,0 @@
|
||||
body { margin: 0; font-family: "Arial"; font-size: 15px; line-height: 1.35; }
|
||||
|
||||
a { text-decoration: none; color: #036; }
|
||||
|
||||
a:hover, a:focus { text-decoration: underline; color: #069; }
|
||||
|
||||
blockquote { background: #FFF; margin: 0; padding: 5px 20px; border-left: 10px solid #CCC; }
|
||||
|
||||
code, pre { font-family: "Courier New"; font-size: 12px; }
|
||||
|
||||
code { color: #900; background-color: #fff; padding: 2px 5px; border-radius: 5px; }
|
||||
|
||||
pre { overflow-x: auto; padding: 20px 50px; }
|
||||
|
||||
pre, pre code { color: #fafafa; background-color: #223; }
|
||||
|
||||
pre code { padding: 0; }
|
||||
|
||||
.hide { display: none; }
|
||||
|
||||
.center { text-align: center; }
|
||||
|
||||
table { border-collapse: collapse; border-spacing: 0; margin: 10pt auto; background: #FFF; }
|
||||
|
||||
table td, table th { border: 1px solid #CCC; padding: 5px 15px; margin: 0; }
|
||||
|
||||
table th { border-color: #555; background: #555; color: #eee; font-weight: normal; }
|
||||
|
||||
table tr:hover { background: rgba(255, 255, 0, 0.2); }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 { font-weight: normal; }
|
||||
|
||||
.wrapper { margin: 0 auto; max-width: 1100px; }
|
||||
|
||||
@media (max-width: 1120px) { .wrapper { max-width: 800px; } }
|
||||
|
||||
.header { line-height: 30px; background-color: black; padding: 10px; margin: 0; }
|
||||
|
||||
.header:after { clear: both; content: ' '; display: block; }
|
||||
|
||||
.header .site-title { float: left; color: white; text-decoration: none; font-size: 15px; line-height: 30px; }
|
||||
|
||||
.header .site-nav { text-align: right; }
|
||||
|
||||
.header .site-nav a { text-decoration: none; color: white; padding: 10px 20px; white-space: nowrap; }
|
||||
|
||||
.header .site-nav a:hover, .header .site-nav a:focus { background: black; }
|
||||
|
||||
.page-content { background: #e0e0e3; padding: 30px 0; }
|
||||
|
||||
.page-content .wrapper { position: relative; background: #FAFAFA; box-shadow: 0 1px 4px #999; outline: 1px solid #CCC; }
|
||||
|
||||
.page-content .wrapper:after { clear: both; content: ''; display: block; }
|
||||
|
||||
.page-content .wrapper:before { content: ''; display: block; position: absolute; width: 300px; height: 100%; left: 800px; top: 0; background: #EEE; }
|
||||
|
||||
.page-content img { max-width: 100%; }
|
||||
|
||||
.col-main { position: relative; box-sizing: border-box; padding: 30px; width: 800px; float: left; }
|
||||
|
||||
.col-second { position: relative; box-sizing: border-box; float: left; width: 300px; padding: 20px; background: #EEE; z-index: 10; }
|
||||
|
||||
.col-box { color: #666; font-size: 15px; padding-bottom: 20px; }
|
||||
|
||||
.col-box p { margin: 0; }
|
||||
|
||||
.col-box ul { padding-left: 20px; margin: 0; }
|
||||
|
||||
.col-box:not(:first-child) { border-top: 1px solid #ccc; padding-top: 20px; }
|
||||
|
||||
.col-box .col-box-title { color: #333; margin-bottom: 10px; font-size: 16.5px; }
|
||||
|
||||
@media (max-width: 1120px) { .page-content .wrapper:before { display: none; } .col-main, .col-second { width: auto; float: none; } .col-box { width: 50%; float: left; margin-bottom: 10px; } .col-box:not(:first-child) { border-top: none; padding-top: 0; } .col-second:after { clear: both; display: block; content: ' '; } }
|
||||
|
||||
.col-box-author { text-align: center; }
|
||||
|
||||
.col-box-author .avatar { width: 135px; height: 135px; border-radius: 100%; margin: 20px auto; display: block; }
|
||||
|
||||
.col-box-author .name { font-size: 15px; }
|
||||
|
||||
.col-box-author .contact { margin-top: 10px; }
|
||||
|
||||
.col-box-author .contact a { background: #999; color: #eee; padding: 5px 10px; text-decoration: none; border-radius: 5px; white-space: nowrap; }
|
||||
|
||||
.col-box-author .contact a:hover { transition: background 0.3s ease; background: #666; }
|
||||
|
||||
.footer { padding: 60px 0; background-color: #e0e0e3; text-align: center; color: #666; font-size: 15px; }
|
||||
|
||||
.post .post-header { margin: 0 100px; margin-bottom: 40px; padding: 0px; }
|
||||
|
||||
.post .post-header .post-title { font-size: 40px; font-weight: normal; margin: 0 -100px; }
|
||||
|
||||
@media screen and (max-width: 600px) { .post .post-header .post-title { font-size: 34px; } }
|
||||
|
||||
.post .post-header .post-meta { color: #999; font-size: 15px; margin: 0 -100px; }
|
||||
|
||||
@media screen and (max-width: 600px) { .post .post-header { text-align: center; margin-bottom: 10px; padding: 10px; } }
|
||||
|
||||
.post .post-content { color: #333; }
|
||||
|
||||
.post .post-content h1, .post .post-content h2, .post .post-content h3, .post .post-content h4, .post .post-content h5, .post .post-content h6 { color: #000; }
|
||||
|
||||
.post .post-content h1 { font-size: xx-large; }
|
||||
|
||||
.post .post-content h1, .post .post-content h2 { margin-bottom: 10px; margin-top: 30px; }
|
||||
|
||||
.post .post-content h1, .post .post-content h2, .post .post-content h3 { border-bottom: 1px dotted #3f3f3f; }
|
||||
|
||||
.post .post-content pre { margin: 0 -30px; }
|
||||
|
||||
@media screen and (max-width: 600px) { .post .post-content pre { margin: 0 -10px; } }
|
||||
|
||||
.post .post-content .middle-image { display: block; margin-left: auto; margin-right: auto; }
|
||||
|
||||
.post .post-comments { padding-top: 30px; }
|
||||
|
||||
.home .page-heading { font-size: 40px; font-weight: normal; margin: 0px; }
|
||||
|
||||
@media screen and (max-width: 600px) { .home .page-heading { margin: 10px; font-size: 34px; } }
|
||||
|
||||
.home .rss-link { float: right; text-decoration: none; border: 1px solid; color: #999; background: #fff; font-size: 10.5px; padding: 1px 8px; }
|
||||
|
||||
.home .rss-link:hover, .home .rss-link:focus { color: #666; }
|
||||
|
||||
.home .post-list { margin: 0; padding: 10px 0px; list-style: none; }
|
||||
|
||||
.home .post-list > li { padding-bottom: 5px; border-bottom: 2px dotted #3f3f3f; margin-bottom: 5px; }
|
||||
|
||||
.home .post-list .post-title { font-size: 28px; font-weight: bold; margin: 0; }
|
||||
|
||||
.home .post-list .post-meta { font-size: 15px; color: #aaaaaa; margin: 0 0px; margin-bottom: .5em; }
|
||||
|
||||
.home .post-list .post-excerpt { margin: 0 0px; }
|
||||
|
||||
.home .post-list .post-excerpt, .home .post-list .post-excerpt * { font-size: 15px; line-height: 16.5px; padding-top: 0; padding-bottom: 0; color: #333; }
|
||||
|
||||
.home .post-list .post-excerpt code, .home .post-list .post-excerpt pre, .home .post-list .post-excerpt pre * { color: #666; background-color: #eee; }
|
||||
|
||||
.home .post-list .post-excerpt th { border-color: #ccc; background-color: #ccc; }
|
||||
|
||||
.home .post-list .post-excerpt a { color: #002335; }
|
||||
|
||||
.home .post-list .post-excerpt img { display: block; margin: 1em auto; max-height: 16em; opacity: .7; transition: opacity .3s; }
|
||||
|
||||
.home .post-list .post-excerpt img:hover { opacity: 1; }
|
||||
|
||||
@media screen and (max-width: 600px) { .home .post-list { padding: 10px; } }
|
||||
|
||||
.home .pagination { text-align: center; text-decoration: none; color: #666; margin: 30px 0; }
|
||||
|
||||
.home .pagination .page_number { margin: 0 30px; }
|
||||
|
||||
.home .pagination .previous, .home .pagination .next { padding: 10px 20px; white-space: nowrap; }
|
||||
|
||||
.home .pagination a.previous, .home .pagination a.next { color: #333; border-radius: 20px; border: 1px solid #CCC; }
|
||||
|
||||
.home .pagination a.previous:hover, .home .pagination a.next:hover { background: #fefefe; color: #000; text-decoration: none; }
|
||||
|
||||
@media screen and (max-width: 800px) { .page-content { padding: 0; } .footer { padding: 15px 0; } }
|
||||
|
||||
@media screen and (max-width: 600px) { .header, .header .site-nav { text-align: center; } .header .site-title { float: none; } .col-main { padding: 10px; } .col-box { width: 100%; float: none; margin-bottom: 20px; } pre { padding: 10px; } }
|
||||
|
||||
/* Monokai Theme from https://github.com/richleland/pygments-css/blob/master/monokai.css */
|
||||
.highlight { /* Comment */ /* Error */ /* Keyword */ /* Literal */ /* Name */ /* Operator */ /* Punctuation */ /* Comment.Multiline */ /* Comment.Preproc */ /* Comment.Single */ /* Comment.Special */ /* Generic.Emph */ /* Generic.Strong */ /* Keyword.Constant */ /* Keyword.Declaration */ /* Keyword.Namespace */ /* Keyword.Pseudo */ /* Keyword.Reserved */ /* Keyword.Type */ /* Literal.Date */ /* Literal.Number */ /* Literal.String */ /* Name.Attribute */ /* Name.Builtin */ /* Name.Class */ /* Name.Constant */ /* Name.Decorator */ /* Name.Entity */ /* Name.Exception */ /* Name.Function */ /* Name.Label */ /* Name.Namespace */ /* Name.Other */ /* Name.Property */ /* Name.Tag */ /* Name.Variable */ /* Operator.Word */ /* Text.Whitespace */ /* Literal.Number.Float */ /* Literal.Number.Hex */ /* Literal.Number.Integer */ /* Literal.Number.Oct */ /* Literal.String.Backtick */ /* Literal.String.Char */ /* Literal.String.Doc */ /* Literal.String.Double */ /* Literal.String.Escape */ /* Literal.String.Heredoc */ /* Literal.String.Interpol */ /* Literal.String.Other */ /* Literal.String.Regex */ /* Literal.String.Single */ /* Literal.String.Symbol */ /* Name.Builtin.Pseudo */ /* Name.Variable.Class */ /* Name.Variable.Global */ /* Name.Variable.Instance */ /* Literal.Number.Integer.Long */ /* Generic Heading & Diff Header */ /* Generic.Subheading & Diff Unified/Comment? */ /* Generic.Deleted & Diff Deleted */ /* Generic.Inserted & Diff Inserted */ }
|
||||
|
||||
.highlight .hll { background-color: #49483e; }
|
||||
|
||||
.highlight .c { color: #75715e; }
|
||||
|
||||
.highlight .err { color: #960050; background-color: #1e0010; }
|
||||
|
||||
.highlight .k { color: #66d9ef; }
|
||||
|
||||
.highlight .l { color: #ae81ff; }
|
||||
|
||||
.highlight .n { color: #f8f8f2; }
|
||||
|
||||
.highlight .o { color: #f92672; }
|
||||
|
||||
.highlight .p { color: #f8f8f2; }
|
||||
|
||||
.highlight .cm { color: #75715e; }
|
||||
|
||||
.highlight .cp { color: #75715e; }
|
||||
|
||||
.highlight .c1 { color: #75715e; }
|
||||
|
||||
.highlight .cs { color: #75715e; }
|
||||
|
||||
.highlight .ge { font-style: italic; }
|
||||
|
||||
.highlight .gs { font-weight: bold; }
|
||||
|
||||
.highlight .kc { color: #66d9ef; }
|
||||
|
||||
.highlight .kd { color: #66d9ef; }
|
||||
|
||||
.highlight .kn { color: #f92672; }
|
||||
|
||||
.highlight .kp { color: #66d9ef; }
|
||||
|
||||
.highlight .kr { color: #66d9ef; }
|
||||
|
||||
.highlight .kt { color: #66d9ef; }
|
||||
|
||||
.highlight .ld { color: #e6db74; }
|
||||
|
||||
.highlight .m { color: #ae81ff; }
|
||||
|
||||
.highlight .s { color: #e6db74; }
|
||||
|
||||
.highlight .na { color: #a6e22e; }
|
||||
|
||||
.highlight .nb { color: #f8f8f2; }
|
||||
|
||||
.highlight .nc { color: #a6e22e; }
|
||||
|
||||
.highlight .no { color: #66d9ef; }
|
||||
|
||||
.highlight .nd { color: #a6e22e; }
|
||||
|
||||
.highlight .ni { color: #f8f8f2; }
|
||||
|
||||
.highlight .ne { color: #a6e22e; }
|
||||
|
||||
.highlight .nf { color: #a6e22e; }
|
||||
|
||||
.highlight .nl { color: #f8f8f2; }
|
||||
|
||||
.highlight .nn { color: #f8f8f2; }
|
||||
|
||||
.highlight .nx { color: #a6e22e; }
|
||||
|
||||
.highlight .py { color: #f8f8f2; }
|
||||
|
||||
.highlight .nt { color: #f92672; }
|
||||
|
||||
.highlight .nv { color: #f8f8f2; }
|
||||
|
||||
.highlight .ow { color: #f92672; }
|
||||
|
||||
.highlight .w { color: #f8f8f2; }
|
||||
|
||||
.highlight .mf { color: #ae81ff; }
|
||||
|
||||
.highlight .mh { color: #ae81ff; }
|
||||
|
||||
.highlight .mi { color: #ae81ff; }
|
||||
|
||||
.highlight .mo { color: #ae81ff; }
|
||||
|
||||
.highlight .sb { color: #e6db74; }
|
||||
|
||||
.highlight .sc { color: #e6db74; }
|
||||
|
||||
.highlight .sd { color: #e6db74; }
|
||||
|
||||
.highlight .s2 { color: #e6db74; }
|
||||
|
||||
.highlight .se { color: #ae81ff; }
|
||||
|
||||
.highlight .sh { color: #e6db74; }
|
||||
|
||||
.highlight .si { color: #e6db74; }
|
||||
|
||||
.highlight .sx { color: #e6db74; }
|
||||
|
||||
.highlight .sr { color: #e6db74; }
|
||||
|
||||
.highlight .s1 { color: #e6db74; }
|
||||
|
||||
.highlight .ss { color: #e6db74; }
|
||||
|
||||
.highlight .bp { color: #f8f8f2; }
|
||||
|
||||
.highlight .vc { color: #f8f8f2; }
|
||||
|
||||
.highlight .vg { color: #f8f8f2; }
|
||||
|
||||
.highlight .vi { color: #f8f8f2; }
|
||||
|
||||
.highlight .il { color: #ae81ff; }
|
||||
|
||||
.highlight .gu { color: #75715e; }
|
||||
|
||||
.highlight .gd { color: #f92672; }
|
||||
|
||||
.highlight .gi { color: #a6e22e; }
|
||||
|
||||
.page-content .wrapper .post-toc > ul { overflow: auto; }
|
||||
|
||||
.util-notify1 { position: absolute; z-index: 100; background: rgba(0, 0, 0, 0.7); color: #FFF; padding: 5px 10px; font-size: 14px; pointer-events: none; opacity: 1; transition: .2s ease; }
|
||||
|
||||
.util-notify1.hidden { opacity: 0; display: none; }
|
||||
|
||||
/*# sourceMappingURL=main.css.map */
|
||||
@@ -1,235 +0,0 @@
|
||||
.timeline{
|
||||
--uiTimelineMainColor: var(--timelineMainColor, #35008a);
|
||||
--uiTimelineSecondaryColor: var(--timelineSecondaryColor, #fff);
|
||||
--uiTimelineDateColor: var(--timelineYearColor, #1470ff);
|
||||
|
||||
position: relative;
|
||||
/* padding-top: 3rem; */
|
||||
/* padding-bottom: 3rem; */
|
||||
}
|
||||
|
||||
.timeline:before{
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background-color: var(--uiTimelineMainColor);
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.timeline__group{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline__group:not(:first-of-type){
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.timeline__group:last-of-type{
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.timeline__year{
|
||||
padding: .5rem 1.5rem;
|
||||
color: var(--uiTimelineSecondaryColor);
|
||||
background-color: var(--uiTimelineMainColor);
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.timeline__box{
|
||||
position: relative;
|
||||
bottom: 6rem;
|
||||
}
|
||||
|
||||
.timeline__box:not(:last-of-type){
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.timeline__box:before{
|
||||
content: "";
|
||||
/* width: 100%; */
|
||||
width: auto;
|
||||
height: 2px;
|
||||
background-color: var(--uiTimelineMainColor);
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.timeline__date{
|
||||
min-width: 65px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
box-sizing: border-box;
|
||||
padding: .5rem 1.5rem;
|
||||
text-align: center;
|
||||
|
||||
background-color: var(--uiTimelineDateColor);
|
||||
color: var(--uiTimelineSecondaryColor);
|
||||
}
|
||||
|
||||
.timeline__day{
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.timeline__month{
|
||||
display: block;
|
||||
font-size: .8em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.timeline__post{
|
||||
padding: 1.5rem 1rem 1.5rem 1rem;
|
||||
border-radius: 2px;
|
||||
border-left: 3px solid var(--uiTimelineMainColor);
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 1px 2px 0 rgba(0, 0, 0, .24);
|
||||
background-color: var(--uiTimelineSecondaryColor);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 641px){
|
||||
|
||||
.timeline:before{
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
.timeline__group{
|
||||
padding-top: 55px;
|
||||
}
|
||||
|
||||
.timeline__box{
|
||||
padding-left: 80px;
|
||||
}
|
||||
|
||||
.timeline__box:before{
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.timeline__date{
|
||||
top: 50%;
|
||||
margin-top: -27px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px){
|
||||
|
||||
.timeline:before{
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.timeline__group{
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.timeline__box{
|
||||
padding-left: 20px;
|
||||
padding-top: 70px;
|
||||
}
|
||||
|
||||
.timeline__box:before{
|
||||
top: 90px;
|
||||
}
|
||||
|
||||
.timeline__date{
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline{
|
||||
--timelineMainColor: #4557bb;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px){
|
||||
|
||||
html{
|
||||
font-size: 62.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px){
|
||||
|
||||
html{
|
||||
font-size: 55%;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* demo page
|
||||
*/
|
||||
|
||||
@media screen and (min-width: 768px){
|
||||
|
||||
html{
|
||||
font-size: 62.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px){
|
||||
|
||||
html{
|
||||
font-size: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.page{
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page__demo{
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.main-container{
|
||||
max-width: 960px;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.page__container{
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.footer{
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
text-align: center;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.footer__link{
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 361px){
|
||||
|
||||
.footer__container{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 360px){
|
||||
|
||||
.melnik909{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*!
|
||||
* EasyBook Jekyll Theme Javascript
|
||||
*
|
||||
* http://laobubu.github.io/jekyll-theme-EasyBook
|
||||
* https://github.com/laobubu/jekyll-theme-EasyBook
|
||||
*
|
||||
* This is just a extension for my theme.
|
||||
*/
|
||||
|
||||
function TOCize(toc, content, matchHeightTo) {
|
||||
if (!(toc && content && matchHeightTo)) return false
|
||||
|
||||
var cnt = 0;
|
||||
|
||||
var make = function(tag) {
|
||||
return document.createElement(tag)
|
||||
}
|
||||
|
||||
var aniscroll = {
|
||||
to: function(top) {
|
||||
aniscroll.target = top;
|
||||
if (aniscroll.running) return;
|
||||
aniscroll.running = setInterval(aniscroll.tick, 20);
|
||||
},
|
||||
target: 0,
|
||||
running: 0,
|
||||
getTop: function() {
|
||||
return window.scrollY || window.pageYOffset || document.documentElement.scrollTop;
|
||||
},
|
||||
setTop: function(value) {
|
||||
(window['scrollTo'] && window.scrollTo(window.scrollX, value))
|
||||
},
|
||||
tick: function() {
|
||||
var oldST = aniscroll.getTop(), newST = ~~((oldST + aniscroll.target) / 2);
|
||||
aniscroll.setTop(newST);
|
||||
if (aniscroll.getTop() < newST || Math.abs(newST - aniscroll.target) < 10) {
|
||||
aniscroll.setTop(aniscroll.target);
|
||||
clearInterval(aniscroll.running)
|
||||
aniscroll.running = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToHeader(header, hash, ev) {
|
||||
var y = header.getBoundingClientRect().top + aniscroll.getTop();
|
||||
if (window.history['pushState']) {
|
||||
window.history.pushState({}, header.textContent, "#" + hash);
|
||||
aniscroll.to(y);
|
||||
ev.preventDefault();
|
||||
} else {
|
||||
var y2 = aniscroll.getTop();
|
||||
setTimeout(function() {
|
||||
aniscroll.setTop(y2);
|
||||
aniscroll.to(y);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
var generateLink = function(h) {
|
||||
var q = make('a');
|
||||
cnt++;
|
||||
var hash = h.getAttribute('id');
|
||||
if (!hash) {
|
||||
hash = ('generated-hash-' + cnt);
|
||||
h.setAttribute('id', hash);
|
||||
}
|
||||
q.textContent = h.textContent;
|
||||
q.setAttribute('href', '#' + hash );
|
||||
q.addEventListener('click', scrollToHeader.bind(this, h, hash), false);
|
||||
return q;
|
||||
};
|
||||
|
||||
var hs = content.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||
var cul = null, plevel = 1;
|
||||
var uls = [make('ul')];
|
||||
for (var i=0;i<hs.length;i++) {
|
||||
var level = +hs[i].tagName.substr(1);
|
||||
var hi = hs[i];
|
||||
var ti = make('li');
|
||||
ti.appendChild(generateLink(hi));
|
||||
if (plevel < level) {
|
||||
do {
|
||||
uls.push(make('ul'));
|
||||
uls[uls.length-2].appendChild(uls[uls.length-1]);
|
||||
} while (++plevel < level);
|
||||
} else if (plevel > level) {
|
||||
do {
|
||||
cul = uls.pop();
|
||||
} while (--plevel > level);
|
||||
}
|
||||
cul = uls[uls.length-1];
|
||||
cul.appendChild(ti);
|
||||
}
|
||||
while(true) {
|
||||
var chs = uls[0].children;
|
||||
if (chs.length == 1 && chs[0].tagName == 'UL')
|
||||
uls.shift();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cnt) return false;
|
||||
|
||||
var scrolldummy=make('div');
|
||||
toc.appendChild(scrolldummy);
|
||||
toc.appendChild(uls[0]);
|
||||
toc.style.display = 'block';
|
||||
|
||||
var maxHeightTOC = '';
|
||||
var ppc = document.querySelector('.col-main');
|
||||
var s1 = function(){
|
||||
var scrollTop=aniscroll.getTop(), dummyClientTop=scrolldummy.getBoundingClientRect().top,
|
||||
margin = 10,c,d; // c = dummyHeight, d = TOC.maxHeight (+'px')
|
||||
if ((c = -dummyClientTop + margin) < 0) c = 0;
|
||||
if (c) {
|
||||
var wh = window.innerHeight
|
||||
|| document.documentElement.clientHeight
|
||||
|| document.body.clientHeight,
|
||||
cbox = matchHeightTo.getBoundingClientRect(),
|
||||
vq = cbox.bottom - dummyClientTop - uls[0].offsetHeight;
|
||||
if (c>vq) c=vq;
|
||||
d = (wh - (margin<<1)) + 'px';
|
||||
} else {
|
||||
d = "";
|
||||
}
|
||||
if (d != maxHeightTOC) { //status lock.
|
||||
maxHeightTOC = d;
|
||||
if (d) {
|
||||
uls[0].setAttribute('style', 'max-height:' + d + '; width:' + (toc.offsetWidth-20) + "px" );
|
||||
} else {
|
||||
uls[0].setAttribute("style","");
|
||||
}
|
||||
}
|
||||
scrolldummy.style.height = (c+'px');
|
||||
};
|
||||
window.addEventListener('scroll', s1, false);
|
||||
window.addEventListener('resize', s1, false);
|
||||
}
|
||||
|
||||
function SelectAllize(selector,tips) {
|
||||
if (!window.getSelection) return null;
|
||||
|
||||
var obj = document.querySelectorAll(selector);
|
||||
var selection=window.getSelection();
|
||||
var z = document.createElement("div");
|
||||
z.className = "util-notify1";
|
||||
z.textContent = tips;
|
||||
document.body.appendChild(z)
|
||||
|
||||
function hide() {
|
||||
z.classList.add('hidden')
|
||||
z.style.top = '-200px'
|
||||
}
|
||||
|
||||
hide();
|
||||
z.addEventListener('mouseover', hide, false);
|
||||
|
||||
function clickHandler(e){
|
||||
if (!selection.isCollapsed) return;
|
||||
|
||||
var tt = e.pageY-z.offsetHeight - 15;
|
||||
z.setAttribute('style', 'left:' + (e.pageX-z.offsetWidth/2) + 'px;top:' + (tt+10) + 'px');
|
||||
z.classList.remove('hidden');
|
||||
setTimeout(hide, 1000);
|
||||
}
|
||||
|
||||
function dblClickHandler(e){
|
||||
selection.selectAllChildren(this);
|
||||
hide();
|
||||
}
|
||||
|
||||
for(var i = obj.length; i--;) {
|
||||
var oi = obj[i];
|
||||
oi.addEventListener('click', clickHandler, false);
|
||||
oi.addEventListener('dblclick', dblClickHandler, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function RealLoad(){
|
||||
TOCize(
|
||||
document.querySelector('.post-toc'),
|
||||
document.querySelector('.post-content'),
|
||||
document.querySelector('.col-main')
|
||||
);
|
||||
|
||||
SelectAllize("pre.highlight", "Dblclick to select all");
|
||||
|
||||
var imgs = document.querySelectorAll('.post-content > p > img');
|
||||
for(var i=imgs.length; i--;){
|
||||
if (imgs[i].parentElement.childNodes.length === 1) {
|
||||
imgs[i].classList.add('middle-image');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RealLoad();
|
||||
@@ -1,322 +0,0 @@
|
||||
/**
|
||||
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
;(function(window, document) {
|
||||
/*jshint evil:true */
|
||||
/** version */
|
||||
var version = '3.7.2';
|
||||
|
||||
/** Preset options */
|
||||
var options = window.html5 || {};
|
||||
|
||||
/** Used to skip problem elements */
|
||||
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
|
||||
|
||||
/** Not all elements can be cloned in IE **/
|
||||
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
|
||||
|
||||
/** Detect whether the browser supports default html5 styles */
|
||||
var supportsHtml5Styles;
|
||||
|
||||
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
||||
var expando = '_html5shiv';
|
||||
|
||||
/** The id for the the documents expando */
|
||||
var expanID = 0;
|
||||
|
||||
/** Cached data for each document */
|
||||
var expandoData = {};
|
||||
|
||||
/** Detect whether the browser supports unknown elements */
|
||||
var supportsUnknownElements;
|
||||
|
||||
(function() {
|
||||
try {
|
||||
var a = document.createElement('a');
|
||||
a.innerHTML = '<xyz></xyz>';
|
||||
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
|
||||
supportsHtml5Styles = ('hidden' in a);
|
||||
|
||||
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
||||
// assign a false positive if unable to shiv
|
||||
(document.createElement)('a');
|
||||
var frag = document.createDocumentFragment();
|
||||
return (
|
||||
typeof frag.cloneNode == 'undefined' ||
|
||||
typeof frag.createDocumentFragment == 'undefined' ||
|
||||
typeof frag.createElement == 'undefined'
|
||||
);
|
||||
}());
|
||||
} catch(e) {
|
||||
// assign a false positive if detection fails => unable to shiv
|
||||
supportsHtml5Styles = true;
|
||||
supportsUnknownElements = true;
|
||||
}
|
||||
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Creates a style sheet with the given CSS text and adds it to the document.
|
||||
* @private
|
||||
* @param {Document} ownerDocument The document.
|
||||
* @param {String} cssText The CSS text.
|
||||
* @returns {StyleSheet} The style element.
|
||||
*/
|
||||
function addStyleSheet(ownerDocument, cssText) {
|
||||
var p = ownerDocument.createElement('p'),
|
||||
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
||||
|
||||
p.innerHTML = 'x<style>' + cssText + '</style>';
|
||||
return parent.insertBefore(p.lastChild, parent.firstChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of `html5.elements` as an array.
|
||||
* @private
|
||||
* @returns {Array} An array of shived element node names.
|
||||
*/
|
||||
function getElements() {
|
||||
var elements = html5.elements;
|
||||
return typeof elements == 'string' ? elements.split(' ') : elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the built-in list of html5 elements
|
||||
* @memberOf html5
|
||||
* @param {String|Array} newElements whitespace separated list or array of new element names to shiv
|
||||
* @param {Document} ownerDocument The context document.
|
||||
*/
|
||||
function addElements(newElements, ownerDocument) {
|
||||
var elements = html5.elements;
|
||||
if(typeof elements != 'string'){
|
||||
elements = elements.join(' ');
|
||||
}
|
||||
if(typeof newElements != 'string'){
|
||||
newElements = newElements.join(' ');
|
||||
}
|
||||
html5.elements = elements +' '+ newElements;
|
||||
shivDocument(ownerDocument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data associated to the given document
|
||||
* @private
|
||||
* @param {Document} ownerDocument The document.
|
||||
* @returns {Object} An object of data.
|
||||
*/
|
||||
function getExpandoData(ownerDocument) {
|
||||
var data = expandoData[ownerDocument[expando]];
|
||||
if (!data) {
|
||||
data = {};
|
||||
expanID++;
|
||||
ownerDocument[expando] = expanID;
|
||||
expandoData[expanID] = data;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a shived element for the given nodeName and document
|
||||
* @memberOf html5
|
||||
* @param {String} nodeName name of the element
|
||||
* @param {Document} ownerDocument The context document.
|
||||
* @returns {Object} The shived element.
|
||||
*/
|
||||
function createElement(nodeName, ownerDocument, data){
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
if(supportsUnknownElements){
|
||||
return ownerDocument.createElement(nodeName);
|
||||
}
|
||||
if (!data) {
|
||||
data = getExpandoData(ownerDocument);
|
||||
}
|
||||
var node;
|
||||
|
||||
if (data.cache[nodeName]) {
|
||||
node = data.cache[nodeName].cloneNode();
|
||||
} else if (saveClones.test(nodeName)) {
|
||||
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
||||
} else {
|
||||
node = data.createElem(nodeName);
|
||||
}
|
||||
|
||||
// Avoid adding some elements to fragments in IE < 9 because
|
||||
// * Attributes like `name` or `type` cannot be set/changed once an element
|
||||
// is inserted into a document/fragment
|
||||
// * Link elements with `src` attributes that are inaccessible, as with
|
||||
// a 403 response, will cause the tab/window to crash
|
||||
// * Script elements appended to fragments will execute when their `src`
|
||||
// or `text` property is set
|
||||
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a shived DocumentFragment for the given document
|
||||
* @memberOf html5
|
||||
* @param {Document} ownerDocument The context document.
|
||||
* @returns {Object} The shived DocumentFragment.
|
||||
*/
|
||||
function createDocumentFragment(ownerDocument, data){
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
if(supportsUnknownElements){
|
||||
return ownerDocument.createDocumentFragment();
|
||||
}
|
||||
data = data || getExpandoData(ownerDocument);
|
||||
var clone = data.frag.cloneNode(),
|
||||
i = 0,
|
||||
elems = getElements(),
|
||||
l = elems.length;
|
||||
for(;i<l;i++){
|
||||
clone.createElement(elems[i]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
|
||||
* @private
|
||||
* @param {Document|DocumentFragment} ownerDocument The document.
|
||||
* @param {Object} data of the document.
|
||||
*/
|
||||
function shivMethods(ownerDocument, data) {
|
||||
if (!data.cache) {
|
||||
data.cache = {};
|
||||
data.createElem = ownerDocument.createElement;
|
||||
data.createFrag = ownerDocument.createDocumentFragment;
|
||||
data.frag = data.createFrag();
|
||||
}
|
||||
|
||||
|
||||
ownerDocument.createElement = function(nodeName) {
|
||||
//abort shiv
|
||||
if (!html5.shivMethods) {
|
||||
return data.createElem(nodeName);
|
||||
}
|
||||
return createElement(nodeName, ownerDocument, data);
|
||||
};
|
||||
|
||||
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
|
||||
'var n=f.cloneNode(),c=n.createElement;' +
|
||||
'h.shivMethods&&(' +
|
||||
// unroll the `createElement` calls
|
||||
getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
|
||||
data.createElem(nodeName);
|
||||
data.frag.createElement(nodeName);
|
||||
return 'c("' + nodeName + '")';
|
||||
}) +
|
||||
');return n}'
|
||||
)(html5, data.frag);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Shivs the given document.
|
||||
* @memberOf html5
|
||||
* @param {Document} ownerDocument The document to shiv.
|
||||
* @returns {Document} The shived document.
|
||||
*/
|
||||
function shivDocument(ownerDocument) {
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
var data = getExpandoData(ownerDocument);
|
||||
|
||||
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
||||
data.hasCSS = !!addStyleSheet(ownerDocument,
|
||||
// corrects block display not defined in IE6/7/8/9
|
||||
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
|
||||
// adds styling not present in IE6/7/8/9
|
||||
'mark{background:#FF0;color:#000}' +
|
||||
// hides non-rendered elements
|
||||
'template{display:none}'
|
||||
);
|
||||
}
|
||||
if (!supportsUnknownElements) {
|
||||
shivMethods(ownerDocument, data);
|
||||
}
|
||||
return ownerDocument;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The `html5` object is exposed so that more elements can be shived and
|
||||
* existing shiving can be detected on iframes.
|
||||
* @type Object
|
||||
* @example
|
||||
*
|
||||
* // options can be changed before the script is included
|
||||
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
|
||||
*/
|
||||
var html5 = {
|
||||
|
||||
/**
|
||||
* An array or space separated string of node names of the elements to shiv.
|
||||
* @memberOf html5
|
||||
* @type Array|String
|
||||
*/
|
||||
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
|
||||
|
||||
/**
|
||||
* current version of html5shiv
|
||||
*/
|
||||
'version': version,
|
||||
|
||||
/**
|
||||
* A flag to indicate that the HTML5 style sheet should be inserted.
|
||||
* @memberOf html5
|
||||
* @type Boolean
|
||||
*/
|
||||
'shivCSS': (options.shivCSS !== false),
|
||||
|
||||
/**
|
||||
* Is equal to true if a browser supports creating unknown/HTML5 elements
|
||||
* @memberOf html5
|
||||
* @type boolean
|
||||
*/
|
||||
'supportsUnknownElements': supportsUnknownElements,
|
||||
|
||||
/**
|
||||
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
|
||||
* methods should be overwritten.
|
||||
* @memberOf html5
|
||||
* @type Boolean
|
||||
*/
|
||||
'shivMethods': (options.shivMethods !== false),
|
||||
|
||||
/**
|
||||
* A string to describe the type of `html5` object ("default" or "default print").
|
||||
* @memberOf html5
|
||||
* @type String
|
||||
*/
|
||||
'type': 'default',
|
||||
|
||||
// shivs the document according to the specified `html5` object options
|
||||
'shivDocument': shivDocument,
|
||||
|
||||
//creates a shived element
|
||||
createElement: createElement,
|
||||
|
||||
//creates a shived documentFragment
|
||||
createDocumentFragment: createDocumentFragment,
|
||||
|
||||
//extends list of elements
|
||||
addElements: addElements
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// expose html5
|
||||
window.html5 = html5;
|
||||
|
||||
// shiv the document
|
||||
shivDocument(document);
|
||||
|
||||
}(this, document));
|
||||
@@ -1,353 +0,0 @@
|
||||
/* Respond.js: min/max-width media query polyfill. (c) Scott Jehl. MIT Lic. j.mp/respondjs */
|
||||
(function( w ){
|
||||
|
||||
"use strict";
|
||||
|
||||
//exposed namespace
|
||||
var respond = {};
|
||||
w.respond = respond;
|
||||
|
||||
//define update even in native-mq-supporting browsers, to avoid errors
|
||||
respond.update = function(){};
|
||||
|
||||
//define ajax obj
|
||||
var requestQueue = [],
|
||||
xmlHttp = (function() {
|
||||
var xmlhttpmethod = false;
|
||||
try {
|
||||
xmlhttpmethod = new w.XMLHttpRequest();
|
||||
}
|
||||
catch( e ){
|
||||
xmlhttpmethod = new w.ActiveXObject( "Microsoft.XMLHTTP" );
|
||||
}
|
||||
return function(){
|
||||
return xmlhttpmethod;
|
||||
};
|
||||
})(),
|
||||
|
||||
//tweaked Ajax functions from Quirksmode
|
||||
ajax = function( url, callback ) {
|
||||
var req = xmlHttp();
|
||||
if (!req){
|
||||
return;
|
||||
}
|
||||
req.open( "GET", url, true );
|
||||
req.onreadystatechange = function () {
|
||||
if ( req.readyState !== 4 || req.status !== 200 && req.status !== 304 ){
|
||||
return;
|
||||
}
|
||||
callback( req.responseText );
|
||||
};
|
||||
if ( req.readyState === 4 ){
|
||||
return;
|
||||
}
|
||||
req.send( null );
|
||||
},
|
||||
isUnsupportedMediaQuery = function( query ) {
|
||||
return query.replace( respond.regex.minmaxwh, '' ).match( respond.regex.other );
|
||||
};
|
||||
|
||||
//expose for testing
|
||||
respond.ajax = ajax;
|
||||
respond.queue = requestQueue;
|
||||
respond.unsupportedmq = isUnsupportedMediaQuery;
|
||||
respond.regex = {
|
||||
media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
|
||||
keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
|
||||
comments: /\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,
|
||||
urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
|
||||
findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
|
||||
only: /(only\s+)?([a-zA-Z]+)\s?/,
|
||||
minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
|
||||
maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
|
||||
minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
|
||||
other: /\([^\)]*\)/g
|
||||
};
|
||||
|
||||
//expose media query support flag for external use
|
||||
respond.mediaQueriesSupported = w.matchMedia && w.matchMedia( "only all" ) !== null && w.matchMedia( "only all" ).matches;
|
||||
|
||||
//if media queries are supported, exit here
|
||||
if( respond.mediaQueriesSupported ){
|
||||
return;
|
||||
}
|
||||
|
||||
//define vars
|
||||
var doc = w.document,
|
||||
docElem = doc.documentElement,
|
||||
mediastyles = [],
|
||||
rules = [],
|
||||
appendedEls = [],
|
||||
parsedSheets = {},
|
||||
resizeThrottle = 30,
|
||||
head = doc.getElementsByTagName( "head" )[0] || docElem,
|
||||
base = doc.getElementsByTagName( "base" )[0],
|
||||
links = head.getElementsByTagName( "link" ),
|
||||
|
||||
lastCall,
|
||||
resizeDefer,
|
||||
|
||||
//cached container for 1em value, populated the first time it's needed
|
||||
eminpx,
|
||||
|
||||
// returns the value of 1em in pixels
|
||||
getEmValue = function() {
|
||||
var ret,
|
||||
div = doc.createElement('div'),
|
||||
body = doc.body,
|
||||
originalHTMLFontSize = docElem.style.fontSize,
|
||||
originalBodyFontSize = body && body.style.fontSize,
|
||||
fakeUsed = false;
|
||||
|
||||
div.style.cssText = "position:absolute;font-size:1em;width:1em";
|
||||
|
||||
if( !body ){
|
||||
body = fakeUsed = doc.createElement( "body" );
|
||||
body.style.background = "none";
|
||||
}
|
||||
|
||||
// 1em in a media query is the value of the default font size of the browser
|
||||
// reset docElem and body to ensure the correct value is returned
|
||||
docElem.style.fontSize = "100%";
|
||||
body.style.fontSize = "100%";
|
||||
|
||||
body.appendChild( div );
|
||||
|
||||
if( fakeUsed ){
|
||||
docElem.insertBefore( body, docElem.firstChild );
|
||||
}
|
||||
|
||||
ret = div.offsetWidth;
|
||||
|
||||
if( fakeUsed ){
|
||||
docElem.removeChild( body );
|
||||
}
|
||||
else {
|
||||
body.removeChild( div );
|
||||
}
|
||||
|
||||
// restore the original values
|
||||
docElem.style.fontSize = originalHTMLFontSize;
|
||||
if( originalBodyFontSize ) {
|
||||
body.style.fontSize = originalBodyFontSize;
|
||||
}
|
||||
|
||||
|
||||
//also update eminpx before returning
|
||||
ret = eminpx = parseFloat(ret);
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
//enable/disable styles
|
||||
applyMedia = function( fromResize ){
|
||||
var name = "clientWidth",
|
||||
docElemProp = docElem[ name ],
|
||||
currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
|
||||
styleBlocks = {},
|
||||
lastLink = links[ links.length-1 ],
|
||||
now = (new Date()).getTime();
|
||||
|
||||
//throttle resize calls
|
||||
if( fromResize && lastCall && now - lastCall < resizeThrottle ){
|
||||
w.clearTimeout( resizeDefer );
|
||||
resizeDefer = w.setTimeout( applyMedia, resizeThrottle );
|
||||
return;
|
||||
}
|
||||
else {
|
||||
lastCall = now;
|
||||
}
|
||||
|
||||
for( var i in mediastyles ){
|
||||
if( mediastyles.hasOwnProperty( i ) ){
|
||||
var thisstyle = mediastyles[ i ],
|
||||
min = thisstyle.minw,
|
||||
max = thisstyle.maxw,
|
||||
minnull = min === null,
|
||||
maxnull = max === null,
|
||||
em = "em";
|
||||
|
||||
if( !!min ){
|
||||
min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
|
||||
}
|
||||
if( !!max ){
|
||||
max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
|
||||
}
|
||||
|
||||
// if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
|
||||
if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
|
||||
if( !styleBlocks[ thisstyle.media ] ){
|
||||
styleBlocks[ thisstyle.media ] = [];
|
||||
}
|
||||
styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remove any existing respond style element(s)
|
||||
for( var j in appendedEls ){
|
||||
if( appendedEls.hasOwnProperty( j ) ){
|
||||
if( appendedEls[ j ] && appendedEls[ j ].parentNode === head ){
|
||||
head.removeChild( appendedEls[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
appendedEls.length = 0;
|
||||
|
||||
//inject active styles, grouped by media type
|
||||
for( var k in styleBlocks ){
|
||||
if( styleBlocks.hasOwnProperty( k ) ){
|
||||
var ss = doc.createElement( "style" ),
|
||||
css = styleBlocks[ k ].join( "\n" );
|
||||
|
||||
ss.type = "text/css";
|
||||
ss.media = k;
|
||||
|
||||
//originally, ss was appended to a documentFragment and sheets were appended in bulk.
|
||||
//this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
|
||||
head.insertBefore( ss, lastLink.nextSibling );
|
||||
|
||||
if ( ss.styleSheet ){
|
||||
ss.styleSheet.cssText = css;
|
||||
}
|
||||
else {
|
||||
ss.appendChild( doc.createTextNode( css ) );
|
||||
}
|
||||
|
||||
//push to appendedEls to track for later removal
|
||||
appendedEls.push( ss );
|
||||
}
|
||||
}
|
||||
},
|
||||
//find media blocks in css text, convert to style blocks
|
||||
translate = function( styles, href, media ){
|
||||
var qs = styles.replace( respond.regex.comments, '' )
|
||||
.replace( respond.regex.keyframes, '' )
|
||||
.match( respond.regex.media ),
|
||||
ql = qs && qs.length || 0;
|
||||
|
||||
//try to get CSS path
|
||||
href = href.substring( 0, href.lastIndexOf( "/" ) );
|
||||
|
||||
var repUrls = function( css ){
|
||||
return css.replace( respond.regex.urls, "$1" + href + "$2$3" );
|
||||
},
|
||||
useMedia = !ql && media;
|
||||
|
||||
//if path exists, tack on trailing slash
|
||||
if( href.length ){ href += "/"; }
|
||||
|
||||
//if no internal queries exist, but media attr does, use that
|
||||
//note: this currently lacks support for situations where a media attr is specified on a link AND
|
||||
//its associated stylesheet has internal CSS media queries.
|
||||
//In those cases, the media attribute will currently be ignored.
|
||||
if( useMedia ){
|
||||
ql = 1;
|
||||
}
|
||||
|
||||
for( var i = 0; i < ql; i++ ){
|
||||
var fullq, thisq, eachq, eql;
|
||||
|
||||
//media attr
|
||||
if( useMedia ){
|
||||
fullq = media;
|
||||
rules.push( repUrls( styles ) );
|
||||
}
|
||||
//parse for styles
|
||||
else{
|
||||
fullq = qs[ i ].match( respond.regex.findStyles ) && RegExp.$1;
|
||||
rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
|
||||
}
|
||||
|
||||
eachq = fullq.split( "," );
|
||||
eql = eachq.length;
|
||||
|
||||
for( var j = 0; j < eql; j++ ){
|
||||
thisq = eachq[ j ];
|
||||
|
||||
if( isUnsupportedMediaQuery( thisq ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mediastyles.push( {
|
||||
media : thisq.split( "(" )[ 0 ].match( respond.regex.only ) && RegExp.$2 || "all",
|
||||
rules : rules.length - 1,
|
||||
hasquery : thisq.indexOf("(") > -1,
|
||||
minw : thisq.match( respond.regex.minw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
|
||||
maxw : thisq.match( respond.regex.maxw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
applyMedia();
|
||||
},
|
||||
|
||||
//recurse through request queue, get css text
|
||||
makeRequests = function(){
|
||||
if( requestQueue.length ){
|
||||
var thisRequest = requestQueue.shift();
|
||||
|
||||
ajax( thisRequest.href, function( styles ){
|
||||
translate( styles, thisRequest.href, thisRequest.media );
|
||||
parsedSheets[ thisRequest.href ] = true;
|
||||
|
||||
// by wrapping recursive function call in setTimeout
|
||||
// we prevent "Stack overflow" error in IE7
|
||||
w.setTimeout(function(){ makeRequests(); },0);
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
//loop stylesheets, send text content to translate
|
||||
ripCSS = function(){
|
||||
|
||||
for( var i = 0; i < links.length; i++ ){
|
||||
var sheet = links[ i ],
|
||||
href = sheet.href,
|
||||
media = sheet.media,
|
||||
isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
|
||||
|
||||
//only links plz and prevent re-parsing
|
||||
if( !!href && isCSS && !parsedSheets[ href ] ){
|
||||
// selectivizr exposes css through the rawCssText expando
|
||||
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
|
||||
translate( sheet.styleSheet.rawCssText, href, media );
|
||||
parsedSheets[ href ] = true;
|
||||
} else {
|
||||
if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) ||
|
||||
href.replace( RegExp.$1, "" ).split( "/" )[0] === w.location.host ){
|
||||
// IE7 doesn't handle urls that start with '//' for ajax request
|
||||
// manually add in the protocol
|
||||
if ( href.substring(0,2) === "//" ) { href = w.location.protocol + href; }
|
||||
requestQueue.push( {
|
||||
href: href,
|
||||
media: media
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
makeRequests();
|
||||
};
|
||||
|
||||
//translate CSS
|
||||
ripCSS();
|
||||
|
||||
//expose update for re-running respond later on
|
||||
respond.update = ripCSS;
|
||||
|
||||
//expose getEmValue
|
||||
respond.getEmValue = getEmValue;
|
||||
|
||||
//adjust on resize
|
||||
function callMedia(){
|
||||
applyMedia( true );
|
||||
}
|
||||
|
||||
if( w.addEventListener ){
|
||||
w.addEventListener( "resize", callMedia, false );
|
||||
}
|
||||
else if( w.attachEvent ){
|
||||
w.attachEvent( "onresize", callMedia );
|
||||
}
|
||||
})(this);
|
||||
@@ -1,166 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//page2/">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="home">
|
||||
<a class="rss-link" href="/feed.xml">RSS Feed</a>
|
||||
<h1 class="page-heading">Articles</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
|
||||
<li>
|
||||
<h2>
|
||||
<a class="post-link" href="/archivers/hello">Stop Talking is the worst title of one blog</a>
|
||||
</h2>
|
||||
|
||||
<div class="post-meta">Oct 26, 2016</div>
|
||||
|
||||
<div class="post-excerpt">
|
||||
|
||||
|
||||
<p>
|
||||
<a class="post-link" href="/archivers/hello">Read More »</a>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<!-- Pagination links -->
|
||||
<div class="pagination">
|
||||
|
||||
<a href="/" class="previous">PREV</a>
|
||||
|
||||
<span class="page_number ">2 of 2</span>
|
||||
|
||||
<span class="next ">NEXT</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,974 @@
|
||||
<!DOCTYPE html><html lang="en">
|
||||
<head><meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Using charles proxy to monitor mobile SSL traffics - Stop Talking, Start Doing</title>
|
||||
|
||||
<meta name="description" content="In this blog, I will generally talk about how to use proper tools to monitor SSL traffics of a mobile devices. Currently, I only can dealing with those SSL t...">
|
||||
<link rel="canonical" href="http://localhost:4000/posts/charles-is-not-a-good-tool"><link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="/feed.xml"><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico">
|
||||
|
||||
<meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<!-- end favicons snippet --><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css" ><!-- start custom head snippets -->
|
||||
|
||||
<!-- end custom head snippets -->
|
||||
<script>(function() {
|
||||
window.isArray = function(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
};
|
||||
window.isString = function(val) {
|
||||
return typeof val === 'string';
|
||||
};
|
||||
|
||||
window.hasEvent = function(event) {
|
||||
return 'on'.concat(event) in window.document;
|
||||
};
|
||||
|
||||
window.isOverallScroller = function(node) {
|
||||
return node === document.documentElement || node === document.body || node === window;
|
||||
};
|
||||
|
||||
window.isFormElement = function(node) {
|
||||
var tagName = node.tagName;
|
||||
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
||||
};
|
||||
|
||||
window.pageLoad = (function () {
|
||||
var loaded = false, cbs = [];
|
||||
window.addEventListener('load', function () {
|
||||
var i;
|
||||
loaded = true;
|
||||
if (cbs.length > 0) {
|
||||
for (i = 0; i < cbs.length; i++) {
|
||||
cbs[i]();
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
then: function(cb) {
|
||||
cb && (loaded ? cb() : (cbs.push(cb)));
|
||||
}
|
||||
};
|
||||
})();
|
||||
})();
|
||||
(function() {
|
||||
window.throttle = function(func, wait) {
|
||||
var args, result, thisArg, timeoutId, lastCalled = 0;
|
||||
|
||||
function trailingCall() {
|
||||
lastCalled = new Date;
|
||||
timeoutId = null;
|
||||
result = func.apply(thisArg, args);
|
||||
}
|
||||
return function() {
|
||||
var now = new Date,
|
||||
remaining = wait - (now - lastCalled);
|
||||
|
||||
args = arguments;
|
||||
thisArg = this;
|
||||
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
lastCalled = now;
|
||||
result = func.apply(thisArg, args);
|
||||
} else if (!timeoutId) {
|
||||
timeoutId = setTimeout(trailingCall, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
})();
|
||||
(function() {
|
||||
var Set = (function() {
|
||||
var add = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (data[i] === item) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.size ++;
|
||||
data.push(item);
|
||||
return data;
|
||||
};
|
||||
|
||||
var Set = function(data) {
|
||||
this.size = 0;
|
||||
this._data = [];
|
||||
var i;
|
||||
if (data.length > 0) {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
add.call(this, data[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Set.prototype.add = add;
|
||||
Set.prototype.get = function(index) { return this._data[index]; };
|
||||
Set.prototype.has = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.get(i) === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Set.prototype.is = function(map) {
|
||||
if (map._data.length !== this._data.length) { return false; }
|
||||
var i, j, flag, tData = this._data, mData = map._data;
|
||||
for (i = 0; i < tData.length; i++) {
|
||||
for (flag = false, j = 0; j < mData.length; j++) {
|
||||
if (tData[i] === mData[j]) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Set.prototype.values = function() {
|
||||
return this._data;
|
||||
};
|
||||
return Set;
|
||||
})();
|
||||
|
||||
window.Lazyload = (function(doc) {
|
||||
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
||||
var createNode = function(name, attrs) {
|
||||
var node = doc.createElement(name), attr;
|
||||
for (attr in attrs) {
|
||||
if (attrs.hasOwnProperty(attr)) {
|
||||
node.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
var end = function(type, url) {
|
||||
var s, q, qi, cbs, i, j, cur, val, flag;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
s[url] = true;
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (cur.urls.has(url)) {
|
||||
qi = cur, val = qi.urls.values();
|
||||
qi && (cbs = qi.callbacks);
|
||||
for (flag = true, j = 0; j < val.length; j++) {
|
||||
cur = val[j];
|
||||
if (!s[cur]) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
if (flag && cbs && cbs.length > 0) {
|
||||
for (j = 0; j < cbs.length; j++) {
|
||||
cbs[j].call(context);
|
||||
}
|
||||
qi.load = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var load = function(type, urls, callback) {
|
||||
var s, q, qi, node, i, cur,
|
||||
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (_urls.is(cur.urls)) {
|
||||
qi = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = _urls.values();
|
||||
if (qi) {
|
||||
callback && (qi.load || qi.callbacks.push(callback));
|
||||
callback && (qi.load && callback());
|
||||
} else {
|
||||
q.push({
|
||||
urls: _urls,
|
||||
callbacks: callback ? [callback] : [],
|
||||
load: false
|
||||
});
|
||||
for (i = 0; i < val.length; i++) {
|
||||
node = null, url = val[i];
|
||||
if (s[url] === undefined) {
|
||||
(type === 'js' ) && (node = createNode('script', { src: url }));
|
||||
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
||||
if (node) {
|
||||
node.onload = (function(type, url) {
|
||||
return function() {
|
||||
end(type, url);
|
||||
};
|
||||
})(type, url);
|
||||
(doc.head || doc.body).appendChild(node);
|
||||
s[url] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
js: function(url, callback) {
|
||||
load('js', url, callback);
|
||||
},
|
||||
css: function(url, callback) {
|
||||
load('css', url, callback);
|
||||
}
|
||||
};
|
||||
})(this.document);
|
||||
})();
|
||||
</script><script>
|
||||
(function() {
|
||||
var TEXT_VARIABLES = {
|
||||
version: '2.2.6',
|
||||
sources: {
|
||||
font_awesome: 'https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css',
|
||||
jquery: 'https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js',
|
||||
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
||||
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
||||
gitalk: {
|
||||
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
||||
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
||||
},
|
||||
valine: 'https://unpkg.com/valine/dist/Valine.min.js',
|
||||
mathjax: 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML',
|
||||
mermaid: 'https://cdn.bootcss.com/mermaid/8.0.0-rc.8/mermaid.min.js'
|
||||
},
|
||||
site: {
|
||||
toc: {
|
||||
selectors: 'h1,h2,h3'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
search_js: '/assets/search.js'
|
||||
}
|
||||
};
|
||||
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="root" data-is-touch="false">
|
||||
<div class="layout--page js-page-root"><div class="page__main js-page-main page__viewport has-aside cell cell--auto">
|
||||
|
||||
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
||||
<div class="header__title">
|
||||
<div class="header__brand"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<style type="text/css">
|
||||
.st0{fill:#515151;}
|
||||
</style>
|
||||
<path class="st0" d="M1.7,22.3c5.7-5.7,11.3-5.7,17,0c3.3-3.3,3.5-5.3,0.8-6c2.7,0.7,3.5-1.1,2.3-5.6s-3.3-5.2-6.3-2.1
|
||||
c3-3,2.3-5.2-2.1-6.3S7,1.8,7.7,4.6C7,1.8,5,2.1,1.7,5.3C7.3,11,7.3,16.7,1.7,22.3"/>
|
||||
</svg>
|
||||
<a title="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
" href="/">Stop Talking, Start Doing</a></div><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></div><nav class="navigation">
|
||||
<ul><li class="navigation__item"><a href="/archive.html">Archive</a></li><li class="navigation__item"><a href="/about.html">About</a></li><li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li></ul>
|
||||
</nav></div>
|
||||
</header>
|
||||
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
||||
|
||||
<div class="col-aside d-print-none js-col-aside"><aside class="page__aside js-page-aside"><div class="toc-aside js-toc-root"></div>
|
||||
</aside></div>
|
||||
|
||||
<div class="col-main cell cell--auto"><!-- start custom main top snippet -->
|
||||
|
||||
<!-- end custom main top snippet -->
|
||||
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1>Using charles proxy to monitor mobile SSL traffics</h1></header><span class="split-space"> </span>
|
||||
<a class="edit-on-github"
|
||||
title="Edit on Github"
|
||||
href="https://github.com/CoderSherlock/CoderSherlock.github.io/tree/master/_posts/2016-10-27-charles-is-not-a-good-tool.md">
|
||||
<i class="far fa-edit"></i></a></div><meta itemprop="headline" content="Using charles proxy to monitor mobile SSL traffics"><div class="article__info clearfix"><ul class="right-col menu"><li><i class="far fa-calendar-alt"></i> <span>Oct 27, 2016</span>
|
||||
</li></ul></div><meta itemprop="author" content="Pengzhan Hao"/><meta itemprop="datePublished" content="2016-10-27T22:50:33-04:00"><div class="js-article-content"><div class="layout--article"><!-- start custom article top snippet -->
|
||||
|
||||
<!-- end custom article top snippet -->
|
||||
<div class="article__content" itemprop="articleBody"><p>In this blog, I will generally talk about how to use proper tools to monitor SSL traffics of a mobile devices. Currently, I only can dealing with those SSL traffics which use an obviously certification. Some applications may not using system root cert or they doesn’t provide us a method to modify their own certs. For these situation, I still didn’t find a good solutions for it. But I’ll keep updating this if I get one.<br />
|
||||
My current solution is using AP to forward all SSL traffic to a proxy, <a href="https://www.charlesproxy.com/">charles proxy</a> is my first choice (Prof asked). It’s a non-free software which still update new versions now. So mainly, I’ll talk about how to charles SSL proxy.</p>
|
||||
|
||||
<h3 id="preparations">Preparations</h3>
|
||||
<ul>
|
||||
<li>Monitor device situation: Linux Machine with wireless adapter</li>
|
||||
<li>Download the newest version(4.0.1) of charles</li>
|
||||
<li>Target android devices with root privilege</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="install-charles-and-configuration">Install Charles and Configuration</h3>
|
||||
|
||||
<ul>
|
||||
<li>You have to install charles first. After downloading the charles proxy, you have to unzip it and configure some basic settings.</li>
|
||||
</ul>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># open charles first</span>
|
||||
./bin/charles
|
||||
</code></pre></div></div>
|
||||
<ul>
|
||||
<li>Save charles’ private key and public key</li>
|
||||
</ul>
|
||||
|
||||
<p>In Help -> SSL Proxying -> Export Charles Root Certificate and Private Key, enter a password and save the public and private key in *.p12 format.<br />
|
||||
You also need to save charles Root Certificate, it also contains in the same menu. For convience, save it as *.pem format.</p>
|
||||
|
||||
<ul>
|
||||
<li>Set Proxy and SSL Proxy</li>
|
||||
</ul>
|
||||
</div><section class="article__sharing d-print-none"></section><div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2016-10-27T22:50:33-04:00"><!-- start custom article footer snippet -->
|
||||
|
||||
<!-- end custom article footer snippet -->
|
||||
<div class="article__subscribe"><div class="subscribe"><i class="fas fa-rss"></i> <a type="application/rss+xml" href="/feed.xml">Subscribe</a></div>
|
||||
</div><div class="article__license"></div></footer>
|
||||
<div class="article__section-navigator clearfix"><div class="previous"><span>PREVIOUS</span><a href="/posts/welcome-to-my-blog">Stop Talking is the worst title of one blog</a></div><div class="next"><span>NEXT</span><a href="/posts/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></div></div></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
$(function() {
|
||||
var $this ,$scroll;
|
||||
var $articleContent = $('.js-article-content');
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
||||
$scroll = $(scroll);
|
||||
|
||||
$articleContent.find('.highlight').each(function() {
|
||||
$this = $(this);
|
||||
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
||||
});
|
||||
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
||||
$this = $(this);
|
||||
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
||||
});
|
||||
$articleContent.on('click', '.anchor', function() {
|
||||
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
||||
|
||||
<!-- end custom main bottom snippet -->
|
||||
</div>
|
||||
</div></div></div><div class="page__footer d-print-none">
|
||||
<footer class="footer py-4 js-page-footer">
|
||||
<div class="main"><div itemscope itemtype="http://schema.org/Person">
|
||||
<meta itemprop="name" content="Pengzhan Hao"><meta itemprop="url" content="/"><div class="footer__author-links"><div class="author-links">
|
||||
<ul class="menu menu--nowrap menu--inline"><li title="Send me an Email.">
|
||||
<a class="button button--circle mail-button" itemprop="email" href="mailto:haopengzhan@gmail.com" target="_blank">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</a><li title="Follow me on Github.">
|
||||
<a class="button button--circle github-button" itemprop="sameAs" href="https://github.com/codersherlock" target="_blank">
|
||||
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="svgpath" data-index="path_0" fill="#272636" d="M0 525.2c0 223.6 143.3 413.7 343 483.5 26.9 6.8 22.8-12.4 22.8-25.4l0-88.7c-155.3 18.2-161.5-84.6-172-101.7-21.1-36-70.8-45.2-56-62.3 35.4-18.2 71.4 4.6 113.1 66.3 30.2 44.7 89.1 37.2 119 29.7 6.5-26.9 20.5-50.9 39.7-69.6C248.8 728.2 181.7 630 181.7 513.2c0-56.6 18.7-108.7 55.3-150.7-23.3-69.3 2.2-128.5 5.6-137.3 66.5-6 135.5 47.6 140.9 51.8 37.8-10.2 80.9-15.6 129.1-15.6 48.5 0 91.8 5.6 129.8 15.9 12.9-9.8 77-55.8 138.8-50.2 3.3 8.8 28.2 66.7 6.3 135 37.1 42.1 56 94.6 56 151.4 0 117-67.5 215.3-228.8 243.7 26.9 26.6 43.6 63.4 43.6 104.2l0 128.8c0.9 10.3 0 20.5 17.2 20.5C878.1 942.4 1024 750.9 1024 525.3c0-282.9-229.3-512-512-512C229.1 13.2 0 242.3 0 525.2L0 525.2z" />
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</li></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="site-info mt-2">
|
||||
<div>© Stop Talking, Start Doing 2021,
|
||||
Powered by <a title="Jekyll is a simple, blog-aware, static site generator." href="http://jekyllrb.com/">Jekyll</a> & <a
|
||||
title="TeXt is a super customizable Jekyll theme." href="https://github.com/kitian616/jekyll-TeXt-theme">TeXt Theme</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div></div>
|
||||
</div><script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $body = $('body'), $window = $(window);
|
||||
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
||||
var activeCount = 0;
|
||||
function modal(options) {
|
||||
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
||||
var scrollTop;
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
visible = _options.initialVisible === undefined ? false : show;
|
||||
onChange = _options.onChange;
|
||||
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
||||
}
|
||||
function init() {
|
||||
setState(visible);
|
||||
}
|
||||
function setState(isShow) {
|
||||
if (isShow === visible) {
|
||||
return;
|
||||
}
|
||||
visible = isShow;
|
||||
if (visible) {
|
||||
activeCount++;
|
||||
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
||||
$root.addClass('modal--show');
|
||||
$pageMain.scrollTop(scrollTop);
|
||||
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
||||
$window.on('keyup', handleKeyup);
|
||||
} else {
|
||||
activeCount > 0 && activeCount--;
|
||||
$root.removeClass('modal--show');
|
||||
$window.scrollTop(scrollTop);
|
||||
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
||||
$window.off('keyup', handleKeyup);
|
||||
}
|
||||
onChange && onChange(visible);
|
||||
}
|
||||
function show() {
|
||||
setState(true);
|
||||
}
|
||||
function hide() {
|
||||
setState(false);
|
||||
}
|
||||
function handleKeyup(e) {
|
||||
// Char Code: 27 ESC
|
||||
if (e.which === 27) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
setOptions(options);
|
||||
init();
|
||||
return {
|
||||
show: show,
|
||||
hide: hide,
|
||||
$el: $root
|
||||
};
|
||||
}
|
||||
$.fn.modal = modal;
|
||||
});
|
||||
})();
|
||||
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
||||
(function () {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
// search panel
|
||||
var search = (window.search || (window.search = {}));
|
||||
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
||||
true : window.useDefaultSearchBox ;
|
||||
|
||||
var $searchModal = $('.js-page-search-modal');
|
||||
var $searchToggle = $('.js-search-toggle');
|
||||
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
||||
var modalVisible = false;
|
||||
search.searchModal = searchModal;
|
||||
|
||||
var $searchBox = null;
|
||||
var $searchInput = null;
|
||||
var $searchClear = null;
|
||||
|
||||
function getModalVisible() {
|
||||
return modalVisible;
|
||||
}
|
||||
search.getModalVisible = getModalVisible;
|
||||
|
||||
function handleModalChange(visible) {
|
||||
modalVisible = visible;
|
||||
if (visible) {
|
||||
search.onShow && search.onShow();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
||||
} else {
|
||||
search.onShow && search.onHide();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
||||
setTimeout(function() {
|
||||
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
||||
search.clear && search.clear();
|
||||
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
$searchToggle.on('click', function() {
|
||||
modalVisible ? searchModal.hide() : searchModal.show();
|
||||
});
|
||||
// Char Code: 83 S, 191 /
|
||||
$(window).on('keyup', function(e) {
|
||||
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
||||
modalVisible || searchModal.show();
|
||||
}
|
||||
});
|
||||
|
||||
if (useDefaultSearchBox) {
|
||||
$searchBox = $('.js-search-box');
|
||||
$searchInput = $searchBox.children('input');
|
||||
$searchClear = $searchBox.children('.js-icon-clear');
|
||||
search.getSearchInput = function() {
|
||||
return $searchInput.get(0);
|
||||
};
|
||||
search.getVal = function() {
|
||||
return $searchInput.val();
|
||||
};
|
||||
search.setVal = function(val) {
|
||||
$searchInput.val(val);
|
||||
};
|
||||
|
||||
$searchInput.on('focus', function() {
|
||||
$(this).addClass('focus');
|
||||
});
|
||||
$searchInput.on('blur', function() {
|
||||
$(this).removeClass('focus');
|
||||
});
|
||||
$searchInput.on('input', window.throttle(function() {
|
||||
var val = $(this).val();
|
||||
if (val === '' || typeof val !== 'string') {
|
||||
search.clear && search.clear();
|
||||
} else {
|
||||
$searchBox.addClass('not-empty');
|
||||
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
||||
}
|
||||
}, 400));
|
||||
$searchClear.on('click', function() {
|
||||
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
||||
search.clear && search.clear();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><div class="search search--dark">
|
||||
<div class="main">
|
||||
<div class="search__header">Search</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-box js-search-box">
|
||||
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
||||
<input type="text" />
|
||||
<div class="search-box__icon-clear js-icon-clear">
|
||||
<a><i class="fas fa-times"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
||||
Cancel</button>
|
||||
</div>
|
||||
<div class="search-result js-search-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var PAHTS = window.TEXT_VARIABLES.paths;
|
||||
window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
|
||||
var search = (window.search || (window.search = {}));
|
||||
var searchData = window.TEXT_SEARCH_DATA || {};
|
||||
|
||||
function memorize(f) {
|
||||
var cache = {};
|
||||
return function () {
|
||||
var key = Array.prototype.join.call(arguments, ',');
|
||||
if (key in cache) return cache[key];
|
||||
else return cache[key] = f.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/// search
|
||||
function searchByQuery(query) {
|
||||
var i, j, key, keys, cur, _title, result = {};
|
||||
keys = Object.keys(searchData);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (j = 0; j < searchData[key].length; j++) {
|
||||
cur = searchData[key][j], _title = cur.title;
|
||||
if ((result[key] === undefined || result[key] && result[key].length < 4 )
|
||||
&& _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
result[key].push(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var renderHeader = memorize(function(header) {
|
||||
return $('<p class="search-result__header">' + header + '</p>');
|
||||
});
|
||||
|
||||
var renderItem = function(index, title, url) {
|
||||
return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
|
||||
};
|
||||
|
||||
function render(data) {
|
||||
if (!data) { return null; }
|
||||
var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
|
||||
keys = Object.keys(data);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
$root.append(renderHeader(key));
|
||||
for (j = 0; j < data[key].length; j++) {
|
||||
cur = data[key][j];
|
||||
$root.append(renderItem(itemIndex++, cur.title, cur.url));
|
||||
}
|
||||
}
|
||||
return $root;
|
||||
}
|
||||
|
||||
// search box
|
||||
var $result = $('.js-search-result'), $resultItems;
|
||||
var lastActiveIndex, activeIndex;
|
||||
|
||||
function clear() {
|
||||
$result.html(null);
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
}
|
||||
function onInputNotEmpty(val) {
|
||||
$result.html(render(searchByQuery(val)));
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
$resultItems.eq(0).addClass('active');
|
||||
}
|
||||
|
||||
search.clear = clear;
|
||||
search.onInputNotEmpty = onInputNotEmpty;
|
||||
|
||||
function updateResultItems() {
|
||||
lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
|
||||
activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
|
||||
}
|
||||
|
||||
function moveActiveIndex(direction) {
|
||||
var itemsCount = $resultItems ? $resultItems.length : 0;
|
||||
if (itemsCount > 1) {
|
||||
lastActiveIndex = activeIndex;
|
||||
if (direction === 'up') {
|
||||
activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
|
||||
} else if (direction === 'down') {
|
||||
activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
|
||||
}
|
||||
updateResultItems();
|
||||
}
|
||||
}
|
||||
|
||||
// Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇
|
||||
$(window).on('keyup', function(e) {
|
||||
var modalVisible = search.getModalVisible && search.getModalVisible();
|
||||
if (modalVisible) {
|
||||
if (e.which === 38) {
|
||||
modalVisible && moveActiveIndex('up');
|
||||
} else if (e.which === 40) {
|
||||
modalVisible && moveActiveIndex('down');
|
||||
} else if (e.which === 13) {
|
||||
modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$result.on('mouseover', '.search-result__item > a', function() {
|
||||
var itemIndex = $(this).parent().data('index');
|
||||
itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div></div>
|
||||
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function scrollToAnchor(anchor, duration, callback) {
|
||||
var $root = this;
|
||||
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
||||
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
$.fn.scrollToAnchor = scrollToAnchor;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function affix(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
||||
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
||||
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
||||
hasInit = false, curState;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroll && (scroll = _options.scroll);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$scrollTarget = $(scrollTarget);
|
||||
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
||||
$scroll = $(scroll);
|
||||
}
|
||||
function preCalc() {
|
||||
top();
|
||||
rootHeight = $root.outerHeight();
|
||||
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
||||
rootLeft = $root.offset().left;
|
||||
}
|
||||
function calc(needPreCalc) {
|
||||
needPreCalc && preCalc();
|
||||
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
||||
rootBottomTop = scrollBottom - rootTop;
|
||||
}
|
||||
function top() {
|
||||
if (curState !== 'top') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: 0
|
||||
});
|
||||
curState = 'top';
|
||||
}
|
||||
}
|
||||
function fixed() {
|
||||
if (curState !== 'fixed') {
|
||||
$root.addClass('fixed').css({
|
||||
left: rootLeft + 'px',
|
||||
top: 0
|
||||
});
|
||||
curState = 'fixed';
|
||||
}
|
||||
}
|
||||
function bottom() {
|
||||
if (curState !== 'bottom') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: rootBottomTop + 'px'
|
||||
});
|
||||
curState = 'bottom';
|
||||
}
|
||||
}
|
||||
function setState() {
|
||||
var scrollTop = $scrollTarget.scrollTop();
|
||||
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
||||
fixed();
|
||||
} else if (scrollTop < rootTop) {
|
||||
top();
|
||||
} else {
|
||||
bottom();
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
if(!hasInit) {
|
||||
var interval, timeout;
|
||||
calc(true); setState();
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState();
|
||||
});
|
||||
$window.on('resize', function() {
|
||||
disabled || (calc(true), setState());
|
||||
});
|
||||
hasInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions,
|
||||
refresh: function() {
|
||||
calc(true, { animation: false }); setState();
|
||||
}
|
||||
};
|
||||
}
|
||||
$.fn.affix = affix;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function toc(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
||||
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
||||
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.selectors && (selectors = _options.selectors);
|
||||
_options.container && (container = _options.container);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroller && (scroller = _options.scroller);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$headings = $(container).find(selectors).filter('[id]');
|
||||
$scrollTarget = $(scrollTarget);
|
||||
$scroller = $(scroller);
|
||||
}
|
||||
function calc() {
|
||||
headingsPos = [];
|
||||
$headings.each(function() {
|
||||
headingsPos.push(Math.floor($(this).position().top));
|
||||
});
|
||||
}
|
||||
function setState(element, disabled) {
|
||||
var scrollTop = $scrollTarget.scrollTop(), i;
|
||||
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
||||
if (element) {
|
||||
$activeCur = element;
|
||||
} else {
|
||||
for (i = 0; i < headingsPos.length; i++) {
|
||||
if (scrollTop >= headingsPos[i]) {
|
||||
$activeCur = $tocLi.eq(i);
|
||||
} else {
|
||||
$activeCur || ($activeCur = $tocLi.eq(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$activeLast && $activeLast.removeClass('active');
|
||||
($activeLast = $activeCur).addClass('active');
|
||||
}
|
||||
function render() {
|
||||
if(!hasRendered) {
|
||||
$root.append($tocUl);
|
||||
$headings.each(function() {
|
||||
var $this = $(this);
|
||||
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
||||
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
||||
});
|
||||
$tocLi = $tocUl.children('li');
|
||||
$tocUl.on('click', 'a', function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
scrolling = true;
|
||||
setState($this.parent());
|
||||
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
||||
scrolling = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
hasRendered = true;
|
||||
}
|
||||
function init() {
|
||||
var interval, timeout;
|
||||
if(!hasInit) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState(null, scrolling);
|
||||
});
|
||||
$window.on('resize', window.throttle(function() {
|
||||
if (!disabled) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
}
|
||||
}, 100));
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions
|
||||
};
|
||||
}
|
||||
$.fn.toc = toc;
|
||||
});
|
||||
})();
|
||||
/*(function () {
|
||||
|
||||
})();*/
|
||||
</script><script>
|
||||
/* toc must before affix, since affix need to konw toc' height. */(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $window = $(window);
|
||||
var $articleContent = $('.js-article-content');
|
||||
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
|
||||
var toc;
|
||||
var tocDisabled = false;
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
|
||||
|
||||
function disabled() {
|
||||
return $col2.css('display') === 'none' || !hasToc;
|
||||
}
|
||||
|
||||
tocDisabled = disabled();
|
||||
|
||||
toc = $tocRoot.toc({
|
||||
selectors: TOC_SELECTOR,
|
||||
container: $articleContent,
|
||||
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
||||
scroller: hasSidebar ? '.js-page-main' : null,
|
||||
disabled: tocDisabled
|
||||
});
|
||||
|
||||
$window.on('resize', window.throttle(function() {
|
||||
tocDisabled = disabled();
|
||||
toc && toc.setOptions({
|
||||
disabled: tocDisabled
|
||||
});
|
||||
}, 100));
|
||||
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $window = $(window), $pageFooter = $('.js-page-footer');
|
||||
var $pageAside = $('.js-page-aside');
|
||||
var affix;
|
||||
var tocDisabled = false;
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
|
||||
affix = $pageAside.affix({
|
||||
offsetBottom: $pageFooter.outerHeight(),
|
||||
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
||||
scroller: hasSidebar ? '.js-page-main' : null,
|
||||
scroll: hasSidebar ? $('.js-page-main').children() : null,
|
||||
disabled: tocDisabled
|
||||
});
|
||||
|
||||
$window.on('resize', window.throttle(function() {
|
||||
affix && affix.setOptions({
|
||||
disabled: tocDisabled
|
||||
});
|
||||
}, 100));
|
||||
|
||||
window.pageAsideAffix = affix;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<script>(function () {
|
||||
var $root = document.getElementsByClassName('root')[0];
|
||||
if (window.hasEvent('touchstart')) {
|
||||
$root.dataset.isTouch = true;
|
||||
document.addEventListener('touchstart', function(){}, false);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,950 @@
|
||||
<!DOCTYPE html><html lang="en">
|
||||
<head><meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Stop Talking is the worst title of one blog - Stop Talking, Start Doing</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<link rel="canonical" href="http://localhost:4000/posts/welcome-to-my-blog"><link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="/feed.xml"><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico">
|
||||
|
||||
<meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<!-- end favicons snippet --><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css" ><!-- start custom head snippets -->
|
||||
|
||||
<!-- end custom head snippets -->
|
||||
<script>(function() {
|
||||
window.isArray = function(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
};
|
||||
window.isString = function(val) {
|
||||
return typeof val === 'string';
|
||||
};
|
||||
|
||||
window.hasEvent = function(event) {
|
||||
return 'on'.concat(event) in window.document;
|
||||
};
|
||||
|
||||
window.isOverallScroller = function(node) {
|
||||
return node === document.documentElement || node === document.body || node === window;
|
||||
};
|
||||
|
||||
window.isFormElement = function(node) {
|
||||
var tagName = node.tagName;
|
||||
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
||||
};
|
||||
|
||||
window.pageLoad = (function () {
|
||||
var loaded = false, cbs = [];
|
||||
window.addEventListener('load', function () {
|
||||
var i;
|
||||
loaded = true;
|
||||
if (cbs.length > 0) {
|
||||
for (i = 0; i < cbs.length; i++) {
|
||||
cbs[i]();
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
then: function(cb) {
|
||||
cb && (loaded ? cb() : (cbs.push(cb)));
|
||||
}
|
||||
};
|
||||
})();
|
||||
})();
|
||||
(function() {
|
||||
window.throttle = function(func, wait) {
|
||||
var args, result, thisArg, timeoutId, lastCalled = 0;
|
||||
|
||||
function trailingCall() {
|
||||
lastCalled = new Date;
|
||||
timeoutId = null;
|
||||
result = func.apply(thisArg, args);
|
||||
}
|
||||
return function() {
|
||||
var now = new Date,
|
||||
remaining = wait - (now - lastCalled);
|
||||
|
||||
args = arguments;
|
||||
thisArg = this;
|
||||
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
lastCalled = now;
|
||||
result = func.apply(thisArg, args);
|
||||
} else if (!timeoutId) {
|
||||
timeoutId = setTimeout(trailingCall, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
})();
|
||||
(function() {
|
||||
var Set = (function() {
|
||||
var add = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (data[i] === item) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.size ++;
|
||||
data.push(item);
|
||||
return data;
|
||||
};
|
||||
|
||||
var Set = function(data) {
|
||||
this.size = 0;
|
||||
this._data = [];
|
||||
var i;
|
||||
if (data.length > 0) {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
add.call(this, data[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Set.prototype.add = add;
|
||||
Set.prototype.get = function(index) { return this._data[index]; };
|
||||
Set.prototype.has = function(item) {
|
||||
var i, data = this._data;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.get(i) === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Set.prototype.is = function(map) {
|
||||
if (map._data.length !== this._data.length) { return false; }
|
||||
var i, j, flag, tData = this._data, mData = map._data;
|
||||
for (i = 0; i < tData.length; i++) {
|
||||
for (flag = false, j = 0; j < mData.length; j++) {
|
||||
if (tData[i] === mData[j]) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Set.prototype.values = function() {
|
||||
return this._data;
|
||||
};
|
||||
return Set;
|
||||
})();
|
||||
|
||||
window.Lazyload = (function(doc) {
|
||||
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
||||
var createNode = function(name, attrs) {
|
||||
var node = doc.createElement(name), attr;
|
||||
for (attr in attrs) {
|
||||
if (attrs.hasOwnProperty(attr)) {
|
||||
node.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
var end = function(type, url) {
|
||||
var s, q, qi, cbs, i, j, cur, val, flag;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
s[url] = true;
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (cur.urls.has(url)) {
|
||||
qi = cur, val = qi.urls.values();
|
||||
qi && (cbs = qi.callbacks);
|
||||
for (flag = true, j = 0; j < val.length; j++) {
|
||||
cur = val[j];
|
||||
if (!s[cur]) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
if (flag && cbs && cbs.length > 0) {
|
||||
for (j = 0; j < cbs.length; j++) {
|
||||
cbs[j].call(context);
|
||||
}
|
||||
qi.load = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var load = function(type, urls, callback) {
|
||||
var s, q, qi, node, i, cur,
|
||||
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
||||
if (type === 'js' || type ==='css') {
|
||||
s = sources[type], q = queue[type];
|
||||
for (i = 0; i < q.length; i++) {
|
||||
cur = q[i];
|
||||
if (_urls.is(cur.urls)) {
|
||||
qi = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = _urls.values();
|
||||
if (qi) {
|
||||
callback && (qi.load || qi.callbacks.push(callback));
|
||||
callback && (qi.load && callback());
|
||||
} else {
|
||||
q.push({
|
||||
urls: _urls,
|
||||
callbacks: callback ? [callback] : [],
|
||||
load: false
|
||||
});
|
||||
for (i = 0; i < val.length; i++) {
|
||||
node = null, url = val[i];
|
||||
if (s[url] === undefined) {
|
||||
(type === 'js' ) && (node = createNode('script', { src: url }));
|
||||
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
||||
if (node) {
|
||||
node.onload = (function(type, url) {
|
||||
return function() {
|
||||
end(type, url);
|
||||
};
|
||||
})(type, url);
|
||||
(doc.head || doc.body).appendChild(node);
|
||||
s[url] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
js: function(url, callback) {
|
||||
load('js', url, callback);
|
||||
},
|
||||
css: function(url, callback) {
|
||||
load('css', url, callback);
|
||||
}
|
||||
};
|
||||
})(this.document);
|
||||
})();
|
||||
</script><script>
|
||||
(function() {
|
||||
var TEXT_VARIABLES = {
|
||||
version: '2.2.6',
|
||||
sources: {
|
||||
font_awesome: 'https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.1/css/all.css',
|
||||
jquery: 'https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js',
|
||||
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
||||
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
||||
gitalk: {
|
||||
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
||||
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
||||
},
|
||||
valine: 'https://unpkg.com/valine/dist/Valine.min.js',
|
||||
mathjax: 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML',
|
||||
mermaid: 'https://cdn.bootcss.com/mermaid/8.0.0-rc.8/mermaid.min.js'
|
||||
},
|
||||
site: {
|
||||
toc: {
|
||||
selectors: 'h1,h2,h3'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
search_js: '/assets/search.js'
|
||||
}
|
||||
};
|
||||
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="root" data-is-touch="false">
|
||||
<div class="layout--page js-page-root"><div class="page__main js-page-main page__viewport has-aside cell cell--auto">
|
||||
|
||||
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
||||
<div class="header__title">
|
||||
<div class="header__brand"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24">
|
||||
<style type="text/css">
|
||||
.st0{fill:#515151;}
|
||||
</style>
|
||||
<path class="st0" d="M1.7,22.3c5.7-5.7,11.3-5.7,17,0c3.3-3.3,3.5-5.3,0.8-6c2.7,0.7,3.5-1.1,2.3-5.6s-3.3-5.2-6.3-2.1
|
||||
c3-3,2.3-5.2-2.1-6.3S7,1.8,7.7,4.6C7,1.8,5,2.1,1.7,5.3C7.3,11,7.3,16.7,1.7,22.3"/>
|
||||
</svg>
|
||||
<a title="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
" href="/">Stop Talking, Start Doing</a></div><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></div><nav class="navigation">
|
||||
<ul><li class="navigation__item"><a href="/archive.html">Archive</a></li><li class="navigation__item"><a href="/about.html">About</a></li><li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li></ul>
|
||||
</nav></div>
|
||||
</header>
|
||||
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
||||
|
||||
<div class="col-aside d-print-none js-col-aside"><aside class="page__aside js-page-aside"><div class="toc-aside js-toc-root"></div>
|
||||
</aside></div>
|
||||
|
||||
<div class="col-main cell cell--auto"><!-- start custom main top snippet -->
|
||||
|
||||
<!-- end custom main top snippet -->
|
||||
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1>Stop Talking is the worst title of one blog</h1></header><span class="split-space"> </span>
|
||||
<a class="edit-on-github"
|
||||
title="Edit on Github"
|
||||
href="https://github.com/CoderSherlock/CoderSherlock.github.io/tree/master/_posts/2016-10-26-welcome-to-my-blog.markdown">
|
||||
<i class="far fa-edit"></i></a></div><meta itemprop="headline" content="Stop Talking is the worst title of one blog"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
||||
<a class="button button--secondary button--pill button--sm"
|
||||
href="/archive.html?tag=Nonsense">Nonsense</a>
|
||||
</li></ul><ul class="right-col menu"><li><i class="far fa-calendar-alt"></i> <span>Oct 26, 2016</span>
|
||||
</li></ul></div><meta itemprop="author" content="Pengzhan Hao"/><meta itemprop="datePublished" content="2016-10-26T22:50:33-04:00">
|
||||
<meta itemprop="keywords" content="Nonsense"><div class="js-article-content"><div class="layout--article"><!-- start custom article top snippet -->
|
||||
|
||||
<!-- end custom article top snippet -->
|
||||
<div class="article__content" itemprop="articleBody">
|
||||
</div><section class="article__sharing d-print-none"></section><div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2016-10-26T22:50:33-04:00"><!-- start custom article footer snippet -->
|
||||
|
||||
<!-- end custom article footer snippet -->
|
||||
<div class="article__subscribe"><div class="subscribe"><i class="fas fa-rss"></i> <a type="application/rss+xml" href="/feed.xml">Subscribe</a></div>
|
||||
</div><div class="article__license"></div></footer>
|
||||
<div class="article__section-navigator clearfix"><div class="next"><span>NEXT</span><a href="/posts/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></div></div></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
$(function() {
|
||||
var $this ,$scroll;
|
||||
var $articleContent = $('.js-article-content');
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
||||
$scroll = $(scroll);
|
||||
|
||||
$articleContent.find('.highlight').each(function() {
|
||||
$this = $(this);
|
||||
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
||||
});
|
||||
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
||||
$this = $(this);
|
||||
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
||||
});
|
||||
$articleContent.on('click', '.anchor', function() {
|
||||
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
||||
|
||||
<!-- end custom main bottom snippet -->
|
||||
</div>
|
||||
</div></div></div><div class="page__footer d-print-none">
|
||||
<footer class="footer py-4 js-page-footer">
|
||||
<div class="main"><div itemscope itemtype="http://schema.org/Person">
|
||||
<meta itemprop="name" content="Pengzhan Hao"><meta itemprop="url" content="/"><div class="footer__author-links"><div class="author-links">
|
||||
<ul class="menu menu--nowrap menu--inline"><li title="Send me an Email.">
|
||||
<a class="button button--circle mail-button" itemprop="email" href="mailto:haopengzhan@gmail.com" target="_blank">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</a><li title="Follow me on Github.">
|
||||
<a class="button button--circle github-button" itemprop="sameAs" href="https://github.com/codersherlock" target="_blank">
|
||||
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="svgpath" data-index="path_0" fill="#272636" d="M0 525.2c0 223.6 143.3 413.7 343 483.5 26.9 6.8 22.8-12.4 22.8-25.4l0-88.7c-155.3 18.2-161.5-84.6-172-101.7-21.1-36-70.8-45.2-56-62.3 35.4-18.2 71.4 4.6 113.1 66.3 30.2 44.7 89.1 37.2 119 29.7 6.5-26.9 20.5-50.9 39.7-69.6C248.8 728.2 181.7 630 181.7 513.2c0-56.6 18.7-108.7 55.3-150.7-23.3-69.3 2.2-128.5 5.6-137.3 66.5-6 135.5 47.6 140.9 51.8 37.8-10.2 80.9-15.6 129.1-15.6 48.5 0 91.8 5.6 129.8 15.9 12.9-9.8 77-55.8 138.8-50.2 3.3 8.8 28.2 66.7 6.3 135 37.1 42.1 56 94.6 56 151.4 0 117-67.5 215.3-228.8 243.7 26.9 26.6 43.6 63.4 43.6 104.2l0 128.8c0.9 10.3 0 20.5 17.2 20.5C878.1 942.4 1024 750.9 1024 525.3c0-282.9-229.3-512-512-512C229.1 13.2 0 242.3 0 525.2L0 525.2z" />
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</li></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="site-info mt-2">
|
||||
<div>© Stop Talking, Start Doing 2021,
|
||||
Powered by <a title="Jekyll is a simple, blog-aware, static site generator." href="http://jekyllrb.com/">Jekyll</a> & <a
|
||||
title="TeXt is a super customizable Jekyll theme." href="https://github.com/kitian616/jekyll-TeXt-theme">TeXt Theme</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div></div>
|
||||
</div><script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $body = $('body'), $window = $(window);
|
||||
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
||||
var activeCount = 0;
|
||||
function modal(options) {
|
||||
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
||||
var scrollTop;
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
visible = _options.initialVisible === undefined ? false : show;
|
||||
onChange = _options.onChange;
|
||||
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
||||
}
|
||||
function init() {
|
||||
setState(visible);
|
||||
}
|
||||
function setState(isShow) {
|
||||
if (isShow === visible) {
|
||||
return;
|
||||
}
|
||||
visible = isShow;
|
||||
if (visible) {
|
||||
activeCount++;
|
||||
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
||||
$root.addClass('modal--show');
|
||||
$pageMain.scrollTop(scrollTop);
|
||||
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
||||
$window.on('keyup', handleKeyup);
|
||||
} else {
|
||||
activeCount > 0 && activeCount--;
|
||||
$root.removeClass('modal--show');
|
||||
$window.scrollTop(scrollTop);
|
||||
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
||||
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
||||
$window.off('keyup', handleKeyup);
|
||||
}
|
||||
onChange && onChange(visible);
|
||||
}
|
||||
function show() {
|
||||
setState(true);
|
||||
}
|
||||
function hide() {
|
||||
setState(false);
|
||||
}
|
||||
function handleKeyup(e) {
|
||||
// Char Code: 27 ESC
|
||||
if (e.which === 27) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
setOptions(options);
|
||||
init();
|
||||
return {
|
||||
show: show,
|
||||
hide: hide,
|
||||
$el: $root
|
||||
};
|
||||
}
|
||||
$.fn.modal = modal;
|
||||
});
|
||||
})();
|
||||
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
||||
(function () {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
// search panel
|
||||
var search = (window.search || (window.search = {}));
|
||||
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
||||
true : window.useDefaultSearchBox ;
|
||||
|
||||
var $searchModal = $('.js-page-search-modal');
|
||||
var $searchToggle = $('.js-search-toggle');
|
||||
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
||||
var modalVisible = false;
|
||||
search.searchModal = searchModal;
|
||||
|
||||
var $searchBox = null;
|
||||
var $searchInput = null;
|
||||
var $searchClear = null;
|
||||
|
||||
function getModalVisible() {
|
||||
return modalVisible;
|
||||
}
|
||||
search.getModalVisible = getModalVisible;
|
||||
|
||||
function handleModalChange(visible) {
|
||||
modalVisible = visible;
|
||||
if (visible) {
|
||||
search.onShow && search.onShow();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
||||
} else {
|
||||
search.onShow && search.onHide();
|
||||
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
||||
setTimeout(function() {
|
||||
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
||||
search.clear && search.clear();
|
||||
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
$searchToggle.on('click', function() {
|
||||
modalVisible ? searchModal.hide() : searchModal.show();
|
||||
});
|
||||
// Char Code: 83 S, 191 /
|
||||
$(window).on('keyup', function(e) {
|
||||
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
||||
modalVisible || searchModal.show();
|
||||
}
|
||||
});
|
||||
|
||||
if (useDefaultSearchBox) {
|
||||
$searchBox = $('.js-search-box');
|
||||
$searchInput = $searchBox.children('input');
|
||||
$searchClear = $searchBox.children('.js-icon-clear');
|
||||
search.getSearchInput = function() {
|
||||
return $searchInput.get(0);
|
||||
};
|
||||
search.getVal = function() {
|
||||
return $searchInput.val();
|
||||
};
|
||||
search.setVal = function(val) {
|
||||
$searchInput.val(val);
|
||||
};
|
||||
|
||||
$searchInput.on('focus', function() {
|
||||
$(this).addClass('focus');
|
||||
});
|
||||
$searchInput.on('blur', function() {
|
||||
$(this).removeClass('focus');
|
||||
});
|
||||
$searchInput.on('input', window.throttle(function() {
|
||||
var val = $(this).val();
|
||||
if (val === '' || typeof val !== 'string') {
|
||||
search.clear && search.clear();
|
||||
} else {
|
||||
$searchBox.addClass('not-empty');
|
||||
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
||||
}
|
||||
}, 400));
|
||||
$searchClear.on('click', function() {
|
||||
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
||||
search.clear && search.clear();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><div class="search search--dark">
|
||||
<div class="main">
|
||||
<div class="search__header">Search</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-box js-search-box">
|
||||
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
||||
<input type="text" />
|
||||
<div class="search-box__icon-clear js-icon-clear">
|
||||
<a><i class="fas fa-times"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
||||
Cancel</button>
|
||||
</div>
|
||||
<div class="search-result js-search-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var PAHTS = window.TEXT_VARIABLES.paths;
|
||||
window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
|
||||
var search = (window.search || (window.search = {}));
|
||||
var searchData = window.TEXT_SEARCH_DATA || {};
|
||||
|
||||
function memorize(f) {
|
||||
var cache = {};
|
||||
return function () {
|
||||
var key = Array.prototype.join.call(arguments, ',');
|
||||
if (key in cache) return cache[key];
|
||||
else return cache[key] = f.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/// search
|
||||
function searchByQuery(query) {
|
||||
var i, j, key, keys, cur, _title, result = {};
|
||||
keys = Object.keys(searchData);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (j = 0; j < searchData[key].length; j++) {
|
||||
cur = searchData[key][j], _title = cur.title;
|
||||
if ((result[key] === undefined || result[key] && result[key].length < 4 )
|
||||
&& _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
result[key].push(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var renderHeader = memorize(function(header) {
|
||||
return $('<p class="search-result__header">' + header + '</p>');
|
||||
});
|
||||
|
||||
var renderItem = function(index, title, url) {
|
||||
return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
|
||||
};
|
||||
|
||||
function render(data) {
|
||||
if (!data) { return null; }
|
||||
var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
|
||||
keys = Object.keys(data);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
$root.append(renderHeader(key));
|
||||
for (j = 0; j < data[key].length; j++) {
|
||||
cur = data[key][j];
|
||||
$root.append(renderItem(itemIndex++, cur.title, cur.url));
|
||||
}
|
||||
}
|
||||
return $root;
|
||||
}
|
||||
|
||||
// search box
|
||||
var $result = $('.js-search-result'), $resultItems;
|
||||
var lastActiveIndex, activeIndex;
|
||||
|
||||
function clear() {
|
||||
$result.html(null);
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
}
|
||||
function onInputNotEmpty(val) {
|
||||
$result.html(render(searchByQuery(val)));
|
||||
$resultItems = $('.search-result__item'); activeIndex = 0;
|
||||
$resultItems.eq(0).addClass('active');
|
||||
}
|
||||
|
||||
search.clear = clear;
|
||||
search.onInputNotEmpty = onInputNotEmpty;
|
||||
|
||||
function updateResultItems() {
|
||||
lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
|
||||
activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
|
||||
}
|
||||
|
||||
function moveActiveIndex(direction) {
|
||||
var itemsCount = $resultItems ? $resultItems.length : 0;
|
||||
if (itemsCount > 1) {
|
||||
lastActiveIndex = activeIndex;
|
||||
if (direction === 'up') {
|
||||
activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
|
||||
} else if (direction === 'down') {
|
||||
activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
|
||||
}
|
||||
updateResultItems();
|
||||
}
|
||||
}
|
||||
|
||||
// Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇
|
||||
$(window).on('keyup', function(e) {
|
||||
var modalVisible = search.getModalVisible && search.getModalVisible();
|
||||
if (modalVisible) {
|
||||
if (e.which === 38) {
|
||||
modalVisible && moveActiveIndex('up');
|
||||
} else if (e.which === 40) {
|
||||
modalVisible && moveActiveIndex('down');
|
||||
} else if (e.which === 13) {
|
||||
modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$result.on('mouseover', '.search-result__item > a', function() {
|
||||
var itemIndex = $(this).parent().data('index');
|
||||
itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div></div>
|
||||
|
||||
|
||||
<script>(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function scrollToAnchor(anchor, duration, callback) {
|
||||
var $root = this;
|
||||
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
||||
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
$.fn.scrollToAnchor = scrollToAnchor;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function affix(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
||||
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
||||
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
||||
hasInit = false, curState;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroll && (scroll = _options.scroll);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$scrollTarget = $(scrollTarget);
|
||||
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
||||
$scroll = $(scroll);
|
||||
}
|
||||
function preCalc() {
|
||||
top();
|
||||
rootHeight = $root.outerHeight();
|
||||
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
||||
rootLeft = $root.offset().left;
|
||||
}
|
||||
function calc(needPreCalc) {
|
||||
needPreCalc && preCalc();
|
||||
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
||||
rootBottomTop = scrollBottom - rootTop;
|
||||
}
|
||||
function top() {
|
||||
if (curState !== 'top') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: 0
|
||||
});
|
||||
curState = 'top';
|
||||
}
|
||||
}
|
||||
function fixed() {
|
||||
if (curState !== 'fixed') {
|
||||
$root.addClass('fixed').css({
|
||||
left: rootLeft + 'px',
|
||||
top: 0
|
||||
});
|
||||
curState = 'fixed';
|
||||
}
|
||||
}
|
||||
function bottom() {
|
||||
if (curState !== 'bottom') {
|
||||
$root.removeClass('fixed').css({
|
||||
left: 0,
|
||||
top: rootBottomTop + 'px'
|
||||
});
|
||||
curState = 'bottom';
|
||||
}
|
||||
}
|
||||
function setState() {
|
||||
var scrollTop = $scrollTarget.scrollTop();
|
||||
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
||||
fixed();
|
||||
} else if (scrollTop < rootTop) {
|
||||
top();
|
||||
} else {
|
||||
bottom();
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
if(!hasInit) {
|
||||
var interval, timeout;
|
||||
calc(true); setState();
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState();
|
||||
});
|
||||
$window.on('resize', function() {
|
||||
disabled || (calc(true), setState());
|
||||
});
|
||||
hasInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions,
|
||||
refresh: function() {
|
||||
calc(true, { animation: false }); setState();
|
||||
}
|
||||
};
|
||||
}
|
||||
$.fn.affix = affix;
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
function toc(options) {
|
||||
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
||||
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
||||
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
||||
|
||||
function setOptions(options) {
|
||||
var _options = options || {};
|
||||
_options.selectors && (selectors = _options.selectors);
|
||||
_options.container && (container = _options.container);
|
||||
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
||||
_options.scroller && (scroller = _options.scroller);
|
||||
_options.disabled !== undefined && (disabled = _options.disabled);
|
||||
$headings = $(container).find(selectors).filter('[id]');
|
||||
$scrollTarget = $(scrollTarget);
|
||||
$scroller = $(scroller);
|
||||
}
|
||||
function calc() {
|
||||
headingsPos = [];
|
||||
$headings.each(function() {
|
||||
headingsPos.push(Math.floor($(this).position().top));
|
||||
});
|
||||
}
|
||||
function setState(element, disabled) {
|
||||
var scrollTop = $scrollTarget.scrollTop(), i;
|
||||
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
||||
if (element) {
|
||||
$activeCur = element;
|
||||
} else {
|
||||
for (i = 0; i < headingsPos.length; i++) {
|
||||
if (scrollTop >= headingsPos[i]) {
|
||||
$activeCur = $tocLi.eq(i);
|
||||
} else {
|
||||
$activeCur || ($activeCur = $tocLi.eq(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$activeLast && $activeLast.removeClass('active');
|
||||
($activeLast = $activeCur).addClass('active');
|
||||
}
|
||||
function render() {
|
||||
if(!hasRendered) {
|
||||
$root.append($tocUl);
|
||||
$headings.each(function() {
|
||||
var $this = $(this);
|
||||
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
||||
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
||||
});
|
||||
$tocLi = $tocUl.children('li');
|
||||
$tocUl.on('click', 'a', function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
scrolling = true;
|
||||
setState($this.parent());
|
||||
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
||||
scrolling = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
hasRendered = true;
|
||||
}
|
||||
function init() {
|
||||
var interval, timeout;
|
||||
if(!hasInit) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
// run calc every 100 millisecond
|
||||
interval = setInterval(function() {
|
||||
calc();
|
||||
}, 100);
|
||||
timeout = setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
}, 45000);
|
||||
window.pageLoad.then(function() {
|
||||
setTimeout(function() {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
});
|
||||
$scrollTarget.on('scroll', function() {
|
||||
disabled || setState(null, scrolling);
|
||||
});
|
||||
$window.on('resize', window.throttle(function() {
|
||||
if (!disabled) {
|
||||
render(); calc(); setState(null, scrolling);
|
||||
}
|
||||
}, 100));
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
setOptions(options);
|
||||
if (!disabled) {
|
||||
init();
|
||||
}
|
||||
$window.on('resize', window.throttle(function() {
|
||||
init();
|
||||
}, 200));
|
||||
return {
|
||||
setOptions: setOptions
|
||||
};
|
||||
}
|
||||
$.fn.toc = toc;
|
||||
});
|
||||
})();
|
||||
/*(function () {
|
||||
|
||||
})();*/
|
||||
</script><script>
|
||||
/* toc must before affix, since affix need to konw toc' height. */(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $window = $(window);
|
||||
var $articleContent = $('.js-article-content');
|
||||
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
|
||||
var toc;
|
||||
var tocDisabled = false;
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
|
||||
|
||||
function disabled() {
|
||||
return $col2.css('display') === 'none' || !hasToc;
|
||||
}
|
||||
|
||||
tocDisabled = disabled();
|
||||
|
||||
toc = $tocRoot.toc({
|
||||
selectors: TOC_SELECTOR,
|
||||
container: $articleContent,
|
||||
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
||||
scroller: hasSidebar ? '.js-page-main' : null,
|
||||
disabled: tocDisabled
|
||||
});
|
||||
|
||||
$window.on('resize', window.throttle(function() {
|
||||
tocDisabled = disabled();
|
||||
toc && toc.setOptions({
|
||||
disabled: tocDisabled
|
||||
});
|
||||
}, 100));
|
||||
|
||||
});
|
||||
})();
|
||||
(function() {
|
||||
var SOURCES = window.TEXT_VARIABLES.sources;
|
||||
window.Lazyload.js(SOURCES.jquery, function() {
|
||||
var $window = $(window), $pageFooter = $('.js-page-footer');
|
||||
var $pageAside = $('.js-page-aside');
|
||||
var affix;
|
||||
var tocDisabled = false;
|
||||
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
||||
|
||||
affix = $pageAside.affix({
|
||||
offsetBottom: $pageFooter.outerHeight(),
|
||||
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
||||
scroller: hasSidebar ? '.js-page-main' : null,
|
||||
scroll: hasSidebar ? $('.js-page-main').children() : null,
|
||||
disabled: tocDisabled
|
||||
});
|
||||
|
||||
$window.on('resize', window.throttle(function() {
|
||||
affix && affix.setOptions({
|
||||
disabled: tocDisabled
|
||||
});
|
||||
}, 100));
|
||||
|
||||
window.pageAsideAffix = affix;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<script>(function () {
|
||||
var $root = document.getElementsByClassName('root')[0];
|
||||
if (window.hasEvent('touchstart')) {
|
||||
$root.dataset.isTouch = true;
|
||||
document.addEventListener('touchstart', function(){}, false);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1 @@
|
||||
Sitemap: https://codersherlock.github.com//sitemap.xml
|
||||
Sitemap: http://localhost:4000/sitemap.xml
|
||||
|
||||
@@ -1,62 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/hello</loc>
|
||||
<loc>http://localhost:4000/posts/welcome-to-my-blog</loc>
|
||||
<lastmod>2016-10-26T22:50:33-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/charles-is-not-a-good-tool</loc>
|
||||
<loc>http://localhost:4000/posts/charles-is-not-a-good-tool</loc>
|
||||
<lastmod>2016-10-27T22:50:33-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/some-of-my-previews-exper-work</loc>
|
||||
<loc>http://localhost:4000/posts/some-of-my-previews-exper-work</loc>
|
||||
<lastmod>2016-10-28T12:27:33-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/intro-xv6</loc>
|
||||
<loc>http://localhost:4000/posts/intro-xv6</loc>
|
||||
<lastmod>2017-07-28T14:56:55-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/generate-word-cloud-with-chinese-fenci</loc>
|
||||
<loc>http://localhost:4000/posts/generate-word-cloud-with-chinese-fenci</loc>
|
||||
<lastmod>2020-09-15T22:00:14-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//archivers/eddl-how-do-we-train-on-limited-edge-devices</loc>
|
||||
<loc>http://localhost:4000/posts/eddl-how-do-we-train-on-limited-edge-devices</loc>
|
||||
<lastmod>2021-10-13T16:53:20-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//about/</loc>
|
||||
<loc>http://localhost:4000/about.html</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//category/</loc>
|
||||
<loc>http://localhost:4000/archive</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//</loc>
|
||||
<loc>http://localhost:4000/</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//timeline/</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//page2/</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//static/2017-07/eps_poster.pdf</loc>
|
||||
<loc>http://localhost:4000/static/2017-07/eps_poster.pdf</loc>
|
||||
<lastmod>2018-08-29T16:16:03-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//static/2017-07/p163-hao.pdf</loc>
|
||||
<loc>http://localhost:4000/static/2017-07/p163-hao.pdf</loc>
|
||||
<lastmod>2018-08-29T16:16:03-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//static/2017-07/p169-zhang.pdf</loc>
|
||||
<loc>http://localhost:4000/static/2017-07/p169-zhang.pdf</loc>
|
||||
<lastmod>2018-08-29T16:16:03-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//static/2018-02/a7-hao.pdf</loc>
|
||||
<loc>http://localhost:4000/static/2018-02/a7-hao.pdf</loc>
|
||||
<lastmod>2018-08-29T16:16:03-04:00</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://codersherlock.github.com//static/2021-10/eta-infocom18.pdf</loc>
|
||||
<loc>http://localhost:4000/static/2021-10/eta-infocom18.pdf</loc>
|
||||
<lastmod>2021-10-12T16:53:06-04:00</lastmod>
|
||||
</url>
|
||||
</urlset>
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>About - Timeline « Stop Talking, Start Doing</title>
|
||||
<meta name="description" content="My personal blog, with some boring research staff and some tricks I was fancy to. I'll try my best to make this blog fun and useful. Not just a place I complain about all happens in my Lab.
|
||||
">
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link rel="stylesheet" href="/css/timeline.css">
|
||||
<link rel="canonical" href="https://codersherlock.github.com//timeline/">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
|
||||
<link rel="alternate" type="application/rss+xml" title="Stop Talking, Start Doing" href="https://codersherlock.github.com//feed.xml" />
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-82637164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({
|
||||
google_ad_client: "ca-pub-6651321038908478",
|
||||
enable_page_level_ads: true
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
<div class="wrapper">
|
||||
<a class="site-title" href="/">Stop Talking, Start Doing</a>
|
||||
<nav class="site-nav">
|
||||
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/about/">About</a>
|
||||
|
||||
|
||||
|
||||
<a class="page-link" href="/category/">Category</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
<div class="col-main">
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">About - Timeline</h1>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
<div class="timeline">
|
||||
|
||||
<div class="timeline__group">
|
||||
<span class="timeline__year">Now</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">21</span>
|
||||
<span clas="timeline__month">Aug</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<p>Look up at the Starry Sky</p>
|
||||
<audio controls=""><source src="/static/2018-09/beihang.mp3" type="audio/mpeg" /></audio>
|
||||
<img src="http://www.fsaona.com/images/imagesbigimg.jpg" height="auto" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">2011</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">10</span>
|
||||
<span clas="timeline__month">Sept</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<!-- <p> Transfered to another high school</p> -->
|
||||
<img src="http://school.zhongkao.com/style/school/pictures/school/734/73421/logo.jpg" height="250" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">2010</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">1</span>
|
||||
<span clas="timeline__month">Sept</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<!-- <p> Attened high school</p> -->
|
||||
<img src="http://www.fuzhong.sd.cn/uploadfile/2015/0704/20150704044140866.jpg" height="250" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">2008</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">1</span>
|
||||
<span clas="timeline__month">Sept</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<!-- <p> Attened middle school</p> -->
|
||||
<img src="https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike72%2C5%2C5%2C72%2C24/sign=5bc3fe5949540923be646b2cf331ba6c/3812b31bb051f819506a0330dab44aed2e73e779.jpg" height="250" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">2005</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">1</span>
|
||||
<span clas="timeline__month">Sept</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<!-- <p> Attened primary school</p> -->
|
||||
<img src="http://www.sdsdfx.com:85/fxjylm/u/cms/www/201510/27194804xvgc.jpg" height="250" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">1999</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline__group">
|
||||
<div class="timeline__box">
|
||||
<div class="timeline__date">
|
||||
<span class="timeline__day">26</span>
|
||||
<span class="timeline__month">Aug</span>
|
||||
</div>
|
||||
<div class="timeline__post">
|
||||
<div class="timeline__content">
|
||||
<p> Borned in <a href="https://en.wikipedia.org/wiki/Jinan">Jinan</a>, <a href="https://en.wikipedia.org/wiki/Shandong">Shandong Province</a>, China </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="timeline__year">1993</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-second">
|
||||
<div class="col-box col-box-author">
|
||||
<img class="avatar" src="/static/avatar.jpg" alt="Pengzhan Hao">
|
||||
<div class="col-box-title name">Pengzhan Hao</div>
|
||||
<p></p>
|
||||
<p class="contact">
|
||||
|
||||
<a href="https://github.com/codersherlock">GitHub</a>
|
||||
|
||||
|
||||
|
||||
<a href="mailto:haopengzhan@gmail.com">Email</a>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-box">
|
||||
<div class="col-box-title">Newest Posts</div>
|
||||
<ul class="post-list">
|
||||
|
||||
<li><a class="post-link" href="/archivers/eddl-how-do-we-train-on-limited-edge-devices">EDDL: How do we train neural networks on limited edge devices - PART 1</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/intro-xv6">Xv6 introduction</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></li>
|
||||
|
||||
<li><a class="post-link" href="/archivers/charles-is-not-a-good-tool">Using charles proxy to monitor mobile SSL traffics</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-box post-toc hide">
|
||||
<div class="col-box-title">Indexes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrapper">
|
||||
© 2016 Pengzhan Hao
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/easybook.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||