mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-24 07:14:47 +00:00
deploy: 06a1bdf735
This commit is contained in:
commit
ca571eb691
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.c linguist-language=Go
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/_book
|
||||||
|
/book
|
||||||
|
|
||||||
|
*.out*
|
||||||
|
_zz*
|
4
FontAwesome/css/font-awesome.css
vendored
Normal file
4
FontAwesome/css/font-awesome.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
FontAwesome/fonts/FontAwesome.ttf
Normal file
BIN
FontAwesome/fonts/FontAwesome.ttf
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.eot
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
FontAwesome/fonts/fontawesome-webfont.svg
Normal file
2671
FontAwesome/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
BIN
FontAwesome/fonts/fontawesome-webfont.ttf
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.woff
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.woff2
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
27
LICENSE
Normal file
27
LICENSE
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2015 Golang-China. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
12
Makefile
Normal file
12
Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Copyright 2015 Golang-China. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
# install mkbook
|
||||||
|
|
||||||
|
# http://www.imagemagick.org/
|
||||||
|
|
||||||
|
default:
|
||||||
|
mdbook serve
|
||||||
|
|
||||||
|
clean:
|
272
appendix/appendix-a-errata.html
Normal file
272
appendix/appendix-a-errata.html
Normal file
File diff suppressed because one or more lines are too long
251
appendix/appendix-b-author.html
Normal file
251
appendix/appendix-b-author.html
Normal file
File diff suppressed because one or more lines are too long
240
appendix/appendix-c-cpoyright.html
Normal file
240
appendix/appendix-c-cpoyright.html
Normal file
File diff suppressed because one or more lines are too long
243
appendix/appendix-d-translations.html
Normal file
243
appendix/appendix-d-translations.html
Normal file
File diff suppressed because one or more lines are too long
240
appendix/appendix.html
Normal file
240
appendix/appendix.html
Normal file
File diff suppressed because one or more lines are too long
79
ayu-highlight.css
Normal file
79
ayu-highlight.css
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
Based off of the Ayu theme
|
||||||
|
Original by Dempfi (https://github.com/dempfi/ayu)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
background: #191f26;
|
||||||
|
color: #e6e1cf;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #5c6773;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class {
|
||||||
|
color: #ff7733;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-builtin-name,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-params {
|
||||||
|
color: #ffee99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-bullet {
|
||||||
|
color: #b8cc52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-section {
|
||||||
|
color: #ffb454;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-symbol {
|
||||||
|
color: #ff7733;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-name {
|
||||||
|
color: #36a3d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag {
|
||||||
|
color: #00568d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: #91b362;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: #d96c75;
|
||||||
|
}
|
660
book.js
Normal file
660
book.js
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Fix back button cache problem
|
||||||
|
window.onunload = function () { };
|
||||||
|
|
||||||
|
// Global variable, shared between modules
|
||||||
|
function playground_text(playground) {
|
||||||
|
let code_block = playground.querySelector("code");
|
||||||
|
|
||||||
|
if (window.ace && code_block.classList.contains("editable")) {
|
||||||
|
let editor = window.ace.edit(code_block);
|
||||||
|
return editor.getValue();
|
||||||
|
} else {
|
||||||
|
return code_block.textContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function codeSnippets() {
|
||||||
|
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||||
|
return Promise.race([
|
||||||
|
fetch(url, options),
|
||||||
|
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var playgrounds = Array.from(document.querySelectorAll(".playground"));
|
||||||
|
if (playgrounds.length > 0) {
|
||||||
|
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': "application/json",
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
// get list of crates available in the rust playground
|
||||||
|
let playground_crates = response.crates.map(item => item["id"]);
|
||||||
|
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_crate_list_update(playground_block, playground_crates) {
|
||||||
|
// update the play buttons after receiving the response
|
||||||
|
update_play_button(playground_block, playground_crates);
|
||||||
|
|
||||||
|
// and install on change listener to dynamically update ACE editors
|
||||||
|
if (window.ace) {
|
||||||
|
let code_block = playground_block.querySelector("code");
|
||||||
|
if (code_block.classList.contains("editable")) {
|
||||||
|
let editor = window.ace.edit(code_block);
|
||||||
|
editor.addEventListener("change", function (e) {
|
||||||
|
update_play_button(playground_block, playground_crates);
|
||||||
|
});
|
||||||
|
// add Ctrl-Enter command to execute rust code
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: "run",
|
||||||
|
bindKey: {
|
||||||
|
win: "Ctrl-Enter",
|
||||||
|
mac: "Ctrl-Enter"
|
||||||
|
},
|
||||||
|
exec: _editor => run_rust_code(playground_block)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// updates the visibility of play button based on `no_run` class and
|
||||||
|
// used crates vs ones available on http://play.rust-lang.org
|
||||||
|
function update_play_button(pre_block, playground_crates) {
|
||||||
|
var play_button = pre_block.querySelector(".play-button");
|
||||||
|
|
||||||
|
// skip if code is `no_run`
|
||||||
|
if (pre_block.querySelector('code').classList.contains("no_run")) {
|
||||||
|
play_button.classList.add("hidden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get list of `extern crate`'s from snippet
|
||||||
|
var txt = playground_text(pre_block);
|
||||||
|
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
||||||
|
var snippet_crates = [];
|
||||||
|
var item;
|
||||||
|
while (item = re.exec(txt)) {
|
||||||
|
snippet_crates.push(item[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if all used crates are available on play.rust-lang.org
|
||||||
|
var all_available = snippet_crates.every(function (elem) {
|
||||||
|
return playground_crates.indexOf(elem) > -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (all_available) {
|
||||||
|
play_button.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
play_button.classList.add("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_rust_code(code_block) {
|
||||||
|
var result_block = code_block.querySelector(".result");
|
||||||
|
if (!result_block) {
|
||||||
|
result_block = document.createElement('code');
|
||||||
|
result_block.className = 'result hljs language-bash';
|
||||||
|
|
||||||
|
code_block.append(result_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
let text = playground_text(code_block);
|
||||||
|
let classes = code_block.querySelector('code').classList;
|
||||||
|
let has_2018 = classes.contains("edition2018");
|
||||||
|
let edition = has_2018 ? "2018" : "2015";
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
version: "stable",
|
||||||
|
optimize: "0",
|
||||||
|
code: text,
|
||||||
|
edition: edition
|
||||||
|
};
|
||||||
|
|
||||||
|
if (text.indexOf("#![feature") !== -1) {
|
||||||
|
params.version = "nightly";
|
||||||
|
}
|
||||||
|
|
||||||
|
result_block.innerText = "Running...";
|
||||||
|
|
||||||
|
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': "application/json",
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
body: JSON.stringify(params)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => result_block.innerText = response.result)
|
||||||
|
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syntax highlighting Configuration
|
||||||
|
hljs.configure({
|
||||||
|
tabReplace: ' ', // 4 spaces
|
||||||
|
languages: [], // Languages used for auto-detection
|
||||||
|
});
|
||||||
|
|
||||||
|
let code_nodes = Array
|
||||||
|
.from(document.querySelectorAll('code'))
|
||||||
|
// Don't highlight `inline code` blocks in headers.
|
||||||
|
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
|
||||||
|
|
||||||
|
if (window.ace) {
|
||||||
|
// language-rust class needs to be removed for editable
|
||||||
|
// blocks or highlightjs will capture events
|
||||||
|
Array
|
||||||
|
.from(document.querySelectorAll('code.editable'))
|
||||||
|
.forEach(function (block) { block.classList.remove('language-rust'); });
|
||||||
|
|
||||||
|
Array
|
||||||
|
.from(document.querySelectorAll('code:not(.editable)'))
|
||||||
|
.forEach(function (block) { hljs.highlightBlock(block); });
|
||||||
|
} else {
|
||||||
|
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding the hljs class gives code blocks the color css
|
||||||
|
// even if highlighting doesn't apply
|
||||||
|
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
|
||||||
|
|
||||||
|
Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
|
||||||
|
|
||||||
|
var lines = Array.from(block.querySelectorAll('.boring'));
|
||||||
|
// If no lines were hidden, return
|
||||||
|
if (!lines.length) { return; }
|
||||||
|
block.classList.add("hide-boring");
|
||||||
|
|
||||||
|
var buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
||||||
|
|
||||||
|
// add expand button
|
||||||
|
var pre_block = block.parentNode;
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
|
||||||
|
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
|
||||||
|
if (e.target.classList.contains('fa-eye')) {
|
||||||
|
e.target.classList.remove('fa-eye');
|
||||||
|
e.target.classList.add('fa-eye-slash');
|
||||||
|
e.target.title = 'Hide lines';
|
||||||
|
e.target.setAttribute('aria-label', e.target.title);
|
||||||
|
|
||||||
|
block.classList.remove('hide-boring');
|
||||||
|
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||||
|
e.target.classList.remove('fa-eye-slash');
|
||||||
|
e.target.classList.add('fa-eye');
|
||||||
|
e.target.title = 'Show hidden lines';
|
||||||
|
e.target.setAttribute('aria-label', e.target.title);
|
||||||
|
|
||||||
|
block.classList.add('hide-boring');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.playground_copyable) {
|
||||||
|
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
|
||||||
|
var pre_block = block.parentNode;
|
||||||
|
if (!pre_block.classList.contains('playground')) {
|
||||||
|
var buttons = pre_block.querySelector(".buttons");
|
||||||
|
if (!buttons) {
|
||||||
|
buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
var clipButton = document.createElement('button');
|
||||||
|
clipButton.className = 'fa fa-copy clip-button';
|
||||||
|
clipButton.title = 'Copy to clipboard';
|
||||||
|
clipButton.setAttribute('aria-label', clipButton.title);
|
||||||
|
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
|
||||||
|
|
||||||
|
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process playground code blocks
|
||||||
|
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
|
||||||
|
// Add play button
|
||||||
|
var buttons = pre_block.querySelector(".buttons");
|
||||||
|
if (!buttons) {
|
||||||
|
buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
var runCodeButton = document.createElement('button');
|
||||||
|
runCodeButton.className = 'fa fa-play play-button';
|
||||||
|
runCodeButton.hidden = true;
|
||||||
|
runCodeButton.title = 'Run this code';
|
||||||
|
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||||
|
runCodeButton.addEventListener('click', function (e) {
|
||||||
|
run_rust_code(pre_block);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.playground_copyable) {
|
||||||
|
var copyCodeClipboardButton = document.createElement('button');
|
||||||
|
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
|
||||||
|
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||||
|
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||||
|
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
let code_block = pre_block.querySelector("code");
|
||||||
|
if (window.ace && code_block.classList.contains("editable")) {
|
||||||
|
var undoChangesButton = document.createElement('button');
|
||||||
|
undoChangesButton.className = 'fa fa-history reset-button';
|
||||||
|
undoChangesButton.title = 'Undo changes';
|
||||||
|
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||||
|
|
||||||
|
undoChangesButton.addEventListener('click', function () {
|
||||||
|
let editor = window.ace.edit(code_block);
|
||||||
|
editor.setValue(editor.originalCode);
|
||||||
|
editor.clearSelection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function themes() {
|
||||||
|
var html = document.querySelector('html');
|
||||||
|
var themeToggleButton = document.getElementById('theme-toggle');
|
||||||
|
var themePopup = document.getElementById('theme-list');
|
||||||
|
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||||
|
var stylesheets = {
|
||||||
|
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||||
|
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||||||
|
highlight: document.querySelector("[href$='highlight.css']"),
|
||||||
|
};
|
||||||
|
|
||||||
|
function showThemes() {
|
||||||
|
themePopup.style.display = 'block';
|
||||||
|
themeToggleButton.setAttribute('aria-expanded', true);
|
||||||
|
themePopup.querySelector("button#" + get_theme()).focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideThemes() {
|
||||||
|
themePopup.style.display = 'none';
|
||||||
|
themeToggleButton.setAttribute('aria-expanded', false);
|
||||||
|
themeToggleButton.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_theme() {
|
||||||
|
var theme;
|
||||||
|
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
||||||
|
if (theme === null || theme === undefined) {
|
||||||
|
return default_theme;
|
||||||
|
} else {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_theme(theme, store = true) {
|
||||||
|
let ace_theme;
|
||||||
|
|
||||||
|
if (theme == 'coal' || theme == 'navy') {
|
||||||
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
|
stylesheets.tomorrowNight.disabled = false;
|
||||||
|
stylesheets.highlight.disabled = true;
|
||||||
|
|
||||||
|
ace_theme = "ace/theme/tomorrow_night";
|
||||||
|
} else if (theme == 'ayu') {
|
||||||
|
stylesheets.ayuHighlight.disabled = false;
|
||||||
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
|
stylesheets.highlight.disabled = true;
|
||||||
|
ace_theme = "ace/theme/tomorrow_night";
|
||||||
|
} else {
|
||||||
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
|
stylesheets.highlight.disabled = false;
|
||||||
|
ace_theme = "ace/theme/dawn";
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
if (window.ace && window.editors) {
|
||||||
|
window.editors.forEach(function (editor) {
|
||||||
|
editor.setTheme(ace_theme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var previousTheme = get_theme();
|
||||||
|
|
||||||
|
if (store) {
|
||||||
|
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
html.classList.remove(previousTheme);
|
||||||
|
html.classList.add(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set theme
|
||||||
|
var theme = get_theme();
|
||||||
|
|
||||||
|
set_theme(theme, false);
|
||||||
|
|
||||||
|
themeToggleButton.addEventListener('click', function () {
|
||||||
|
if (themePopup.style.display === 'block') {
|
||||||
|
hideThemes();
|
||||||
|
} else {
|
||||||
|
showThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
themePopup.addEventListener('click', function (e) {
|
||||||
|
var theme = e.target.id || e.target.parentElement.id;
|
||||||
|
set_theme(theme);
|
||||||
|
});
|
||||||
|
|
||||||
|
themePopup.addEventListener('focusout', function(e) {
|
||||||
|
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||||
|
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
|
||||||
|
hideThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
|
||||||
|
hideThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||||
|
if (!themePopup.contains(e.target)) { return; }
|
||||||
|
|
||||||
|
switch (e.key) {
|
||||||
|
case 'Escape':
|
||||||
|
e.preventDefault();
|
||||||
|
hideThemes();
|
||||||
|
break;
|
||||||
|
case 'ArrowUp':
|
||||||
|
e.preventDefault();
|
||||||
|
var li = document.activeElement.parentElement;
|
||||||
|
if (li && li.previousElementSibling) {
|
||||||
|
li.previousElementSibling.querySelector('button').focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ArrowDown':
|
||||||
|
e.preventDefault();
|
||||||
|
var li = document.activeElement.parentElement;
|
||||||
|
if (li && li.nextElementSibling) {
|
||||||
|
li.nextElementSibling.querySelector('button').focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Home':
|
||||||
|
e.preventDefault();
|
||||||
|
themePopup.querySelector('li:first-child button').focus();
|
||||||
|
break;
|
||||||
|
case 'End':
|
||||||
|
e.preventDefault();
|
||||||
|
themePopup.querySelector('li:last-child button').focus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function sidebar() {
|
||||||
|
var html = document.querySelector("html");
|
||||||
|
var sidebar = document.getElementById("sidebar");
|
||||||
|
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||||
|
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
||||||
|
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
|
||||||
|
var firstContact = null;
|
||||||
|
|
||||||
|
function showSidebar() {
|
||||||
|
html.classList.remove('sidebar-hidden')
|
||||||
|
html.classList.add('sidebar-visible');
|
||||||
|
Array.from(sidebarLinks).forEach(function (link) {
|
||||||
|
link.setAttribute('tabIndex', 0);
|
||||||
|
});
|
||||||
|
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||||||
|
sidebar.setAttribute('aria-hidden', false);
|
||||||
|
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
|
||||||
|
|
||||||
|
function toggleSection(ev) {
|
||||||
|
ev.currentTarget.parentElement.classList.toggle('expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.from(sidebarAnchorToggles).forEach(function (el) {
|
||||||
|
el.addEventListener('click', toggleSection);
|
||||||
|
});
|
||||||
|
|
||||||
|
function hideSidebar() {
|
||||||
|
html.classList.remove('sidebar-visible')
|
||||||
|
html.classList.add('sidebar-hidden');
|
||||||
|
Array.from(sidebarLinks).forEach(function (link) {
|
||||||
|
link.setAttribute('tabIndex', -1);
|
||||||
|
});
|
||||||
|
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||||||
|
sidebar.setAttribute('aria-hidden', true);
|
||||||
|
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle sidebar
|
||||||
|
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
||||||
|
if (html.classList.contains("sidebar-hidden")) {
|
||||||
|
var current_width = parseInt(
|
||||||
|
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||||
|
if (current_width < 150) {
|
||||||
|
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||||
|
}
|
||||||
|
showSidebar();
|
||||||
|
} else if (html.classList.contains("sidebar-visible")) {
|
||||||
|
hideSidebar();
|
||||||
|
} else {
|
||||||
|
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
||||||
|
hideSidebar();
|
||||||
|
} else {
|
||||||
|
showSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||||||
|
|
||||||
|
function initResize(e) {
|
||||||
|
window.addEventListener('mousemove', resize, false);
|
||||||
|
window.addEventListener('mouseup', stopResize, false);
|
||||||
|
html.classList.add('sidebar-resizing');
|
||||||
|
}
|
||||||
|
function resize(e) {
|
||||||
|
var pos = (e.clientX - sidebar.offsetLeft);
|
||||||
|
if (pos < 20) {
|
||||||
|
hideSidebar();
|
||||||
|
} else {
|
||||||
|
if (html.classList.contains("sidebar-hidden")) {
|
||||||
|
showSidebar();
|
||||||
|
}
|
||||||
|
pos = Math.min(pos, window.innerWidth - 100);
|
||||||
|
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//on mouseup remove windows functions mousemove & mouseup
|
||||||
|
function stopResize(e) {
|
||||||
|
html.classList.remove('sidebar-resizing');
|
||||||
|
window.removeEventListener('mousemove', resize, false);
|
||||||
|
window.removeEventListener('mouseup', stopResize, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('touchstart', function (e) {
|
||||||
|
firstContact = {
|
||||||
|
x: e.touches[0].clientX,
|
||||||
|
time: Date.now()
|
||||||
|
};
|
||||||
|
}, { passive: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', function (e) {
|
||||||
|
if (!firstContact)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var curX = e.touches[0].clientX;
|
||||||
|
var xDiff = curX - firstContact.x,
|
||||||
|
tDiff = Date.now() - firstContact.time;
|
||||||
|
|
||||||
|
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||||||
|
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
|
||||||
|
showSidebar();
|
||||||
|
else if (xDiff < 0 && curX < 300)
|
||||||
|
hideSidebar();
|
||||||
|
|
||||||
|
firstContact = null;
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
|
||||||
|
// Scroll sidebar to current active section
|
||||||
|
var activeSection = document.getElementById("sidebar").querySelector(".active");
|
||||||
|
if (activeSection) {
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||||||
|
activeSection.scrollIntoView({ block: 'center' });
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function chapterNavigation() {
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||||
|
if (window.search && window.search.hasFocus()) { return; }
|
||||||
|
|
||||||
|
switch (e.key) {
|
||||||
|
case 'ArrowRight':
|
||||||
|
e.preventDefault();
|
||||||
|
var nextButton = document.querySelector('.nav-chapters.next');
|
||||||
|
if (nextButton) {
|
||||||
|
window.location.href = nextButton.href;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ArrowLeft':
|
||||||
|
e.preventDefault();
|
||||||
|
var previousButton = document.querySelector('.nav-chapters.previous');
|
||||||
|
if (previousButton) {
|
||||||
|
window.location.href = previousButton.href;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function clipboard() {
|
||||||
|
var clipButtons = document.querySelectorAll('.clip-button');
|
||||||
|
|
||||||
|
function hideTooltip(elem) {
|
||||||
|
elem.firstChild.innerText = "";
|
||||||
|
elem.className = 'fa fa-copy clip-button';
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTooltip(elem, msg) {
|
||||||
|
elem.firstChild.innerText = msg;
|
||||||
|
elem.className = 'fa fa-copy tooltipped';
|
||||||
|
}
|
||||||
|
|
||||||
|
var clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||||
|
text: function (trigger) {
|
||||||
|
hideTooltip(trigger);
|
||||||
|
let playground = trigger.closest("pre");
|
||||||
|
return playground_text(playground);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.from(clipButtons).forEach(function (clipButton) {
|
||||||
|
clipButton.addEventListener('mouseout', function (e) {
|
||||||
|
hideTooltip(e.currentTarget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardSnippets.on('success', function (e) {
|
||||||
|
e.clearSelection();
|
||||||
|
showTooltip(e.trigger, "Copied!");
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardSnippets.on('error', function (e) {
|
||||||
|
showTooltip(e.trigger, "Clipboard error!");
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function scrollToTop () {
|
||||||
|
var menuTitle = document.querySelector('.menu-title');
|
||||||
|
|
||||||
|
menuTitle.addEventListener('click', function () {
|
||||||
|
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function controllMenu() {
|
||||||
|
var menu = document.getElementById('menu-bar');
|
||||||
|
|
||||||
|
(function controllPosition() {
|
||||||
|
var scrollTop = document.scrollingElement.scrollTop;
|
||||||
|
var prevScrollTop = scrollTop;
|
||||||
|
var minMenuY = -menu.clientHeight - 50;
|
||||||
|
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
||||||
|
menu.style.top = scrollTop + 'px';
|
||||||
|
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
||||||
|
var topCache = menu.style.top.slice(0, -2);
|
||||||
|
menu.classList.remove('sticky');
|
||||||
|
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
||||||
|
document.addEventListener('scroll', function () {
|
||||||
|
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
||||||
|
// `null` means that it doesn't need to be updated
|
||||||
|
var nextSticky = null;
|
||||||
|
var nextTop = null;
|
||||||
|
var scrollDown = scrollTop > prevScrollTop;
|
||||||
|
var menuPosAbsoluteY = topCache - scrollTop;
|
||||||
|
if (scrollDown) {
|
||||||
|
nextSticky = false;
|
||||||
|
if (menuPosAbsoluteY > 0) {
|
||||||
|
nextTop = prevScrollTop;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (menuPosAbsoluteY > 0) {
|
||||||
|
nextSticky = true;
|
||||||
|
} else if (menuPosAbsoluteY < minMenuY) {
|
||||||
|
nextTop = prevScrollTop + minMenuY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextSticky === true && stickyCache === false) {
|
||||||
|
menu.classList.add('sticky');
|
||||||
|
stickyCache = true;
|
||||||
|
} else if (nextSticky === false && stickyCache === true) {
|
||||||
|
menu.classList.remove('sticky');
|
||||||
|
stickyCache = false;
|
||||||
|
}
|
||||||
|
if (nextTop !== null) {
|
||||||
|
menu.style.top = nextTop + 'px';
|
||||||
|
topCache = nextTop;
|
||||||
|
}
|
||||||
|
prevScrollTop = scrollTop;
|
||||||
|
}, { passive: true });
|
||||||
|
})();
|
||||||
|
(function controllBorder() {
|
||||||
|
menu.classList.remove('bordered');
|
||||||
|
document.addEventListener('scroll', function () {
|
||||||
|
if (menu.offsetTop === 0) {
|
||||||
|
menu.classList.remove('bordered');
|
||||||
|
} else {
|
||||||
|
menu.classList.add('bordered');
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
})();
|
||||||
|
})();
|
20
book.toml
Normal file
20
book.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# https://giscus.app
|
||||||
|
# https://github.com/badboy/mdbook-mermaid
|
||||||
|
|
||||||
|
[book]
|
||||||
|
title = "Go语言圣经"
|
||||||
|
authors = ["译者:", "chai2010", "Xargin", "CrazySssst", "foreversmart"]
|
||||||
|
description = "<The Go Programming Language>中文版"
|
||||||
|
language = "zh"
|
||||||
|
multilingual = false
|
||||||
|
src = "."
|
||||||
|
|
||||||
|
[build]
|
||||||
|
build-dir = "book"
|
||||||
|
|
||||||
|
[output.html]
|
||||||
|
additional-css = ["style.css"]
|
||||||
|
additional-js = ["js/custom.js", "js/bigPicture.js"]
|
||||||
|
git-repository-url = "https://github.com/gopl-zh/gopl-zh.github.com"
|
||||||
|
edit-url-template = "https://github.com/gopl-zh/gopl-zh.github.com/edit/master/{path}"
|
||||||
|
git-repository-icon = "fa-github"
|
172
builder.go
Normal file
172
builder.go
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright 2015 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ingore
|
||||||
|
|
||||||
|
// 打包 gopl-zh 为 zip 文件.
|
||||||
|
//
|
||||||
|
// 文件名格式: gopl-zh-20151001-2ae607.zip
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Git版本号
|
||||||
|
gitVersion := getGitCommitVersion()
|
||||||
|
|
||||||
|
// zip文件名
|
||||||
|
zipBaseName := fmt.Sprintf("gopl-zh-%s-%s", time.Now().Format("20060102"), gitVersion[:6])
|
||||||
|
|
||||||
|
// 导出Git
|
||||||
|
exportGitToZip("./_book/" + "gopl-zh-" + gitVersion + ".zip")
|
||||||
|
|
||||||
|
os.Remove(zipBaseName + ".zip")
|
||||||
|
file, err := os.Create(zipBaseName + ".zip")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("os.Create: ", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
zipFile := zip.NewWriter(file)
|
||||||
|
defer zipFile.Close()
|
||||||
|
|
||||||
|
// create /gopl-zh-20151001-2ae607/
|
||||||
|
f, err := zipFile.Create(zipBaseName + "/")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err = f.Write([]byte("")); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := "_book"
|
||||||
|
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("filepath.Walk: ", err)
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
relpath, err := filepath.Rel(dir, path)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("filepath.Rel: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := filepath.ToSlash(relpath)
|
||||||
|
if isIngoreFile(filename) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("ioutil.ReadFile: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := zipFile.Create(zipBaseName + "/" + filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err = f.Write(data); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", filename)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Printf("Done\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取Git最新的版本号
|
||||||
|
//
|
||||||
|
// git log -1
|
||||||
|
// commit 0460c1b3bb8fbb7e2fc88961e69aa37f4041d6c1
|
||||||
|
// Merge: b2d582a e826457
|
||||||
|
// Author: chai2010 <chaishushan{AT}gmail.com>
|
||||||
|
// Date: Mon Feb 1 08:04:44 2016 +0800
|
||||||
|
//
|
||||||
|
// Merge pull request #249 from sunclx/patch-3
|
||||||
|
//
|
||||||
|
// fix typo
|
||||||
|
func getGitCommitVersion() (version string) {
|
||||||
|
cmdOut, err := exec.Command(`git`, `log`, `-1`).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(string(cmdOut), "\n") {
|
||||||
|
line := strings.TrimSpace(line)
|
||||||
|
if strings.HasPrefix(line, "commit") {
|
||||||
|
version = strings.TrimSpace(line[len("commit"):])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出Git到Zip文件
|
||||||
|
func exportGitToZip(filename string) error {
|
||||||
|
if !strings.HasSuffix(filename, ".zip") {
|
||||||
|
filename += ".zip"
|
||||||
|
}
|
||||||
|
if _, err := exec.Command(`git`, `archive`, `--format`, `zip`, `--output`, filename, `master`).CombinedOutput(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cpFile(dst, src string) {
|
||||||
|
err := os.MkdirAll(filepath.Dir(dst), 0666)
|
||||||
|
if err != nil && !os.IsExist(err) {
|
||||||
|
log.Fatal("cpFile: ", err)
|
||||||
|
}
|
||||||
|
fsrc, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cpFile: ", err)
|
||||||
|
}
|
||||||
|
defer fsrc.Close()
|
||||||
|
|
||||||
|
fdst, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cpFile: ", err)
|
||||||
|
}
|
||||||
|
defer fdst.Close()
|
||||||
|
if _, err = io.Copy(fdst, fsrc); err != nil {
|
||||||
|
log.Fatal("cpFile: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIngoreFile(path string) bool {
|
||||||
|
if strings.HasPrefix(path, ".git") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(path, ".gitignore") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(path, "vendor") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(path, "tools") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(path, "testdata") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(path, ".go") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
279
ch1/ch1-01.html
Normal file
279
ch1/ch1-01.html
Normal file
File diff suppressed because one or more lines are too long
338
ch1/ch1-02.html
Normal file
338
ch1/ch1-02.html
Normal file
File diff suppressed because one or more lines are too long
375
ch1/ch1-03.html
Normal file
375
ch1/ch1-03.html
Normal file
File diff suppressed because one or more lines are too long
314
ch1/ch1-04.html
Normal file
314
ch1/ch1-04.html
Normal file
File diff suppressed because one or more lines are too long
288
ch1/ch1-05.html
Normal file
288
ch1/ch1-05.html
Normal file
File diff suppressed because one or more lines are too long
295
ch1/ch1-06.html
Normal file
295
ch1/ch1-06.html
Normal file
File diff suppressed because one or more lines are too long
362
ch1/ch1-07.html
Normal file
362
ch1/ch1-07.html
Normal file
File diff suppressed because one or more lines are too long
285
ch1/ch1-08.html
Normal file
285
ch1/ch1-08.html
Normal file
File diff suppressed because one or more lines are too long
240
ch1/ch1.html
Normal file
240
ch1/ch1.html
Normal file
File diff suppressed because one or more lines are too long
242
ch10/ch10-01.html
Normal file
242
ch10/ch10-01.html
Normal file
File diff suppressed because one or more lines are too long
251
ch10/ch10-02.html
Normal file
251
ch10/ch10-02.html
Normal file
File diff suppressed because one or more lines are too long
255
ch10/ch10-03.html
Normal file
255
ch10/ch10-03.html
Normal file
File diff suppressed because one or more lines are too long
266
ch10/ch10-04.html
Normal file
266
ch10/ch10-04.html
Normal file
File diff suppressed because one or more lines are too long
309
ch10/ch10-05.html
Normal file
309
ch10/ch10-05.html
Normal file
File diff suppressed because one or more lines are too long
266
ch10/ch10-06.html
Normal file
266
ch10/ch10-06.html
Normal file
File diff suppressed because one or more lines are too long
535
ch10/ch10-07.html
Normal file
535
ch10/ch10-07.html
Normal file
File diff suppressed because one or more lines are too long
241
ch10/ch10.html
Normal file
241
ch10/ch10.html
Normal file
File diff suppressed because one or more lines are too long
241
ch11/ch11-01.html
Normal file
241
ch11/ch11-01.html
Normal file
File diff suppressed because one or more lines are too long
715
ch11/ch11-02.html
Normal file
715
ch11/ch11-02.html
Normal file
File diff suppressed because one or more lines are too long
310
ch11/ch11-03.html
Normal file
310
ch11/ch11-03.html
Normal file
File diff suppressed because one or more lines are too long
309
ch11/ch11-04.html
Normal file
309
ch11/ch11-04.html
Normal file
File diff suppressed because one or more lines are too long
284
ch11/ch11-05.html
Normal file
284
ch11/ch11-05.html
Normal file
File diff suppressed because one or more lines are too long
253
ch11/ch11-06.html
Normal file
253
ch11/ch11-06.html
Normal file
File diff suppressed because one or more lines are too long
244
ch11/ch11.html
Normal file
244
ch11/ch11.html
Normal file
File diff suppressed because one or more lines are too long
266
ch12/ch12-01.html
Normal file
266
ch12/ch12-01.html
Normal file
File diff suppressed because one or more lines are too long
316
ch12/ch12-02.html
Normal file
316
ch12/ch12-02.html
Normal file
File diff suppressed because one or more lines are too long
412
ch12/ch12-03.html
Normal file
412
ch12/ch12-03.html
Normal file
File diff suppressed because one or more lines are too long
362
ch12/ch12-04.html
Normal file
362
ch12/ch12-04.html
Normal file
File diff suppressed because one or more lines are too long
304
ch12/ch12-05.html
Normal file
304
ch12/ch12-05.html
Normal file
File diff suppressed because one or more lines are too long
371
ch12/ch12-06.html
Normal file
371
ch12/ch12-06.html
Normal file
File diff suppressed because one or more lines are too long
270
ch12/ch12-08.html
Normal file
270
ch12/ch12-08.html
Normal file
File diff suppressed because one or more lines are too long
247
ch12/ch12-09.html
Normal file
247
ch12/ch12-09.html
Normal file
File diff suppressed because one or more lines are too long
240
ch12/ch12.html
Normal file
240
ch12/ch12.html
Normal file
File diff suppressed because one or more lines are too long
288
ch13/ch13-01.html
Normal file
288
ch13/ch13-01.html
Normal file
File diff suppressed because one or more lines are too long
282
ch13/ch13-02.html
Normal file
282
ch13/ch13-02.html
Normal file
File diff suppressed because one or more lines are too long
341
ch13/ch13-03.html
Normal file
341
ch13/ch13-03.html
Normal file
File diff suppressed because one or more lines are too long
410
ch13/ch13-04.html
Normal file
410
ch13/ch13-04.html
Normal file
File diff suppressed because one or more lines are too long
243
ch13/ch13-05.html
Normal file
243
ch13/ch13-05.html
Normal file
File diff suppressed because one or more lines are too long
247
ch13/ch13.html
Normal file
247
ch13/ch13.html
Normal file
File diff suppressed because one or more lines are too long
262
ch2/ch2-01.html
Normal file
262
ch2/ch2-01.html
Normal file
File diff suppressed because one or more lines are too long
275
ch2/ch2-02.html
Normal file
275
ch2/ch2-02.html
Normal file
File diff suppressed because one or more lines are too long
440
ch2/ch2-03.html
Normal file
440
ch2/ch2-03.html
Normal file
File diff suppressed because one or more lines are too long
314
ch2/ch2-04.html
Normal file
314
ch2/ch2-04.html
Normal file
File diff suppressed because one or more lines are too long
301
ch2/ch2-05.html
Normal file
301
ch2/ch2-05.html
Normal file
File diff suppressed because one or more lines are too long
378
ch2/ch2-06.html
Normal file
378
ch2/ch2-06.html
Normal file
File diff suppressed because one or more lines are too long
352
ch2/ch2-07.html
Normal file
352
ch2/ch2-07.html
Normal file
File diff suppressed because one or more lines are too long
240
ch2/ch2.html
Normal file
240
ch2/ch2.html
Normal file
File diff suppressed because one or more lines are too long
359
ch3/ch3-01.html
Normal file
359
ch3/ch3-01.html
Normal file
File diff suppressed because one or more lines are too long
355
ch3/ch3-02.html
Normal file
355
ch3/ch3-02.html
Normal file
File diff suppressed because one or more lines are too long
310
ch3/ch3-03.html
Normal file
310
ch3/ch3-03.html
Normal file
File diff suppressed because one or more lines are too long
269
ch3/ch3-04.html
Normal file
269
ch3/ch3-04.html
Normal file
File diff suppressed because one or more lines are too long
525
ch3/ch3-05.html
Normal file
525
ch3/ch3-05.html
Normal file
File diff suppressed because one or more lines are too long
402
ch3/ch3-06.html
Normal file
402
ch3/ch3-06.html
Normal file
File diff suppressed because one or more lines are too long
240
ch3/ch3.html
Normal file
240
ch3/ch3.html
Normal file
File diff suppressed because one or more lines are too long
325
ch4/ch4-01.html
Normal file
325
ch4/ch4-01.html
Normal file
File diff suppressed because one or more lines are too long
482
ch4/ch4-02.html
Normal file
482
ch4/ch4-02.html
Normal file
File diff suppressed because one or more lines are too long
442
ch4/ch4-03.html
Normal file
442
ch4/ch4-03.html
Normal file
File diff suppressed because one or more lines are too long
495
ch4/ch4-04.html
Normal file
495
ch4/ch4-04.html
Normal file
File diff suppressed because one or more lines are too long
448
ch4/ch4-05.html
Normal file
448
ch4/ch4-05.html
Normal file
File diff suppressed because one or more lines are too long
360
ch4/ch4-06.html
Normal file
360
ch4/ch4-06.html
Normal file
File diff suppressed because one or more lines are too long
240
ch4/ch4.html
Normal file
240
ch4/ch4.html
Normal file
File diff suppressed because one or more lines are too long
276
ch5/ch5-01.html
Normal file
276
ch5/ch5-01.html
Normal file
File diff suppressed because one or more lines are too long
370
ch5/ch5-02.html
Normal file
370
ch5/ch5-02.html
Normal file
File diff suppressed because one or more lines are too long
323
ch5/ch5-03.html
Normal file
323
ch5/ch5-03.html
Normal file
File diff suppressed because one or more lines are too long
362
ch5/ch5-04.html
Normal file
362
ch5/ch5-04.html
Normal file
File diff suppressed because one or more lines are too long
336
ch5/ch5-05.html
Normal file
336
ch5/ch5-05.html
Normal file
File diff suppressed because one or more lines are too long
479
ch5/ch5-06.html
Normal file
479
ch5/ch5-06.html
Normal file
File diff suppressed because one or more lines are too long
281
ch5/ch5-07.html
Normal file
281
ch5/ch5-07.html
Normal file
File diff suppressed because one or more lines are too long
415
ch5/ch5-08.html
Normal file
415
ch5/ch5-08.html
Normal file
File diff suppressed because one or more lines are too long
334
ch5/ch5-09.html
Normal file
334
ch5/ch5-09.html
Normal file
File diff suppressed because one or more lines are too long
288
ch5/ch5-10.html
Normal file
288
ch5/ch5-10.html
Normal file
File diff suppressed because one or more lines are too long
240
ch5/ch5.html
Normal file
240
ch5/ch5.html
Normal file
File diff suppressed because one or more lines are too long
301
ch6/ch6-01.html
Normal file
301
ch6/ch6-01.html
Normal file
File diff suppressed because one or more lines are too long
347
ch6/ch6-02.html
Normal file
347
ch6/ch6-02.html
Normal file
File diff suppressed because one or more lines are too long
331
ch6/ch6-03.html
Normal file
331
ch6/ch6-03.html
Normal file
File diff suppressed because one or more lines are too long
302
ch6/ch6-04.html
Normal file
302
ch6/ch6-04.html
Normal file
File diff suppressed because one or more lines are too long
329
ch6/ch6-05.html
Normal file
329
ch6/ch6-05.html
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user