diff --git a/doc-src/01-bootstrap.min.css b/doc-src/01-bootstrap.min.css new file mode 100644 index 000000000..2e79d91a5 --- /dev/null +++ b/doc-src/01-bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;line-height:22px;color:#555;background-color:#fff}a{color:#007fff;text-decoration:none}a:hover,a:focus{color:#06c;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:32px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 11px}.lead{margin-bottom:22px;font-size:24px;font-weight:200;line-height:33px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#dfdfdf}a.muted:hover,a.muted:focus{color:#c6c6c6}.text-warning{color:#fff}a.text-warning:hover,a.text-warning:focus{color:#e6e6e6}.text-error{color:#fff}a.text-error:hover,a.text-error:focus{color:#e6e6e6}.text-info{color:#fff}a.text-info:hover,a.text-info:focus{color:#e6e6e6}.text-success{color:#fff}a.text-success:hover,a.text-success:focus{color:#e6e6e6}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:11px 0;font-family:inherit;font-weight:300;line-height:22px;color:#080808;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#dfdfdf}h1,h2,h3{line-height:44px}h1{font-size:44px}h2{font-size:36px}h3{font-size:28px}h4{font-size:20px}h5{font-size:16px}h6{font-size:13.6px}h1 small{font-size:28px}h2 small{font-size:20px}h3 small{font-size:16px}h4 small{font-size:16px}.page-header{padding-bottom:10px;margin:44px 0 22px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 11px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:22px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:22px}dt,dd{line-height:22px}dt{font-weight:bold}dd{margin-left:11px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:22px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #dfdfdf}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 22px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:20px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:22px;color:#dfdfdf}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:22px;font-style:normal;line-height:22px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:14px;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:10.5px;margin:0 0 11px;font-size:15px;line-height:22px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}pre.prettyprint{margin-bottom:22px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 22px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:22px;font-size:24px;line-height:44px;color:#999;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:16.5px;color:#dfdfdf}label,input,button,select,textarea{font-size:16px;font-weight:normal;line-height:22px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:22px;padding:4px 6px;margin-bottom:11px;font-size:16px;line-height:22px;color:#bbb;vertical-align:middle;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #bbb;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:32px;*margin-top:4px;line-height:32px}select{width:220px;background-color:#fff;border:1px solid #bbb}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#dfdfdf;cursor:not-allowed;background-color:#fcfcfc;border-color:#bbb;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#bbb}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#bbb}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#bbb}.radio,.checkbox{min-height:22px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#fff}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#fff}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#fff;background-color:#ff7518;border-color:#fff}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#fff}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#fff}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#fff;background-color:#ff0039;border-color:#fff}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#fff}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#fff}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#fff;background-color:#3fb618;border-color:#fff}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#fff}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#fff}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#fff;background-color:#9954bb;border-color:#fff}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:21px 20px 22px;margin-top:22px;margin-bottom:22px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#7b7b7b}.help-block{display:block;margin-bottom:11px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:11px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:16px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:22px;min-width:16px;padding:4px 5px;font-size:16px;font-weight:normal;line-height:22px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#96ed7a;border-color:#3fb618}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:11px}legend+.control-group{margin-top:22px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:22px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:11px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:22px}.table th,.table td{padding:8px;line-height:22px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-topleft:0}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:0;border-top-right-radius:0;-moz-border-radius-topright:0}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-topleft:0}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:0;border-top-right-radius:0;-moz-border-radius-topright:0}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#e8f8fd}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#3fb618}.table tbody tr.error>td{background-color:#ff0039}.table tbody tr.warning>td{background-color:#ff7518}.table tbody tr.info>td{background-color:#9954bb}.table-hover tbody tr.success:hover>td{background-color:#379f15}.table-hover tbody tr.error:hover>td{background-color:#e60033}.table-hover tbody tr.warning:hover>td{background-color:#fe6600}.table-hover tbody tr.info:hover>td{background-color:#8d46b0}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:22px;color:#999;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#007af5;background-image:-moz-linear-gradient(top,#007fff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#0072e6));background-image:-webkit-linear-gradient(top,#007fff,#0072e6);background-image:-o-linear-gradient(top,#007fff,#0072e6);background-image:linear-gradient(to bottom,#007fff,#0072e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff0072e6',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#007af5;background-image:-moz-linear-gradient(top,#007fff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#0072e6));background-image:-webkit-linear-gradient(top,#007fff,#0072e6);background-image:-o-linear-gradient(top,#007fff,#0072e6);background-image:linear-gradient(to bottom,#007fff,#0072e6);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff0072e6',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#dfdfdf}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.well-small{padding:9px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:22px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:16px;line-height:22px;color:#999;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#dfdfdf;*background-color:#c8c8c8;background-image:-moz-linear-gradient(top,#eee,#c8c8c8);background-image:-webkit-gradient(linear,0 0,0 100%,from(#eee),to(#c8c8c8));background-image:-webkit-linear-gradient(top,#eee,#c8c8c8);background-image:-o-linear-gradient(top,#eee,#c8c8c8);background-image:linear-gradient(to bottom,#eee,#c8c8c8);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:#c8c8c8 #c8c8c8 #a2a2a2;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#a2a2a2;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffeeeeee',endColorstr='#ffc8c8c8',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#999;background-color:#c8c8c8;*background-color:#bbb}.btn:active,.btn.active{background-color:#aeaeae \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#999;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:22px 30px;font-size:20px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:13.6px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:2px 6px;font-size:12px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0f82f5;*background-color:#0072e6;background-image:-moz-linear-gradient(top,#1a8cff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#1a8cff),to(#0072e6));background-image:-webkit-linear-gradient(top,#1a8cff,#0072e6);background-image:-o-linear-gradient(top,#1a8cff,#0072e6);background-image:linear-gradient(to bottom,#1a8cff,#0072e6);background-repeat:repeat-x;border-color:#0072e6 #0072e6 #004c99;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1a8cff',endColorstr='#ff0072e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#0072e6;*background-color:#06c}.btn-primary:active,.btn-primary.active{background-color:#0059b3 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#fe781e;*background-color:#fe6600;background-image:-moz-linear-gradient(top,#ff8432,#fe6600);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ff8432),to(#fe6600));background-image:-webkit-linear-gradient(top,#ff8432,#fe6600);background-image:-o-linear-gradient(top,#ff8432,#fe6600);background-image:linear-gradient(to bottom,#ff8432,#fe6600);background-repeat:repeat-x;border-color:#fe6600 #fe6600 #b14700;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff8432',endColorstr='#fffe6600',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#fe6600;*background-color:#e45c00}.btn-warning:active,.btn-warning.active{background-color:#cb5200 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#f50f43;*background-color:#e60033;background-image:-moz-linear-gradient(top,#ff1a4d,#e60033);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ff1a4d),to(#e60033));background-image:-webkit-linear-gradient(top,#ff1a4d,#e60033);background-image:-o-linear-gradient(top,#ff1a4d,#e60033);background-image:linear-gradient(to bottom,#ff1a4d,#e60033);background-repeat:repeat-x;border-color:#e60033 #e60033 #902;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff1a4d',endColorstr='#ffe60033',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#e60033;*background-color:#cc002e}.btn-danger:active,.btn-danger.active{background-color:#b30028 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#41bb19;*background-color:#379f15;background-image:-moz-linear-gradient(top,#47cd1b,#379f15);background-image:-webkit-gradient(linear,0 0,0 100%,from(#47cd1b),to(#379f15));background-image:-webkit-linear-gradient(top,#47cd1b,#379f15);background-image:-o-linear-gradient(top,#47cd1b,#379f15);background-image:linear-gradient(to bottom,#47cd1b,#379f15);background-repeat:repeat-x;border-color:#379f15 #379f15 #205c0c;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff47cd1b',endColorstr='#ff379f15',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#379f15;*background-color:#2f8912}.btn-success:active,.btn-success.active{background-color:#28720f \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#9b59bb;*background-color:#8d46b0;background-image:-moz-linear-gradient(top,#a466c2,#8d46b0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#a466c2),to(#8d46b0));background-image:-webkit-linear-gradient(top,#a466c2,#8d46b0);background-image:-o-linear-gradient(top,#a466c2,#8d46b0);background-image:linear-gradient(to bottom,#a466c2,#8d46b0);background-repeat:repeat-x;border-color:#8d46b0 #8d46b0 #613079;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa466c2',endColorstr='#ff8d46b0',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#8d46b0;*background-color:#7e3f9d}.btn-info:active,.btn-info.active{background-color:#6f378b \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#080808;*background-color:#000;background-image:-moz-linear-gradient(top,#0d0d0d,#000);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0d0d0d),to(#000));background-image:-webkit-linear-gradient(top,#0d0d0d,#000);background-image:-o-linear-gradient(top,#0d0d0d,#000);background-image:linear-gradient(to bottom,#0d0d0d,#000);background-repeat:repeat-x;border-color:#000 #000 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0d0d0d',endColorstr='#ff000000',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#000;*background-color:#000}.btn-inverse:active,.btn-inverse.active{background-color:#000 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#007fff;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#06c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#999;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:11px;margin-bottom:11px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:16px}.btn-group>.btn-mini{font-size:12px}.btn-group>.btn-small{font-size:13.6px}.btn-group>.btn-large{font-size:20px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#c8c8c8}.btn-group.open .btn-primary.dropdown-toggle{background-color:#0072e6}.btn-group.open .btn-warning.dropdown-toggle{background-color:#fe6600}.btn-group.open .btn-danger.dropdown-toggle{background-color:#e60033}.btn-group.open .btn-success.dropdown-toggle{background-color:#379f15}.btn-group.open .btn-info.dropdown-toggle{background-color:#8d46b0}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#000}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert{padding:8px 35px 8px 14px;margin-bottom:22px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#ff7518;border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert,.alert h4{color:#fff}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:22px}.alert-success{color:#fff;background-color:#3fb618;border-color:transparent}.alert-success h4{color:#fff}.alert-danger,.alert-error{color:#fff;background-color:#ff0039;border-color:transparent}.alert-danger h4,.alert-error h4{color:#fff}.alert-info{color:#fff;background-color:#9954bb;border-color:transparent}.alert-info h4{color:#fff}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:22px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:22px;color:#dfdfdf;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#007fff}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:22px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#bbb;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#007fff}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#007fff;border-bottom-color:#007fff}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#06c;border-bottom-color:#06c}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#bbb;border-bottom-color:#bbb}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#dfdfdf;border-color:#dfdfdf}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#dfdfdf}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#dfdfdf}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:22px;overflow:visible}.navbar-inner{min-height:50px;padding-right:20px;padding-left:20px;background-color:#080808;background-image:-moz-linear-gradient(top,#080808,#080808);background-image:-webkit-gradient(linear,0 0,0 100%,from(#080808),to(#080808));background-image:-webkit-linear-gradient(top,#080808,#080808);background-image:-o-linear-gradient(top,#080808,#080808);background-image:linear-gradient(to bottom,#080808,#080808);background-repeat:repeat-x;border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808',endColorstr='#ff080808',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:14px 20px 14px;margin-left:-20px;font-size:20px;font-weight:200;color:#fff;text-shadow:0 1px 0 #080808}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:50px;color:#fff}.navbar-link{color:#fff}.navbar-link:hover,.navbar-link:focus{color:#fff}.navbar .divider-vertical{height:50px;margin:0 9px;border-right:1px solid #080808;border-left:1px solid #080808}.navbar .btn,.navbar .btn-group{margin-top:10px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:10px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:10px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:14px 15px 14px;color:#fff;text-decoration:none;text-shadow:0 1px 0 #080808}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#fff;text-decoration:none;background-color:#3b3b3b}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#fff;text-decoration:none;background-color:transparent;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#000;*background-color:#000;background-image:-moz-linear-gradient(top,#000,#000);background-image:-webkit-gradient(linear,0 0,0 100%,from(#000),to(#000));background-image:-webkit-linear-gradient(top,#000,#000);background-image:-o-linear-gradient(top,#000,#000);background-image:linear-gradient(to bottom,#000,#000);background-repeat:repeat-x;border-color:#000 #000 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff000000',endColorstr='#ff000000',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#000;*background-color:#000}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#000 \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:transparent}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#007fff;background-image:-moz-linear-gradient(top,#007fff,#007fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#007fff));background-image:-webkit-linear-gradient(top,#007fff,#007fff);background-image:-o-linear-gradient(top,#007fff,#007fff);background-image:linear-gradient(to bottom,#007fff,#007fff);background-repeat:repeat-x;border-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff007fff',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#fff}.navbar-inverse .navbar-text{color:#fff}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:rgba(0,0,0,0.05)}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#007fff}.navbar-inverse .navbar-link{color:#fff}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#007fff;border-left-color:#007fff}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#007fff}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#80bfff;border-color:#007fff;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#999}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#999}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#999}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#999;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0072e6;*background-color:#0072e6;background-image:-moz-linear-gradient(top,#0072e6,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0072e6),to(#0072e6));background-image:-webkit-linear-gradient(top,#0072e6,#0072e6);background-image:-o-linear-gradient(top,#0072e6,#0072e6);background-image:linear-gradient(to bottom,#0072e6,#0072e6);background-repeat:repeat-x;border-color:#0072e6 #0072e6 #004c99;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0072e6',endColorstr='#ff0072e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#0072e6;*background-color:#06c}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#0059b3 \9}.breadcrumb{padding:8px 15px;margin:0 0 22px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#dfdfdf}.pagination{margin:22px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:22px;text-decoration:none;background-color:#dfdfdf;border:1px solid transparent;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#007fff}.pagination ul>.active>a,.pagination ul>.active>span{color:#dfdfdf;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#dfdfdf;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:22px 30px;font-size:20px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:13.6px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:2px 6px;font-size:12px}.pager{margin:22px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#dfdfdf;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#ff7518;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#ff7518;border-bottom:1px solid #fe6600;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:16px}.popover .arrow:after{border-width:15px;content:""}.popover.top .arrow{bottom:-16px;left:50%;margin-left:-16px;border-top-color:#999;border-top-color:transparent;border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-15px;border-top-color:#ff7518;border-bottom-width:0}.popover.right .arrow{top:50%;left:-16px;margin-top:-16px;border-right-color:#999;border-right-color:transparent;border-left-width:0}.popover.right .arrow:after{bottom:-15px;left:1px;border-right-color:#ff7518;border-left-width:0}.popover.bottom .arrow{top:-16px;left:50%;margin-left:-16px;border-bottom-color:#999;border-bottom-color:transparent;border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-15px;border-bottom-color:#ff7518;border-top-width:0}.popover.left .arrow{top:50%;right:-16px;margin-top:-16px;border-left-color:#999;border-left-color:transparent;border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-15px;border-left-color:#ff7518;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:22px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:22px;border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#007fff;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#bbb}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:13.536px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#dfdfdf}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#fff}.label-important[href],.badge-important[href]{background-color:#e6e6e6}.label-warning,.badge-warning{background-color:#ff7518}.label-warning[href],.badge-warning[href]{background-color:#e45c00}.label-success,.badge-success{background-color:#fff}.label-success[href],.badge-success[href]{background-color:#e6e6e6}.label-info,.badge-info{background-color:#fff}.label-info[href],.badge-info[href]{background-color:#e6e6e6}.label-inverse,.badge-inverse{background-color:#999}.label-inverse[href],.badge-inverse[href]{background-color:#808080}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:22px;margin-bottom:22px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#ff9046;background-image:-moz-linear-gradient(top,#ffa365,#ff7518);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ffa365),to(#ff7518));background-image:-webkit-linear-gradient(top,#ffa365,#ff7518);background-image:-o-linear-gradient(top,#ffa365,#ff7518);background-image:linear-gradient(to bottom,#ffa365,#ff7518);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffa365',endColorstr='#ffff7518',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#ffa365;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:22px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:22px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#080808;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#999;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:22px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:33px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:33px}body{overflow-y:scroll;font-weight:300}h1{font-size:50px}h2,h3{font-size:26px}h4{font-size:14px}h5,h6{font-size:11px}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#999}blockquote{padding:10px 15px;background-color:#eee;border-left-color:#bbb}blockquote.pull-right{padding:10px 15px;border-right-color:#bbb}blockquote small{color:#999}.muted{color:#bbb}.text-warning{color:#ff7518}a.text-warning:hover{color:#e45c00}.text-error{color:#ff0039}a.text-error:hover{color:#cc002e}.text-info{color:#9954bb}a.text-info:hover{color:#7e3f9d}.text-success{color:#3fb618}a.text-success:hover{color:#2f8912}.navbar .navbar-inner{background-image:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.navbar .brand:hover{color:#fff}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{background-color:#3b3b3b;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#fff}.navbar .nav li.dropdown.open>.dropdown-toggle:hover,.navbar .nav li.dropdown.active>.dropdown-toggle:hover,.navbar .nav li.dropdown.open.active>.dropdown-toggle:hover{color:#eee}.navbar .navbar-search .search-query{line-height:normal}.navbar-inverse .brand,.navbar-inverse .nav>li>a{text-shadow:none}.navbar-inverse .brand:hover,.navbar-inverse .nav>.active>a,.navbar-inverse .nav>.active>a:hover,.navbar-inverse .nav>.active>a:focus{color:#fff;background-color:rgba(0,0,0,0.05);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.navbar-inverse .navbar-search .search-query{color:#080808}div.subnav{margin:0 1px;background:#dfdfdf none;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}div.subnav .nav{background-color:transparent}div.subnav .nav>li>a{border-color:transparent}div.subnav .nav>.active>a,div.subnav .nav>.active>a:hover{color:#fff;background-color:#000;border-color:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}div.subnav-fixed{top:51px;margin:0}.nav .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#007fff}.nav-tabs>li>a{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li>a:hover{color:#fff;background-color:#007fff}.nav-tabs.nav-stacked>.active>a,.nav-tabs.nav-stacked>.active>a:hover{color:#bbb;background-color:#fff}.nav-tabs.nav-stacked>li:first-child>a,.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.tabs-below>.nav-tabs>li>a,.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-pills>li>a{color:#000;background-color:#dfdfdf;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-pills>li>a:hover{color:#fff;background-color:#000}.nav-pills>.disabled>a,.nav-pills>.disabled>a:hover{color:#999;background-color:#eee}.nav-list>li>a{color:#080808}.nav-list>li>a:hover{color:#fff;text-shadow:none;background-color:#007fff}.nav-list .nav-header{font-size:16px;color:#000}.nav-list .divider{background-color:#bbb;border-bottom:0}.pagination ul{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.pagination ul>li>a,.pagination ul>li>span{margin-right:6px;color:#080808}.pagination ul>li>a:hover,.pagination ul>li>span:hover{color:#fff;background-color:#080808}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{margin-right:0}.pagination ul>.active>a,.pagination ul>.active>span{color:#fff}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999;background-color:#eee}.pager li>a,.pager li>span{color:#080808;background-color:#dfdfdf;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.pager li>a:hover,.pager li>span:hover{color:#fff;background-color:#080808}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999;background-color:#eee}.breadcrumb{background-color:#dfdfdf}.breadcrumb li{text-shadow:none}.breadcrumb .divider,.breadcrumb .active{color:#080808;text-shadow:none}.btn{padding:5px 12px;color:#080808;text-shadow:none;background-image:none;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn.disabled{box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus{color:#000}.btn-large{padding:22px 30px}.btn-small{padding:2px 10px}.btn-mini{padding:2px 6px}.btn-group>.btn:first-child,.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.dropdown-toggle{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.table tbody tr.success td{color:#fff}.table tbody tr.error td{color:#fff}.table tbody tr.info td{color:#fff}.table-bordered{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"]{color:#080808}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#ff7518}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#080808;border-color:#ff7518}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#ff0039}.control-group.error input,.control-group.error select,.control-group.error textarea{color:#080808;border-color:#ff0039}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#3fb618}.control-group.success input,.control-group.success select,.control-group.success textarea{color:#080808;border-color:#3fb618}legend{color:#080808;border-bottom:0}.form-actions{background-color:#eee;border-top:0}.dropdown-menu{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert{text-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert-heading,.alert h1,.alert h2,.alert h3,.alert h4,.alert h5,.alert h6{color:#fff}.label{min-width:80px;min-height:80px;font-weight:300;text-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.label-success{background-color:#3fb618}.label-important{background-color:#ff0039}.label-info{background-color:#9954bb}.label-inverse{background-color:#000}.badge{font-weight:300;text-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.badge-success{background-color:#3fb618}.badge-important{background-color:#ff0039}.badge-info{background-color:#9954bb}.badge-inverse{background-color:#000}.hero-unit{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.well{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}[class^="icon-"],[class*=" icon-"]{margin:0 2px;vertical-align:-2px}a.thumbnail{background-color:#dfdfdf}a.thumbnail:hover{background-color:#bbb;border-color:transparent}.progress{height:6px;background-color:#eee;background-image:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.progress .bar{background-color:#007fff;background-image:none}.progress-info{background-color:#9954bb}.progress-success{background-color:#3fb618}.progress-warning{background-color:#ff7518}.progress-danger{background-color:#ff0039}.modal{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.modal-header{border-bottom:0}.modal-footer{background-color:transparent;border-top:0}.popover{color:#fff;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.popover-title{color:#fff;border-bottom:0}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}pre{margin-top:10px;color:#333}pre.terminal{font-size:1em;color:#c0c0c0;background:#000}.tlist li{padding-top:.3em;paddint-bottom:.3em} diff --git a/doc-src/02-docstyle.css b/doc-src/02-docstyle.css new file mode 100644 index 000000000..8e07434b9 --- /dev/null +++ b/doc-src/02-docstyle.css @@ -0,0 +1,16 @@ +body { + padding-top: 60px; + padding-bottom: 40px; +} + +.tablenum { + font-weight: bold; +} + +.nowrap { + white-space: nowrap; +} + +h1 { + line-height: 1.1; +} \ No newline at end of file diff --git a/doc-src/_explicit.graffle/data.plist b/doc-src/_explicit.graffle/data.plist new file mode 100644 index 000000000..bc5ef104a --- /dev/null +++ b/doc-src/_explicit.graffle/data.plist @@ -0,0 +1,572 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle.MacAppStore + 139.16 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {559.19998741149902, 782.79998779296875}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-01-02 19:31:53 +0000 + Creator + Aldo Cortesi + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + ID + 4074 + Points + + {300.4483540852865, 420.70833897590637} + {344.88497416178387, 420.70833897590654} + {362.21830749511713, 420.04167230923986} + {413.55166625976557, 419.70833905537921} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4070 + Points + + {84.896692911783873, 420.66667453447985} + {129.33331298828122, 420.66667453448002} + {146.66664632161454, 420.00000786781334} + {198.00000508626297, 419.66667461395269} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{326.00000000000023, 391.39999198913591}, {62, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4063 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 2: Forwarded \ +Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{110, 403.39997863769622}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4061 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{430.83098347981803, 515.99999999999989}, {36, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4026 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Server} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{40.499999999999993, 486.66666666666663}, {31, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4025 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Client} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}} + Class + ShapedGraphic + ID + 4004 + ImageID + 6 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Bounds + {{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}} + Class + ShapedGraphic + ID + 4023 + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.463735 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 mitmproxy} + + + + Bounds + {{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}} + Class + ShapedGraphic + ID + 134 + ImageID + 3 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 7 + ImageLinkBack + + + + + ImageList + + image6.tiff + image3.icns + + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-01-03 02:27:49 +0000 + Modifier + Aldo Cortesi + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595.19998741149902, 841.79998779296875} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{300, 236}, {974, 874}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 202}, {550, 469.33333333333337}} + Zoom + 1.5 + ZoomValues + + + Canvas 1 + 1.5 + 1 + + + + + diff --git a/doc-src/_explicit.graffle/image3.icns b/doc-src/_explicit.graffle/image3.icns new file mode 100644 index 000000000..964df4b8c Binary files /dev/null and b/doc-src/_explicit.graffle/image3.icns differ diff --git a/doc-src/_explicit.graffle/image6.tiff b/doc-src/_explicit.graffle/image6.tiff new file mode 100644 index 000000000..bd6ed534b Binary files /dev/null and b/doc-src/_explicit.graffle/image6.tiff differ diff --git a/doc-src/_explicit_https.graffle/data.plist b/doc-src/_explicit_https.graffle/data.plist new file mode 100644 index 000000000..306630a09 --- /dev/null +++ b/doc-src/_explicit_https.graffle/data.plist @@ -0,0 +1,1054 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle.MacAppStore + 139.16 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {559.19998741149902, 782.79998779296875}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-01-02 19:31:53 +0000 + Creator + Aldo Cortesi + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + ID + 4075 + Points + + {299.94835408528644, 473.66668184598285} + {344.38497416178376, 473.66668184598302} + {361.71830749511713, 473.00001517931634} + {413.05166625976557, 472.66668192545569} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4074 + Points + + {300.4483540852865, 420.70833897590637} + {344.88497416178387, 420.70833897590654} + {362.21830749511713, 420.04167230923986} + {413.55166625976557, 419.70833905537921} + + Style + + stroke + + HeadArrow + 0 + Legacy + + TailArrow + FilledArrow + + + + + Class + LineGraphic + ID + 4073 + Points + + {300.44835408528655, 367.66666611035561} + {344.88497416178393, 367.66666611035578} + {362.21830749511719, 366.99999944368909} + {413.55166625976568, 366.66666618982845} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4072 + Points + + {84.896697998046875, 526.66670727729809} + {129.33331807454422, 526.6667072772982} + {146.66665140787754, 526.00004061063157} + {198.00001017252598, 525.66670735677087} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4071 + Points + + {84.896687825520942, 472.91668446858688} + {197.99999491373694, 472.66668319702148} + + Style + + stroke + + HeadArrow + 0 + Legacy + + TailArrow + FilledArrow + + + + + Class + LineGraphic + ID + 4070 + Points + + {84.896692911783873, 420.66667453447985} + {129.33331298828122, 420.66667453448002} + {146.66664632161454, 420.00000786781334} + {198.00000508626297, 419.66667461395269} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{316.49998792012531, 326.66665395100904}, {65, 36}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4069 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 4: Initiate SSL \ +handshake \ +with SNI} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{317.00000000000006, 456.66707356770831}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4067 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 8: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.187746683756515, 509.33333333333331}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4066 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 7: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.1877466837567, 441.50006103515642}, {76, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4065 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 6: Complete SSL\ +handshake} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{316.99998982747411, 403.66686820983904}, {64, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4063 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 5: CN & SANs} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.187741597493542, 380.00018183390387}, {65, 36}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4061 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 3: Initiate SSL \ +handshake \ +with SNI} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.187745571136503, 338.66666666666669}, {84, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4060 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 2: 200 Connection \ +Established} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.187741915384976, 283.66659164428717}, {64, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4058 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1: CONNECT \ +request} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 4041 + Points + + {84.896692911783944, 366.91666793823208} + {198, 366.66666666666669} + + Style + + stroke + + HeadArrow + 0 + Legacy + + TailArrow + FilledArrow + + + + + Class + LineGraphic + ID + 31 + Points + + {84.896687825520857, 314.66666126251221} + {129.33330790201822, 314.66666126251238} + {146.66664123535153, 313.99999459584569} + {198, 313.66666134198505} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{430.83098347981803, 515.99999999999989}, {36, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4026 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Server} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{40.499999999999993, 486.66666666666663}, {31, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4025 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Client} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}} + Class + ShapedGraphic + ID + 4004 + ImageID + 6 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Bounds + {{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}} + Class + ShapedGraphic + ID + 4023 + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.463735 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 mitmproxy} + + + + Bounds + {{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}} + Class + ShapedGraphic + ID + 134 + ImageID + 3 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 7 + ImageLinkBack + + + + + ImageList + + image6.tiff + image3.icns + + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-01-03 02:14:45 +0000 + Modifier + Aldo Cortesi + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595.19998741149902, 841.79998779296875} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{271, 336}, {974, 874}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 202}, {550, 469.33333333333337}} + Zoom + 1.5 + ZoomValues + + + Canvas 1 + 1.5 + 1 + + + + + diff --git a/doc-src/_explicit_https.graffle/image3.icns b/doc-src/_explicit_https.graffle/image3.icns new file mode 100644 index 000000000..964df4b8c Binary files /dev/null and b/doc-src/_explicit_https.graffle/image3.icns differ diff --git a/doc-src/_explicit_https.graffle/image6.tiff b/doc-src/_explicit_https.graffle/image6.tiff new file mode 100644 index 000000000..bd6ed534b Binary files /dev/null and b/doc-src/_explicit_https.graffle/image6.tiff differ diff --git a/doc-src/_layout.html b/doc-src/_layout.html new file mode 100644 index 000000000..c5fb6376b --- /dev/null +++ b/doc-src/_layout.html @@ -0,0 +1,36 @@ + + + +
+
+
+ +
+ +
+ + $!body!$ +
+
+ +
+ + +
diff --git a/doc-src/_nav.html b/doc-src/_nav.html new file mode 100644 index 000000000..b256f47f5 --- /dev/null +++ b/doc-src/_nav.html @@ -0,0 +1,48 @@ + diff --git a/doc-src/_transparent.graffle/data.plist b/doc-src/_transparent.graffle/data.plist new file mode 100644 index 000000000..722b4a44a --- /dev/null +++ b/doc-src/_transparent.graffle/data.plist @@ -0,0 +1,771 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle.MacAppStore + 139.16 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {559.19998741149902, 782.79998779296875}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-01-02 19:31:53 +0000 + Creator + Aldo Cortesi + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{101.18773396809897, 358.41662979125977}, {62, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4079 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 2: Redirection} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{102.18775939941409, 405.16666666666663}, {78, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4078 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 3: HTTP Request} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ControlPoints + + {-29.333333333333343, 15.666671991348267} + {-14, -7.3333333333333712} + + ID + 37 + Points + + {196.99999491373691, 331.83332316080725} + {198.00000508626303, 402.49998982747394} + + Style + + stroke + + Bezier + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{205.34387397766082, 289.3333333333328}, {84, 52.666667938232422}} + Class + ShapedGraphic + ID + 4076 + Shape + Rectangle + Style + + fill + + Color + + b + 0.547829 + g + 1 + r + 0.790866 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 router} + + + + Class + LineGraphic + ID + 4075 + Points + + {304.061024983724, 422.16667167345679} + {348.49764506022132, 422.16667167345696} + {365.83097839355469, 421.50000500679027} + {417.16433715820312, 421.16667175292963} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{321.11267089843761, 405.16706339518225}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4067 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 4: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{101.18773682912195, 295.66660690307623}, {62, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4058 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1: Connection} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 4041 + Points + + {85.896713256836037, 421.41666793823208} + {199.00002034505209, 421.16666666666669} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 31 + Points + + {84.896687825520857, 314.66666126251221} + {129.33330790201822, 314.66666126251238} + {146.66664123535153, 313.99999459584569} + {198, 313.66666134198505} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{430.83098347981803, 515.99999999999989}, {36, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4026 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Server} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{40.499999999999993, 486.66666666666663}, {31, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4025 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Client} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}} + Class + ShapedGraphic + ID + 4004 + ImageID + 6 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Bounds + {{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}} + Class + ShapedGraphic + ID + 4023 + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.463735 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 mitmproxy} + + + + Bounds + {{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}} + Class + ShapedGraphic + ID + 134 + ImageID + 3 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 7 + ImageLinkBack + + + + + ImageList + + image6.tiff + image3.icns + + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-01-03 04:13:10 +0000 + Modifier + Aldo Cortesi + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595.19998741149902, 841.79998779296875} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{295, 141}, {974, 874}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 208}, {550, 469.33333333333337}} + Zoom + 1.5 + ZoomValues + + + Canvas 1 + 1.5 + 1 + + + + + diff --git a/doc-src/_transparent.graffle/image3.icns b/doc-src/_transparent.graffle/image3.icns new file mode 100644 index 000000000..964df4b8c Binary files /dev/null and b/doc-src/_transparent.graffle/image3.icns differ diff --git a/doc-src/_transparent.graffle/image6.tiff b/doc-src/_transparent.graffle/image6.tiff new file mode 100644 index 000000000..bd6ed534b Binary files /dev/null and b/doc-src/_transparent.graffle/image6.tiff differ diff --git a/doc-src/_transparent_https.graffle/data.plist b/doc-src/_transparent_https.graffle/data.plist new file mode 100644 index 000000000..9c1395d78 --- /dev/null +++ b/doc-src/_transparent_https.graffle/data.plist @@ -0,0 +1,1096 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle.MacAppStore + 139.16 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {559.19998741149902, 782.79998779296875}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-01-02 19:31:53 +0000 + Creator + Aldo Cortesi + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + ID + 4075 + Points + + {299.99999999999994, 470.90565482775372} + {344.43662007649726, 470.90565482775389} + {361.76995340983063, 470.23898816108721} + {413.10331217447907, 469.90565490722656} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4074 + Points + + {300.5, 417.94731195767724} + {344.93662007649738, 417.94731195767741} + {362.26995340983063, 417.28064529101073} + {413.60331217447907, 416.94731203715008} + + Style + + stroke + + HeadArrow + 0 + Legacy + + TailArrow + FilledArrow + + + + + Class + LineGraphic + ID + 4073 + Points + + {300.50000000000006, 364.90563909212648} + {344.93662007649743, 364.90563909212665} + {362.26995340983069, 364.23897242545996} + {413.60331217447919, 363.90563917159932} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{316.55163383483881, 323.90562693277991}, {65, 36}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4069 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 4: Initiate SSL \ +handshake \ +with SNI} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{317.05164591471356, 453.90604654947919}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4067 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 8: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{317.05163574218761, 400.90584119160991}, {64, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4063 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 5: CN & SANs} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 4072 + Points + + {85.333343505859332, 525.3331921100596} + {129.7699635823565, 525.3331921100596} + {147.10329691568987, 524.66652544339308} + {198.4366556803383, 524.33319218953238} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Class + LineGraphic + ID + 4071 + Points + + {85.3333333333334, 471.58316930134964} + {198.43664042154924, 471.33316802978419} + + Style + + stroke + + HeadArrow + 0 + Legacy + + TailArrow + FilledArrow + + + + + Class + LineGraphic + ID + 4070 + Points + + {85.33333841959633, 419.33315936724267} + {129.76995849609349, 419.33315936724279} + {147.10329182942687, 418.66649270057616} + {198.4366505940753, 418.33315944671557} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{97.957725524902315, 508.66666666666663}, {49, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4066 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 7: Request} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.624392191569157, 440.16654586791918}, {76, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4065 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 6: Complete SSL\ +handshake} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.624387105305999, 377.33333333333331}, {65, 36}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4061 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 3: Initiate SSL \ +handshake \ +with SNI} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{94.624387105305971, 344.58320871988946}, {62, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4079 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 2: Redirection} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ControlPoints + + {-29.333333333333343, 15.666671991348267} + {-14, -7.3333333333333712} + + ID + 37 + Points + + {197.43664042154938, 317.99990208943694} + {198.4366505940755, 388.66656875610363} + + Style + + stroke + + Bezier + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{205.34387397766082, 289.3333333333328}, {84, 52.666667938232422}} + Class + ShapedGraphic + ID + 4076 + Shape + Rectangle + Style + + fill + + Color + + b + 0.547829 + g + 1 + r + 0.790866 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 router} + + + + Bounds + {{97.957725842793792, 284.99970499674527}, {62, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4058 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1: Connection} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 31 + Points + + {85.333333333333329, 300.8332401911419} + {129.76995340983069, 300.83324019114207} + {147.10328674316401, 300.16657352447538} + {198.43664550781247, 299.83324027061474} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + + + Bounds + {{430.83098347981803, 515.99999999999989}, {36, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4026 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Server} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{40.499999999999993, 486.66666666666663}, {31, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + ID + 4025 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Client} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}} + Class + ShapedGraphic + ID + 4004 + ImageID + 6 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Bounds + {{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}} + Class + ShapedGraphic + ID + 4023 + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.463735 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red37\green17\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf2 mitmproxy} + + + + Bounds + {{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}} + Class + ShapedGraphic + ID + 134 + ImageID + 3 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 7 + ImageLinkBack + + + + + ImageList + + image6.tiff + image3.icns + + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-01-03 04:16:32 +0000 + Modifier + Aldo Cortesi + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595.19998741149902, 841.79998779296875} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{869, 248}, {974, 874}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 208}, {550, 469.33333333333337}} + Zoom + 1.5 + ZoomValues + + + Canvas 1 + 1.5 + 1 + + + + + diff --git a/doc-src/_transparent_https.graffle/image3.icns b/doc-src/_transparent_https.graffle/image3.icns new file mode 100644 index 000000000..964df4b8c Binary files /dev/null and b/doc-src/_transparent_https.graffle/image3.icns differ diff --git a/doc-src/_transparent_https.graffle/image6.tiff b/doc-src/_transparent_https.graffle/image6.tiff new file mode 100644 index 000000000..bd6ed534b Binary files /dev/null and b/doc-src/_transparent_https.graffle/image6.tiff differ diff --git a/doc-src/_websitelayout.html b/doc-src/_websitelayout.html new file mode 100644 index 000000000..cd0d23e24 --- /dev/null +++ b/doc-src/_websitelayout.html @@ -0,0 +1,42 @@ + + +
+
+ +
+ +
+
+ + $!body!$ +
+
+ +
+ + +
diff --git a/doc-src/certinstall/android-settingssecurityinstallca.png b/doc-src/certinstall/android-settingssecurityinstallca.png new file mode 100644 index 000000000..f0f97273e Binary files /dev/null and b/doc-src/certinstall/android-settingssecurityinstallca.png differ diff --git a/doc-src/certinstall/android-settingssecuritymenu.png b/doc-src/certinstall/android-settingssecuritymenu.png new file mode 100644 index 000000000..fea412fec Binary files /dev/null and b/doc-src/certinstall/android-settingssecuritymenu.png differ diff --git a/doc-src/certinstall/android-settingssecurityuserinstalledca.png b/doc-src/certinstall/android-settingssecurityuserinstalledca.png new file mode 100644 index 000000000..1f7717ad4 Binary files /dev/null and b/doc-src/certinstall/android-settingssecurityuserinstalledca.png differ diff --git a/doc-src/certinstall/android-shellwgetmitmproxyca.png b/doc-src/certinstall/android-shellwgetmitmproxyca.png new file mode 100644 index 000000000..4a4e326f0 Binary files /dev/null and b/doc-src/certinstall/android-shellwgetmitmproxyca.png differ diff --git a/doc-src/certinstall/android.html b/doc-src/certinstall/android.html new file mode 100644 index 000000000..9b0c5d716 --- /dev/null +++ b/doc-src/certinstall/android.html @@ -0,0 +1,45 @@ +The proxy situation on Android is [an +embarrasment](http://code.google.com/p/android/issues/detail?id=1273). It's +scarcely credible, but Android didn't have a global proxy setting at all until +quite recently, and it's still not supported on many common Android versions. +In the meantime the app ecosystem has grown used to life without this basic +necessity, and many apps merrily ignore it even if it's there. This situation +is improving, but in many circumstances using [transparent +mode](@!urlTo("transparent.html")!@) is mandatory for testing Android apps. + +We used an Asus Transformer Prime TF201 with Android 4.0.3 in the examples +below - your device may differ, but the broad process should be similar. + + +## Getting the certificate onto the device + +First we need to get the __mitmproxy-ca-cert.cer__ file into the +__/sdcard__ folder on the device (/sdcard/Download on older devices). There are a number of ways to do +this. If you have the Android Developer Tools installed, you can use [__adb +push__](http://developer.android.com/tools/help/adb.html) to accomplish this. +Depending on your device, you could also transfer the file using external media +like an SD Card. In this example, we're using wget from within a terminal +emulator to transfer the certificate from a local HTTP server: + + + + +## Installing the certificate + +Once we have the certificate on the local disk, we need to import it into the +list of trusted CAs. Go to Settings -> Security -> Credential Storage, +and select "Install from storage": + + + +The certificate in /sdcard is automatically located and offered for +installation. Installing the cert will delete the download file from the local +disk: + + + +Afterwards, you should see the certificate listed in the Trusted Credentials +store: + + + diff --git a/doc-src/certinstall/firefox.html b/doc-src/certinstall/firefox.html new file mode 100644 index 000000000..66fa9d797 --- /dev/null +++ b/doc-src/certinstall/firefox.html @@ -0,0 +1,23 @@ + +How to install the __mitmproxy__ certificate authority in Firefox: + +
    +
  1. If needed, copy the ~/.mitmproxy/mitmproxy-ca-cert.pem file to the target.
  2. + +
  3. Open preferences, click on "Advanced", then select"Encryption": + +
  4. + +
  5. Click "View Certificates", "Import", and select the certificate file: + +
  6. + +
  7. Tick "Trust this CS to identify web sites", and click "Ok": + +
  8. + +
  9. You should now see the mitmproxy certificate listed in the Authorities + tab.
  10. + +
+ diff --git a/doc-src/certinstall/index.py b/doc-src/certinstall/index.py new file mode 100644 index 000000000..3f145fbc6 --- /dev/null +++ b/doc-src/certinstall/index.py @@ -0,0 +1,10 @@ +from countershape import Page + +pages = [ + Page("firefox.html", "Firefox"), + Page("osx.html", "OSX"), + Page("windows7.html", "Windows 7"), + Page("ios.html", "IOS"), + Page("ios-simulator.html", "IOS Simulator"), + Page("android.html", "Android"), +] diff --git a/doc-src/certinstall/ios-simulator.html b/doc-src/certinstall/ios-simulator.html new file mode 100644 index 000000000..9eb981086 --- /dev/null +++ b/doc-src/certinstall/ios-simulator.html @@ -0,0 +1,23 @@ + +How to install the __mitmproxy__ certificate authority in the IOS simulator: + +
    + +
  1. First, check out the ADVTrustStore tool + from github.
  2. + +
  3. Now, run the following command: + +
    ./iosCertTrustManager.py -a ~/.mitmproxy/mitmproxy-ca-cert.pem
    + +
  4. + +
+ + +Note that although the IOS simulator has its own certificate store, it shares +the proxy settings of the host operating system. You will therefore to have +configure your OSX host's proxy settings to use the mitmproxy instance you want +to test with. + diff --git a/doc-src/certinstall/ios.html b/doc-src/certinstall/ios.html new file mode 100644 index 000000000..fd14e65aa --- /dev/null +++ b/doc-src/certinstall/ios.html @@ -0,0 +1,21 @@ + +How to install the __mitmproxy__ certificate authority on IOS devices: + +
    +
  1. Set up the Mail app on the device to receive email.
  2. + +
  3. Mail the mitmproxy-ca-cert.pem file to the device, and tap on the attachment.
  4. + +
  5. You will be prompted to install a profile. Click "Install": + +
  6. + +
  7. Accept the warning by clicking "Install" again: + +
  8. + +
  9. The certificate should now be trusted: + +
  10. + +
diff --git a/doc-src/certinstall/osx.html b/doc-src/certinstall/osx.html new file mode 100644 index 000000000..a532d5380 --- /dev/null +++ b/doc-src/certinstall/osx.html @@ -0,0 +1,16 @@ + +How to install the __mitmproxy__ certificate authority in OSX: + +
    + +
  1. Open Finder, and double-click on the mitmproxy-ca-cert.pem file.
  2. + +
  3. You will be prompted to add the certificate. Click "Always Trust": + + +
  4. + +
  5. You may be prompted for your password. You should now see the + mitmproxy cert listed under "Certificates".
  6. +
+ diff --git a/doc-src/certinstall/windows7.html b/doc-src/certinstall/windows7.html new file mode 100644 index 000000000..47c807c6e --- /dev/null +++ b/doc-src/certinstall/windows7.html @@ -0,0 +1,32 @@ + +How to install the __mitmproxy__ certificate authority in Windows 7: + +
    + +
  1. Copy the ~/.mitmproxy/mitmproxy-ca-cert.p12 file to the target system.
  2. + +
  3. + Double-click the certificate file. You should see a certificate import wizard: + + +
  4. + +
  5. + Click "Next" until you're prompted for the certificate store: + + + +
  6. + + +
  7. +

    Select "Place all certificates in the following store", and select "Trusted Root Certification Authorities":

    + + + +
  8. + +
  9. Click "Next" and "Finish".
  10. + +
+ diff --git a/doc-src/dev/addingviews.html b/doc-src/dev/addingviews.html new file mode 100644 index 000000000..12623a311 --- /dev/null +++ b/doc-src/dev/addingviews.html @@ -0,0 +1,52 @@ +As discussed in [the Flow View section of the mitmproxy +overview](@!urlTo("mitmproxy.html")!@), mitmproxy allows you to inspect and +manipulate flows. When inspecting a single flow, mitmproxy uses a number of +heuristics to show a friendly view of various content types; if mitmproxy +cannot show a friendly view, mitmproxy defaults to a __raw__ view. + +Each content type invokes a different flow viewer to parse the data and display +the friendly view. Users can add custom content viewers by adding a view class +to contentview.py, discussed below. + +## Adding a new View class to contentview.py + +The content viewers used by mitmproxy to present a friendly view of various +content types are stored in contentview.py. Reviewing this file shows a number +of classes named ViewSomeDataType, each with the properties: __name__, +__prompt__, and __content\_types__ and a function named __\_\_call\_\___. + +Adding a new content viewer to parse a data type is as simple as writing a new +View class. Your new content viewer View class should have the same properties +as the other View classes: __name__, __prompt__, and __content\_types__ and a +__\_\_call\_\___ function to parse the content of the request/response. + +* The __name__ property should be a string describing the contents and new content viewer; +* The __prompt__ property should be a two item tuple: + + - __1__: A string that will be used to display the new content viewer's type; and + - __2__: A one character string that will be the hotkey used to select the new content viewer from the Flow View screen; + +* The __content\_types__ property should be a list of strings of HTTP Content\-Types that the new content viewer can parse. + * Note that mitmproxy will use the content\_types to try and heuristically show a friendly view of content and that you can override the built-in views by populating content\_types with values for content\_types that are already parsed -- e.g. "image/png". + +After defining the __name__, __prompt__, and __content\_types__ properties of +the class, you should write the __\_\_call\_\___ function, which will parse the +request/response data and provide a friendly view of the data. The +__\_\_call\_\___ function should take the following arguments: __self__, +__hdrs__, __content__, __limit__; __hdrs__ is a ODictCaseless object containing +the headers of the request/response; __content__ is the content of the +request/response, and __limit__ is an integer representing the amount of data +to display in the view window. + +The __\_\_call\_\___ function returns two values: (1) a string describing the +parsed data; and (2) the parsed data for friendly display. The parsed data to +be displayed should be a list of strings formatted for display. You can use +the __\_view\_text__ function in contentview.py to format text for display. +Alternatively, you can display content as a series of key-value pairs; to do +so, prepare a list of lists, where each list item is a two item list -- a key +that describes the data, and then the data itself; after preparing the list of +lists, use the __common.format\_keyvals__ function on it to prepare it as text +for display. + +If the new content viewer fails or throws an exception, mitmproxy will default +to a __raw__ view. diff --git a/doc-src/dev/index.py b/doc-src/dev/index.py new file mode 100644 index 000000000..001c2b89a --- /dev/null +++ b/doc-src/dev/index.py @@ -0,0 +1,6 @@ +from countershape import Page + +pages = [ + Page("testing.html", "Testing"), +# Page("addingviews.html", "Writing Content Views"), +] diff --git a/doc-src/dev/testing.html b/doc-src/dev/testing.html new file mode 100644 index 000000000..4cee29e8f --- /dev/null +++ b/doc-src/dev/testing.html @@ -0,0 +1,43 @@ + +All the mitmproxy projects strive to maintain 100% code coverage. In general, +patches and pull requests will be declined unless they're accompanied by a +suitable extension to the test suite. + +Our tests are written for the [nose](https://nose.readthedocs.org/en/latest/). +At the point where you send your pull request, a command like this: + +
+> nosetests --with-cov --cov-report term-missing ./test
+
+ +Should give output something like this: + +
+> ---------- coverage: platform darwin, python 2.7.2-final-0 --
+> Name                   Stmts   Miss  Cover   Missing
+> ----------------------------------------------------
+> libmproxy/__init__         0      0   100%
+> libmproxy/app              4      0   100%
+> libmproxy/cmdline        100      0   100%
+> libmproxy/controller      69      0   100%
+> libmproxy/dump           150      0   100%
+> libmproxy/encoding        39      0   100%
+> libmproxy/filt           201      0   100%
+> libmproxy/flow           891      0   100%
+> libmproxy/proxy          427      0   100%
+> libmproxy/script          27      0   100%
+> libmproxy/utils          133      0   100%
+> libmproxy/version          4      0   100%
+> ----------------------------------------------------
+> TOTAL                   2045      0   100%
+> ----------------------------------------------------
+> Ran 251 tests in 11.864s
+
+ + +There are exceptions to the coverage requirement - for instance, much of the +console interface code can't sensibly be unit tested. These portions are +excluded from coverage analysis either in the **.coveragerc** file, or using +**#pragma no-cover** directives. To keep our coverage analysis relevant, we use +these measures as sparingly as possible. + diff --git a/doc-src/explicit.png b/doc-src/explicit.png new file mode 100644 index 000000000..c9ba26a73 Binary files /dev/null and b/doc-src/explicit.png differ diff --git a/doc-src/explicit_https.png b/doc-src/explicit_https.png new file mode 100644 index 000000000..1f1ca0231 Binary files /dev/null and b/doc-src/explicit_https.png differ diff --git a/doc-src/features/anticache.html b/doc-src/features/anticache.html new file mode 100644 index 000000000..f42903e8a --- /dev/null +++ b/doc-src/features/anticache.html @@ -0,0 +1,18 @@ + +When the __anticache__ option is passed to mitmproxy, it removes headers +(__if-none-match__ and __if-modified-since__) that might elicit a +304-not-modified response from the server. This is useful when you want to make +sure you capture an HTTP exchange in its totality. It's also often used during +[client replay](@!urlTo("clientreplay.html")!@), when you want to make sure the +server responds with complete data. + + + + + + + + + + +
command-line --anticache
mitmproxy shortcut o then a
diff --git a/doc-src/features/clientreplay.html b/doc-src/features/clientreplay.html new file mode 100644 index 000000000..6638d0780 --- /dev/null +++ b/doc-src/features/clientreplay.html @@ -0,0 +1,22 @@ + +Client-side replay does what it says on the tin: you provide a previously saved +HTTP conversation, and mitmproxy replays the client requests one by one. Note +that mitmproxy serializes the requests, waiting for a response from the server +before starting the next request. This might differ from the recorded +conversation, where requests may have been made concurrently. + +You may want to use client-side replay in conjunction with the +[anticache](@!urlTo("anticache.html")!@) option, to make sure the server +responds with complete data. + + + + + + + + + + + +
command-line -c path
mitmproxy shortcut c
diff --git a/doc-src/features/filters.html b/doc-src/features/filters.html new file mode 100644 index 000000000..c7f0f78bc --- /dev/null +++ b/doc-src/features/filters.html @@ -0,0 +1,36 @@ + +Many commands in __mitmproxy__ and __mitmdump__ take a filter expression. +Filter expressions consist of the following operators: + + + + + + + + + + +
@!i[0]!@@!i[1]!@
+ +- Regexes are Python-style +- Regexes can be specified as quoted strings +- Header matching (~h, ~hq, ~hs) is against a string of the form "name: value". +- Strings with no operators are matched against the request URL. +- The default binary operator is &. + +Examples +======== + +URL containing "google.com": + + google\.com + +Requests whose body contains the string "test": + + ~q ~b test + +Anything but requests with a text/html content type: + + !(~q & ~t \"text/html\") + diff --git a/doc-src/features/forwardproxy.html b/doc-src/features/forwardproxy.html new file mode 100644 index 000000000..203520d51 --- /dev/null +++ b/doc-src/features/forwardproxy.html @@ -0,0 +1,16 @@ + +In this mode, mitmproxy accepts proxy requests and unconditionally forwards all +requests to a specified upstream server. This is in contrast to reverse proxy mode, in which +mitmproxy forwards ordinary HTTP requests to an upstream server. + + + + + + + + + + +
command-line -F http[s]://hostname[:port]
mitmproxy shortcut F
diff --git a/doc-src/features/index.py b/doc-src/features/index.py new file mode 100644 index 000000000..e15f3311c --- /dev/null +++ b/doc-src/features/index.py @@ -0,0 +1,15 @@ +from countershape import Page + +pages = [ + Page("anticache.html", "Anticache"), + Page("clientreplay.html", "Client-side replay"), + Page("filters.html", "Filter expressions"), + Page("forwardproxy.html", "Forward proxy mode"), + Page("setheaders.html", "Set Headers"), + Page("serverreplay.html", "Server-side replay"), + Page("sticky.html", "Sticky cookies and auth"), + Page("proxyauth.html", "Proxy Authentication"), + Page("replacements.html", "Replacements"), + Page("reverseproxy.html", "Reverse proxy mode"), + Page("upstreamcerts.html", "Upstream Certs"), +] diff --git a/doc-src/features/proxyauth.html b/doc-src/features/proxyauth.html new file mode 100644 index 000000000..c22d50f39 --- /dev/null +++ b/doc-src/features/proxyauth.html @@ -0,0 +1,26 @@ + +Asks the user for authentication before they are permitted to use the proxy. +Authentication headers are stripped from the flows, so they are not passed to +upstream servers. For now, only HTTP Basic authentication is supported. The +proxy auth options are ignored if the proxy is in transparent or reverse proxy +mode. + + + + + + + + +
command-line +
    +
  • --nonanonymous
  • + +
  • --singleuser USER
  • + +
  • --htpasswd PATH
  • +
+
+ + + diff --git a/doc-src/features/replacements.html b/doc-src/features/replacements.html new file mode 100644 index 000000000..c10fe2c36 --- /dev/null +++ b/doc-src/features/replacements.html @@ -0,0 +1,74 @@ +Mitmproxy lets you specify an arbitrary number of patterns that define text +replacements within flows. Each pattern has 3 components: a filter that defines +which flows a replacement applies to, a regular expression that defines what +gets replaced, and a target value that defines what is substituted in. + +Replace hooks fire when either a client request or a server response is +received. Only the matching flow component is affected: so, for example, if a +replace hook is triggered on server response, the replacement is only run on +the Response object leaving the Request intact. You control whether the hook +triggers on the request, response or both using the filter pattern. If you need +finer-grained control than this, it's simple to create a script using the +replacement API on Flow components. + +Replacement hooks are extremely handy in interactive testing of applications. +For instance you can use a replace hook to replace the text "XSS" with a +complicated XSS exploit, and then "inject" the exploit simply by interacting +with the application through the browser. When used with tools like Firebug and +mitmproxy's own interception abilities, replacement hooks can be an amazingly +flexible and powerful feature. + + +## On the command-line + +The replacement hook command-line options use a compact syntax to make it easy +to specify all three components at once. The general form is as follows: + + /patt/regex/replacement + +Here, __patt__ is a mitmproxy filter expression, __regex__ is a valid Python +regular expression, and __replacement__ is a string literal. The first +character in the expression (__/__ in this case) defines what the separation +character is. Here's an example of a valid expression that replaces "foo" with +"bar" in all requests: + + :~q:foo:bar + +In practice, it's pretty common for the replacement literal to be long and +complex. For instance, it might be an XSS exploit that weighs in at hundreds or +thousands of characters. To cope with this, there's a variation of the +replacement hook specifier that lets you load the replacement text from a file. +So, you might start __mitmdump__ as follows: + +
+mitmdump --replace-from-file :~q:foo:~/xss-exploit
+
+ +This will load the replacement text from the file __~/xss-exploit__. + +Both the _--replace_ and _--replace-from-file_ flags can be passed multiple +times. + + +## Interactively + +The _R_ shortcut key in mitmproxy lets you add and edit replacement hooks using +a built-in editor. The context-sensitive help (_h_) has complete usage +information. + + + + + + + + + + + +
command-line +
    +
  • --replace
  • +
  • --replace-from-file
  • +
+
mitmproxy shortcut R
diff --git a/doc-src/features/reverseproxy.html b/doc-src/features/reverseproxy.html new file mode 100644 index 000000000..d399cdc0c --- /dev/null +++ b/doc-src/features/reverseproxy.html @@ -0,0 +1,19 @@ + +In reverse proxy mode, mitmproxy accepts standard HTTP requests and forwards +them to the specified upstream server. This is in contrast to forward proxy mode, in which +mitmproxy forwards HTTP proxy requests to an upstream server. + +Note that the displayed URL for flows in this mode will use the value of the +__Host__ header field from the request, not the reverse proxy server. + + + + + + + + + + +
command-line -P http[s]://hostname[:port]
mitmproxy shortcut P
diff --git a/doc-src/features/serverreplay.html b/doc-src/features/serverreplay.html new file mode 100644 index 000000000..1282be065 --- /dev/null +++ b/doc-src/features/serverreplay.html @@ -0,0 +1,35 @@ + +- command-line: _-S path_ +- mitmproxy shortcut: _S_ + +Server-side replay lets us replay server responses from a saved HTTP +conversation. + +Matching requests with responses +-------------------------------- + +By default, __mitmproxy__ excludes request headers when matching incoming +requests with responses from the replay file. This works in most circumstances, +and makes it possible to replay server responses in situations where request +headers would naturally vary, e.g. using a different user agent. The _--rheader +headername_ command-line option allows you to override this behaviour by +specifying individual headers that should be included in matching. + + +Response refreshing +------------------- + +Simply replaying server responses without modification will often result in +unexpected behaviour. For example cookie timeouts that were in the future at +the time a conversation was recorded might be in the past at the time it is +replayed. By default, __mitmproxy__ refreshes server responses before sending +them to the client. The __date__, __expires__ and __last-modified__ headers are +all updated to have the same relative time offset as they had at the time of +recording. So, if they were in the past at the time of recording, they will be +in the past at the time of replay, and vice versa. Cookie expiry times are +updated in a similar way. + +You can turn off response refreshing using the _--norefresh_ argument, or using +the _o_ options shortcut within __mitmproxy__. + + diff --git a/doc-src/features/setheaders.html b/doc-src/features/setheaders.html new file mode 100644 index 000000000..b74525df2 --- /dev/null +++ b/doc-src/features/setheaders.html @@ -0,0 +1,18 @@ + +This feature lets you specify a set of headers to be added to requests or +responses, based on a filter pattern. You can specify these either on the +command-line, or through an interactive editor in mitmproxy. + + + + + + + + + + + +
command-line + --setheader PATTERN +
mitmproxy shortcut H
diff --git a/doc-src/features/sticky.html b/doc-src/features/sticky.html new file mode 100644 index 000000000..591160672 --- /dev/null +++ b/doc-src/features/sticky.html @@ -0,0 +1,60 @@ + +## Sticky cookies + +When the sticky cookie option is set, __mitmproxy__ will add the cookie most +recently set by the server to any cookie-less request. Consider a service that +sets a cookie to track the session after authentication. Using sticky cookies, +you can fire up mitmproxy, and authenticate to a service as you usually would +using a browser. After authentication, you can request authenticated resources +through mitmproxy as if they were unauthenticated, because mitmproxy will +automatically add the session tracking cookie to requests. Among other things, +this lets you script interactions with authenticated resources (using tools +like wget or curl) without having to worry about authentication. + +Sticky cookies are especially powerful when used in conjunction with [client +replay](@!urlTo("clientreplay.html")!@) - you can record the authentication +process once, and simply replay it on startup every time you need to interact +with the secured resources. + + + + + + + + + + + +
command-line +
    +
  • -t FILTER
  • +
+
mitmproxy shortcut t
+ + +## Sticky auth + +The sticky auth option is analogous to the sticky cookie option, in that HTTP +__Authorization__ headers are simply replayed to the server once they have been +seen. This is enough to allow you to access a server resource using HTTP Basic +authentication through the proxy. Note that __mitmproxy__ doesn't (yet) support +replay of HTTP Digest authentication. + + + + + + + + + + + +
command-line +
    +
  • -u FILTER
  • +
+
mitmproxy shortcut u
+ + diff --git a/doc-src/features/upstreamcerts.html b/doc-src/features/upstreamcerts.html new file mode 100644 index 000000000..8de75ee34 --- /dev/null +++ b/doc-src/features/upstreamcerts.html @@ -0,0 +1,21 @@ +When mitmproxy receives a connection destined for an SSL-protected service, it +freezes the connection before reading its request data, and makes a connection +to the upstream server to "sniff" the contents of its SSL certificate. The +information gained - the __Common Name__ and __Subject Alternative Names__ - is +then used to generate the interception certificate, which is sent to the client +so the connection can continue. + +This rather intricate little dance lets us seamlessly generate correct +certificates even if the client has specifed only an IP address rather than the +hostname. It also means that we don't need to sniff additional data to generate +certs in transparent mode. + +Upstream cert sniffing is on by default, and can optionally be turned off. + + + + + + + +
command-line --no-upstream-cert
diff --git a/doc-src/howmitmproxy.html b/doc-src/howmitmproxy.html new file mode 100644 index 000000000..94afd5224 --- /dev/null +++ b/doc-src/howmitmproxy.html @@ -0,0 +1,360 @@ + + +Mitmproxy is an enormously flexible tool. Knowing exactly how the proxying +process works will help you deploy it creatively, and take into account its +fundamental assumptions and how to work around them. This document explains +mitmproxy's proxy mechanism in detail, starting with the simplest unencrypted +explicit proxying, and working up to the most complicated interaction - +transparent proxying of SSL-protected traffic[^ssl] in the presence of +[SNI](http://en.wikipedia.org/wiki/Server_Name_Indication). + + + + +Configuring the client to use mitmproxy as an explicit proxy is the simplest +and most reliable way to intercept traffic. The proxy protocol is codified in +the [HTTP RFC](http://www.ietf.org/rfc/rfc2068.txt), so the behaviour of both +the client and the server is well defined, and usually reliable. In the +simplest possible interaction with mitmproxy, a client connects directly to the +proxy, and makes a request that looks like this: + +
GET http://example.com/index.html HTTP/1.1
+ +This is a proxy GET request - an extended form of the vanilla HTTP GET request +that includes a schema and host specification, and it includes all the +information mitmproxy needs to proceed. + + + + + + + + + + + + + + + + + + + + + +
1The client connects to the proxy and makes a request.
2Mitmproxy connects to the upstream server and simply forwards + the request on.
+ + + + +The process for an explicitly proxied HTTPS connection is quite different. The +client connects to the proxy and makes a request that looks like this: + +
CONNECT example.com:443 HTTP/1.1
+ +A conventional proxy can neither view nor manipulate an SSL-encrypted data +stream, so a CONNECT request simply asks the proxy to open a pipe between the +client and server. The proxy here is just a facilitator - it blindly forwards +data in both directions without knowing anything about the contents. The +negotiation of the SSL connection happens over this pipe, and the subsequent +flow of requests and responses are completely opaque to the proxy. + +## The MITM in mitmproxy + +This is where mitmproxy's fundamental trick comes into play. The MITM in its +name stands for Man-In-The-Middle - a reference to the process we use to +intercept and interfere with these theoretically opaque data streams. The basic +idea is to pretend to be the server to the client, and pretend to be the client +to the server, while we sit in the middle decoding traffic from both sides. The +tricky part is that the [Certificate +Authority](http://en.wikipedia.org/wiki/Certificate_authority) system is +designed to prevent exactly this attack, by allowing a trusted third-party to +cryptographically sign a server's SSL certificates to verify that they are +legit. If this signature doesn't match or is from a non-trusted party, a secure +client will simply drop the connection and refuse to proceed. Despite the many +shortcomings of the CA system as it exists today, this is usually fatal to +attempts to MITM an SSL connection for analysis. Our answer to this conundrum +is to become a trusted Certificate Authority ourselves. Mitmproxy includes a +full CA implementation that generates interception certificates on the fly. To +get the client to trust these certificates, we [register mitmproxy as a trusted +CA with the device manually](@!urlTo("ssl.html")!@). + +## Complication 1: What's the remote hostname? + +To proceed with this plan, we need to know the domain name to use in the +interception certificate - the client will verify that the certificate is for +the domain it's connecting to, and abort if this is not the case. At first +blush, it seems that the CONNECT request above gives us all we need - in this +example, both of these values are "example.com". But what if the client had +initiated the connection as follows: + +
CONNECT 10.1.1.1:443 HTTP/1.1
+ +Using the IP address is perfectly legitimate because it gives us enough +information to initiate the pipe, even though it doesn't reveal the remote +hostname. + +Mitmproxy has a cunning mechanism that smooths this over - [upstream +certificate sniffing](@!urlTo("features/upstreamcerts.html")!@). As soon as we +see the CONNECT request, we pause the client part of the conversation, and +initiate a simultaneous connection to the server. We complete the SSL handshake +with the server, and inspect the certificates it used. Now, we use the Common +Name in the upstream SSL certificates to generate the dummy certificate for the +client. Voila, we have the correct hostname to present to the client, even if +it was never specified. + + +## Complication 2: Subject Alternative Name + +Enter the next complication. Sometimes, the certificate Common Name is not, in +fact, the hostname that the client is connecting to. This is because of the +optional [Subject Alternative +Name](http://en.wikipedia.org/wiki/SubjectAltName) field in the SSL certificate +that allows an arbitrary number of alternative domains to be specified. If the +expected domain matches any of these, the client will proceed, even though the +domain doesn't match the certificate Common Name. The answer here is simple: +when extract the CN from the upstream cert, we also extract the SANs, and add +them to the generated dummy certificate. + + +## Complication 3: Server Name Indication + +One of the big limitations of vanilla SSL is that each certificate requires its +own IP address. This means that you couldn't do virtual hosting where multiple +domains with independent certificates share the same IP address. In a world +with a rapidly shrinking IPv4 address pool this is a problem, and we have a +solution in the form of the [Server Name +Indication](http://en.wikipedia.org/wiki/Server_Name_Indication) extension to +the SSL and TLS protocols. This lets the client specify the remote server name +at the start of the SSL handshake, which then lets the server select the right +certificate to complete the process. + +SNI breaks our upstream certificate sniffing process, because when we connect +without using SNI, we get served a default certificate that may have nothing to +do with the certificate expected by the client. The solution is another tricky +complication to the client connection process. After the client connects, we +allow the SSL handshake to continue until just _after_ the SNI value has been +passed to us. Now we can pause the conversation, and initiate an upstream +connection using the correct SNI value, which then serves us the correct +upstream certificate, from which we can extract the expected CN and SANs. + +There's another wrinkle here. Due to a limitation of the SSL library mitmproxy +uses, we can't detect that a connection _hasn't_ sent an SNI request until it's +too late for upstream certificate sniffing. In practice, we therefore make a +vanilla SSL connection upstream to sniff non-SNI certificates, and then discard +the connection if the client sends an SNI notification. If you're watching your +traffic with a packet sniffer, you'll see two connections to the server when an +SNI request is made, the first of which is immediately closed after the SSL +handshake. Luckily, this is almost never an issue in practice. + +## Putting it all together + +Lets put all of this together into the complete explicitly proxied HTTPS flow. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1The client makes a connection to mitmproxy, and issues an HTTP + CONNECT request.
2Mitmproxy responds with a 200 Connection Established, as if it + has set up the CONNECT pipe.
3The client believes it's talking to the remote server, and + initiates the SSL connection. It uses SNI to indicate the hostname + it is connecting to.
4Mitmproxy connects to the server, and establishes an SSL + connection using the SNI hostname indicated by the client.
5The server responds with the matching SSL certificate, which + contains the CN and SAN values needed to generate the interception + certificate.
6Mitmproxy generates the interception cert, and continues the + client SSL handshake paused in step 3.
7The client sends the request over the established SSL + connection.
7Mitmproxy passes the request on to the server over the SSL + connection initiated in step 4.
+ + + + +When a transparent proxy is used, the HTTP/S connection is redirected into a +proxy at the network layer, without any client configuration being required. +This makes transparent proxying ideal for those situations where you can't +change client behaviour - proxy-oblivious Android applications being a common +example. + +To achieve this, we need to introduce two extra components. The first is a +redirection mechanism that transparently reroutes a TCP connection destined for +a server on the Internet to a listening proxy server. This usually takes the +form of a firewall on the same host as the proxy server - +[iptables](http://www.netfilter.org/) on Linux or +[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. Once the client has +initiated the connection, it makes a vanilla HTTP request, which might look +something like this: + +
GET /index.html HTTP/1.1
+ +Note that this request differs from the explicit proxy variation, in that it +omits the scheme and hostname. How, then, do we know which upstream host to +forward the request to? The routing mechanism that has performed the +redirection keeps track of the original destination for us. Each routing +mechanism has a different way of exposing this data, so this introduces the +second component required for working transparent proxying: a host module that +knows how to retrieve the original destination address from the router. In +mitmproxy, this takes the form of a built-in set of +[modules](https://github.com/mitmproxy/mitmproxy/tree/master/libmproxy/platform) +that know how to talk to each platform's redirection mechanism. Once we have +this information, the process is fairly straight-forward. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1The client makes a connection to the server.
2The router redirects the connection to mitmproxy, which is + typically listening on a local port of the same host. Mitmproxy + then consults the routing mechanism to establish what the original + destination was.
3Now, we simply read the client's request...
4... and forward it upstream.
+ + + +The first step is to determine whether we should treat an incoming connection +as HTTPS. The mechanism for doing this is simple - we use the routing mechanism +to find out what the original destination port is. By default, we treat all +traffic destined for ports 443 and 8443 as SSL. + +From here, the process is a merger of the methods we've described for +transparently proxying HTTP, and explicitly proxying HTTPS. We use the routing +mechanism to establish the upstream server address, and then proceed as for +explicit HTTPS connections to establish the CN and SANs, and cope with SNI. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1The client makes a connection to the server.
2The router redirects the connection to mitmproxy, which is + typically listening on a local port of the same host. Mitmproxy + then consults the routing mechanism to establish what the original + destination was.
3The client believes it's talking to the remote server, and + initiates the SSL connection. It uses SNI to indicate the hostname + it is connecting to.
4Mitmproxy connects to the server, and establishes an SSL + connection using the SNI hostname indicated by the client.
5The server responds with the matching SSL certificate, which + contains the CN and SAN values needed to generate the interception + certificate.
6Mitmproxy generates the interception cert, and continues the + client SSL handshake paused in step 3.
7The client sends the request over the established SSL + connection.
7Mitmproxy passes the request on to the server over the SSL + connection initiated in step 4.
+ + +[^ssl]: I use "SSL" to refer to both SSL and TLS in the generic sense, unless otherwise specified. diff --git a/doc-src/index.html b/doc-src/index.html new file mode 100644 index 000000000..79687ec61 --- /dev/null +++ b/doc-src/index.html @@ -0,0 +1,4 @@ + +@!index_contents!@ + + diff --git a/doc-src/index.py b/doc-src/index.py new file mode 100644 index 000000000..f222de14a --- /dev/null +++ b/doc-src/index.py @@ -0,0 +1,89 @@ +import os, sys, datetime +import countershape +from countershape import Page, Directory, PythonModule, markup, model +import countershape.template +sys.path.insert(0, "..") +from libmproxy import filt, version + +MITMPROXY_SRC = os.environ.get("MITMPROXY_SRC", os.path.abspath("..")) +ns.VERSION = version.VERSION + +if ns.options.website: + ns.idxpath = "doc/index.html" + this.layout = countershape.Layout("_websitelayout.html") +else: + ns.idxpath = "index.html" + this.layout = countershape.Layout("_layout.html") + +ns.title = countershape.template.Template(None, "

@!this.title!@

") +this.titlePrefix = "%s - " % version.NAMEVERSION +this.markup = markup.Markdown(extras=["footnotes"]) + +ns.docMaintainer = "Aldo Cortesi" +ns.docMaintainerEmail = "aldo@corte.si" +ns.copyright = u"\u00a9 mitmproxy project, %s" % datetime.date.today().year + +def mpath(p): + p = os.path.join(MITMPROXY_SRC, p) + return os.path.expanduser(p) + +with open(mpath("README.mkd")) as f: + readme = f.read() + ns.index_contents = readme.split("\n", 1)[1] #remove first line (contains build status) + +def example(s): + d = file(mpath(s)).read().rstrip() + extemp = """
%s
(%s)
""" + return extemp%(countershape.template.Syntax("py")(d), s) +ns.example = example + + +filt_help = [] +for i in filt.filt_unary: + filt_help.append( + ("~%s"%i.code, i.help) + ) +for i in filt.filt_rex: + filt_help.append( + ("~%s regex"%i.code, i.help) + ) +for i in filt.filt_int: + filt_help.append( + ("~%s int"%i.code, i.help) + ) +filt_help.sort() +filt_help.extend( + [ + ("!", "unary not"), + ("&", "and"), + ("|", "or"), + ("(...)", "grouping"), + ] +) +ns.filt_help = filt_help + + +def nav(page, current, state): + if current.match(page, False): + pre = '
  • ' + else: + pre = "
  • " + p = state.application.getPage(page) + return pre + '%s
  • '%(model.UrlTo(page), p.title) +ns.nav = nav +ns.navbar = countershape.template.File(None, "_nav.html") + +pages = [ + Page("index.html", "Introduction"), + Page("install.html", "Installation"), + Page("mitmproxy.html", "mitmproxy"), + Page("mitmdump.html", "mitmdump"), + Page("howmitmproxy.html", "How mitmproxy works"), + + Page("ssl.html", "Overview"), + Directory("certinstall"), + Directory("scripting"), + Directory("tutorials"), + Page("transparent.html", "Overview"), + Directory("transparent"), +] diff --git a/doc-src/install.html b/doc-src/install.html new file mode 100644 index 000000000..70003d600 --- /dev/null +++ b/doc-src/install.html @@ -0,0 +1,52 @@ + +The preferred way to install mitmproxy - whether you're installing the latest +release or from source - is to use [pip](http://www.pip-installer.org/). If you +don't already have pip on your system, you can find installation instructions +[here](http://www.pip-installer.org/en/latest/installing.html). + + +## Installing the latest release + +A single command will download and install the latest release of mitmproxy, +along with all its dependencies: + +
    +pip install mitmproxy
    +
    + + +## Installing from source + +When installing from source, the easiest method is still to use pip. In this +case run: + +
    +pip install /path/to/source
    +
    + +Note that if you're installing current git master, you will also have to +install the current git master of [netlib](http://github.com/mitmproxy/netlib) by +hand. + +## OSX + +- If you're running a Python interpreter installed with homebrew (or similar), +you may have to install some dependencies by hand. +- Make sure that XCode is installed from the App Store, and that the +command-line tools have been downloaded (XCode/Preferences/Downloads). +- Now use __pip__ to do the installation, as above. + +There are a few bits of customization you might want to do to make mitmproxy +comfortable to use on OSX. The default color scheme is optimized for a dark +background terminal, but you can select a palette for a light terminal +background with the --palette option. You can use the OSX open program +to create a simple and effective ~/.mailcap file to view request and +response bodies: + +
    +application/*; /usr/bin/open -Wn %s
    +audio/*; /usr/bin/open -Wn %s
    +image/*; /usr/bin/open -Wn %s
    +video/*; /usr/bin/open -Wn %s
    +
    + diff --git a/doc-src/mitmdump.html b/doc-src/mitmdump.html new file mode 100644 index 000000000..792f9c52f --- /dev/null +++ b/doc-src/mitmdump.html @@ -0,0 +1,68 @@ + +__mitmdump__ is the command-line companion to mitmproxy. It provides +tcpdump-like functionality to let you view, record, and programmatically +transform HTTP traffic. See the _--help_ flag output for complete +documentation. + + + +# Examples + + +## Saving traffic + +
    +> mitmdump -w outfile
    +
    + +Start up mitmdump in proxy mode, and write all traffic to __outfile__. + + +## Filtering saved traffic + +
    +> mitmdump -nr infile -w outfile "~m post"
    +
    + +Start mitmdump without binding to the proxy port (_-n_), read all flows from +infile, apply the specified filter expression (only match POSTs), and write to +outfile. + + +## Client replay + +
    +> mitmdump -nc outfile
    +
    + +Start mitmdump without binding to the proxy port (_-n_), then replay all +requests from outfile (_-c filename_). Flags combine in the obvious way, so +you can replay requests from one file, and write the resulting flows to +another: + +
    +> mitmdump -nc srcfile -w dstfile
    +
    + +See the [Client-side Replay](@!urlTo("clientreplay.html")!@) section for more information. + + +## Running a script + +
    +> mitmdump -s examples/add_header.py
    +
    + +This runs the __add_header.py__ example script, which simply adds a new header +to all responses. + + +## Scripted data transformation + +
    +> mitmdump -ns examples/add_header.py -r srcfile -w dstfile
    +
    + +This command loads flows from __srcfile__, transforms it according to the +specified script, then writes it back to __dstfile__. + diff --git a/doc-src/mitmproxy.html b/doc-src/mitmproxy.html new file mode 100644 index 000000000..d41c1b21a --- /dev/null +++ b/doc-src/mitmproxy.html @@ -0,0 +1,115 @@ + +__mitmproxy__ is a console tool that allows interactive examination and +modification of HTTP traffic. It differs from mitmdump in that all flows are +kept in memory, which means that it's intended for taking and manipulating +small-ish samples. Use the _?_ shortcut key to view, context-sensitive +documentation from any __mitmproxy__ screen. + +## Flow list + +The flow list shows an index of captured flows in chronological order. + + + +- __1__: A GET request, returning a 302 Redirect response. +- __2__: A GET request, returning 16.75kb of text/html data. +- __3__: A replayed request. +- __4__: Intercepted flows are indicated with orange text. The user may edit +these flows, and then accept them (using the _a_ key) to continue. In this +case, the request has been intercepted on the way to the server. +- __5__: A response intercepted from the server on the way to the client. +- __6__: The event log can be toggled on and off using the _e_ shortcut key. This +pane shows events and errors that may not result in a flow that shows up in the +flow pane. +- __7__: Flow count. +- __8__: Various information on mitmproxy's state. In this case, we have an +interception pattern set to ".*". +- __9__: Bind address indicator - mitmproxy is listening on port 8080 of all +interfaces. + + +## Flow view + +The __Flow View__ lets you inspect and manipulate a single flow: + + + +- __1__: Flow summary. +- __2__: The Request/Response tabs, showing you which part of the flow you are +currently viewing. In the example above, we're viewing the Response. Hit _tab_ +to switch between the Response and the Request. +- __3__: Headers. +- __4__: Body. +- __5__: View Mode indicator. In this case, we're viewing the body in __hex__ +mode. The other available modes are __pretty__, which uses a number of +heuristics to show you a friendly view of various content types, and __raw__, +which shows you exactly what's there without any changes. You can change modes +using the _m_ key. + + + +## Grid Editor + +Much of the data that we'd like to interact with in mitmproxy is structured. +For instance, headers, queries and form data can all be thought of as a list of +key/value pairs. Mitmproxy has a built-in editor that lays this type of data +out in a grid for easy manipulation. + +At the moment, the Grid Editor is used in four parts of mitmproxy: + +- Editing request or response headers (_e_ for edit, then _h_ for headers in flow view) +- Editing a query string (_e_ for edit, then _q_ for query in flow view) +- Editing a URL-encoded form (_e_ for edit, then _f_ for form in flow view) +- Editing replacement patterns (_R_ globally) + +If there is is no data, an empty editor will be started to let you add some. +Here is the editor showing the headers from a request: + + + +To edit, navigate to the key or value you want to modify using the arrow or vi +navigation keys, and press enter. The background color will change to show that +you are in edit mode for the specified field: + + + +Modify the field as desired, then press escape to exit edit mode when you're +done. You can also add a row (_a_ key), delete a row (_d_ key), spawn an +external editor on a field (_e_ key). Be sure to consult the context-sensitive +help (_?_ key) for more. + + +# Example: Interception + +__mitmproxy__'s interception functionality lets you pause an HTTP request or +response, inspect and modify it, and then accept it to send it on to the server +or client. + + +### 1: Set an interception pattern + + + +We press _i_ to set an interception pattern. In this case, the __~q__ filter +pattern tells __mitmproxy__ to intercept all requests. For complete filter +syntax, see the [Filter expressions](@!urlTo("filters.html")!@) section of this +document, or the built-in help function in __mitmproxy__. + +### 2: Intercepted connections are indicated with orange text: + + + +### 3: You can now view and modify the request: + + + +In this case, we viewed the request by selecting it, pressed _e_ for "edit" +and _m_ for "method" to change the HTTP request method. + +### 4: Accept the intercept to continue: + + + +Finally, we press _a_ to accept the modified request, which is then sent on to +the server. In this case, we changed the request from an HTTP GET to +OPTIONS, and Google's server has responded with a 405 "Method not allowed". diff --git a/doc-src/screenshots/firefox3-import.jpg b/doc-src/screenshots/firefox3-import.jpg new file mode 100644 index 000000000..47fcd672f Binary files /dev/null and b/doc-src/screenshots/firefox3-import.jpg differ diff --git a/doc-src/screenshots/firefox3-trust.jpg b/doc-src/screenshots/firefox3-trust.jpg new file mode 100644 index 000000000..50a2f3413 Binary files /dev/null and b/doc-src/screenshots/firefox3-trust.jpg differ diff --git a/doc-src/screenshots/firefox3.jpg b/doc-src/screenshots/firefox3.jpg new file mode 100644 index 000000000..6c4613b62 Binary files /dev/null and b/doc-src/screenshots/firefox3.jpg differ diff --git a/doc-src/screenshots/ios-installed.png b/doc-src/screenshots/ios-installed.png new file mode 100644 index 000000000..2071e441a Binary files /dev/null and b/doc-src/screenshots/ios-installed.png differ diff --git a/doc-src/screenshots/ios-profile.png b/doc-src/screenshots/ios-profile.png new file mode 100644 index 000000000..5bcd5a0d4 Binary files /dev/null and b/doc-src/screenshots/ios-profile.png differ diff --git a/doc-src/screenshots/ios-warning.png b/doc-src/screenshots/ios-warning.png new file mode 100644 index 000000000..d882c514a Binary files /dev/null and b/doc-src/screenshots/ios-warning.png differ diff --git a/doc-src/screenshots/mitmproxy-flowview.png b/doc-src/screenshots/mitmproxy-flowview.png new file mode 100644 index 000000000..154963fe2 Binary files /dev/null and b/doc-src/screenshots/mitmproxy-flowview.png differ diff --git a/doc-src/screenshots/mitmproxy-intercept-filt.png b/doc-src/screenshots/mitmproxy-intercept-filt.png new file mode 100644 index 000000000..60556ee71 Binary files /dev/null and b/doc-src/screenshots/mitmproxy-intercept-filt.png differ diff --git a/doc-src/screenshots/mitmproxy-intercept-mid.png b/doc-src/screenshots/mitmproxy-intercept-mid.png new file mode 100644 index 000000000..d5b039223 Binary files /dev/null and b/doc-src/screenshots/mitmproxy-intercept-mid.png differ diff --git a/doc-src/screenshots/mitmproxy-intercept-options.png b/doc-src/screenshots/mitmproxy-intercept-options.png new file mode 100644 index 000000000..8dc4ad2cb Binary files /dev/null and b/doc-src/screenshots/mitmproxy-intercept-options.png differ diff --git a/doc-src/screenshots/mitmproxy-intercept-result.png b/doc-src/screenshots/mitmproxy-intercept-result.png new file mode 100644 index 000000000..7d9f5c94d Binary files /dev/null and b/doc-src/screenshots/mitmproxy-intercept-result.png differ diff --git a/doc-src/screenshots/mitmproxy-kveditor-editmode.png b/doc-src/screenshots/mitmproxy-kveditor-editmode.png new file mode 100644 index 000000000..a8315ee51 Binary files /dev/null and b/doc-src/screenshots/mitmproxy-kveditor-editmode.png differ diff --git a/doc-src/screenshots/mitmproxy-kveditor.png b/doc-src/screenshots/mitmproxy-kveditor.png new file mode 100644 index 000000000..144b9701f Binary files /dev/null and b/doc-src/screenshots/mitmproxy-kveditor.png differ diff --git a/doc-src/screenshots/mitmproxy.png b/doc-src/screenshots/mitmproxy.png new file mode 100644 index 000000000..42a10e329 Binary files /dev/null and b/doc-src/screenshots/mitmproxy.png differ diff --git a/doc-src/screenshots/osx-addcert-alwaystrust.png b/doc-src/screenshots/osx-addcert-alwaystrust.png new file mode 100644 index 000000000..4c5cc704e Binary files /dev/null and b/doc-src/screenshots/osx-addcert-alwaystrust.png differ diff --git a/doc-src/screenshots/win7-certstore-trustedroot.png b/doc-src/screenshots/win7-certstore-trustedroot.png new file mode 100644 index 000000000..e15a87f5a Binary files /dev/null and b/doc-src/screenshots/win7-certstore-trustedroot.png differ diff --git a/doc-src/screenshots/win7-certstore.png b/doc-src/screenshots/win7-certstore.png new file mode 100644 index 000000000..f8ce54bd5 Binary files /dev/null and b/doc-src/screenshots/win7-certstore.png differ diff --git a/doc-src/screenshots/win7-wizard.png b/doc-src/screenshots/win7-wizard.png new file mode 100644 index 000000000..eff6ad096 Binary files /dev/null and b/doc-src/screenshots/win7-wizard.png differ diff --git a/doc-src/scripting/index.py b/doc-src/scripting/index.py new file mode 100644 index 000000000..b83120839 --- /dev/null +++ b/doc-src/scripting/index.py @@ -0,0 +1,6 @@ +from countershape import Page + +pages = [ + Page("inlinescripts.html", "Inline Scripts"), + Page("libmproxy.html", "libmproxy"), +] diff --git a/doc-src/scripting/inlinescripts.html b/doc-src/scripting/inlinescripts.html new file mode 100644 index 000000000..7ab1c1013 --- /dev/null +++ b/doc-src/scripting/inlinescripts.html @@ -0,0 +1,149 @@ +__mitmproxy__ has a powerful scripting API that allows you to modify flows +on-the-fly or rewrite previously saved flows locally. + +The mitmproxy scripting API is event driven - a script is simply a Python +module that exposes a set of event methods. Here's a complete mitmproxy script +that adds a new header to every HTTP response before it is returned to the +client: + +$!example("examples/add_header.py")!$ + +The first argument to each event method is an instance of ScriptContext that +lets the script interact with the global mitmproxy state. The __response__ +event also gets an instance of Flow, which we can use to manipulate the +response itself. + +We can now run this script using mitmdump or mitmproxy as follows: + +
    +> mitmdump -s add_header.py
    +
    + +The new header will be added to all responses passing through the proxy. + + + +## Events + +### start(ScriptContext, argv) + +Called once on startup, before any other events. + + +### clientconnect(ScriptContext, ClientConnect) + +Called when a client initiates a connection to the proxy. Note that +a connection can correspond to multiple HTTP requests. + + +### serverconnect(ScriptContext, ServerConnection) + +Called when the proxy initiates a connection to the target server. Note that +a connection can correspond to multiple HTTP requests. + +### request(ScriptContext, Flow) + +Called when a client request has been received. The __Flow__ object is +guaranteed to have a non-None __request__ attribute. + + +### response(ScriptContext, Flow) + +Called when a server response has been received. The __Flow__ object is +guaranteed to have non-None __request__ and __response__ attributes. + + +### error(ScriptContext, Flow) + +Called when a flow error has occurred, e.g. invalid server responses, or +interrupted connections. This is distinct from a valid server HTTP error +response, which is simply a response with an HTTP error code. The __Flow__ +object is guaranteed to have non-None __request__ and __error__ attributes. + + +### clientdisconnect(ScriptContext, ClientDisconnect) + +Called when a client disconnects from the proxy. + +### done(ScriptContext) + +Called once on script shutdown, after any other events. + + +## API + +The main classes you will deal with in writing mitmproxy scripts are: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    libmproxy.flow.ClientConnectionDescribes a client connection.
    libmproxy.flow.ClientDisconnectionDescribes a client disconnection.
    libmproxy.flow.ErrorA communications error.
    libmproxy.flow.FlowA collection of objects representing a single HTTP transaction.
    libmproxy.flow.HeadersHTTP headers for a request or response.
    libmproxy.flow.ODictA dictionary-like object for managing sets of key/value data. There + is also a variant called CaselessODict that ignores key case for some + calls (used mainly for headers).
    libmproxy.flow.ResponseAn HTTP response.
    libmproxy.flow.RequestAn HTTP request.
    libmproxy.flow.ScriptContext A handle for interacting with mitmproxy's from within scripts.
    libmproxy.certutils.SSLCertExposes information SSL certificates.
    + +The canonical API documentation is the code. You can view the API documentation +using pydoc (which is installed with Python by default), like this: + +
    +> pydoc libmproxy.flow.Request
    +
    + + +## Running scripts in parallel + +We have a single flow primitive, so when a script is handling something, other requests block. +While that's a very desirable behaviour under some circumstances, scripts can be run threaded by using the libmproxy.script.concurrent decorator. + +$!example("examples/nonblocking.py")!$ + +## Running scripts on saved flows + +Sometimes, we want to run a script on __Flow__ objects that are already +complete. This happens when you start a script, and then load a saved set of +flows from a file (see the "scripted data transformation" example on the +[mitmdump](@!urlTo("mitmdump.html")!@) page). It also happens when you run a +one-shot script on a single flow through the _|_ (pipe) shortcut in mitmproxy. + +In this case, there are no client connections, and the events are run in the +following order: __start__, __request__, __response__, __error__, __done__. If +the flow doesn't have a __response__ or __error__ associated with it, the +matching event will be skipped. diff --git a/doc-src/scripting/libmproxy.html b/doc-src/scripting/libmproxy.html new file mode 100644 index 000000000..e2d2ff6a8 --- /dev/null +++ b/doc-src/scripting/libmproxy.html @@ -0,0 +1,12 @@ + +All of mitmproxy's basic functionality is exposed through the __libmproxy__ +library. The example below shows a simple implementation of the "sticky cookie" +functionality included in the interactive mitmproxy program. Traffic is +monitored for __cookie__ and __set-cookie__ headers, and requests are rewritten +to include a previously seen cookie if they don't already have one. In effect, +this lets you log in to a site using your browser, and then make subsequent +requests using a tool like __curl__, which will then seem to be part of the +authenticated session. + +$!example("examples/stickycookies")!$ + diff --git a/doc-src/ssl.html b/doc-src/ssl.html new file mode 100644 index 000000000..c904cf617 --- /dev/null +++ b/doc-src/ssl.html @@ -0,0 +1,63 @@ + +The first time __mitmproxy__ or __mitmdump__ is run, a set of certificate files +for the mitmproxy Certificate Authority are created in the config directory +(~/.mitmproxy by default). The files are as follows: + + + + + + + + + + + + + + + + + + +
    mitmproxy-ca.pemThe private key and certificate in PEM format.
    mitmproxy-ca-cert.pemThe certificate in PEM format. Use this to distribute to most + non-Windows platforms.
    mitmproxy-ca-cert.p12The certificate in PKCS12 format. For use on Windows.
    mitmproxy-ca-cert.cerSame file as .pem, but with an extension expected by some Android + devices.
    + +This CA is used for on-the-fly generation of dummy certificates for SSL +interception. Since your browser won't trust the __mitmproxy__ CA out of the +box (and rightly so), you will see an SSL cert warning every time you visit a +new SSL domain through __mitmproxy__. When you're testing a single site through +a browser, just accepting the bogus SSL cert manually is not too much trouble, +but there are a many circumstances where you will want to configure your +testing system or browser to trust the __mitmproxy__ CA as a signing root +authority. + + +Using a custom certificate +-------------------------- + +You can use your own certificate by passing the __--cert__ option to mitmproxy. + +The certificate file is expected to be in the PEM format. You can generate +a certificate in this format using these instructions: + +
    +> openssl genrsa -out cert.key 8192
    +> openssl req -new -x509 -key cert.key -out cert.crt
    +    (Specify the mitm domain as Common Name, e.g. *.google.com)
    +> cat cert.key cert.crt > cert.pem
    +> mitmproxy --cert=cert.pem
    +
    + + +Installing the mitmproxy CA +--------------------------- + +* [Firefox](@!urlTo("certinstall/firefox.html")!@) +* [OSX](@!urlTo("certinstall/osx.html")!@) +* [Windows 7](@!urlTo("certinstall/windows7.html")!@) +* [iPhone/iPad](@!urlTo("certinstall/ios.html")!@) +* [IOS Simulator](@!urlTo("certinstall/ios-simulator.html")!@) +* [Android](@!urlTo("certinstall/android.html")!@) + diff --git a/doc-src/syntax.css b/doc-src/syntax.css new file mode 100644 index 000000000..e371658ab --- /dev/null +++ b/doc-src/syntax.css @@ -0,0 +1,120 @@ +.highlight { background: #f8f8f8; } +.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ +.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ +.grokdoc { background: #f8f8f8; } +.grokdoc .c { color: #408080; font-style: italic } /* Comment */ +.grokdoc .err { border: 1px solid #FF0000 } /* Error */ +.grokdoc .k { color: #008000; font-weight: bold } /* Keyword */ +.grokdoc .o { color: #666666 } /* Operator */ +.grokdoc .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.grokdoc .cp { color: #BC7A00 } /* Comment.Preproc */ +.grokdoc .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.grokdoc .cs { color: #408080; font-style: italic } /* Comment.Special */ +.grokdoc .gd { color: #A00000 } /* Generic.Deleted */ +.grokdoc .ge { font-style: italic } /* Generic.Emph */ +.grokdoc .gr { color: #FF0000 } /* Generic.Error */ +.grokdoc .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.grokdoc .gi { color: #00A000 } /* Generic.Inserted */ +.grokdoc .go { color: #808080 } /* Generic.Output */ +.grokdoc .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.grokdoc .gs { font-weight: bold } /* Generic.Strong */ +.grokdoc .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.grokdoc .gt { color: #0040D0 } /* Generic.Traceback */ +.grokdoc .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.grokdoc .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.grokdoc .kp { color: #008000 } /* Keyword.Pseudo */ +.grokdoc .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.grokdoc .kt { color: #B00040 } /* Keyword.Type */ +.grokdoc .m { color: #666666 } /* Literal.Number */ +.grokdoc .s { color: #BA2121 } /* Literal.String */ +.grokdoc .na { color: #7D9029 } /* Name.Attribute */ +.grokdoc .nb { color: #008000 } /* Name.Builtin */ +.grokdoc .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.grokdoc .no { color: #880000 } /* Name.Constant */ +.grokdoc .nd { color: #AA22FF } /* Name.Decorator */ +.grokdoc .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.grokdoc .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.grokdoc .nf { color: #0000FF } /* Name.Function */ +.grokdoc .nl { color: #A0A000 } /* Name.Label */ +.grokdoc .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.grokdoc .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.grokdoc .nv { color: #19177C } /* Name.Variable */ +.grokdoc .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.grokdoc .w { color: #bbbbbb } /* Text.Whitespace */ +.grokdoc .mf { color: #666666 } /* Literal.Number.Float */ +.grokdoc .mh { color: #666666 } /* Literal.Number.Hex */ +.grokdoc .mi { color: #666666 } /* Literal.Number.Integer */ +.grokdoc .mo { color: #666666 } /* Literal.Number.Oct */ +.grokdoc .sb { color: #BA2121 } /* Literal.String.Backtick */ +.grokdoc .sc { color: #BA2121 } /* Literal.String.Char */ +.grokdoc .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.grokdoc .s2 { color: #BA2121 } /* Literal.String.Double */ +.grokdoc .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.grokdoc .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.grokdoc .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.grokdoc .sx { color: #008000 } /* Literal.String.Other */ +.grokdoc .sr { color: #BB6688 } /* Literal.String.Regex */ +.grokdoc .s1 { color: #BA2121 } /* Literal.String.Single */ +.grokdoc .ss { color: #19177C } /* Literal.String.Symbol */ +.grokdoc .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.grokdoc .vc { color: #19177C } /* Name.Variable.Class */ +.grokdoc .vg { color: #19177C } /* Name.Variable.Global */ +.grokdoc .vi { color: #19177C } /* Name.Variable.Instance */ +.grokdoc .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/doc-src/transparent.html b/doc-src/transparent.html new file mode 100644 index 000000000..4e9b6774c --- /dev/null +++ b/doc-src/transparent.html @@ -0,0 +1,19 @@ + +When a transparent proxy is used, traffic is redirected into a proxy at the +network layer, without any client configuration being required. This makes +transparent proxying ideal for those situations where you can't change client +behaviour - proxy-oblivious Android applications being a common example. + +To set up transparent proxying, we need two new components. The first is a +redirection mechanism that transparently reroutes a TCP connection destined for +a server on the Internet to a listening proxy server. This usually takes the +form of a firewall on the same host as the proxy server - +[iptables](http://www.netfilter.org/) on Linux or +[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. When the proxy +receives a redirected connection, it sees a vanilla HTTP request, without a +host specification. This is where the second new component comes in - a host +module that allows us to query the redirector for the original destination of +the TCP connection. + +At the moment, mitmproxy supports transparent proxying on OSX Lion and above, +and all current flavors of Linux. diff --git a/doc-src/transparent.png b/doc-src/transparent.png new file mode 100644 index 000000000..3994d6815 Binary files /dev/null and b/doc-src/transparent.png differ diff --git a/doc-src/transparent/index.py b/doc-src/transparent/index.py new file mode 100644 index 000000000..091b34717 --- /dev/null +++ b/doc-src/transparent/index.py @@ -0,0 +1,6 @@ +from countershape import Page + +pages = [ + Page("osx.html", "OSX"), + Page("linux.html", "Linux"), +] diff --git a/doc-src/transparent/linux.html b/doc-src/transparent/linux.html new file mode 100644 index 000000000..96b7132a1 --- /dev/null +++ b/doc-src/transparent/linux.html @@ -0,0 +1,43 @@ +On Linux, mitmproxy integrates with the iptables redirection mechanism to +achieve transparent mode. + +
      + +
    1. Install the mitmproxy + certificates on the test device.
    2. + +
    3. Enable IP forwarding: + +
      sysctl -w net.ipv4.ip_forward=1
      + + You may also want to consider enabling this permanently in + /etc/sysctl.conf. + +
    4. + +
    5. Create an iptables ruleset that redirects the desired traffic to the + mitmproxy port. Details will differ according to your setup, but the + ruleset should look something like this: + +
      iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
      +iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080
      + +
    6. + +
    7. Fire up mitmproxy. You probably want a command like this: + +
      mitmproxy -T --host
      + + The -T flag turns on transparent mode, and the --host + argument tells mitmproxy to use the value of the Host header for URL + display. + +
    8. + +
    9. Finally, configure your test device to use the host on which mitmproxy is + running as the default gateway.
    10. + +
    + + +For a detailed walkthrough, have a look at the Transparently proxify virtual machines tutorial. diff --git a/doc-src/transparent/osx.html b/doc-src/transparent/osx.html new file mode 100644 index 000000000..c1ae823d9 --- /dev/null +++ b/doc-src/transparent/osx.html @@ -0,0 +1,81 @@ + + +OSX Lion integrated the [pf](http://www.openbsd.org/faq/pf/) packet filter from +the OpenBSD project, which mitmproxy uses to implement transparent mode on OSX. +Note that this means we don't support transparent mode for earlier versions of +OSX. + +
      + +
    1. Install the mitmproxy + certificates on the test device.
    2. + +
    3. Enable IP forwarding: + +
      sudo sysctl -w net.inet.ip.forwarding=1
      +
    4. + +
    5. Place the following two lines in a file called, say, pf.conf: + +
      rdr on en2 inet proto tcp to any port 80 -> 127.0.0.1 port 8080
      +rdr on en2 inet proto tcp to any port 443 -> 127.0.0.1 port 8080
      +
      + + These rules tell pf to redirect all traffic destined for port 80 or 443 + to the local mitmproxy instance running on port 8080. You should + replace en2 with the interface on which your test device will + appear. + +
    6. + +
    7. Configure pf with the rules: + +
      sudo pfctl -f pf.conf
      + +
    8. + +
    9. And now enable it: + +
      sudo pfctl -e
      + +
    10. + +
    11. Configure sudoers to allow mitmproxy to access pfctl. Edit the file + /etc/sudoers on your system as root. Add the following line to the end + of the file: + +
      ALL ALL=NOPASSWD: /sbin/pfctl -s state
      + + Note that this allows any user on the system to run the command + "/sbin/pfctl -s state" as root without a password. This only allows + inspection of the state table, so should not be an undue security risk. If + you're special feel free to tighten the restriction up to the user running + mitmproxy.
    12. + +
    13. Fire up mitmproxy. You probably want a command like this: + +
      mitmproxy -T --host
      + + The -T flag turns on transparent mode, and the --host + argument tells mitmproxy to use the value of the Host header for URL + display. + +
    14. + +
    15. Finally, configure your test device to use the host on which mitmproxy is + running as the default gateway.
    16. + + +
    + +Note that the **rdr** rules in the pf.conf given above only apply to inbound +traffic. This means that they will NOT redirect traffic coming from the box +running pf itself. We can't distinguish between an outbound connection from a +non-mitmproxy app, and an outbound connection from mitmproxy itself - if you +want to intercept your OSX traffic, you should use an external host to run +mitmproxy. None the less, pf is flexible to cater for a range of creative +possibilities, like intercepting traffic emanating from VMs. See the +**pf.conf** man page for more. + + + diff --git a/doc-src/transparent_https.png b/doc-src/transparent_https.png new file mode 100644 index 000000000..559cddd21 Binary files /dev/null and b/doc-src/transparent_https.png differ diff --git a/doc-src/tutorials/30second.html b/doc-src/tutorials/30second.html new file mode 100644 index 000000000..fe9581c57 --- /dev/null +++ b/doc-src/tutorials/30second.html @@ -0,0 +1,61 @@ + +My local cafe is serviced by a rickety and unreliable wireless network, +generously sponsored with ratepayers' money by our city council. After +connecting, you are redirected to an SSL-protected page that prompts you for a +username and password. Once you've entered your details, you are free to enjoy +the intermittent dropouts, treacle-like speeds and incorrectly configured +transparent proxy. + +I tend to automate this kind of thing at the first opportunity, on the theory +that time spent now will be more than made up in the long run. In this case, I +might use [Firebug](http://getfirebug.com/) to ferret out the form post +parameters and target URL, then fire up an editor to write a little script +using Python's [urllib](http://docs.python.org/library/urllib.html) to simulate +a submission. That's a lot of futzing about. With mitmproxy we can do the job +in literally 30 seconds, without having to worry about any of the details. +Here's how. + +## 1. Run mitmdump to record our HTTP conversation to a file. + +
    +> mitmdump -w wireless-login
    +
    + +## 2. Point your browser at the mitmdump instance. + +I use a tiny Firefox addon called [Toggle +Proxy](https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/) to +switch quickly to and from mitmproxy. I'm assuming you've already [configured +your browser with mitmproxy's SSL certificate +authority](http://mitmproxy.org/doc/ssl.html). + +## 3. Log in as usual. + + +And that's it! You now have a serialized version of the login process in the +file wireless-login, and you can replay it at any time like this: + +
    +> mitmdump -c wireless-login
    +
    + +## Embellishments + +We're really done at this point, but there are a couple of embellishments we +could make if we wanted. I use [wicd](http://wicd.sourceforge.net/) to +automatically join wireless networks I frequent, and it lets me specify a +command to run after connecting. I used the client replay command above and +voila! - totally hands-free wireless network startup. + +We might also want to prune requests that download CSS, JS, images and so +forth. These add only a few moments to the time it takes to replay, but they're +not really needed and I somehow feel compelled to trim them anyway. So, we fire up +the mitmproxy console tool on our serialized conversation, like so: + +
    +> mitmproxy -r wireless-login
    +
    + +We can now go through and manually delete (using the __d__ keyboard shortcut) +everything we want to trim. When we're done, we use __w__ to save the +conversation back to the file. diff --git a/doc-src/tutorials/gamecenter.html b/doc-src/tutorials/gamecenter.html new file mode 100644 index 000000000..d8209f5e5 --- /dev/null +++ b/doc-src/tutorials/gamecenter.html @@ -0,0 +1,122 @@ + +## The setup + +In this tutorial, I'm going to show you how simple it is to creatively +interfere with Apple Game Center traffic using mitmproxy. To set things up, I +registered my mitmproxy CA certificate with my iPhone - there's a [step by step +set of instructions](@!urlTo("certinstall/ios.html")!@) elsewhere in this manual. I then +started mitmproxy on my desktop, and configured the iPhone to use it as a +proxy. + + +## Taking a look at the Game Center traffic + +Lets take a first look at the Game Center traffic. The game I'll use in this +tutorial is [Super Mega +Worm](http://itunes.apple.com/us/app/super-mega-worm/id388541990?mt=8) - a +great little retro-apocalyptic sidescroller for the iPhone: + +
    + +
    + +After finishing a game (take your time), watch the traffic flowing through +mitmproxy: + +
    + +
    + +We see a bunch of things we might expect - initialisation, the retrieval of +leaderboards and so forth. Then, right at the end, there's a POST to this +tantalising URL: + +
    +https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore
    +
    + +The contents of the submission are particularly interesting: + + + + + scores + + + category + SMW_Adv_USA1 + context + 0 + score-value + 0 + timestamp + 1363515361321 + + + + + + +This is a [property list](http://en.wikipedia.org/wiki/Property_list), +containing an identifier for the game, a score (55, in this case), and a +timestamp. Looks pretty simple to mess with. + + +## Modifying and replaying the score submission + +Lets edit the score submission. First, select it in mitmproxy, then press +__enter__ to view it. Make sure you're viewing the request, not the response - +you can use __tab__ to flick between the two. Now press __e__ for edit. You'll +be prompted for the part of the request you want to change - press __b__ for +body. Your preferred editor (taken from the EDITOR environment variable) will +now fire up. Lets bump the score up to something a bit more ambitious: + + + + + scores + + + category + SMW_Adv_USA1 + context + 0 + score-value + 2200272667 + timestamp + 1363515361321 + + + + + + +Save the file and exit your editor. + +The final step is to replay this modified request. Simply press __r__ for +replay. + +## The glorious result and some intrigue + +
    + +
    + +And that's it - according to the records, I am the greatest Super Mega Worm +player of all time. + +There's a curious addendum to this tale. When I first wrote this tutorial, all +the top competitors' scores were the same: 2,147,483,647 (this is no longer the +case, beacause there are now so many fellow cheaters using this tutorial). If +you think that number seems familiar, you're right: it's 2^31-1, the maximum +value you can fit into a signed 32-bit int. Now let me tell you another +peculiar thing about Super Mega Worm - at the end of every game, it submits +your highest previous score to the Game Center, not your current score. This +means that it stores your highscore somewhere, and I'm guessing that it reads +that stored score back into a signed integer. So, if you _were_ to cheat by the +relatively pedestrian means of modifying the saved score on your jailbroken +phone, then 2^31-1 might well be the maximum score you could get. Then again, +if the game itself stores its score in a signed 32-bit int, you could get the +same score through perfect play, effectively beating the game. So, which is it +in this case? I'll leave that for you to decide. + diff --git a/doc-src/tutorials/index.py b/doc-src/tutorials/index.py new file mode 100644 index 000000000..1cb04679a --- /dev/null +++ b/doc-src/tutorials/index.py @@ -0,0 +1,7 @@ +from countershape import Page + +pages = [ + Page("30second.html", "Client playback: a 30 second example"), + Page("gamecenter.html", "Setting highscores on Apple's GameCenter"), + Page("transparent-dhcp.html", "Transparently proxify virtual machines") +] \ No newline at end of file diff --git a/doc-src/tutorials/leaderboard.png b/doc-src/tutorials/leaderboard.png new file mode 100644 index 000000000..c1be8df58 Binary files /dev/null and b/doc-src/tutorials/leaderboard.png differ diff --git a/doc-src/tutorials/one.png b/doc-src/tutorials/one.png new file mode 100644 index 000000000..78a636cf3 Binary files /dev/null and b/doc-src/tutorials/one.png differ diff --git a/doc-src/tutorials/supermega.png b/doc-src/tutorials/supermega.png new file mode 100644 index 000000000..d416f71f2 Binary files /dev/null and b/doc-src/tutorials/supermega.png differ diff --git a/doc-src/tutorials/transparent-dhcp.html b/doc-src/tutorials/transparent-dhcp.html new file mode 100644 index 000000000..ce8a10fd8 --- /dev/null +++ b/doc-src/tutorials/transparent-dhcp.html @@ -0,0 +1,54 @@ +This walkthrough illustrates how to set up transparent proxying with mitmproxy. We use VirtualBox VMs with an Ubuntu proxy machine in this example, but the general principle can be applied to other setups. + +1. **Configure VirtualBox Network Adapters for the proxy machine** + The network setup is simple: `internet <--> proxy vm <--> (virtual) internal network`. + For the proxy machine, *eth0* represents the outgoing network. *eth1* is connected to the internal network that will be proxified, using a static ip (192.168.3.1). +
    VirtualBox configuration: +

    + +
    Proxy VM: + +
    +2. **Configure DHCP and DNS** + We use dnsmasq to provide DHCP and DNS in our internal network. + Dnsmasq is a lightweight server designed to provide DNS (and optionally DHCP and TFTP) services to a small-scale + network. + + - Before we get to that, we need to fix some Ubuntu quirks: + **Ubuntu >12.04** runs an internal dnsmasq instance (listening on loopback only) by default + [1]. For our use case, this needs to be + disabled by changing
    `dns=dnsmasq` to `#dns=dnsmasq` in */etc/NetworkManager/NetworkManager.conf* + and running `sudo restart network-manager` afterwards. + - Now, dnsmasq can be be installed and configured: + `sudo apt-get install dnsmasq` + Replace */etc/dnsmasq.conf* with the following configuration: +
    \# Listen for DNS requests on the internal network
    +        interface=eth1
    +        \# Act as a DHCP server, assign IP addresses to clients
    +        dhcp-range=192.168.3.10,192.168.3.100,96h
    +        \# Broadcast gateway and dns server information
    +        dhcp-option=option:router,192.168.3.1
    +        dhcp-option=option:dns-server,192.168.3.1
    +        
    + Apply changes: + `sudo service dnsmasq restart` +
    + Your proxied machine's network settings should now look similar to this: + +
    + +3. **Set up traffic redirection to mitmproxy** + To redirect traffic to mitmproxy, we need to add two iptables rules: +
    +    iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
    +        -j REDIRECT --to-port 8080
    +    iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 443 \
    +        -j REDIRECT --to-port 8080
    +    
    + +4. If required, install the mitmproxy + certificates on the test device. + +5. Finally, we can run mitmproxy -T. + The proxied machine cannot to leak any data outside of HTTP or DNS requests. + diff --git a/doc-src/tutorials/transparent-dhcp/step1_proxy.png b/doc-src/tutorials/transparent-dhcp/step1_proxy.png new file mode 100644 index 000000000..a0c944843 Binary files /dev/null and b/doc-src/tutorials/transparent-dhcp/step1_proxy.png differ diff --git a/doc-src/tutorials/transparent-dhcp/step1_vbox_eth0.png b/doc-src/tutorials/transparent-dhcp/step1_vbox_eth0.png new file mode 100644 index 000000000..4b7b4e9b8 Binary files /dev/null and b/doc-src/tutorials/transparent-dhcp/step1_vbox_eth0.png differ diff --git a/doc-src/tutorials/transparent-dhcp/step1_vbox_eth1.png b/doc-src/tutorials/transparent-dhcp/step1_vbox_eth1.png new file mode 100644 index 000000000..b994d4cbc Binary files /dev/null and b/doc-src/tutorials/transparent-dhcp/step1_vbox_eth1.png differ diff --git a/doc-src/tutorials/transparent-dhcp/step2_proxied_vm.png b/doc-src/tutorials/transparent-dhcp/step2_proxied_vm.png new file mode 100644 index 000000000..2046cc579 Binary files /dev/null and b/doc-src/tutorials/transparent-dhcp/step2_proxied_vm.png differ