├── CNAME ├── README.md ├── _config.yml ├── index.md └── stylesheets ├── github-light.css ├── print.css ├── pygment_trac.css └── stylesheet.css /CNAME: -------------------------------------------------------------------------------- 1 | www.raspberrypifullnode.com 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raspberrypifullnode 2 | How to create your own Raspberry Pi Bitcoin full node. 3 | 4 | I wanted to create a simple guide to enable people to create a Bitcoin full node with only a Raspberry Pi. I know articles have been written before, but they become out of date so quickly that I wanted to create something that could be kept up to date indefinately. Feel free to fork at will. 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | title: Raspberrypifullnode 2 | description: How to Create Your Own Bitcoin Full Node With a Raspberry Pi 3 | google_analytics: UA-62136133-1 4 | show_downloads: true 5 | theme: jekyll-theme-architect 6 | 7 | gems: 8 | - jekyll-mentions 9 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | ## Why a Bitcoin Full Node? 2 | Bitcoin is a digital currency supported by a peer-to-peer network. In order to run efficiently and effectively, it needs peers run by different people....and the more the better. 3 | 4 | This tutorial will describe how to create a Bitcoin "full node" (a Bitcoin server that contains the full blockchain and propagates transactions throughout the Bitcoin network via peers). This system *will not* mine for Bitcoins...it *will* play its part to keep the Bitcoin peer-to-peer network healthy and strong. For a detailed explanation for why it is important to have a healthy Bitcoin peer-to-peer network, read this article [about Bitcoin full nodes](https://medium.com/@lopp/bitcoin-nodes-how-many-is-enough-9b8e8f6fd2cf). 5 | 6 | Also please note this will be a "headless" server...meaning we will not be using a GUI to configure Bitcoin or check to see how things are running. In fact, once the server is set up, you will only interact with it using command line calls over [SSH](http://en.wikipedia.org/wiki/Secure_Shell). The idea is to have this full node be simple, low-power, and something that "just runs" in your basement, closet, etc. 7 | 8 | ## Why a Raspberry Pi? 9 | 10 | Raspberry Pi is an inexpensive computing hardware platform that generates little heat, draws little power, and can run silently 24 hours a day without having to think about it. 11 | 12 | ## Background 13 | 14 | I decided to create my own Bitcoin full node on a Raspberry Pi. My Raspberry Pi full node is up and running, performing well, has about 75 peers and is relaying transactions to the Bitcoin network. I have to say, ever since I got it set up it has been low maintenance. 15 | 16 | I am going to assume that if you are reading this to create your own Raspberry Pi bitcoin full node, then you already know a little bit about linux, electronics, or running command line tools like SSH. 17 | 18 | ## Parts List (total cost ~$80) 19 | 20 | * [Raspberry Pi 2 - Model B](https://www.adafruit.com/products/2358) (~$40) 21 | * [Raspberry Pi Case](https://www.adafruit.com/products/2285) (~$5) 22 | * [MicroSD card with 64 GB of storage](http://amzn.com/B00R7CSHWW) (~$25) 23 | * [Mirco USB charger that you can dedicate to the Raspberry Pi](https://www.adafruit.com/products/1995) (~$8) 24 | 25 | * Ethernet CAT45 cable (assuming you have one around somewhere) 26 | * (Temporarily you will need a keyboard and monitor that supports HDMI to make things easier. You don't need this technically, but it sure makes the initial config process much easier.) 27 | 28 | ## Steps to Follow 29 | 30 | 1. **Prepare the MicroSD Card:** The blockchain is growing quickly (30+ GBs at the time of this writing), so I felt 64 GB was a good size for the Raspberry Pi's storage. I suppose you could go for 128 GBs to be even more future-proof, if you are willing to spend the money. The MicroSD card will likely come formatted as exfat, instead of FAT32, but the Raspberry Pi needs FAT32. I recommend using the built-in tools on Windows or Mac OSX to format the MicroSD. If you only have a Linux box to start, you probably already know how to format the microSD card. Since I run a Mac, I just used the built-in Disk Utility and formatted as "MS-DOS (FAT)," which is really FAT32. 31 | 32 | 2. **Install the operating system:** Installing software on a Raspberry Pi can be mildly complicated. I suggest using their [NOOBS](https://www.raspberrypi.org/documentation/installation/noobs.md) install manager to make it painless. Just follow the link for [NOOBS](https://www.raspberrypi.org/documentation/installation/noobs.md), download the files and copy them to your FAT32 microSD card and get ready to turning things on. 33 | 34 | 3. **Initial configuration:** There are ways to avoid using a keyboard, video display, and mouse (KVM) altogether. But in the interest of keeping things simple I recommend putting your Raspberry Pi into its case, **then insert the microSD card** into your Raspberry Pi (trust me, it is easier to put the case on first), hook up the KVM cables, plugin the ethernet cable, and plugin the power. 35 | 36 | At boot up, select Raspbian as your operating system and let NOOBS get the OS set up. Do not bother with any setting that will launch "startx" (the GUI interface) at boot time, since this full node will only be configured via command line. 37 | 38 | 4. **Update Raspberry Pi:** 39 | 40 | Add "en_US.UTF-8 UTF-8" to the locale list and set your time zone and then reboot: 41 | ``` 42 | sudo raspi-config 43 | sudo reboot 44 | ``` 45 | Keep everything fresh: 46 | ``` 47 | sudo apt-get update 48 | sudo apt-get upgrade 49 | ``` 50 | Install dependencies (broken up here to show more cleanly - you can do one apt-get call if you want): 51 | ``` 52 | sudo apt-get install build-essential autoconf libssl-dev libboost-dev 53 | sudo apt-get install libboost-chrono-dev libboost-filesystem-dev 54 | sudo apt-get install libboost-program-options-dev libboost-system-dev 55 | sudo apt-get install libboost-test-dev libboost-thread-dev libtool 56 | ``` 57 | Prepare for and download bitcoin source code: 58 | ``` 59 | mkdir ~/bin 60 | cd ~/bin 61 | git clone -b v0.11.2 https://github.com/bitcoin/bitcoin.git 62 | cd bitcoin/ 63 | ``` 64 | Configure and compile the source code; install to the bin directory (this will take 30+ minutes): 65 | ``` 66 | ./autogen.sh 67 | ./configure CPPFLAGS="-I/usr/local/BerkeleyDB.4.8/include -O2" LDFLAGS="-L/usr/local/BerkeleyDB.4.8/lib" --disable-wallet 68 | make 69 | sudo make install 70 | ``` 71 | 5. **Verify your Bitcoin full node is working:** Assuming all went well (above) you can just type the following in your command line: 72 | 73 | ``` 74 | bitcoind & 75 | ``` 76 | The & at the end tells the app to run in the background so that your command line interface can be used for more commands. If you type the following you will see the status of your Bitcoin full node: 77 | ``` 78 | bitcoin-cli getinfo 79 | ``` 80 | It will likely tell you that it is loading the blockchain or tell you how many blocks have been loaded thus far. If you made it this far, *congratulations!* Unfortunately, you are far from over. 81 | 82 | For now, just stop the Bitcoin server you just worked so hard to start with the following command: 83 | 84 | ``` 85 | bitcoin-cli stop 86 | ```` 87 | 88 | 6. **Side-load the blockchain:** In my experience, the Raspberry Pi 2 with its 1 GB of RAM and quad processors was not able to synchronize the blockchain on its own. Once it gets to about block 300,000 it starts to run out of RAM and all of the coaxing in the world does not help. (Note: one reader of this guide explained that you can control the RAM usage by starting the Bitcoin server with the following command 'bitcoind --dbcache=50 &'. If you want to give it a try, start up the Bitcoin service using that switch and see if that will allow you to synchronize the blockchain without running out of RAM.) Again, just my experience and newer versions of Bitcoin may resolve this issue. 89 | 90 | Solution? Synchronize the blockchain on your primary machine and then simply copy your personal seed of the Bitcoin blockchain to your Raspberry Pi full node. The files you need are in the 'blocks' folder and the 'chainstate' folder. You can use the following command using SCP (basically SSH for copying files) to move the files from your main computer to your Raspberry Pi full node (you can also use WinSCP on a Windows machine or Cyberduck on a Mac - but I prefer the command line): 91 | 92 | ``` 93 | scp -r blocks your_username@raspberrypiIPaddress:/home/pi/.bitcoin 94 | scp -r chainstate your_username@raspberrypiIPaddress:/home/pi/.bitcoin 95 | ``` 96 | 97 | Now you should be able to start up your bitcoin server again and start relaying Bitcoin transactions in realtime. Just execute the Bitcoin server command: 98 | 99 | ``` 100 | bitcoind & 101 | ```` 102 | 103 | 7. **Make sure port forwarding is turned on in your router:** One more, quite important thing...you need to enable port forwarding on your router to point to *port 8333* to your internal Bitcoin full node IP address. I'm not sure if you need both TCP and UDP forwarded, but I did both and everything is working great. How do you do this? Each router is different and each cable/fiber/DSL provider has instructions somewhere. Your router, in fact, might automatically do it for you, since gaming machines like the XBOX and Playstation benefit from port forwarding and ISPs don't want to deal with explaining how to set it up, so they auto-detect services you are running that need port forwarding and make it happen. 104 | 105 | Why do you need port forwarding? Basically it allows other Bitcoin peers to automatically connect to *you* without the need for you to invite them first. Without port forwarding you will have far fewer peers and not allow the Bitcoin network to be healthy. So much so, that you cannot really claim you are running a full node without port forwarding (or wide open IP access) enabled. 106 | 107 | ## **You're Done!** 108 | 109 | You should be all set! Remember when you want to check in on things just open and SSH connection and run: 110 | 111 | ``` 112 | bitcoin-cli getinfo 113 | ``` 114 | 115 | ## Like this information and want to tip me in Bitcoin? -thanks! 116 | 117 | ![Bitcoin Tip Address](https://s3.amazonaws.com/dcarns/Public/bitcoinaddress.png) 118 | 119 | [19qNSoJdTfRLNoXJUBndgcd9uusr1BroY](bitcoin://19qNSoJdTfRLNoXJUBndgcd9uusr1BroY) -------------------------------------------------------------------------------- /stylesheets/github-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 GitHub Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | 18 | .pl-c /* comment */ { 19 | color: #969896; 20 | } 21 | 22 | .pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */, 23 | .pl-s .pl-v /* string variable */ { 24 | color: #0086b3; 25 | } 26 | 27 | .pl-e /* entity */, 28 | .pl-en /* entity.name */ { 29 | color: #795da3; 30 | } 31 | 32 | .pl-s .pl-s1 /* string source */, 33 | .pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ { 34 | color: #333; 35 | } 36 | 37 | .pl-ent /* entity.name.tag */ { 38 | color: #63a35c; 39 | } 40 | 41 | .pl-k /* keyword, storage, storage.type */ { 42 | color: #a71d5d; 43 | } 44 | 45 | .pl-pds /* punctuation.definition.string, string.regexp.character-class */, 46 | .pl-s /* string */, 47 | .pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, 48 | .pl-sr /* string.regexp */, 49 | .pl-sr .pl-cce /* string.regexp constant.character.escape */, 50 | .pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */, 51 | .pl-sr .pl-sre /* string.regexp source.ruby.embedded */ { 52 | color: #183691; 53 | } 54 | 55 | .pl-v /* variable */ { 56 | color: #ed6a43; 57 | } 58 | 59 | .pl-id /* invalid.deprecated */ { 60 | color: #b52a1d; 61 | } 62 | 63 | .pl-ii /* invalid.illegal */ { 64 | background-color: #b52a1d; 65 | color: #f8f8f8; 66 | } 67 | 68 | .pl-sr .pl-cce /* string.regexp constant.character.escape */ { 69 | color: #63a35c; 70 | font-weight: bold; 71 | } 72 | 73 | .pl-ml /* markup.list */ { 74 | color: #693a17; 75 | } 76 | 77 | .pl-mh /* markup.heading */, 78 | .pl-mh .pl-en /* markup.heading entity.name */, 79 | .pl-ms /* meta.separator */ { 80 | color: #1d3e81; 81 | font-weight: bold; 82 | } 83 | 84 | .pl-mq /* markup.quote */ { 85 | color: #008080; 86 | } 87 | 88 | .pl-mi /* markup.italic */ { 89 | color: #333; 90 | font-style: italic; 91 | } 92 | 93 | .pl-mb /* markup.bold */ { 94 | color: #333; 95 | font-weight: bold; 96 | } 97 | 98 | .pl-md /* markup.deleted, meta.diff.header.from-file */ { 99 | background-color: #ffecec; 100 | color: #bd2c00; 101 | } 102 | 103 | .pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { 104 | background-color: #eaffea; 105 | color: #55a532; 106 | } 107 | 108 | .pl-mdr /* meta.diff.range */ { 109 | color: #795da3; 110 | font-weight: bold; 111 | } 112 | 113 | .pl-mo /* meta.output */ { 114 | color: #1d3e81; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /stylesheets/print.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, ol, ul, li, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td, 10 | article, aside, canvas, details, embed, 11 | figure, figcaption, footer, header, hgroup, 12 | menu, nav, output, ruby, section, summary, 13 | time, mark, audio, video { 14 | padding: 0; 15 | margin: 0; 16 | font: inherit; 17 | font-size: 100%; 18 | vertical-align: baseline; 19 | border: 0; 20 | } 21 | /* HTML5 display-role reset for older browsers */ 22 | article, aside, details, figcaption, figure, 23 | footer, header, hgroup, menu, nav, section { 24 | display: block; 25 | } 26 | body { 27 | line-height: 1; 28 | } 29 | ol, ul { 30 | list-style: none; 31 | } 32 | blockquote, q { 33 | quotes: none; 34 | } 35 | blockquote:before, blockquote:after, 36 | q:before, q:after { 37 | content: ''; 38 | content: none; 39 | } 40 | table { 41 | border-spacing: 0; 42 | border-collapse: collapse; 43 | } 44 | body { 45 | font-family: 'Helvetica Neue', Helvetica, Arial, serif; 46 | font-size: 13px; 47 | line-height: 1.5; 48 | color: #000; 49 | } 50 | 51 | a { 52 | font-weight: bold; 53 | color: #d5000d; 54 | } 55 | 56 | header { 57 | padding-top: 35px; 58 | padding-bottom: 10px; 59 | } 60 | 61 | header h1 { 62 | font-size: 48px; 63 | font-weight: bold; 64 | line-height: 1.2; 65 | color: #303030; 66 | letter-spacing: -1px; 67 | } 68 | 69 | header h2 { 70 | font-size: 24px; 71 | font-weight: normal; 72 | line-height: 1.3; 73 | color: #aaa; 74 | letter-spacing: -1px; 75 | } 76 | #downloads { 77 | display: none; 78 | } 79 | #main_content { 80 | padding-top: 20px; 81 | } 82 | 83 | code, pre { 84 | margin-bottom: 30px; 85 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal; 86 | font-size: 12px; 87 | color: #222; 88 | } 89 | 90 | code { 91 | padding: 0 3px; 92 | } 93 | 94 | pre { 95 | padding: 20px; 96 | overflow: auto; 97 | border: solid 1px #ddd; 98 | } 99 | pre code { 100 | padding: 0; 101 | } 102 | 103 | ul, ol, dl { 104 | margin-bottom: 20px; 105 | } 106 | 107 | 108 | /* COMMON STYLES */ 109 | 110 | table { 111 | width: 100%; 112 | border: 1px solid #ebebeb; 113 | } 114 | 115 | th { 116 | font-weight: 500; 117 | } 118 | 119 | td { 120 | font-weight: 300; 121 | text-align: center; 122 | border: 1px solid #ebebeb; 123 | } 124 | 125 | form { 126 | padding: 20px; 127 | background: #f2f2f2; 128 | 129 | } 130 | 131 | 132 | /* GENERAL ELEMENT TYPE STYLES */ 133 | 134 | h1 { 135 | font-size: 2.8em; 136 | } 137 | 138 | h2 { 139 | margin-bottom: 8px; 140 | font-size: 22px; 141 | font-weight: bold; 142 | color: #303030; 143 | } 144 | 145 | h3 { 146 | margin-bottom: 8px; 147 | font-size: 18px; 148 | font-weight: bold; 149 | color: #d5000d; 150 | } 151 | 152 | h4 { 153 | font-size: 16px; 154 | font-weight: bold; 155 | color: #303030; 156 | } 157 | 158 | h5 { 159 | font-size: 1em; 160 | color: #303030; 161 | } 162 | 163 | h6 { 164 | font-size: .8em; 165 | color: #303030; 166 | } 167 | 168 | p { 169 | margin-bottom: 20px; 170 | font-weight: 300; 171 | } 172 | 173 | a { 174 | text-decoration: none; 175 | } 176 | 177 | p a { 178 | font-weight: 400; 179 | } 180 | 181 | blockquote { 182 | padding: 0 0 0 30px; 183 | margin-bottom: 20px; 184 | font-size: 1.6em; 185 | border-left: 10px solid #e9e9e9; 186 | } 187 | 188 | ul li { 189 | padding-left: 20px; 190 | list-style-position: inside; 191 | list-style: disc; 192 | } 193 | 194 | ol li { 195 | padding-left: 3px; 196 | list-style-position: inside; 197 | list-style: decimal; 198 | } 199 | 200 | dl dd { 201 | font-style: italic; 202 | font-weight: 100; 203 | } 204 | 205 | footer { 206 | padding-top: 20px; 207 | padding-bottom: 30px; 208 | margin-top: 40px; 209 | font-size: 13px; 210 | color: #aaa; 211 | } 212 | 213 | footer a { 214 | color: #666; 215 | } 216 | 217 | /* MISC */ 218 | .clearfix:after { 219 | display: block; 220 | height: 0; 221 | clear: both; 222 | visibility: hidden; 223 | content: '.'; 224 | } 225 | 226 | .clearfix {display: inline-block;} 227 | * html .clearfix {height: 1%;} 228 | .clearfix {display: block;} 229 | -------------------------------------------------------------------------------- /stylesheets/pygment_trac.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; } 2 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { font-weight: bold } /* Keyword */ 5 | .highlight .o { font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 20 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 24 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */ 25 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 26 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 27 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 28 | .highlight .m { color: #009999 } /* Literal.Number */ 29 | .highlight .s { color: #d14 } /* Literal.String */ 30 | .highlight .na { color: #008080 } /* Name.Attribute */ 31 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 32 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 33 | .highlight .no { color: #008080 } /* Name.Constant */ 34 | .highlight .ni { color: #800080 } /* Name.Entity */ 35 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 36 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 37 | .highlight .nn { color: #555555 } /* Name.Namespace */ 38 | .highlight .nt { color: #000080 } /* Name.Tag */ 39 | .highlight .nv { color: #008080 } /* Name.Variable */ 40 | .highlight .ow { font-weight: bold } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 48 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 50 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 51 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 62 | 63 | .type-csharp .highlight .k { color: #0000FF } 64 | .type-csharp .highlight .kt { color: #0000FF } 65 | .type-csharp .highlight .nf { color: #000000; font-weight: normal } 66 | .type-csharp .highlight .nc { color: #2B91AF } 67 | .type-csharp .highlight .nn { color: #000000 } 68 | .type-csharp .highlight .s { color: #A31515 } 69 | .type-csharp .highlight .sc { color: #A31515 } 70 | -------------------------------------------------------------------------------- /stylesheets/stylesheet.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -webkit-text-size-adjust: 100%; /* 2 */ 12 | -ms-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | margin: 0.67em 0; 137 | font-size: 2em; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | color: #000; 146 | background: #ff0; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | position: relative; 164 | font-size: 75%; 165 | line-height: 0; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | height: 0; 213 | -moz-box-sizing: content-box; 214 | box-sizing: content-box; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | margin: 0; /* 3 */ 258 | font: inherit; /* 2 */ 259 | color: inherit; /* 1 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | padding: 0; 314 | border: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-box-sizing: content-box; /* 2 */ 359 | -moz-box-sizing: content-box; 360 | box-sizing: content-box; 361 | -webkit-appearance: textfield; /* 1 */ 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | padding: 0.35em 0.625em 0.75em; 381 | margin: 0 2px; 382 | border: 1px solid #c0c0c0; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | padding: 0; /* 2 */ 392 | border: 0; /* 1 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-spacing: 0; 421 | border-collapse: collapse; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } 428 | 429 | /* LAYOUT STYLES */ 430 | body { 431 | font-family: 'Helvetica Neue', Helvetica, Arial, serif; 432 | font-size: 15px; 433 | font-weight: 400; 434 | line-height: 1.5; 435 | color: #666; 436 | background: #fafafa url(../images/body-bg.jpg) 0 0 repeat; 437 | } 438 | 439 | p { 440 | margin-top: 0; 441 | } 442 | 443 | a { 444 | color: #2879d0; 445 | } 446 | a:hover { 447 | color: #2268b2; 448 | } 449 | 450 | header { 451 | padding-top: 40px; 452 | padding-bottom: 40px; 453 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 454 | background: #2e7bcf url(../images/header-bg.jpg) 0 0 repeat-x; 455 | border-bottom: solid 1px #275da1; 456 | } 457 | 458 | header h1 { 459 | width: 540px; 460 | margin-top: 0; 461 | margin-bottom: 0.2em; 462 | font-size: 72px; 463 | font-weight: normal; 464 | line-height: 1; 465 | color: #fff; 466 | letter-spacing: -1px; 467 | } 468 | 469 | header h2 { 470 | width: 540px; 471 | margin-top: 0; 472 | margin-bottom: 0; 473 | font-size: 26px; 474 | font-weight: normal; 475 | line-height: 1.3; 476 | color: #9ddcff; 477 | letter-spacing: 0; 478 | } 479 | 480 | .inner { 481 | position: relative; 482 | width: 940px; 483 | margin: 0 auto; 484 | } 485 | 486 | #content-wrapper { 487 | padding-top: 30px; 488 | border-top: solid 1px #fff; 489 | } 490 | 491 | #main-content { 492 | float: left; 493 | width: 690px; 494 | } 495 | 496 | #main-content img { 497 | max-width: 100%; 498 | } 499 | 500 | aside#sidebar { 501 | float: right; 502 | width: 200px; 503 | min-height: 504px; 504 | padding-left: 20px; 505 | font-size: 12px; 506 | line-height: 1.3; 507 | background: transparent url(../images/sidebar-bg.jpg) 0 0 no-repeat; 508 | } 509 | 510 | aside#sidebar p.repo-owner, 511 | aside#sidebar p.repo-owner a { 512 | font-weight: bold; 513 | } 514 | 515 | #downloads { 516 | margin-bottom: 40px; 517 | } 518 | 519 | a.button { 520 | width: 134px; 521 | height: 58px; 522 | padding-top: 22px; 523 | padding-left: 68px; 524 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 525 | font-size: 23px; 526 | line-height: 1.2; 527 | color: #fff; 528 | } 529 | a.button small { 530 | display: block; 531 | font-size: 11px; 532 | } 533 | header a.button { 534 | position: absolute; 535 | top: 0; 536 | right: 0; 537 | background: transparent url(../images/github-button.png) 0 0 no-repeat; 538 | } 539 | aside a.button { 540 | display: block; 541 | width: 138px; 542 | padding-left: 64px; 543 | margin-bottom: 20px; 544 | font-size: 21px; 545 | background: transparent url(../images/download-button.png) 0 0 no-repeat; 546 | } 547 | 548 | code, pre { 549 | margin-bottom: 30px; 550 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; 551 | font-size: 13px; 552 | color: #222; 553 | } 554 | 555 | code { 556 | padding: 0 3px; 557 | background-color: #f2f8fc; 558 | border: solid 1px #dbe7f3; 559 | } 560 | 561 | pre { 562 | padding: 20px; 563 | overflow: auto; 564 | text-shadow: none; 565 | background: #fff; 566 | border: solid 1px #f2f2f2; 567 | } 568 | pre code { 569 | padding: 0; 570 | color: #2879d0; 571 | background-color: #fff; 572 | border: none; 573 | } 574 | 575 | ul, ol, dl { 576 | margin-bottom: 20px; 577 | } 578 | 579 | 580 | /* COMMON STYLES */ 581 | 582 | hr { 583 | height: 0; 584 | margin-top: 1em; 585 | margin-bottom: 1em; 586 | border: 0; 587 | border-top: solid 1px #ddd; 588 | } 589 | 590 | table { 591 | width: 100%; 592 | border: 1px solid #ebebeb; 593 | } 594 | 595 | th { 596 | font-weight: 500; 597 | } 598 | 599 | td { 600 | font-weight: 300; 601 | text-align: center; 602 | border: 1px solid #ebebeb; 603 | } 604 | 605 | form { 606 | padding: 20px; 607 | background: #f2f2f2; 608 | 609 | } 610 | 611 | 612 | /* GENERAL ELEMENT TYPE STYLES */ 613 | 614 | #main-content h1 { 615 | margin-top: 0; 616 | margin-bottom: 0; 617 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 618 | font-size: 2.8em; 619 | font-weight: normal; 620 | color: #474747; 621 | text-indent: 6px; 622 | letter-spacing: -1px; 623 | } 624 | 625 | #main-content h1:before { 626 | padding-right: 0.3em; 627 | margin-left: -0.9em; 628 | color: #9ddcff; 629 | content: "/"; 630 | } 631 | 632 | #main-content h2 { 633 | margin-bottom: 8px; 634 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 635 | font-size: 22px; 636 | font-weight: bold; 637 | color: #474747; 638 | text-indent: 4px; 639 | } 640 | #main-content h2:before { 641 | padding-right: 0.3em; 642 | margin-left: -1.5em; 643 | content: "//"; 644 | color: #9ddcff; 645 | } 646 | 647 | #main-content h3 { 648 | margin-top: 24px; 649 | margin-bottom: 8px; 650 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 651 | font-size: 18px; 652 | font-weight: bold; 653 | color: #474747; 654 | text-indent: 3px; 655 | } 656 | 657 | #main-content h3:before { 658 | padding-right: 0.3em; 659 | margin-left: -2em; 660 | content: "///"; 661 | color: #9ddcff; 662 | } 663 | 664 | #main-content h4 { 665 | margin-bottom: 8px; 666 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 667 | font-size: 15px; 668 | font-weight: bold; 669 | color: #474747; 670 | text-indent: 3px; 671 | } 672 | 673 | h4:before { 674 | padding-right: 0.3em; 675 | margin-left: -2.8em; 676 | content: "////"; 677 | color: #9ddcff; 678 | } 679 | 680 | #main-content h5 { 681 | margin-bottom: 8px; 682 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 683 | font-size: 14px; 684 | color: #474747; 685 | text-indent: 3px; 686 | } 687 | h5:before { 688 | padding-right: 0.3em; 689 | margin-left: -3.2em; 690 | content: "/////"; 691 | color: #9ddcff; 692 | } 693 | 694 | #main-content h6 { 695 | margin-bottom: 8px; 696 | font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; 697 | font-size: .8em; 698 | color: #474747; 699 | text-indent: 3px; 700 | } 701 | h6:before { 702 | padding-right: 0.3em; 703 | margin-left: -3.7em; 704 | content: "//////"; 705 | color: #9ddcff; 706 | } 707 | 708 | p { 709 | margin-bottom: 20px; 710 | } 711 | 712 | a { 713 | text-decoration: none; 714 | } 715 | 716 | p a { 717 | font-weight: 400; 718 | } 719 | 720 | blockquote { 721 | padding: 0 0 0 30px; 722 | margin-bottom: 20px; 723 | font-size: 1.6em; 724 | border-left: 10px solid #e9e9e9; 725 | } 726 | 727 | ul { 728 | list-style-position: inside; 729 | list-style: disc; 730 | padding-left: 20px; 731 | } 732 | 733 | ol { 734 | list-style-position: inside; 735 | list-style: decimal; 736 | padding-left: 3px; 737 | } 738 | 739 | dl dd { 740 | font-style: italic; 741 | font-weight: 100; 742 | } 743 | 744 | footer { 745 | padding-top: 20px; 746 | padding-bottom: 30px; 747 | margin-top: 40px; 748 | font-size: 13px; 749 | color: #aaa; 750 | background: transparent url('../images/hr.png') 0 0 no-repeat; 751 | } 752 | 753 | footer a { 754 | color: #666; 755 | } 756 | footer a:hover { 757 | color: #444; 758 | } 759 | 760 | /* MISC */ 761 | .clearfix:after { 762 | display: block; 763 | height: 0; 764 | clear: both; 765 | visibility: hidden; 766 | content: '.'; 767 | } 768 | 769 | .clearfix {display: inline-block;} 770 | * html .clearfix {height: 1%;} 771 | .clearfix {display: block;} 772 | 773 | /* #Media Queries 774 | ================================================== */ 775 | 776 | /* Smaller than standard 960 (devices and browsers) */ 777 | @media only screen and (max-width: 959px) { } 778 | 779 | /* Tablet Portrait size to standard 960 (devices and browsers) */ 780 | @media only screen and (min-width: 768px) and (max-width: 959px) { 781 | .inner { 782 | width: 740px; 783 | } 784 | header h1, header h2 { 785 | width: 340px; 786 | } 787 | header h1 { 788 | font-size: 60px; 789 | } 790 | header h2 { 791 | font-size: 30px; 792 | } 793 | #main-content { 794 | width: 490px; 795 | } 796 | #main-content h1:before, 797 | #main-content h2:before, 798 | #main-content h3:before, 799 | #main-content h4:before, 800 | #main-content h5:before, 801 | #main-content h6:before { 802 | padding-right: 0; 803 | margin-left: 0; 804 | content: none; 805 | } 806 | } 807 | 808 | /* All Mobile Sizes (devices and browser) */ 809 | @media only screen and (max-width: 767px) { 810 | .inner { 811 | width: 93%; 812 | } 813 | header { 814 | padding: 20px 0; 815 | } 816 | header .inner { 817 | position: relative; 818 | } 819 | header h1, header h2 { 820 | width: 100%; 821 | } 822 | header h1 { 823 | font-size: 48px; 824 | } 825 | header h2 { 826 | font-size: 24px; 827 | } 828 | header a.button { 829 | position: relative; 830 | display: inline-block; 831 | width: auto; 832 | height: auto; 833 | padding: 5px 10px; 834 | margin-top: 15px; 835 | font-size: 13px; 836 | line-height: 1; 837 | color: #2879d0; 838 | text-align: center; 839 | background-color: #9ddcff; 840 | background-image: none; 841 | border-radius: 5px; 842 | -moz-border-radius: 5px; 843 | -webkit-border-radius: 5px; 844 | } 845 | header a.button small { 846 | display: inline; 847 | font-size: 13px; 848 | } 849 | #main-content, 850 | aside#sidebar { 851 | float: none; 852 | width: 100% ! important; 853 | } 854 | aside#sidebar { 855 | min-height: 0; 856 | padding: 20px 0; 857 | margin-top: 20px; 858 | background-image: none; 859 | border-top: solid 1px #ddd; 860 | } 861 | aside#sidebar a.button { 862 | display: none; 863 | } 864 | #main-content h1:before, 865 | #main-content h2:before, 866 | #main-content h3:before, 867 | #main-content h4:before, 868 | #main-content h5:before, 869 | #main-content h6:before { 870 | padding-right: 0; 871 | margin-left: 0; 872 | content: none; 873 | } 874 | } 875 | 876 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ 877 | @media only screen and (min-width: 480px) and (max-width: 767px) { } 878 | 879 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ 880 | @media only screen and (max-width: 479px) { } 881 | 882 | --------------------------------------------------------------------------------