[
  {
    "path": "_config.yml",
    "content": "title: gonet/2\ndescription: a game server skeleton in microservice\ngoogle_analytics: \nshow_downloads: true\ntheme: jekyll-theme-dinky\n\ngems:\n  - jekyll-mentions\n"
  },
  {
    "path": "index.md",
    "content": "# 欢迎使用\r\n[gonet/2](https://github.com/gonet2)是新一代游戏服务器骨架，基于[go语言](http://golang.org)开发，采用了先进的[http/2](http://http2.github.io/)作为服务器端主要通信协议，以[microservice](http://martinfowler.com/articles/microservices.html)作为主要思想进行架构，采用[docker](https://www.docker.com/)作为服务发布手段。相比第一代[gonet](http://github.com/xtaci/gonet)，基础技术选型更加先进，结构更加清晰易读可扩展。\r\n\r\n## 相关文档\r\n1. [INSTALL.md](https://github.com/gonet2/doc/blob/master/INSTALL.md) -- 安装\r\n2. [CICD.md](https://github.com/gonet2/doc/blob/master/CICD.md) -- 持续集成与持续部署\r\n\r\n## 为什么用microservice架构?\r\n业务分离是游戏服务器架构的基本思路，通过职能划分，能够更加合理的调配服务器资源。\r\n资源的大分类包括，IO,CPU,MEM,BANDWIDTH, 例如常见的情景：        \r\n\r\n    IO: 如: 数据库，文件服务，消耗大量读写        \r\n    CPU: 如: 游戏逻辑，消耗大量指令        \r\n    MEM: 如: 分词，排名，pubsub， 消耗大量内存   \r\n    BANDWIDTH: 内网带宽高，外网带宽低，物理上越接近的，传输速度越高\r\n\r\n玩家对每种服务的请求量有**巨大的不同**，比如逻辑请求100次，分词请求1次，所以，没有必要1:1配置资源，通过microservice方式分离服务，可以根据业务使用情况，按需配置服务器资源。当服务容量增长，如果在monolithic的架构上做，即全部服务揉在一起成一个大进程，会严重浪费资源，比如大量内存被极少被使用的模块占用, 更严重的问题是，单台服务器的资源不是无限制的，虽然目前顶级配置的服务器可以安装高达96GB的内存，但也极其昂贵，部署量大的时候，产生的费用也不容小觑。\r\n\r\n## 为什么选HTTP/2?\r\n为了把所有的服务串起来，必须满足的条件有：    \r\n1. 支持一元RPC调用 (一般的请求/应答模式，类似于函数调用)      \r\n2. 支持服务器推送（例如pubsub服务，异步通知）        \r\n3. 支持双向流传递 (网关透传设备数据包到后端，后端应答数据经过网关返回到设备)        \r\n\r\n我们暂不想自己设计[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call)，一是目前RPC繁多，没必要重新发明轮子，二是作为开源项目，应充分融入社区，利用现有资源。我们发现目前http/2(rfc7540)满足以上所有条件，google推出的[gRPC](http://grpc.io/)就是一个基于http/2的RPC实现，当前架构中，所有的服务(microservice)全部通过gRPC连接在一起。 http/2支持stream multiplex，即可以在同一条TCP连接上，传输多个stream(1:N)，stream概念能够非常直观的1:1映射玩家双向数据流。\r\n\r\n(**请特别注意一点:** HTTP/2仅用于服务器各个服务间的内部通信，和客户端的通信是自定义协议，位于：https://github.com/gonet2/tools/tree/master/proto_scripts)\r\n\r\n附: HTTP/2 帧封装         \r\n\r\n        +-----------------------------------------------+\r\n        |                 Length (24)                   |\r\n        +---------------+---------------+---------------+\r\n        |   Type (8)    |   Flags (8)   |\r\n        +-+-------------+---------------+-------------------------------+\r\n        |R|                 Stream Identifier (31)                      |\r\n        +=+=============================================================+\r\n        |                   Frame Payload (0...)                      ...\r\n        +---------------------------------------------------------------+\r\n    \r\n                              Figure 1: Frame Layout\r\n          \r\n## 基本服务模型 \r\n\r\n                 +\r\n                 |\r\n                 |\r\n                 +----> game1\r\n                 |\r\n    agent1+------>\r\n                 |\r\n                 +----> game2\r\n                 |                +\r\n    agent2+------>                +-----> snowflake\r\n                 |                |\r\n                 +----> game3+---->\r\n                 |                |\r\n                 |                +-----> chat\r\n                 ++               |\r\n                                  +-----> rank\r\n                                  +        \r\n\r\n使用方式假定为：         \r\n\r\n1. 前端用两个部署在不同物理服务器上的agent服务接入，无状态，客户端随机访问任意一台agent接入，比如使用DNS round-robin方式连接。\r\n2. agent和auth配合处理完鉴权等工作后，数据包透传进入game进行逻辑处理。如果有多台game服务器，那么用户需要指定一个映射关系(userid->server_id)，用来将玩家固定联入某台game服务器。\r\n3. game和各个独立service通信，配合处理逻辑。service如果是无状态的，默认采用round-robin方式请求服务，如果是带状态的，则根据标识联入指定服务器。\r\n\r\n具体的服务描述以及使用案例，请进入各个目录中阅读。\r\n\r\n## 实际项目中怎么使用gonet/2?\r\nclone下来慢慢改，不提供插件接口式的可升级模块，gonet/2只提供关键通路和demo，我不想做一个侵入式的骨架，只想在架构层面提供一个我认为比较优秀的思路并在此基础上努力做到整体最优。\r\n\r\n## 模块划分\r\n进入每个服务阅读对应文档      \r\n1. [agent](https://github.com/gonet2/agent): 网关      \r\n2. [game](https://github.com/gonet2/game): 游戏逻辑     \r\n3. [snowflake](https://github.com/gonet2/snowflake): UUID发生器      \r\n\r\n## 模块设计约定\r\n1. **零**配置，配置集中化到coordinator(etcd/consul)，即：/etc distributed概念。                    \r\n2. **理论上**，唯一可能需要的配置为ETCD_HOST环境变量，用于指定ETCD地址。          \r\n3. 其他模块特定的参数(SERVER_ID什么的)，也通过环境变量指定，docker能方便的设定。\r\n\r\n## 日志分析模型\r\n![loganalyticmodel](http://gonet2.github.io/log.png)\r\n\r\n日志分析是通往数据驱动的关键步骤，内容过于庞大，暂留组建图于此，有机会再详谈。\r\n\r\n## 基础设施\r\n\r\n![design](http://gonet2.github.io/design.png)\r\n\r\n术语：\r\n\r\n1. coordinator -- zk, etcd这种分布式一致性服务。\r\n2. message backbone -- 服务器件消息总线，通常为pub/sub模式，数据密集。\r\n\r\n基础设施是用于支撑整个架构的基石。\r\n\r\n## 链接\r\n* [gonet/2 unity 客户端网络库](https://github.com/en/libunity) -- by ycs\r\n* [Gonet2游戏服务器框架解析](http://blog.csdn.net/q26335804/article/category/5726691)  -- by 高\r\n* [grpc,nsq等源码分析](https://github.com/tenywen/share) -- by tenywen\r\n* [Protobuf安装] (http://ivecode.blog.163.com/blog/static/22094902020156225235159/) -- by __IveCode\r\n\r\nPS. 感谢热心网友对源码的解读\r\n\r\n## 资料\r\n* protobuf: https://github.com/google/protobuf\r\n* protobuf golang plugin: https://github.com/golang/protobuf\r\n* grpc: http://grpc.io\r\n* http/2: http://http2.github.io/\r\n"
  },
  {
    "path": "javascripts/main.js",
    "content": "console.log('This would be the main JS file.');\n"
  },
  {
    "path": "javascripts/respond.js",
    "content": "if(typeof Object.create!==\"function\"){\nObject.create=function(o){\nfunction F(){\n};\nF.prototype=o;\nreturn new F();\n};\n}\nvar ua={toString:function(){\nreturn navigator.userAgent;\n},test:function(s){\nreturn this.toString().toLowerCase().indexOf(s.toLowerCase())>-1;\n}};\nua.version=(ua.toString().toLowerCase().match(/[\\s\\S]+(?:rv|it|ra|ie)[\\/: ]([\\d.]+)/)||[])[1];\nua.webkit=ua.test(\"webkit\");\nua.gecko=ua.test(\"gecko\")&&!ua.webkit;\nua.opera=ua.test(\"opera\");\nua.ie=ua.test(\"msie\")&&!ua.opera;\nua.ie6=ua.ie&&document.compatMode&&typeof document.documentElement.style.maxHeight===\"undefined\";\nua.ie7=ua.ie&&document.documentElement&&typeof document.documentElement.style.maxHeight!==\"undefined\"&&typeof XDomainRequest===\"undefined\";\nua.ie8=ua.ie&&typeof XDomainRequest!==\"undefined\";\nvar domReady=function(){\nvar _1=[];\nvar _2=function(){\nif(!arguments.callee.done){\narguments.callee.done=true;\nfor(var i=0;i<_1.length;i++){\n_1[i]();\n}\n}\n};\nif(document.addEventListener){\ndocument.addEventListener(\"DOMContentLoaded\",_2,false);\n}\nif(ua.ie){\n(function(){\ntry{\ndocument.documentElement.doScroll(\"left\");\n}\ncatch(e){\nsetTimeout(arguments.callee,50);\nreturn;\n}\n_2();\n})();\ndocument.onreadystatechange=function(){\nif(document.readyState===\"complete\"){\ndocument.onreadystatechange=null;\n_2();\n}\n};\n}\nif(ua.webkit&&document.readyState){\n(function(){\nif(document.readyState!==\"loading\"){\n_2();\n}else{\nsetTimeout(arguments.callee,10);\n}\n})();\n}\nwindow.onload=_2;\nreturn function(fn){\nif(typeof fn===\"function\"){\n_1[_1.length]=fn;\n}\nreturn fn;\n};\n}();\nvar cssHelper=function(){\nvar _3={BLOCKS:/[^\\s{][^{]*\\{(?:[^{}]*\\{[^{}]*\\}[^{}]*|[^{}]*)*\\}/g,BLOCKS_INSIDE:/[^\\s{][^{]*\\{[^{}]*\\}/g,DECLARATIONS:/[a-zA-Z\\-]+[^;]*:[^;]+;/g,RELATIVE_URLS:/url\\(['\"]?([^\\/\\)'\"][^:\\)'\"]+)['\"]?\\)/g,REDUNDANT_COMPONENTS:/(?:\\/\\*([^*\\\\\\\\]|\\*(?!\\/))+\\*\\/|@import[^;]+;)/g,REDUNDANT_WHITESPACE:/\\s*(,|:|;|\\{|\\})\\s*/g,MORE_WHITESPACE:/\\s{2,}/g,FINAL_SEMICOLONS:/;\\}/g,NOT_WHITESPACE:/\\S+/g};\nvar _4,_5=false;\nvar _6=[];\nvar _7=function(fn){\nif(typeof fn===\"function\"){\n_6[_6.length]=fn;\n}\n};\nvar _8=function(){\nfor(var i=0;i<_6.length;i++){\n_6[i](_4);\n}\n};\nvar _9={};\nvar _a=function(n,v){\nif(_9[n]){\nvar _b=_9[n].listeners;\nif(_b){\nfor(var i=0;i<_b.length;i++){\n_b[i](v);\n}\n}\n}\n};\nvar _c=function(_d,_e,_f){\nif(ua.ie&&!window.XMLHttpRequest){\nwindow.XMLHttpRequest=function(){\nreturn new ActiveXObject(\"Microsoft.XMLHTTP\");\n};\n}\nif(!XMLHttpRequest){\nreturn \"\";\n}\nvar r=new XMLHttpRequest();\ntry{\nr.open(\"get\",_d,true);\nr.setRequestHeader(\"X_REQUESTED_WITH\",\"XMLHttpRequest\");\n}\ncatch(e){\n_f();\nreturn;\n}\nvar _10=false;\nsetTimeout(function(){\n_10=true;\n},5000);\ndocument.documentElement.style.cursor=\"progress\";\nr.onreadystatechange=function(){\nif(r.readyState===4&&!_10){\nif(!r.status&&location.protocol===\"file:\"||(r.status>=200&&r.status<300)||r.status===304||navigator.userAgent.indexOf(\"Safari\")>-1&&typeof r.status===\"undefined\"){\n_e(r.responseText);\n}else{\n_f();\n}\ndocument.documentElement.style.cursor=\"\";\nr=null;\n}\n};\nr.send(\"\");\n};\nvar _11=function(_12){\n_12=_12.replace(_3.REDUNDANT_COMPONENTS,\"\");\n_12=_12.replace(_3.REDUNDANT_WHITESPACE,\"$1\");\n_12=_12.replace(_3.MORE_WHITESPACE,\" \");\n_12=_12.replace(_3.FINAL_SEMICOLONS,\"}\");\nreturn _12;\n};\nvar _13={mediaQueryList:function(s){\nvar o={};\nvar idx=s.indexOf(\"{\");\nvar lt=s.substring(0,idx);\ns=s.substring(idx+1,s.length-1);\nvar mqs=[],rs=[];\nvar qts=lt.toLowerCase().substring(7).split(\",\");\nfor(var i=0;i<qts.length;i++){\nmqs[mqs.length]=_13.mediaQuery(qts[i],o);\n}\nvar rts=s.match(_3.BLOCKS_INSIDE);\nif(rts!==null){\nfor(i=0;i<rts.length;i++){\nrs[rs.length]=_13.rule(rts[i],o);\n}\n}\no.getMediaQueries=function(){\nreturn mqs;\n};\no.getRules=function(){\nreturn rs;\n};\no.getListText=function(){\nreturn lt;\n};\no.getCssText=function(){\nreturn s;\n};\nreturn o;\n},mediaQuery:function(s,mql){\ns=s||\"\";\nvar not=false,_14;\nvar exp=[];\nvar _15=true;\nvar _16=s.match(_3.NOT_WHITESPACE);\nfor(var i=0;i<_16.length;i++){\nvar _17=_16[i];\nif(!_14&&(_17===\"not\"||_17===\"only\")){\nif(_17===\"not\"){\nnot=true;\n}\n}else{\nif(!_14){\n_14=_17;\n}else{\nif(_17.charAt(0)===\"(\"){\nvar _18=_17.substring(1,_17.length-1).split(\":\");\nexp[exp.length]={mediaFeature:_18[0],value:_18[1]||null};\n}\n}\n}\n}\nreturn {getList:function(){\nreturn mql||null;\n},getValid:function(){\nreturn _15;\n},getNot:function(){\nreturn not;\n},getMediaType:function(){\nreturn _14;\n},getExpressions:function(){\nreturn exp;\n}};\n},rule:function(s,mql){\nvar o={};\nvar idx=s.indexOf(\"{\");\nvar st=s.substring(0,idx);\nvar ss=st.split(\",\");\nvar ds=[];\nvar dts=s.substring(idx+1,s.length-1).split(\";\");\nfor(var i=0;i<dts.length;i++){\nds[ds.length]=_13.declaration(dts[i],o);\n}\no.getMediaQueryList=function(){\nreturn mql||null;\n};\no.getSelectors=function(){\nreturn ss;\n};\no.getSelectorText=function(){\nreturn st;\n};\no.getDeclarations=function(){\nreturn ds;\n};\no.getPropertyValue=function(n){\nfor(var i=0;i<ds.length;i++){\nif(ds[i].getProperty()===n){\nreturn ds[i].getValue();\n}\n}\nreturn null;\n};\nreturn o;\n},declaration:function(s,r){\nvar idx=s.indexOf(\":\");\nvar p=s.substring(0,idx);\nvar v=s.substring(idx+1);\nreturn {getRule:function(){\nreturn r||null;\n},getProperty:function(){\nreturn p;\n},getValue:function(){\nreturn v;\n}};\n}};\nvar _19=function(el){\nif(typeof el.cssHelperText!==\"string\"){\nreturn;\n}\nvar o={mediaQueryLists:[],rules:[],selectors:{},declarations:[],properties:{}};\nvar _1a=o.mediaQueryLists;\nvar ors=o.rules;\nvar _1b=el.cssHelperText.match(_3.BLOCKS);\nif(_1b!==null){\nfor(var i=0;i<_1b.length;i++){\nif(_1b[i].substring(0,7)===\"@media \"){\n_1a[_1a.length]=_13.mediaQueryList(_1b[i]);\nors=o.rules=ors.concat(_1a[_1a.length-1].getRules());\n}else{\nors[ors.length]=_13.rule(_1b[i]);\n}\n}\n}\nvar oss=o.selectors;\nvar _1c=function(r){\nvar ss=r.getSelectors();\nfor(var i=0;i<ss.length;i++){\nvar n=ss[i];\nif(!oss[n]){\noss[n]=[];\n}\noss[n][oss[n].length]=r;\n}\n};\nfor(i=0;i<ors.length;i++){\n_1c(ors[i]);\n}\nvar ods=o.declarations;\nfor(i=0;i<ors.length;i++){\nods=o.declarations=ods.concat(ors[i].getDeclarations());\n}\nvar ops=o.properties;\nfor(i=0;i<ods.length;i++){\nvar n=ods[i].getProperty();\nif(!ops[n]){\nops[n]=[];\n}\nops[n][ops[n].length]=ods[i];\n}\nel.cssHelperParsed=o;\n_4[_4.length]=el;\nreturn o;\n};\nvar _1d=function(el,s){\nel.cssHelperText=_11(s||el.innerHTML);\nreturn _19(el);\n};\nvar _1e=function(){\n_5=true;\n_4=[];\nvar _1f=[];\nvar _20=function(){\nfor(var i=0;i<_1f.length;i++){\n_19(_1f[i]);\n}\nvar _21=document.getElementsByTagName(\"style\");\nfor(i=0;i<_21.length;i++){\n_1d(_21[i]);\n}\n_5=false;\n_8();\n};\nvar _22=document.getElementsByTagName(\"link\");\nfor(var i=0;i<_22.length;i++){\nvar _23=_22[i];\nif(_23.getAttribute(\"rel\").indexOf(\"style\")>-1&&_23.href&&_23.href.length!==0&&!_23.disabled){\n_1f[_1f.length]=_23;\n}\n}\nif(_1f.length>0){\nvar c=0;\nvar _24=function(){\nc++;\nif(c===_1f.length){\n_20();\n}\n};\nvar _25=function(_26){\nvar _27=_26.href;\n_c(_27,function(_28){\n_28=_11(_28).replace(_3.RELATIVE_URLS,\"url(\"+_27.substring(0,_27.lastIndexOf(\"/\"))+\"/$1)\");\n_26.cssHelperText=_28;\n_24();\n},_24);\n};\nfor(i=0;i<_1f.length;i++){\n_25(_1f[i]);\n}\n}else{\n_20();\n}\n};\nvar _29={mediaQueryLists:\"array\",rules:\"array\",selectors:\"object\",declarations:\"array\",properties:\"object\"};\nvar _2a={mediaQueryLists:null,rules:null,selectors:null,declarations:null,properties:null};\nvar _2b=function(_2c,v){\nif(_2a[_2c]!==null){\nif(_29[_2c]===\"array\"){\nreturn (_2a[_2c]=_2a[_2c].concat(v));\n}else{\nvar c=_2a[_2c];\nfor(var n in v){\nif(v.hasOwnProperty(n)){\nif(!c[n]){\nc[n]=v[n];\n}else{\nc[n]=c[n].concat(v[n]);\n}\n}\n}\nreturn c;\n}\n}\n};\nvar _2d=function(_2e){\n_2a[_2e]=(_29[_2e]===\"array\")?[]:{};\nfor(var i=0;i<_4.length;i++){\n_2b(_2e,_4[i].cssHelperParsed[_2e]);\n}\nreturn _2a[_2e];\n};\ndomReady(function(){\nvar els=document.body.getElementsByTagName(\"*\");\nfor(var i=0;i<els.length;i++){\nels[i].checkedByCssHelper=true;\n}\nif(document.implementation.hasFeature(\"MutationEvents\",\"2.0\")||window.MutationEvent){\ndocument.body.addEventListener(\"DOMNodeInserted\",function(e){\nvar el=e.target;\nif(el.nodeType===1){\n_a(\"DOMElementInserted\",el);\nel.checkedByCssHelper=true;\n}\n},false);\n}else{\nsetInterval(function(){\nvar els=document.body.getElementsByTagName(\"*\");\nfor(var i=0;i<els.length;i++){\nif(!els[i].checkedByCssHelper){\n_a(\"DOMElementInserted\",els[i]);\nels[i].checkedByCssHelper=true;\n}\n}\n},1000);\n}\n});\nvar _2f=function(d){\nif(typeof window.innerWidth!=\"undefined\"){\nreturn window[\"inner\"+d];\n}else{\nif(typeof document.documentElement!=\"undefined\"&&typeof document.documentElement.clientWidth!=\"undefined\"&&document.documentElement.clientWidth!=0){\nreturn document.documentElement[\"client\"+d];\n}\n}\n};\nreturn {addStyle:function(s,_30){\nvar el=document.createElement(\"style\");\nel.setAttribute(\"type\",\"text/css\");\ndocument.getElementsByTagName(\"head\")[0].appendChild(el);\nif(el.styleSheet){\nel.styleSheet.cssText=s;\n}else{\nel.appendChild(document.createTextNode(s));\n}\nel.addedWithCssHelper=true;\nif(typeof _30===\"undefined\"||_30===true){\ncssHelper.parsed(function(_31){\nvar o=_1d(el,s);\nfor(var n in o){\nif(o.hasOwnProperty(n)){\n_2b(n,o[n]);\n}\n}\n_a(\"newStyleParsed\",el);\n});\n}else{\nel.parsingDisallowed=true;\n}\nreturn el;\n},removeStyle:function(el){\nreturn el.parentNode.removeChild(el);\n},parsed:function(fn){\nif(_5){\n_7(fn);\n}else{\nif(typeof _4!==\"undefined\"){\nif(typeof fn===\"function\"){\nfn(_4);\n}\n}else{\n_7(fn);\n_1e();\n}\n}\n},mediaQueryLists:function(fn){\ncssHelper.parsed(function(_32){\nfn(_2a.mediaQueryLists||_2d(\"mediaQueryLists\"));\n});\n},rules:function(fn){\ncssHelper.parsed(function(_33){\nfn(_2a.rules||_2d(\"rules\"));\n});\n},selectors:function(fn){\ncssHelper.parsed(function(_34){\nfn(_2a.selectors||_2d(\"selectors\"));\n});\n},declarations:function(fn){\ncssHelper.parsed(function(_35){\nfn(_2a.declarations||_2d(\"declarations\"));\n});\n},properties:function(fn){\ncssHelper.parsed(function(_36){\nfn(_2a.properties||_2d(\"properties\"));\n});\n},broadcast:_a,addListener:function(n,fn){\nif(typeof fn===\"function\"){\nif(!_9[n]){\n_9[n]={listeners:[]};\n}\n_9[n].listeners[_9[n].listeners.length]=fn;\n}\n},removeListener:function(n,fn){\nif(typeof fn===\"function\"&&_9[n]){\nvar ls=_9[n].listeners;\nfor(var i=0;i<ls.length;i++){\nif(ls[i]===fn){\nls.splice(i,1);\ni-=1;\n}\n}\n}\n},getViewportWidth:function(){\nreturn _2f(\"Width\");\n},getViewportHeight:function(){\nreturn _2f(\"Height\");\n}};\n}();\ndomReady(function enableCssMediaQueries(){\nvar _37;\nvar _38={LENGTH_UNIT:/[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/,RESOLUTION_UNIT:/[0-9]+(dpi|dpcm)$/,ASPECT_RATIO:/^[0-9]+\\/[0-9]+$/,ABSOLUTE_VALUE:/^[0-9]*(\\.[0-9]+)*$/};\nvar _39=[];\nvar _3a=function(){\nvar id=\"css3-mediaqueries-test\";\nvar el=document.createElement(\"div\");\nel.id=id;\nvar _3b=cssHelper.addStyle(\"@media all and (width) { #\"+id+\" { width: 1px !important; } }\",false);\ndocument.body.appendChild(el);\nvar ret=el.offsetWidth===1;\n_3b.parentNode.removeChild(_3b);\nel.parentNode.removeChild(el);\n_3a=function(){\nreturn ret;\n};\nreturn ret;\n};\nvar _3c=function(){\n_37=document.createElement(\"div\");\n_37.style.cssText=\"position:absolute;top:-9999em;left:-9999em;\"+\"margin:0;border:none;padding:0;width:1em;font-size:1em;\";\ndocument.body.appendChild(_37);\nif(_37.offsetWidth!==16){\n_37.style.fontSize=16/_37.offsetWidth+\"em\";\n}\n_37.style.width=\"\";\n};\nvar _3d=function(_3e){\n_37.style.width=_3e;\nvar _3f=_37.offsetWidth;\n_37.style.width=\"\";\nreturn _3f;\n};\nvar _40=function(_41,_42){\nvar l=_41.length;\nvar min=(_41.substring(0,4)===\"min-\");\nvar max=(!min&&_41.substring(0,4)===\"max-\");\nif(_42!==null){\nvar _43;\nvar _44;\nif(_38.LENGTH_UNIT.exec(_42)){\n_43=\"length\";\n_44=_3d(_42);\n}else{\nif(_38.RESOLUTION_UNIT.exec(_42)){\n_43=\"resolution\";\n_44=parseInt(_42,10);\nvar _45=_42.substring((_44+\"\").length);\n}else{\nif(_38.ASPECT_RATIO.exec(_42)){\n_43=\"aspect-ratio\";\n_44=_42.split(\"/\");\n}else{\nif(_38.ABSOLUTE_VALUE){\n_43=\"absolute\";\n_44=_42;\n}else{\n_43=\"unknown\";\n}\n}\n}\n}\n}\nvar _46,_47;\nif(\"device-width\"===_41.substring(l-12,l)){\n_46=screen.width;\nif(_42!==null){\nif(_43===\"length\"){\nreturn ((min&&_46>=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _46>0;\n}\n}else{\nif(\"device-height\"===_41.substring(l-13,l)){\n_47=screen.height;\nif(_42!==null){\nif(_43===\"length\"){\nreturn ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _47>0;\n}\n}else{\nif(\"width\"===_41.substring(l-5,l)){\n_46=document.documentElement.clientWidth||document.body.clientWidth;\nif(_42!==null){\nif(_43===\"length\"){\nreturn ((min&&_46>=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _46>0;\n}\n}else{\nif(\"height\"===_41.substring(l-6,l)){\n_47=document.documentElement.clientHeight||document.body.clientHeight;\nif(_42!==null){\nif(_43===\"length\"){\nreturn ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _47>0;\n}\n}else{\nif(\"device-aspect-ratio\"===_41.substring(l-19,l)){\nreturn _43===\"aspect-ratio\"&&screen.width*_44[1]===screen.height*_44[0];\n}else{\nif(\"color-index\"===_41.substring(l-11,l)){\nvar _48=Math.pow(2,screen.colorDepth);\nif(_42!==null){\nif(_43===\"absolute\"){\nreturn ((min&&_48>=_44)||(max&&_48<_44)||(!min&&!max&&_48===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _48>0;\n}\n}else{\nif(\"color\"===_41.substring(l-5,l)){\nvar _49=screen.colorDepth;\nif(_42!==null){\nif(_43===\"absolute\"){\nreturn ((min&&_49>=_44)||(max&&_49<_44)||(!min&&!max&&_49===_44));\n}else{\nreturn false;\n}\n}else{\nreturn _49>0;\n}\n}else{\nif(\"resolution\"===_41.substring(l-10,l)){\nvar res;\nif(_45===\"dpcm\"){\nres=_3d(\"1cm\");\n}else{\nres=_3d(\"1in\");\n}\nif(_42!==null){\nif(_43===\"resolution\"){\nreturn ((min&&res>=_44)||(max&&res<_44)||(!min&&!max&&res===_44));\n}else{\nreturn false;\n}\n}else{\nreturn res>0;\n}\n}else{\nreturn false;\n}\n}\n}\n}\n}\n}\n}\n}\n};\nvar _4a=function(mq){\nvar _4b=mq.getValid();\nvar _4c=mq.getExpressions();\nvar l=_4c.length;\nif(l>0){\nfor(var i=0;i<l&&_4b;i++){\n_4b=_40(_4c[i].mediaFeature,_4c[i].value);\n}\nvar not=mq.getNot();\nreturn (_4b&&!not||not&&!_4b);\n}\n};\nvar _4d=function(mql){\nvar mqs=mql.getMediaQueries();\nvar t={};\nfor(var i=0;i<mqs.length;i++){\nif(_4a(mqs[i])){\nt[mqs[i].getMediaType()]=true;\n}\n}\nvar s=[],c=0;\nfor(var n in t){\nif(t.hasOwnProperty(n)){\nif(c>0){\ns[c++]=\",\";\n}\ns[c++]=n;\n}\n}\nif(s.length>0){\n_39[_39.length]=cssHelper.addStyle(\"@media \"+s.join(\"\")+\"{\"+mql.getCssText()+\"}\",false);\n}\n};\nvar _4e=function(_4f){\nfor(var i=0;i<_4f.length;i++){\n_4d(_4f[i]);\n}\nif(ua.ie){\ndocument.documentElement.style.display=\"block\";\nsetTimeout(function(){\ndocument.documentElement.style.display=\"\";\n},0);\nsetTimeout(function(){\ncssHelper.broadcast(\"cssMediaQueriesTested\");\n},100);\n}else{\ncssHelper.broadcast(\"cssMediaQueriesTested\");\n}\n};\nvar _50=function(){\nfor(var i=0;i<_39.length;i++){\ncssHelper.removeStyle(_39[i]);\n}\n_39=[];\ncssHelper.mediaQueryLists(_4e);\n};\nvar _51=0;\nvar _52=function(){\nvar _53=cssHelper.getViewportWidth();\nvar _54=cssHelper.getViewportHeight();\nif(ua.ie){\nvar el=document.createElement(\"div\");\nel.style.position=\"absolute\";\nel.style.top=\"-9999em\";\nel.style.overflow=\"scroll\";\ndocument.body.appendChild(el);\n_51=el.offsetWidth-el.clientWidth;\ndocument.body.removeChild(el);\n}\nvar _55;\nvar _56=function(){\nvar vpw=cssHelper.getViewportWidth();\nvar vph=cssHelper.getViewportHeight();\nif(Math.abs(vpw-_53)>_51||Math.abs(vph-_54)>_51){\n_53=vpw;\n_54=vph;\nclearTimeout(_55);\n_55=setTimeout(function(){\nif(!_3a()){\n_50();\n}else{\ncssHelper.broadcast(\"cssMediaQueriesTested\");\n}\n},500);\n}\n};\nwindow.onresize=function(){\nvar x=window.onresize||function(){\n};\nreturn function(){\nx();\n_56();\n};\n}();\n};\nvar _57=document.documentElement;\n_57.style.marginLeft=\"-32767px\";\nsetTimeout(function(){\n_57.style.marginTop=\"\";\n},20000);\nreturn function(){\nif(!_3a()){\ncssHelper.addListener(\"newStyleParsed\",function(el){\n_4e(el.cssHelperParsed.mediaQueryLists);\n});\ncssHelper.addListener(\"cssMediaQueriesTested\",function(){\nif(ua.ie){\n_57.style.width=\"1px\";\n}\nsetTimeout(function(){\n_57.style.width=\"\";\n_57.style.marginLeft=\"\";\n},0);\ncssHelper.removeListener(\"cssMediaQueriesTested\",arguments.callee);\n});\n_3c();\n_50();\n}else{\n_57.style.marginLeft=\"\";\n}\n_52();\n};\n}());\ntry{\ndocument.execCommand(\"BackgroundImageCache\",false,true);\n}\ncatch(e){\n}\n\n"
  },
  {
    "path": "javascripts/scale.fix.js",
    "content": "fixScale = function(doc) {\n\n\tvar addEvent = 'addEventListener',\n\t    type = 'gesturestart',\n\t    qsa = 'querySelectorAll',\n\t    scales = [1, 1],\n\t    meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];\n\n\tfunction fix() {\n\t\tmeta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];\n\t\tdoc.removeEventListener(type, fix, true);\n\t}\n\n\tif ((meta = meta[meta.length - 1]) && addEvent in doc) {\n\t\tfix();\n\t\tscales = [.25, 1.6];\n\t\tdoc[addEvent](type, fix, true);\n\t}\n\n};"
  },
  {
    "path": "stylesheets/github-dark.css",
    "content": "/*\n   Copyright 2014 GitHub Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n*/\n\n.pl-c /* comment */ {\n  color: #969896;\n}\n\n.pl-c1      /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */,\n.pl-s .pl-v /* string variable */ {\n  color: #0099cd;\n}\n\n.pl-e  /* entity */,\n.pl-en /* entity.name */ {\n  color: #9774cb;\n}\n\n.pl-s .pl-s1 /* string source */,\n.pl-smi      /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ {\n  color: #ddd;\n}\n\n.pl-ent /* entity.name.tag */ {\n  color: #7bcc72;\n}\n\n.pl-k /* keyword, storage, storage.type */ {\n  color: #cc2372;\n}\n\n.pl-pds              /* punctuation.definition.string, string.regexp.character-class */,\n.pl-s                /* string */,\n.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,\n.pl-sr               /* string.regexp */,\n.pl-sr .pl-cce       /* string.regexp constant.character.escape */,\n.pl-sr .pl-sra       /* string.regexp string.regexp.arbitrary-repitition */,\n.pl-sr .pl-sre       /* string.regexp source.ruby.embedded */ {\n  color: #3c66e2;\n}\n\n.pl-v /* variable */ {\n  color: #fb8764;\n}\n\n.pl-id /* invalid.deprecated */ {\n  color: #e63525;\n}\n\n.pl-ii /* invalid.illegal */ {\n  background-color: #e63525;\n  color: #f8f8f8;\n}\n\n.pl-sr .pl-cce /* string.regexp constant.character.escape */ {\n  color: #7bcc72;\n  font-weight: bold;\n}\n\n.pl-ml /* markup.list */ {\n  color: #c26b2b;\n}\n\n.pl-mh        /* markup.heading */,\n.pl-mh .pl-en /* markup.heading entity.name */,\n.pl-ms        /* meta.separator */ {\n  color: #264ec5;\n  font-weight: bold;\n}\n\n.pl-mq /* markup.quote */ {\n  color: #00acac;\n}\n\n.pl-mi /* markup.italic */ {\n  color: #ddd;\n  font-style: italic;\n}\n\n.pl-mb /* markup.bold */ {\n  color: #ddd;\n  font-weight: bold;\n}\n\n.pl-md /* markup.deleted, meta.diff.header.from-file */ {\n  background-color: #ffecec;\n  color: #bd2c00;\n}\n\n.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ {\n  background-color: #eaffea;\n  color: #55a532;\n}\n\n.pl-mdr /* meta.diff.range */ {\n  color: #9774cb;\n  font-weight: bold;\n}\n\n.pl-mo /* meta.output */ {\n  color: #264ec5;\n}\n\n"
  },
  {
    "path": "stylesheets/github-light.css",
    "content": "/*\nThe MIT License (MIT)\n\nCopyright (c) 2016 GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n*/\n\n.pl-c /* comment */ {\n  color: #969896;\n}\n\n.pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */,\n.pl-s .pl-v /* string variable */ {\n  color: #0086b3;\n}\n\n.pl-e /* entity */,\n.pl-en /* entity.name */ {\n  color: #795da3;\n}\n\n.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,\n.pl-s .pl-s1 /* string source */ {\n  color: #333;\n}\n\n.pl-ent /* entity.name.tag */ {\n  color: #63a35c;\n}\n\n.pl-k /* keyword, storage, storage.type */ {\n  color: #a71d5d;\n}\n\n.pl-s /* string */,\n.pl-pds /* punctuation.definition.string, string.regexp.character-class */,\n.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,\n.pl-sr /* string.regexp */,\n.pl-sr .pl-cce /* string.regexp constant.character.escape */,\n.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,\n.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {\n  color: #183691;\n}\n\n.pl-v /* variable */ {\n  color: #ed6a43;\n}\n\n.pl-id /* invalid.deprecated */ {\n  color: #b52a1d;\n}\n\n.pl-ii /* invalid.illegal */ {\n  color: #f8f8f8;\n  background-color: #b52a1d;\n}\n\n.pl-sr .pl-cce /* string.regexp constant.character.escape */ {\n  font-weight: bold;\n  color: #63a35c;\n}\n\n.pl-ml /* markup.list */ {\n  color: #693a17;\n}\n\n.pl-mh /* markup.heading */,\n.pl-mh .pl-en /* markup.heading entity.name */,\n.pl-ms /* meta.separator */ {\n  font-weight: bold;\n  color: #1d3e81;\n}\n\n.pl-mq /* markup.quote */ {\n  color: #008080;\n}\n\n.pl-mi /* markup.italic */ {\n  font-style: italic;\n  color: #333;\n}\n\n.pl-mb /* markup.bold */ {\n  font-weight: bold;\n  color: #333;\n}\n\n.pl-md /* markup.deleted, meta.diff.header.from-file */ {\n  color: #bd2c00;\n  background-color: #ffecec;\n}\n\n.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ {\n  color: #55a532;\n  background-color: #eaffea;\n}\n\n.pl-mdr /* meta.diff.range */ {\n  font-weight: bold;\n  color: #795da3;\n}\n\n.pl-mo /* meta.output */ {\n  color: #1d3e81;\n}\n\n"
  },
  {
    "path": "stylesheets/ie.css",
    "content": "nav {\n  display: none;\n}\n"
  },
  {
    "path": "stylesheets/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */ /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "stylesheets/print.css",
    "content": "html, body, div, span, applet, object, iframe,\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\na, abbr, acronym, address, big, cite, code,\ndel, dfn, em, img, ins, kbd, q, s, samp,\nsmall, strike, strong, sub, sup, tt, var,\nb, u, i, center,\ndl, dt, dd, ol, ul, li,\nfieldset, form, label, legend,\ntable, caption, tbody, tfoot, thead, tr, th, td,\narticle, aside, canvas, details, embed,\nfigure, figcaption, footer, header, hgroup,\nmenu, nav, output, ruby, section, summary,\ntime, mark, audio, video {\n  padding: 0;\n  margin: 0;\n  font: inherit;\n  font-size: 100%;\n  vertical-align: baseline;\n  border: 0;\n}\n/* HTML5 display-role reset for older browsers */\narticle, aside, details, figcaption, figure,\nfooter, header, hgroup, menu, nav, section {\n  display: block;\n}\nbody {\n  line-height: 1;\n}\nol, ul {\n  list-style: none;\n}\nblockquote, q {\n  quotes: none;\n}\nblockquote:before, blockquote:after,\nq:before, q:after {\n  content: '';\n  content: none;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\nbody {\n  font-family: 'Helvetica Neue', Helvetica, Arial, serif;\n  font-size: 13px;\n  line-height: 1.5;\n  color: #000;\n}\n\na {\n  font-weight: bold;\n  color: #d5000d;\n}\n\nheader {\n  padding-top: 35px;\n  padding-bottom: 10px;\n}\n\nheader h1 {\n  font-size: 48px;\n  font-weight: bold;\n  line-height: 1.2;\n  color: #303030;\n  letter-spacing: -1px;\n}\n\nheader h2 {\n  font-size: 24px;\n  font-weight: normal;\n  line-height: 1.3;\n  color: #aaa;\n  letter-spacing: -1px;\n}\n#downloads {\n  display: none;\n}\n#main_content {\n  padding-top: 20px;\n}\n\ncode, pre {\n  margin-bottom: 30px;\n  font-family: Monaco, \"Bitstream Vera Sans Mono\", \"Lucida Console\", Terminal;\n  font-size: 12px;\n  color: #222;\n}\n\ncode {\n  padding: 0 3px;\n}\n\npre {\n  padding: 20px;\n  overflow: auto;\n  border: solid 1px #ddd;\n}\npre code {\n  padding: 0;\n}\n\nul, ol, dl {\n  margin-bottom: 20px;\n}\n\n\n/* COMMON STYLES */\n\ntable {\n  width: 100%;\n  border: 1px solid #ebebeb;\n}\n\nth {\n  font-weight: 500;\n}\n\ntd {\n  font-weight: 300;\n  text-align: center;\n  border: 1px solid #ebebeb;\n}\n\nform {\n  padding: 20px;\n  background: #f2f2f2;\n\n}\n\n\n/* GENERAL ELEMENT TYPE STYLES */\n\nh1 {\n  font-size: 2.8em;\n}\n\nh2 {\n  margin-bottom: 8px;\n  font-size: 22px;\n  font-weight: bold;\n  color: #303030;\n}\n\nh3 {\n  margin-bottom: 8px;\n  font-size: 18px;\n  font-weight: bold;\n  color: #d5000d;\n}\n\nh4 {\n  font-size: 16px;\n  font-weight: bold;\n  color: #303030;\n}\n\nh5 {\n  font-size: 1em;\n  color: #303030;\n}\n\nh6 {\n  font-size: .8em;\n  color: #303030;\n}\n\np {\n  margin-bottom: 20px;\n  font-weight: 300;\n}\n\na {\n  text-decoration: none;\n}\n\np a {\n  font-weight: 400;\n}\n\nblockquote {\n  padding: 0 0 0 30px;\n  margin-bottom: 20px;\n  font-size: 1.6em;\n  border-left: 10px solid #e9e9e9;\n}\n\nul li {\n  padding-left: 20px;\n  list-style-position: inside;\n  list-style: disc;\n}\n\nol li {\n  padding-left: 3px;\n  list-style-position: inside;\n  list-style: decimal;\n}\n\ndl dd {\n  font-style: italic;\n  font-weight: 100;\n}\n\nfooter {\n  padding-top: 20px;\n  padding-bottom: 30px;\n  margin-top: 40px;\n  font-size: 13px;\n  color: #aaa;\n}\n\nfooter a {\n  color: #666;\n}\n\n/* MISC */\n.clearfix:after {\n  display: block;\n  height: 0;\n  clear: both;\n  visibility: hidden;\n  content: '.';\n}\n\n.clearfix {display: inline-block;}\n* html .clearfix {height: 1%;}\n.clearfix {display: block;}\n"
  },
  {
    "path": "stylesheets/styles.css",
    "content": "@import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic);\n\n/* MeyerWeb Reset */\n\nhtml, body, div, span, applet, object, iframe,\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\na, abbr, acronym, address, big, cite, code,\ndel, dfn, em, img, ins, kbd, q, s, samp,\nsmall, strike, strong, sub, sup, tt, var,\nb, u, i, center,\ndl, dt, dd, ol, ul, li,\nfieldset, form, label, legend,\ntable, caption, tbody, tfoot, thead, tr, th, td,\narticle, aside, canvas, details, embed,\nfigure, figcaption, footer, header, hgroup,\nmenu, nav, output, ruby, section, summary,\ntime, mark, audio, video {\n  margin: 0;\n  padding: 0;\n  border: 0;\n  font: inherit;\n  vertical-align: baseline;\n}\n\n\n/* Base text styles */\n\nbody {\n  padding:10px 50px 0 0;\n  font-family:\"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\tfont-size: 14px;\n\tcolor: #232323;\n\tbackground-color: #FBFAF7;\n\tmargin: 0;\n\tline-height: 1.8em;\n\t-webkit-font-smoothing: antialiased;\n\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color:#232323;\n  margin:36px 0 10px;\n}\n\np, ul, ol, table, dl {\n  margin:0 0 22px;\n}\n\nh1, h2, h3 {\n\tfont-family: Arvo, Monaco, serif;\n  line-height:1.3;\n\tfont-weight: normal;\n}\n\nh1,h2, h3 {\n\tdisplay: block;\n\tborder-bottom: 1px solid #ccc;\n\tpadding-bottom: 5px;\n}\n\nh1 {\n\tfont-size: 30px;\n}\n\nh2 {\n\tfont-size: 24px;\n}\n\nh3 {\n\tfont-size: 18px;\n}\n\nh4, h5, h6 {\n\tfont-family: Arvo, Monaco, serif;\n\tfont-weight: 700;\n}\n\na {\n  color:#C30000;\n  font-weight:200;\n  text-decoration:none;\n}\n\na:hover {\n\ttext-decoration: underline;\n}\n\na small {\n\tfont-size: 12px;\n}\n\nem {\n\tfont-style: italic;\n}\n\nstrong {\n  font-weight:700;\n}\n\nul {\n  list-style-position: inside;\n  list-style: disc;\n  padding-left: 25px;\n}\n\nol {\n  list-style-position: inside;\n  list-style: decimal;\n  padding-left: 25px;\n}\n\nblockquote {\n  margin: 0;\n  padding: 0 0 0 20px;\n  font-style: italic;\n}\n\ndl, dt, dd, dl p {\n\tfont-color: #444;\n}\n\ndl dt {\n  font-weight: bold;\n}\n\ndl dd {\n  padding-left: 20px;\n  font-style: italic;\n}\n\ndl p {\n  padding-left: 20px;\n  font-style: italic;\n}\n\nhr {\n  border:0;\n  background:#ccc;\n  height:1px;\n  margin:0 0 24px;\n}\n\n/* Images */\n\nimg {\n  position: relative;\n  margin: 0 auto;\n  max-width: 650px;\n  padding: 5px;\n  margin: 10px 0 32px 0;\n  border: 1px solid #ccc;\n}\n\np img {\n  display: inline;\n  margin: 0;\n  padding: 0;\n  vertical-align: middle;\n  text-align: center;\n  border: none;\n}\n\n/* Code blocks */\n\ncode, pre {\n\tfont-family: Monaco, \"Bitstream Vera Sans Mono\", \"Lucida Console\", Terminal, monospace;\n  color:#000;\n  font-size:14px;\n}\n\npre {\n\tpadding: 4px 12px;\n  background: #FDFEFB;\n  border-radius:4px;\n  border:1px solid #D7D8C8;\n  overflow: auto;\n  overflow-y: hidden;\n\tmargin-bottom: 32px;\n}\n\n\n/* Tables */\n\ntable {\n  width:100%;\n}\n\ntable {\n  border: 1px solid #ccc;\n  margin-bottom: 32px;\n  text-align: left;\n }\n\nth {\n  font-family: 'Arvo', Helvetica, Arial, sans-serif;\n\tfont-size: 18px;\n\tfont-weight: normal;\n  padding: 10px;\n  background: #232323;\n  color: #FDFEFB;\n }\n\ntd {\n  padding: 10px;\n\tbackground: #ccc;\n }\n\n\n/* Wrapper */\n.wrapper {\n  width:960px;\n}\n\n\n/* Header */\n\nheader {\n\tbackground-color: #171717;\n\tcolor: #FDFDFB;\n  width:170px;\n  float:left;\n  position:fixed;\n\tborder: 1px solid #000;\n\t-webkit-border-top-right-radius: 4px;\n\t-webkit-border-bottom-right-radius: 4px;\n\t-moz-border-radius-topright: 4px;\n\t-moz-border-radius-bottomright: 4px;\n\tborder-top-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\tpadding: 34px 25px 22px 50px;\n\tmargin: 30px 25px 0 0;\n\t-webkit-font-smoothing: antialiased;\n}\n\np.header {\n\tfont-size: 16px;\n}\n\nh1.header {\n\tfont-family: Arvo, sans-serif;\n\tfont-size: 30px;\n\tfont-weight: 300;\n\tline-height: 1.3em;\n\tborder-bottom: none;\n\tmargin-top: 0;\n}\n\n\nh1.header, a.header, a.name, header a{\n\tcolor: #fff;\n}\n\na.header {\n\ttext-decoration: underline;\n}\n\na.name {\n\twhite-space: nowrap;\n}\n\nheader ul {\n  list-style:none;\n  padding:0;\n}\n\nheader li {\n\tlist-style-type: none;\n  width:132px;\n  height:15px;\n\tmargin-bottom: 12px;\n\tline-height: 1em;\n\tpadding: 6px 6px 6px 7px;\n\n\tbackground: #AF0011;\n\tbackground: -moz-linear-gradient(top, #AF0011 0%, #820011 100%);\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));\n  background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%);\n  background: -o-linear-gradient(top, #AF0011 0%,#820011 100%);\n  background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%);\n  background: linear-gradient(top, #AF0011 0%,#820011 100%);\n\n\tborder-radius:4px;\n  border:1px solid #0D0D0D;\n\n\t-webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1);\n\tbox-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1);\n\n}\n\nheader li:hover {\n\tbackground: #C3001D;\n\tbackground: -moz-linear-gradient(top, #C3001D 0%, #950119 100%);\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));\n  background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%);\n  background: -o-linear-gradient(top, #C3001D 0%,#950119 100%);\n  background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%);\n  background: linear-gradient(top, #C3001D 0%,#950119 100%);\n}\n\na.buttons {\n\t-webkit-font-smoothing: antialiased;\n\tbackground: url(../images/arrow-down.png) no-repeat;\n\tfont-weight: normal;\n\ttext-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0;\n\tpadding: 2px 2px 2px 22px;\n\theight: 30px;\n}\n\na.github {\n\tbackground: url(../images/octocat-small.png) no-repeat 1px;\n}\n\na.buttons:hover {\n\tcolor: #fff;\n\ttext-decoration: none;\n}\n\n\n/* Section - for main page content */\n\nsection {\n  width:650px;\n  float:right;\n  padding-bottom:50px;\n}\n\n\n/* Footer */\n\nfooter {\n  width:170px;\n  float:left;\n  position:fixed;\n  bottom:10px;\n\tpadding-left: 50px;\n}\n\n@media print, screen and (max-width: 960px) {\n\n  div.wrapper {\n    width:auto;\n    margin:0;\n  }\n\n  header, section, footer {\n    float:none;\n    position:static;\n    width:auto;\n  }\n\n\tfooter {\n\t\tborder-top: 1px solid #ccc;\n\t\tmargin:0 84px 0 50px;\n\t\tpadding:0;\n\t}\n\n  header {\n    padding-right:320px;\n  }\n\n  section {\n    padding:20px 84px 20px 50px;\n    margin:0 0 20px;\n  }\n\n  header a small {\n    display:inline;\n  }\n\n  header ul {\n    position:absolute;\n    right:130px;\n    top:84px;\n  }\n}\n\n@media print, screen and (max-width: 720px) {\n  body {\n    word-wrap:break-word;\n  }\n\n  header {\n    padding:10px 20px 0;\n\t\tmargin-right: 0;\n  }\n\n\tsection {\n    padding:10px 0 10px 20px;\n    margin:0 0 30px;\n  }\n\n\tfooter {\n\t\tmargin: 0 0 0 30px;\n\t}\n\n  header ul, header p.view {\n    position:static;\n  }\n}\n\n@media print, screen and (max-width: 480px) {\n\n  header ul li.download {\n    display:none;\n  }\n\n\tfooter {\n\t\tmargin: 0 0 0 20px;\n\t}\n\n\tfooter a{\n\t\tdisplay:block;\n\t}\n\n}\n\n@media print {\n  body {\n    padding:0.4in;\n    font-size:12pt;\n    color:#444;\n  }\n}"
  },
  {
    "path": "stylesheets/stylesheet.css",
    "content": "* {\n  box-sizing: border-box; }\n\nbody {\n  padding: 0;\n  margin: 0;\n  font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 16px;\n  line-height: 1.5;\n  color: #606c71; }\n\na {\n  color: #1e6bb8;\n  text-decoration: none; }\n  a:hover {\n    text-decoration: underline; }\n\n.btn {\n  display: inline-block;\n  margin-bottom: 1rem;\n  color: rgba(255, 255, 255, 0.7);\n  background-color: rgba(255, 255, 255, 0.08);\n  border-color: rgba(255, 255, 255, 0.2);\n  border-style: solid;\n  border-width: 1px;\n  border-radius: 0.3rem;\n  transition: color 0.2s, background-color 0.2s, border-color 0.2s; }\n  .btn + .btn {\n    margin-left: 1rem; }\n\n.btn:hover {\n  color: rgba(255, 255, 255, 0.8);\n  text-decoration: none;\n  background-color: rgba(255, 255, 255, 0.2);\n  border-color: rgba(255, 255, 255, 0.3); }\n\n@media screen and (min-width: 64em) {\n  .btn {\n    padding: 0.75rem 1rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .btn {\n    padding: 0.6rem 0.9rem;\n    font-size: 0.9rem; } }\n\n@media screen and (max-width: 42em) {\n  .btn {\n    display: block;\n    width: 100%;\n    padding: 0.75rem;\n    font-size: 0.9rem; }\n    .btn + .btn {\n      margin-top: 1rem;\n      margin-left: 0; } }\n\n.page-header {\n  color: #fff;\n  text-align: center;\n  background-color: #159957;\n  background-image: linear-gradient(120deg, #155799, #159957); }\n\n@media screen and (min-width: 64em) {\n  .page-header {\n    padding: 5rem 6rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .page-header {\n    padding: 3rem 4rem; } }\n\n@media screen and (max-width: 42em) {\n  .page-header {\n    padding: 2rem 1rem; } }\n\n.project-name {\n  margin-top: 0;\n  margin-bottom: 0.1rem; }\n\n@media screen and (min-width: 64em) {\n  .project-name {\n    font-size: 3.25rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .project-name {\n    font-size: 2.25rem; } }\n\n@media screen and (max-width: 42em) {\n  .project-name {\n    font-size: 1.75rem; } }\n\n.project-tagline {\n  margin-bottom: 2rem;\n  font-weight: normal;\n  opacity: 0.7; }\n\n@media screen and (min-width: 64em) {\n  .project-tagline {\n    font-size: 1.25rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .project-tagline {\n    font-size: 1.15rem; } }\n\n@media screen and (max-width: 42em) {\n  .project-tagline {\n    font-size: 1rem; } }\n\n.main-content :first-child {\n  margin-top: 0; }\n.main-content img {\n  max-width: 100%; }\n.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6 {\n  margin-top: 2rem;\n  margin-bottom: 1rem;\n  font-weight: normal;\n  color: #159957; }\n.main-content p {\n  margin-bottom: 1em; }\n.main-content code {\n  padding: 2px 4px;\n  font-family: Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  font-size: 0.9rem;\n  color: #383e41;\n  background-color: #f3f6fa;\n  border-radius: 0.3rem; }\n.main-content pre {\n  padding: 0.8rem;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  font: 1rem Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  color: #567482;\n  word-wrap: normal;\n  background-color: #f3f6fa;\n  border: solid 1px #dce6f0;\n  border-radius: 0.3rem; }\n  .main-content pre > code {\n    padding: 0;\n    margin: 0;\n    font-size: 0.9rem;\n    color: #567482;\n    word-break: normal;\n    white-space: pre;\n    background: transparent;\n    border: 0; }\n.main-content .highlight {\n  margin-bottom: 1rem; }\n  .main-content .highlight pre {\n    margin-bottom: 0;\n    word-break: normal; }\n.main-content .highlight pre, .main-content pre {\n  padding: 0.8rem;\n  overflow: auto;\n  font-size: 0.9rem;\n  line-height: 1.45;\n  border-radius: 0.3rem; }\n.main-content pre code, .main-content pre tt {\n  display: inline;\n  max-width: initial;\n  padding: 0;\n  margin: 0;\n  overflow: initial;\n  line-height: inherit;\n  word-wrap: normal;\n  background-color: transparent;\n  border: 0; }\n  .main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after {\n    content: normal; }\n.main-content ul, .main-content ol {\n  margin-top: 0; }\n.main-content blockquote {\n  padding: 0 1rem;\n  margin-left: 0;\n  color: #819198;\n  border-left: 0.3rem solid #dce6f0; }\n  .main-content blockquote > :first-child {\n    margin-top: 0; }\n  .main-content blockquote > :last-child {\n    margin-bottom: 0; }\n.main-content table {\n  display: block;\n  width: 100%;\n  overflow: auto;\n  word-break: normal;\n  word-break: keep-all; }\n  .main-content table th {\n    font-weight: bold; }\n  .main-content table th, .main-content table td {\n    padding: 0.5rem 1rem;\n    border: 1px solid #e9ebec; }\n.main-content dl {\n  padding: 0; }\n  .main-content dl dt {\n    padding: 0;\n    margin-top: 1rem;\n    font-size: 1rem;\n    font-weight: bold; }\n  .main-content dl dd {\n    padding: 0;\n    margin-bottom: 1rem; }\n.main-content hr {\n  height: 2px;\n  padding: 0;\n  margin: 1rem 0;\n  background-color: #eff0f1;\n  border: 0; }\n\n@media screen and (min-width: 64em) {\n  .main-content {\n    max-width: 64rem;\n    padding: 2rem 6rem;\n    margin: 0 auto;\n    font-size: 1.1rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .main-content {\n    padding: 2rem 4rem;\n    font-size: 1.1rem; } }\n\n@media screen and (max-width: 42em) {\n  .main-content {\n    padding: 2rem 1rem;\n    font-size: 1rem; } }\n\n.site-footer {\n  padding-top: 2rem;\n  margin-top: 2rem;\n  border-top: solid 1px #eff0f1; }\n\n.site-footer-owner {\n  display: block;\n  font-weight: bold; }\n\n.site-footer-credits {\n  color: #819198; }\n\n@media screen and (min-width: 64em) {\n  .site-footer {\n    font-size: 1rem; } }\n\n@media screen and (min-width: 42em) and (max-width: 64em) {\n  .site-footer {\n    font-size: 1rem; } }\n\n@media screen and (max-width: 42em) {\n  .site-footer {\n    font-size: 0.9rem; } }\n"
  }
]