tag:blogger.com,1999:blog-46715413309773814292024-03-26T00:15:46.421-07:00SubCriticalFlowEarth science, programming, woodworking, and other topicsJohn Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-4671541330977381429.post-23736108473695923892022-09-04T11:21:00.002-07:002022-09-04T11:25:13.290-07:00Building a portable air cleaner <p></p><div class="separator" style="clear: both;"><h2 style="clear: both; text-align: left;">How I built a simple dust cleaner from scrap wood.</h2><span><a name='more'></a></span><div class="separator" style="clear: both; text-align: left;">Unless you strictly use hand tools in your shop, more power to you, you probably make a lot of fine dust and really should have an air cleaning system.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Air or dust cleaners remove <i>most</i> of the fine (and most dangerous) dust from the air you breath, and they run much quieter than dust collectors. </div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">You can buy a shop air cleaner but making your own is simple and saves a decent amount of money, especially if you are making multiple. This is not to be confused with an air purifier, a shop air cleaner like this only removes a fraction of the <i>dust</i> that comes through it depending on many things like the fan power, the filters used, the air flow dynamics, leakage points, etc. That said, even a simple system like the one described in this post removes a large amount of dust in a small shop especially if left running and others have shown these simple box fan filters perform comparably to expensive products. </div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">There are many ways to make one of these units using some combination of a fan blowing air through or into a filter and there are tons of resources on this that go into more depth and details. Also, the box aesthetics I decided on might be over the top for your needs so just take what is useful from this post and modify the design. </div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">The simplest method if you are in a pinch or don't feel the urge to make something is to simply tape a standard home furnace/AC filter onto the back of a box fan. The major downfall is that some of the dust will be blown out and around the filter as opposed to directed through it.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">I made this air cleaner about two years ago and unfortunately didn't take many pictures but this post describes the most important concepts and should help if you decide to build one. </div><div class="separator" style="clear: both; text-align: left;"><br /></div><h4 style="clear: both; text-align: left;">A box that holds a fan and filters</h4><div class="separator" style="clear: both; text-align: left;">The idea is to use a cheap box fan to suck up dusty air and deposit the dust into a filter, thereby removing it from the air in your space. </div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">From some research I decided the most efficient build would be to put a less resistant (more open mesh) filter behind the fan to catch larger incoming particles, leave a few inch gap to improve the internal flow, followed by a finer mesh filter on the outflow site. The box was made with grooves that hold standard furnace filters from all sites to reduce air getting around the filters. The final result looks like this:</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiMbhAjADTqDzQLMePCaPqhfKG50b9jqVT21lRI1kfyMiv0w_IU-KVLmSoOs-OHLaDSyI8HhaO7ac5UvVJyLbwpNd7mhXxBFTJ988jSyTAXLX_BRgmulE2R7hMAkhGyUdiXjw0gqCkmI0GONj_9FdFpGapcM0-5KmCtzMlRMfXvW8CKKH0wgVaImZ4mrw=s3264" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3264" data-original-width="2448" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEiMbhAjADTqDzQLMePCaPqhfKG50b9jqVT21lRI1kfyMiv0w_IU-KVLmSoOs-OHLaDSyI8HhaO7ac5UvVJyLbwpNd7mhXxBFTJ988jSyTAXLX_BRgmulE2R7hMAkhGyUdiXjw0gqCkmI0GONj_9FdFpGapcM0-5KmCtzMlRMfXvW8CKKH0wgVaImZ4mrw=w480-h640" width="480" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><h4 style="clear: both; text-align: left;">Details of the build</h4><div class="separator" style="clear: both; text-align: left;">A few pieces of scrap plywood strips were also situated inside the box to hold the box fan securely. Holes were drilled in the top (a removable lid) and bottom of the box for the fan knob and cord respectively. I took a scrap metal and bent it down to hold the cord where it enters the box to avoid it being pulled out if the box was accidentally yanked.</div><div class="separator" style="clear: both; text-align: left;"><br /><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiSQIdTUAU8IAnMMRyjLwkhNsNrgf1OcMlZYS4_JQ3-cxQKOOj03K6t2wkHU0y5pgbnqu_n84ESUm9vzai2hmfj7QgF1beWxDQGFSovLkW1NLqpuNNBSF4ZvZIkaCkwgNmRPrTuQLUtqo8AXZuPpmv1LhC1C8wORg96Zqn4x_2ybG7_pihiKCe9llRVWA=s3264" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3264" data-original-width="2448" height="631" src="https://blogger.googleusercontent.com/img/a/AVvXsEiSQIdTUAU8IAnMMRyjLwkhNsNrgf1OcMlZYS4_JQ3-cxQKOOj03K6t2wkHU0y5pgbnqu_n84ESUm9vzai2hmfj7QgF1beWxDQGFSovLkW1NLqpuNNBSF4ZvZIkaCkwgNmRPrTuQLUtqo8AXZuPpmv1LhC1C8wORg96Zqn4x_2ybG7_pihiKCe9llRVWA=w473-h631" width="473" /></a></div></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><div class="separator" style="clear: both;">The internal box measurements need to be laid out to hold the widths of the fan and the air filters. </div><div class="separator" style="clear: both;"><br /></div></div><div class="separator" style="clear: both; text-align: left;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEifBkWiLf1zZ1v3NgKIBICmK3Mj_IgYS-4vrrSL4MKO4it6HjJQhLxTTWkStAItN2EKZ9yepyabJxZyVAFspmugDDLrJZh0pVcISkTpxJ2x3rXH3sRA8TVuxY2G3X2Sr25exAMOOfMZqnhAQ0kF2RTzz_6pJ023hlMdFsAlmQtB62QWRIZA_bfzewbydA=s3264" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2448" data-original-width="3264" height="308" src="https://blogger.googleusercontent.com/img/a/AVvXsEifBkWiLf1zZ1v3NgKIBICmK3Mj_IgYS-4vrrSL4MKO4it6HjJQhLxTTWkStAItN2EKZ9yepyabJxZyVAFspmugDDLrJZh0pVcISkTpxJ2x3rXH3sRA8TVuxY2G3X2Sr25exAMOOfMZqnhAQ0kF2RTzz_6pJ023hlMdFsAlmQtB62QWRIZA_bfzewbydA=w410-h308" width="410" /></a></div></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">Almost all of this project was assembled with a brad nailer and sometimes with glue, the walls of the box were joined to the bottom using a dado for added strength. There are many other options.</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">For this build, the removable top had spacers that were precisely placed to align with those on the side walls for holding in the front and back filters and box fan. </div><div class="separator" style="clear: both; text-align: center;"><br /></div></div>I used some scrap wood to make 4 latches that hold the top down and pull the walls in at the same time. Also, the handle was made from scrap and sported some hand cut dovetails! The latch assembly was attached with glue, each latch slides under a u -shaped wood on the side of the box and a small piece of wood that was gently attached to the latches turns to put inward force in from the walls. The inner u-shape wood pieces on the lid hold the latches in place when coming into contact with the stop block on the inside edge of the latches. <br /><br /><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgeKxY4AWG2LjtWfVloYawpKu_ZIWLj0pG9Uy4omRiAnW5KcKIR8ieZOdFfr0kZxzKIiqlKvVcpETtAy_HCZCWR9JZmaTqusELzEKruvZ-8_VqNTwIt1RFD8SY5_qsbYgpAV4q3J6Z4xmUo14rjiaLGQceSPONVdRoMRStnx3egMXzVut7ut3z6Q8L9eQ=s3264" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3264" data-original-width="2448" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEgeKxY4AWG2LjtWfVloYawpKu_ZIWLj0pG9Uy4omRiAnW5KcKIR8ieZOdFfr0kZxzKIiqlKvVcpETtAy_HCZCWR9JZmaTqusELzEKruvZ-8_VqNTwIt1RFD8SY5_qsbYgpAV4q3J6Z4xmUo14rjiaLGQceSPONVdRoMRStnx3egMXzVut7ut3z6Q8L9eQ=w480-h640" width="480" /></a></div><div style="text-align: center;"><br /></div><div style="text-align: left;">Lastly, four scrap blocks of wood were slightly rounded and attached to the bottom as "legs", they help with moving the fan, protecting the floor, and protecting the cord. The entire thing was finished with some boiled linseed oil. </div><p></p>John Volkhttp://www.blogger.com/profile/08635472565551583944noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-87341007216531171452021-11-18T22:48:00.006-08:002023-01-27T11:19:21.940-08:00Making a ram puzzle on the scroll saw<head>
<style>
* {
box-sizing: border-box;
}
.column {
float: left;
width: 50.0%;
padding: 5px;
}
/* Clearfix (clear floats) */
.row::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<p>Thoughts from making a ram/Aires upright puzzle on the scroll saw</p><span><a name='more'></a></span><p>This scroll saw project makes a nice keepsake or gift; it is also is a good beginner project that just looks great. </p><p>I picked up the ram template for this piece from the book: <a href="https://www.amazon.com/gp/product/156523393X/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=156523393X&linkCode=as2&tag=subcritflow-20&linkId=22f804e58e459503bc7fb0194b213138" target="_blank">Zodiac Puzzles for Scroll Saw Woodworking: 30 Projects from the Eastern and Western Calendars (Scroll Saw Woodworking & Crafts Book)</a> which includes all the zodiac signs and locations of where to inlay gems or other items to represent at their appropriate constellation locations. It is a nice book and it also has a lot of useful information on using a scroll saw and finishing your work. </p><p>There isn't much to artistic scroll saw projects like this, apply your template to your work piece and follow the lines! No really, it is all about being patient and keeping a steady feed rate and knowing your saw and blade so that you can make turns, and this comes with practice.</p><p>I used an old piece of 3/4" pine board, but the project may come out nicer with hardwood and easier to sand.</p><p></p>
<div class="row">
<div class="column">
<img alt="Front" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj735ZQiX4XiCehDfKt3eUph3jRkwHsRBMCPsv1zSTxDMdcsL7Qtd6fiRe2INF2vpy-Qyj5lGpHAaXpbssDffysona9Ob4Zrz8UCZdFYvTDEF4jA-DfweNRkHTUYzt3CCu3fNBCyqa0OuNd/" style="width: 100%;" />
</div>
<div class="column">
<img alt="Side" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKHMIi0vzTUsMwH90vYdf9jPM37AXOTRhRlR45BItghvYuz-Jujczf7henxvA3icqGlb2OCYQNCBPJ-svDstjgNfDEYa6_WiIxlomLAJtbgpuDvuXzfBzwIfDklA2t_tZGhz2enX_AJvIn/" style="width: 100%;" />
</div>
</div>
<br /><p>A tip on adhering a printed template to wood: I first apply painters blue tape to the wood surface then glue the template down with <a href="https://www.amazon.com/gp/product/B000A8AYO4/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B000A8AYO4&linkCode=as2&tag=subcritflow-20&linkId=955ff86f00e27649f748336e40c6942d" target="_blank">spray adhesive</a> to the tape, not to the wood directly. This makes removing the template later even easier and without any glue remaining on the wood (the painters tape will not leave any residue in my experience). </p><p></p>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigUHp8aAcRkmyzZ-n0ZQF2qVmt1QC5cZ60VynIVepuAKETr-3KHtqE_amCdDuhujOz7CXPNpp9Bg-hWFmLElimxMvhMt33heZ4qiIFg-1k17Gk_JjpHDGZcuyaCgj7Y0bpkvlGYPRLtKyc/" style="margin-left: auto; margin-right: auto;"><img data-original-height="834" data-original-width="758" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigUHp8aAcRkmyzZ-n0ZQF2qVmt1QC5cZ60VynIVepuAKETr-3KHtqE_amCdDuhujOz7CXPNpp9Bg-hWFmLElimxMvhMt33heZ4qiIFg-1k17Gk_JjpHDGZcuyaCgj7Y0bpkvlGYPRLtKyc/w291-h320/staining.jpg" width="291" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><span style="text-align: left;">As you can see, two shades of stain were used to give the base of the puzzle a ground-like look. Possibilities are wide to be creative here, you could add paint, inlays, pyrography, etc... </span></td></tr></tbody></table>
<h4 style="text-align: left;">Tools </h4><p>I used a <a href="https://www.amazon.com/gp/product/B07MC1HLNP/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B07MC1HLNP&linkCode=as2&tag=subcritflow-20&linkId=fce5f995475acb7f1017c48814814a06" target="_blank">Wen 16" scroll saw</a> for this project, as a beginner it seems great to me and was quite affordable. Also, I first made the mistake of using the blades that came with the saw, instead get a decent pair of reverse double tooth blades, <a href="https://www.amazon.com/gp/product/B001FTKXOS/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B001FTKXOS&linkCode=as2&tag=subcritflow-20&linkId=0024bfaf43f2315711c49056f6d0fdf3" target="_blank">this pack</a> with different sizes/teeth density is great to start. Try the different blades to get a feel for them. The nice thing about scroll work is that you don't need a lot of other tools, once you have a saw and some blades (less than $150 investment) you can do make a lot of artistic or functional pieces from any flat piece of wood.</p><p><br /></p><br />John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-84237890040274112992021-11-14T10:10:00.013-08:002023-01-27T11:16:19.051-08:00Regular versus recursive functions in Fortran<script type="text/x-mathjax-config">
//<![CDATA[
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": { availableFonts: ["TeX"] }
});
//]]>
</script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript">
</script>
<p>This is a short post that contrasts recursive versus regular Fortran functions and gives an example factorial $n!$ recursive function. </p><span></span><span><a name='more'></a></span><h3 style="text-align: left;">Basics of a Fortran function</h3><p>In Fortran, unlike many other languages, a user-defined function can only calculate a single value such as an integer, an array, or a character string. Also, the name of the function should also be the name of the value that it calculates by assigning it somewhere inside the function (see example below). Lastly, a return statement is not needed in a Fortran function unless the end of the function is always reached every time it is invoked. </p><p>
<!--HTML generated using hilite.me--></p><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">function </span><span style="color: #996633;">add</span>(<span style="color: #996633;">num1</span>, <span style="color: #996633;">num2</span>)
<span style="color: #888888;">! a regular function that adds two numbers</span>
<span style="color: #008800; font-weight: bold;">implicit none</span>
<span style="color: #008800; font-weight: bold;"> intent</span>(<span style="color: #996633;">in</span>) <span style="color: #008800; font-weight: bold;">::</span> <span style="color: #996633;">num1</span>, <span style="color: #996633;">num2</span>
<span style="color: #333399; font-weight: bold;">real</span> <span style="color: #008800; font-weight: bold;">::</span> <span style="color: #996633;">num1</span>, <span style="color: #996633;">num2</span>, <span style="color: #996633;">add</span>
<span style="color: #888888;">!the function name "add" must be assigned to the return value</span>
<span style="color: #996633;">add</span> <span style="color: #333333;">=</span> <span style="color: #996633;">num1</span> <span style="color: #333333;">+</span> <span style="color: #996633;">num2</span>
<span style="color: #008800; font-weight: bold;">end function </span><span style="color: #996633;">add</span>
</pre></div>
<h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;">What makes a recursive Fortran function different?</h3><p>Recursive functions were added to Fortran 90 and later versions. The main syntactical difference with normal Fortran functions is the intrinsic "recursive" declaration and "result()" assignment that both go in the function declaration line. For example, using the factorial as an example:</p><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">recursive function </span><span style="color: #996633;">factorial</span>(<span style="color: #996633;">n</span>) <span style="color: #008800; font-weight: bold;">result</span>(<span style="color: #996633;">fact</span>)
<span style="color: #008800; font-weight: bold;">implicit none</span>
<span style="color: #008800; font-weight: bold;"> intent</span>(<span style="color: #996633;">in</span>) <span style="color: #008800; font-weight: bold;">::</span> <span style="color: #996633;">n</span>
<span style="color: #333399; font-weight: bold;">integer</span> (<span style="color: #007020;">kind</span><span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">8</span>)<span style="color: #008800; font-weight: bold;">::</span> <span style="color: #996633;">fact</span>, <span style="color: #996633;">n</span> </pre><pre style="line-height: 125%; margin: 0px;"> <span style="color: #008800; font-weight: bold;">if</span> (<span style="color: #996633;">n</span> <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">0</span>) <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #008800; font-weight: bold;"> </span><span style="color: #996633;">fact</span> <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;"> </span><span style="color: #996633;">fact</span> <span style="color: #333333;">=</span> <span style="color: #996633;">n</span> <span style="color: #333333;">*</span> <span style="color: #996633;">factorial</span>(<span style="color: #996633;">n</span><span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1</span>)
<span style="color: #008800; font-weight: bold;">endif </span></pre><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">end function </span><span style="color: #996633;">factorial</span>
</pre></div><br /><div>Notice the function declaration must begin with the intrinsic word "<b>recursive</b>". Also, the returned value, unlike in regular/non-recursive Fortran functions, is declared on the first line as well using the intrinsic "<b>result()</b>". In this case the actual value that is returned is "<b>fact</b>" when the function "<b>factorial</b>" is called. Whereas in non-recursive Fortran functions the name of the function is also the name of the returned value. To use a recursive function in a program however one must still call on the function by its name but in this case the return value is distinguished from the function value. Here is a a program using the above function:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">program </span><span style="color: #996633;">fact</span>
<span style="color: #008800; font-weight: bold;">implicit none</span>
<span style="color: #008800; font-weight: bold;"> </span><span style="color: #333399; font-weight: bold;">integer</span> <span style="color: #008800; font-weight: bold;">::</span> <span style="color: #996633;">n</span>, <span style="color: #996633;">factorial</span> </pre><pre style="line-height: 125%; margin: 0px;"> <span style="color: #008800; font-weight: bold;">print</span> <span style="color: #333333;">*</span>, <span style="background-color: #fff0f0;">"Enter a positive integer: "</span>
<span style="color: #008800; font-weight: bold;">read</span> (<span style="color: #333333;">*</span>,<span style="color: #333333;">*</span>) <span style="color: #996633;">n</span>
<span style="color: #008800; font-weight: bold;">print</span> <span style="color: #333333;">*</span>, <span style="background-color: #fff0f0;">'factorial = '</span>, <span style="color: #996633;">factorial</span>(<span style="color: #996633;">n</span>) </pre><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">end program </span><span style="color: #996633;">fact</span>
</pre></div><br /><div>As you can see, in the main program the recursive function is called by its name just like a regular Fortran function, nothing mysterious here. There you have it, writing a recursive functions in Fortran is just about as simple as writing a regular Fortran function. </div><div><br /></div><div>Check out <a href="https://www.subcriticalflow.com/2015/09/write-and-compile-your-first-fortran-95.html">this post</a> for basics on compiling and running a Fortran program.</div><div><br /></div>John Volkhttp://www.blogger.com/profile/08635472565551583944noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-43305253654068663872021-11-10T14:11:00.009-08:002021-11-17T09:15:56.660-08:00Carve this dragon portrait<div class="separator" style="display: none;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiVVnLqvZrDtxrlNO0xNu6jH2G3YlUIRl_5GEDZJNOeZCPknfmQvYUEbg_mbvdY3Z1JBDgsk3QuQd0-ziocne1FqgE_f28rd1Z5PlEvZcs8BzNc_dJsyDophAXv5KJIx6RTa8TqMv1fSPxfeS4EjAiySAFq6Pu0EFaJ2BSDBbQg4mYvgz3gFTovCSCXIQ=w605-h807" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="255" data-original-width="255" height="255" src="https://blogger.googleusercontent.com/img/a/AVvXsEiVVnLqvZrDtxrlNO0xNu6jH2G3YlUIRl_5GEDZJNOeZCPknfmQvYUEbg_mbvdY3Z1JBDgsk3QuQd0-ziocne1FqgE_f28rd1Z5PlEvZcs8BzNc_dJsyDophAXv5KJIx6RTa8TqMv1fSPxfeS4EjAiySAFq6Pu0EFaJ2BSDBbQg4mYvgz3gFTovCSCXIQ=w605-h807" width="255" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></div>
<p>Recently I took out my old Dremel rotary tool that had been collecting dust and played around with some walking sticks, carving a couple wood spirits. After carving mostly with knifes for the last few years, I wasn't a big fan of the dust! Guess I'll have to get a nicer fitting mask...</p><span></span><span><a name='more'></a></span><p>My son has been playing "<a href="http://www.hardcoregaming101.net/whomp-em/" target="_blank">Whomp' em</a>" lately, a classic Nintendo game and he recently beat the "Ice Ritual" boss and he was so proud, quite the accomplishment. I figured, carving out a picture of the ice boss, which I am calling a dragon but that is up for debate, would be a cool project and a nice gift for him. </p><p>If you would like to try Whomp' em yourself, I highly recommend it, you can get remakes of the old Nintendo with hundreds of games (including Whomp' em) on Amazon. We purchased a cheaper version <a href="https://www.amazon.com/gp/product/B09F3D4CKF/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B09F3D4CKF&linkCode=as2&tag=subcritflow-20&linkId=cea49839c071626cbf885d1da39a5bda" target="_blank">like this</a> for about 25 dollars, however there are issues with the controls working correctly on some games and graphic quality seems poor. If you are willing to pay more, <a href="https://www.amazon.com/gp/product/B07P875QTN/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B07P875QTN&linkCode=as2&tag=subcritflow-20&linkId=f5a1186c74dcd66700d0943e0aae05f8" target="_blank">Nintendo</a> has made their own remake which is much higher quality. A good middle of the road option that also plays SNES (super Nintendo) games is one of these <a href="https://www.amazon.com/gp/product/B001VDZN3O/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B001VDZN3O&linkCode=as2&tag=subcritflow-20&linkId=64cd1861f135a1e0d2975877e787d31b" target="_blank">retro Nintendo systems</a>, which allow you to buy higher quality game boards.</p><p><br /></p><h3 style="text-align: left;">On to the carving</h3><p>First I edited a screenshot of the boss (picture on left) so that it was appropriate for carving, I used the <a href="https://www.gimp.org/" target="_blank">GIMP</a> open-source graphics editor to clip, improve edges, scale-up and remove color. Feel free to download and print the final full size image on the right if you want to try this project:</p>
<table><tbody>
<tr><td><br /><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieK8fI7Rr82UlDyvmlR6JlnUCQhn2CxyNmKxCcu8AoM9XOTW9iCN05Fahs_CMacFmrFhyphenhyphenVnnJfvwgX0kSjyXjvLL4wRBsEHXW-DRhk1f8ALm4FviNBAQLXKMfLIJ78DNbKKIvbC823KOY/s640/whomp-em-3.jpg" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="400" data-original-width="640" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieK8fI7Rr82UlDyvmlR6JlnUCQhn2CxyNmKxCcu8AoM9XOTW9iCN05Fahs_CMacFmrFhyphenhyphenVnnJfvwgX0kSjyXjvLL4wRBsEHXW-DRhk1f8ALm4FviNBAQLXKMfLIJ78DNbKKIvbC823KOY/w352-h221/whomp-em-3.jpg" width="352" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Screenshot from <a href="https://thewiredfishnetwork.com/2012/05/12/retro-weekends-whomp-em/2/">thewiredfishnetwork.com</a></td></tr></tbody></table></td><td><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6N33TQzfY1o7-LYoptQC3jGzktjF9pEtWcMOLKTQyUpjdlUdnF9wB8deo5oYiE8-ETDDMgoY4pJr0qqRCQDOx_7IBnv0r0FqOV0cW37PApiXPrE55OQlqm_OI3sp3562j2Z9_0pl1i_Y/s1000/whomp-em_clipped_whitened.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1000" data-original-width="774" height="369" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6N33TQzfY1o7-LYoptQC3jGzktjF9pEtWcMOLKTQyUpjdlUdnF9wB8deo5oYiE8-ETDDMgoY4pJr0qqRCQDOx_7IBnv0r0FqOV0cW37PApiXPrE55OQlqm_OI3sp3562j2Z9_0pl1i_Y/w286-h369/whomp-em_clipped_whitened.jpg" width="286" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Edited full size image to carve (click to download)</td></tr></tbody></table></td></tr></tbody></table>
<br /><div>I used an old 3/4" pine board that was about 6 1/4" wide by 9 1/4" tall that was exposed to the sun resulting in a darker more golden outer color than the wood beneath. You may have better results with hardwood. The plan was to use the contrast between the outer layer of wood and the wood beneath to help make the carving "pop". </div><div><br /></div><div><a href="https://www.amazon.com/gp/product/B000A8AYO4/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B000A8AYO4&linkCode=as2&tag=subcritflow-20&linkId=955ff86f00e27649f748336e40c6942d" target="_blank">Removable spray adhesive</a> was used to hold the image to the wood during the carving. This is similar to how I do scroll saw work if using a printed template but was the first time I've tried it with power carving, it worked well although the adhesive and paper can sometimes clog the burrs but is easily removed. </div><div><br /></div><div>I recommend carving most of the project with a <a href="https://www.amazon.com/gp/product/B072QXR7QX/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B072QXR7QX&linkCode=as2&tag=subcritflow-20&linkId=d61cdaffd45b9d650976145f36c1344e" target="_blank">Kutzall extreme flame burr</a> for quick material removal, probably the best bit you can get for this type of carving. I use around 20,000 RPM and a <a href="https://www.amazon.com/gp/product/B0000302Y8/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0000302Y8&linkCode=as2&tag=subcritflow-20&linkId=f384ed5fa60caf9cb5d272233a0c3369" target="_blank">flex shaft</a> attachment for better control. Any rotary tool should work, if you are looking and able to spend more I would recommend a <a href="https://www.amazon.com/gp/product/B01M2WJ9HU/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B01M2WJ9HU&linkCode=as2&tag=subcritflow-20&linkId=1d005f84451a6b23c672f6e81fe414bf" target="_blank">Dremel 4000</a> kit, but use what you have. </div><div><br /></div><div><table><tbody><tr><td><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj1IkIZ55rRJEc3451BZOx-e17NZGBqQgbZMwKx-Cf9mHxmT7BBzXWWiZ6klzLNNKfqIABGNR8w1z42i8P2s70aLv-C0cL8VTqlU6omRqgvR0tjBwotdJCULuYZRVzNp8maQJWLudRJMPLsjD9EpxxHXLjMZCy8cL_ET-WZc3z1LQLsmL9Gy5HuJueFHw=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="450" src="https://blogger.googleusercontent.com/img/a/AVvXsEj1IkIZ55rRJEc3451BZOx-e17NZGBqQgbZMwKx-Cf9mHxmT7BBzXWWiZ6klzLNNKfqIABGNR8w1z42i8P2s70aLv-C0cL8VTqlU6omRqgvR0tjBwotdJCULuYZRVzNp8maQJWLudRJMPLsjD9EpxxHXLjMZCy8cL_ET-WZc3z1LQLsmL9Gy5HuJueFHw=w338-h450" width="338" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Glue drawing down with spray adhesive</td></tr></tbody></table></td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhnmAJyW-G-gbBNZ1iq4NhNhnismF_JvuusYuEwJ6LMM_PqVeNI8gOERGnZIaxHY01hl2UzBf8JC4tfIEnkHyb2xEZfOgiKc5i8vUbwpUF-5V6NdGQxj4rPTGa9X7sxhRXZpe5aiN6LhBeITEAaiiWMu9xKjg5LHq3WdC7N-_olZzfWJnZBR6UeX4kaQA=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="467" src="https://blogger.googleusercontent.com/img/a/AVvXsEhnmAJyW-G-gbBNZ1iq4NhNhnismF_JvuusYuEwJ6LMM_PqVeNI8gOERGnZIaxHY01hl2UzBf8JC4tfIEnkHyb2xEZfOgiKc5i8vUbwpUF-5V6NdGQxj4rPTGa9X7sxhRXZpe5aiN6LhBeITEAaiiWMu9xKjg5LHq3WdC7N-_olZzfWJnZBR6UeX4kaQA=w351-h467" width="351" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Rough carving outline</td></tr></tbody></table></td></tr></tbody></table></div><div><br /></div>I decided to relief carve the white areas but it might look nice the other way too.<div><br /></div><div><br /></div>
<table><tbody>
<tr><td><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgVQyoBXUk6Jz4Npi_J_r0iV45trQ34FYzNG1iHX1kJiMqEZIaeI6xwUpip4k0lFJmGiiVgaCVWqhyW0WQ1I95pJybGe4aZ0HxmUNbN9HKz18b_PDhX4TcJGcSLBo8vn63d_SCU73Ax7mWtCKrpMZNrLVPQWchENPAm0oJ0kYUgFC9shY1JBU9Xd9Dwkg=s3264" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="441" src="https://blogger.googleusercontent.com/img/a/AVvXsEgVQyoBXUk6Jz4Npi_J_r0iV45trQ34FYzNG1iHX1kJiMqEZIaeI6xwUpip4k0lFJmGiiVgaCVWqhyW0WQ1I95pJybGe4aZ0HxmUNbN9HKz18b_PDhX4TcJGcSLBo8vn63d_SCU73Ax7mWtCKrpMZNrLVPQWchENPAm0oJ0kYUgFC9shY1JBU9Xd9Dwkg=w331-h441" width="331" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">I had an accident with the burr running over the carving, keep a firm grip and be careful!</td></tr></tbody></table><br /><br /><br /><br /><br /><br /><br /><br /><br /></td><td><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEi-Use6joWhaa8C2HW79KoLClcz-5E7GgGmPoskaD_nsBUVN7UGHZDkGKZ3r3MzaxEzd0zb90RmBNTsn6RE5A0i0b5Go2uUzlA_kjgzwdP_J8nKQnGt9slHxJAEXspUBCHfqEBwAI-Xx69E4wi0akT3zg12Vc3pU2vBAhsGdTYmbrCjwL2sH7TJoSC-XQ=s3264" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="458" src="https://blogger.googleusercontent.com/img/a/AVvXsEi-Use6joWhaa8C2HW79KoLClcz-5E7GgGmPoskaD_nsBUVN7UGHZDkGKZ3r3MzaxEzd0zb90RmBNTsn6RE5A0i0b5Go2uUzlA_kjgzwdP_J8nKQnGt9slHxJAEXspUBCHfqEBwAI-Xx69E4wi0akT3zg12Vc3pU2vBAhsGdTYmbrCjwL2sH7TJoSC-XQ=w344-h458" width="344" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Roughed out with flame burr</td></tr></tbody></table><br /><br /><br /><br /><br /><br /><br /><br /></td></tr></tbody></table><br />
<div><br /></div><div>Clean up the carving and slightly undercut outer edges. I used a a ball bit <a href="https://www.amazon.com/gp/product/B0002PBTIU/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0002PBTIU&linkCode=as2&tag=subcritflow-20&linkId=ff57bc165b0634cdf6f74d77a3a0484f" target="_blank">like this</a> to smooth and clean most of the surface, another really useful bit is a <a href="https://www.amazon.com/gp/product/B0037MGH4Q/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0037MGH4Q&linkCode=as2&tag=subcritflow-20&linkId=f9a5ec8c00eff8f9bc2792b1b0ad7959" target="_blank">dovetail</a> for undercutting the edges of a relief carving and for smoothing flat surfaces, I also used sanding drums and a flat chisel to flatten out the backdrop areas. </div><div><br /></div><div>After most of the clean up was done I removed the glued down drawing to expose the sun-stained pine. </div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiVVnLqvZrDtxrlNO0xNu6jH2G3YlUIRl_5GEDZJNOeZCPknfmQvYUEbg_mbvdY3Z1JBDgsk3QuQd0-ziocne1FqgE_f28rd1Z5PlEvZcs8BzNc_dJsyDophAXv5KJIx6RTa8TqMv1fSPxfeS4EjAiySAFq6Pu0EFaJ2BSDBbQg4mYvgz3gFTovCSCXIQ=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="807" src="https://blogger.googleusercontent.com/img/a/AVvXsEiVVnLqvZrDtxrlNO0xNu6jH2G3YlUIRl_5GEDZJNOeZCPknfmQvYUEbg_mbvdY3Z1JBDgsk3QuQd0-ziocne1FqgE_f28rd1Z5PlEvZcs8BzNc_dJsyDophAXv5KJIx6RTa8TqMv1fSPxfeS4EjAiySAFq6Pu0EFaJ2BSDBbQg4mYvgz3gFTovCSCXIQ=w605-h807" width="605" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Mostly finished.</td></tr></tbody></table><br />Overall this was a lot of fun and really forgiving. If you are just getting into power carving this sort of project is perfect. <div><br /></div><div>I'll finish it up with a thin amount of <a href="https://www.amazon.com/gp/product/B0016KXBU4/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0016KXBU4&linkCode=as2&tag=subcritflow-20&linkId=0bc5bcf42fa0b3099911e9f6f73a1881" target="_blank">satin clear coat</a> to seal the wood from moisture and protect it. <div><br /></div><div>Looking back, I would feather out the interior reliefs more. This carving would also look nice if painted. <br /><div><br /></div><div><br /></div></div></div>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-82071916566284839612021-11-08T21:33:00.013-08:002023-01-27T11:28:36.445-08:00Modeling and animating the evolution of a cinder cone in Python<div class="separator" style="display: none;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGSNxE9zwtannq4UR8ONrjzt4ZhlXO2Zp0mD8XnwKB5PBrs3H4fjq1ZkpQ2YQgIUDfUi6gZebcWX8-LGpmiy1RBpgFu6xyXxziyLuK0qDGjffeKzFCNsHkV-8nXJO9K0vMys6ao7l-5QA/s2048/Cinder+cone+evolution+after+400000+eruptions.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="255" data-original-width="255" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGSNxE9zwtannq4UR8ONrjzt4ZhlXO2Zp0mD8XnwKB5PBrs3H4fjq1ZkpQ2YQgIUDfUi6gZebcWX8-LGpmiy1RBpgFu6xyXxziyLuK0qDGjffeKzFCNsHkV-8nXJO9K0vMys6ao7l-5QA/s2048/Cinder+cone+evolution+after+400000+eruptions.png" width="255" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></div>
<p>Numerically modeling of the evolution of a cinder cone where individual rock particles or "bombs" are launched from a central point with "random" trajectories from a central location and deposition/accumulation. Each process is explicit, eventually this process develops the shape of a classic cinder cone. </p><span><a name='more'></a></span><p>I wrote this as part of a graduate course and added comments throughout so it is easy to follow what is happening. Also included is an example of how to save images of the process and combine them into a gif animation. </p><p>Scientific and numerical modeling in Python is best accomplished with the Numpy library. <a href="https://www.amazon.com/gp/product/1484242459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1484242459&linkCode=as2&tag=subcritflow-20&linkId=2aaff80e45dcf2b25baddce6d26232f2" target="_blank">This book</a> is a great resource if you are interested in improving your numerical methods in Python using Numpy, SciPy, and matplotlib. </p><p><br /></p>
<div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">%</span>matplotlib inline
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">numpy</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">np</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">matplotlib.pyplot</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">plt</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">imageio</span>
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">pathlib</span> <span style="color: #008800; font-weight: bold;">import</span> Path
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">re</span></pre></div>
<p><br /></p><p>Define physical parameters of bomb size and trajectories, determined from literature and trial and error.</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #888888;">## Bomb velocities, m/s</span>
vel_min <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">32</span>
vel_max <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">76</span>
<span style="color: #888888;">## trajectory angles, degrees</span>
ang_min <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">345</span>
ang_max <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">375</span>
<span style="color: #888888;">## diameter range, in meters</span>
dia_min <span style="color: #333333;">=</span> <span style="color: #333333;">.</span><span style="color: #0000dd; font-weight: bold;">1</span>
dia_max <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.9</span>
</pre></div>
<p><br /></p><p>Functions for creating, launching, and depositing bombs and defining the spatial domain.</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #888888;">######</span>
<span style="color: #888888;">## bomb creation</span>
<span style="color: #888888;">######</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">makeBomb</span>(vMin,vMax,aMin,aMax,dMin,dMax,num<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">1</span>):
<span style="color: #dd4422;">"""Inputs are velocity (m/s), angle (degrees), and diameter (m) min and max values </span>
<span style="color: #dd4422;"> outputs are particle resultant velocity, angle(rad), and area (sq m)"""</span>
vel <span style="color: #333333;">=</span> (vMax <span style="color: #333333;">-</span> vMin)<span style="color: #333333;">*</span>np<span style="color: #333333;">.</span>random<span style="color: #333333;">.</span>random(num) <span style="color: #333333;">+</span> vMin <span style="color: #888888;">## velocity in m/s </span>
ang <span style="color: #333333;">=</span> (aMax <span style="color: #333333;">-</span> aMin)<span style="color: #333333;">*</span>np<span style="color: #333333;">.</span>random<span style="color: #333333;">.</span>random(num) <span style="color: #333333;">+</span> aMin
ang <span style="color: #333333;">*=</span> np<span style="color: #333333;">.</span>pi<span style="color: #333333;">/</span><span style="color: #0000dd; font-weight: bold;">180</span> <span style="color: #888888;">## return angle in radians</span>
dia <span style="color: #333333;">=</span> (dMax <span style="color: #333333;">-</span> dMin)<span style="color: #333333;">*</span>np<span style="color: #333333;">.</span>random<span style="color: #333333;">.</span>random(num) <span style="color: #333333;">+</span> dMin
are <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>pi<span style="color: #333333;">*</span>(dia<span style="color: #333333;">/</span><span style="color: #6600ee; font-weight: bold;">2.</span>)<span style="color: #333333;">**</span><span style="color: #0000dd; font-weight: bold;">2</span> <span style="color: #888888;">## return area in square meters</span>
<span style="color: #008800; font-weight: bold;">return</span> {<span style="background-color: #fff0f0;">'velocity'</span>:vel,<span style="background-color: #fff0f0;">'angle'</span>:ang,<span style="background-color: #fff0f0;">'area'</span>:are} <span style="color: #888888;">## returned as dict for readability</span>
<span style="color: #888888;">## x spatial grid for simulation and plotting</span>
x_grid <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>linspace(<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1000</span>,<span style="color: #0000dd; font-weight: bold;">1000</span>,<span style="color: #0000dd; font-weight: bold;">2001</span>) <span style="color: #888888;"># unit meter grid</span>
<span style="color: #888888;">######</span>
<span style="color: #888888;">## bomb launching </span>
<span style="color: #888888;">######</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">launchBomb</span>(vel,ang,z_0<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">0</span>,x<span style="color: #333333;">=</span>x_grid):
<span style="color: #dd4422;">""" Inputs: velocity (vel), angle of launch in rads (ang), launch elev (z_0), </span>
<span style="color: #dd4422;"> and x grid that is defaulted to use a predifined grid in main program</span>
<span style="color: #dd4422;"> return x and z position vectors """</span>
g <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">9.81</span> <span style="color: #888888;">## m/s^2</span>
x_vel <span style="color: #333333;">=</span> vel <span style="color: #333333;">*</span> np<span style="color: #333333;">.</span>sin(ang)
z_vel <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>abs( vel <span style="color: #333333;">*</span> np<span style="color: #333333;">.</span>cos(ang))
z <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>zeros_like(x)
z <span style="color: #333333;">=</span> (z_vel <span style="color: #333333;">*</span> x)<span style="color: #333333;">/</span>x_vel <span style="color: #333333;">-</span> (<span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">/</span><span style="color: #6600ee; font-weight: bold;">2.</span>) <span style="color: #333333;">*</span> g <span style="color: #333333;">*</span> (x<span style="color: #333333;">/</span>x_vel)<span style="color: #333333;">**</span><span style="color: #0000dd; font-weight: bold;">2</span> <span style="color: #333333;">+</span> z_0
<span style="color: #008800; font-weight: bold;">return</span> z <span style="color: #888888;">## elevation position array</span>
<span style="color: #888888;">######</span>
<span style="color: #888888;">## bomb depsiting</span>
<span style="color: #888888;">######</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">depositBomb</span>(x_traj,z_traj,elev_profile,bombArea):
<span style="color: #dd4422;">"""Inputs: x distance grid, z (elevation) coordinates for a trajectory, previous </span>
<span style="color: #dd4422;"> land elevation profile and bomb area. Finds where bomb hits ground and </span>
<span style="color: #dd4422;"> adds accumulated mass to the elevation profile and returns it"""</span>
vent_ind <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>where(x_traj <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">0</span>)[<span style="color: #0000dd; font-weight: bold;">0</span>][<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #888888;">## get index of vent (middle of x grid)</span>
<span style="color: #888888;">## check if lauch went to the right</span>
<span style="color: #008800; font-weight: bold;">if</span> np<span style="color: #333333;">.</span>where(z_traj <span style="color: #333333;">==</span> np<span style="color: #333333;">.</span>max(z_traj)) <span style="color: #333333;">></span> vent_ind:
x <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>where(z_traj[vent_ind:] <span style="color: #333333;"><=</span> elev_profile[vent_ind:])[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #888888;">## where trajectory below elevation</span>
deposit_ind <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>min(x[<span style="color: #0000dd; font-weight: bold;">1</span>:]) <span style="color: #333333;">+</span> vent_ind <span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1</span> <span style="color: #888888;">## get the minimum index of occurence (first intersection with land)</span>
<span style="color: #888888;">## redeposit on cliffs </span>
<span style="color: #008800; font-weight: bold;">while</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> np<span style="color: #333333;">.</span>sin(np<span style="color: #333333;">.</span>pi<span style="color: #333333;">/</span><span style="color: #0000dd; font-weight: bold;">6</span>): <span style="color: #888888;">## forward roll</span>
deposit_ind <span style="color: #333333;">+=</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">while</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> np<span style="color: #333333;">.</span>sin(np<span style="color: #333333;">.</span>pi<span style="color: #333333;">/</span><span style="color: #0000dd; font-weight: bold;">6</span>): <span style="color: #888888;">## backward fall</span>
deposit_ind <span style="color: #333333;">-=</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #888888;">## prevent indefinate rolling if steep in both directions </span>
<span style="color: #008800; font-weight: bold;">if</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind<span style="color: #333333;">+</span><span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> bombArea:
<span style="color: #008800; font-weight: bold;">break</span>
<span style="color: #888888;">## check if launch went to the left of vent </span>
<span style="color: #008800; font-weight: bold;">elif</span> np<span style="color: #333333;">.</span>where(z_traj <span style="color: #333333;">==</span> np<span style="color: #333333;">.</span>max(z_traj)) <span style="color: #333333;"><</span> vent_ind:
deposit_ind <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>max(np<span style="color: #333333;">.</span>where(z_traj[:vent_ind] <span style="color: #333333;"><=</span> elev_profile[:vent_ind])[<span style="color: #0000dd; font-weight: bold;">0</span>]) <span style="color: #888888;">## </span>
<span style="color: #888888;">##redeposit particles on cliffs</span>
<span style="color: #008800; font-weight: bold;">while</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> np<span style="color: #333333;">.</span>sin(np<span style="color: #333333;">.</span>pi<span style="color: #333333;">/</span><span style="color: #0000dd; font-weight: bold;">6</span>): <span style="color: #888888;"># forward</span>
deposit_ind <span style="color: #333333;">-=</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">while</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> np<span style="color: #333333;">.</span>sin(np<span style="color: #333333;">.</span>pi<span style="color: #333333;">/</span><span style="color: #0000dd; font-weight: bold;">6</span>): <span style="color: #888888;"># backwards</span>
deposit_ind <span style="color: #333333;">+=</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #888888;">## Prevent infinite movement if steep on both directions</span>
<span style="color: #008800; font-weight: bold;">if</span> elev_profile[deposit_ind] <span style="color: #333333;">-</span> elev_profile[deposit_ind<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">></span> bombArea:
<span style="color: #008800; font-weight: bold;">break</span>
<span style="color: #888888;">## check if bomb landed in the vent itself</span>
<span style="color: #008800; font-weight: bold;">else</span>:
deposit_ind <span style="color: #333333;">=</span> vent_ind <span style="color: #888888;">## need to fix redistribution in the vent, prevent huge buildup </span>
<span style="color: #008800; font-weight: bold;">if</span> elev[deposit_ind] <span style="color: #333333;">></span> elev[deposit_ind<span style="color: #333333;">+</span><span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: black; font-weight: bold;">or</span> elev[deposit_ind] <span style="color: #333333;">></span> elev[deposit_ind<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1</span>]:
deposit_ind <span style="color: #333333;">+=</span> np<span style="color: #333333;">.</span>random<span style="color: #333333;">.</span>choice(np<span style="color: #333333;">.</span>arange(<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">15</span>,<span style="color: #0000dd; font-weight: bold;">15</span>,<span style="color: #0000dd; font-weight: bold;">1</span>)) <span style="color: #888888;">## create some chaos to redistribute vent deps</span>
elev_profile[vent_ind<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">5</span>:vent_ind<span style="color: #333333;">+</span><span style="color: #0000dd; font-weight: bold;">5</span>] <span style="color: #333333;">-=</span> <span style="color: #6600ee; font-weight: bold;">0.1</span> <span style="color: #888888;">## cause meltdown of vent occasionally to prevent filling in</span>
<span style="color: #888888;">## increment elevation profile at the correct index by area of bomb</span>
elev_profile[deposit_ind] <span style="color: #333333;">+=</span> bombArea
<span style="color: #008800; font-weight: bold;">return</span> elev_profile
</pre></div>
<p><br /></p><p>Combining semi-random bomb creation, ejection, and deposition in a loop. This is also an example of how you can plot and save a series of images and then combine them to make an animation of the physical simulation.</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #888888;">######</span>
<span style="color: #888888;">## Launch Zone</span>
<span style="color: #888888;">######</span>
<span style="color: #888888;">## initialize elevation profile using zero grid as input</span>
bomb <span style="color: #333333;">=</span> makeBomb(vel_min,vel_max,ang_min,ang_max,dia_min,dia_max)
traj <span style="color: #333333;">=</span> launchBomb(bomb[<span style="background-color: #fff0f0;">'velocity'</span>],bomb[<span style="background-color: #fff0f0;">'angle'</span>])
elev <span style="color: #333333;">=</span> depositBomb(x_grid,traj,np<span style="color: #333333;">.</span>zeros_like(x_grid),bomb[<span style="background-color: #fff0f0;">'area'</span>])
<span style="color: #888888;">## number of eruptions and how often to show</span>
ndiv <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">5000</span>
nerupts <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">400000</span>
<span style="color: #888888;">## for final figure, not movie</span>
fig <span style="color: #333333;">=</span> plt<span style="color: #333333;">.</span>figure(figsize<span style="color: #333333;">=</span>(<span style="color: #0000dd; font-weight: bold;">12</span>,<span style="color: #0000dd; font-weight: bold;">9</span>))
ax <span style="color: #333333;">=</span> fig<span style="color: #333333;">.</span>add_subplot(<span style="color: #0000dd; font-weight: bold;">111</span>)
<span style="color: #888888;">## loop through number of eruptions simulating cinder cone development</span>
<span style="color: #008800; font-weight: bold;">for</span> i <span style="color: black; font-weight: bold;">in</span> <span style="color: #007020;">range</span>(nerupts):
bomb <span style="color: #333333;">=</span> makeBomb(vel_min,vel_max,ang_min,ang_max,dia_min,dia_max)
traj <span style="color: #333333;">=</span> launchBomb(bomb[<span style="background-color: #fff0f0;">'velocity'</span>],bomb[<span style="background-color: #fff0f0;">'angle'</span>],z_0<span style="color: #333333;">=</span>elev[np<span style="color: #333333;">.</span>where(x_grid <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">0</span>)[<span style="color: #0000dd; font-weight: bold;">0</span>]])
elev <span style="color: #333333;">=</span> depositBomb(x_grid,traj,elev,bomb[<span style="background-color: #fff0f0;">'area'</span>])
<span style="color: #008800; font-weight: bold;">if</span> (i <span style="color: #333333;">%</span> ndiv <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">0</span>):
plt<span style="color: #333333;">.</span>plot(x_grid,elev) <span style="color: #888888;">## plot updated elevation profile</span>
plt<span style="color: #333333;">.</span>xlim(<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">200</span>,<span style="color: #0000dd; font-weight: bold;">200</span>)
plt<span style="color: #333333;">.</span>show()
plt<span style="color: #333333;">.</span>pause(<span style="color: #6600ee; font-weight: bold;">0.2</span>)
<span style="color: #888888;">## will plot current trajectory </span>
plt<span style="color: #333333;">.</span>plot(x_grid[traj<span style="color: #333333;">></span>elev],traj[traj<span style="color: #333333;">></span>elev], <span style="background-color: #fff0f0;">'r.'</span>, ms <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">1.5</span>)
plt<span style="color: #333333;">.</span>savefig(f<span style="background-color: #fff0f0;">'fig{i}.png'</span>) <span style="color: #888888;"># for animation</span>
<span style="color: #888888;">## plot final elevation profile with every ndiv profile and trajectory overlain</span>
plt<span style="color: #333333;">.</span>plot(x_grid,elev)
plt<span style="color: #333333;">.</span>xlim(<span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">400</span>,<span style="color: #0000dd; font-weight: bold;">400</span>)
plt<span style="color: #333333;">.</span>ylim(<span style="color: #0000dd; font-weight: bold;">0</span>,<span style="color: #0000dd; font-weight: bold;">650</span>)
plt<span style="color: #333333;">.</span>ylabel(<span style="background-color: #fff0f0;">'Height (m)'</span>)
plt<span style="color: #333333;">.</span>title(<span style="background-color: #fff0f0;">'Cinder cone evolution after </span><span style="background-color: #eeeeee;">%i</span><span style="background-color: #fff0f0;"> eruptions,</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\n</span><span style="background-color: #fff0f0;"> deposits and trajectory shown every </span><span style="background-color: #eeeeee;">%i</span><span style="background-color: #fff0f0;"> th eruption'</span> <span style="color: #333333;">%</span> (nerupts,ndiv), fontsize <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">16</span>)
plt<span style="color: #333333;">.</span>savefig(<span style="background-color: #fff0f0;">'Cinder cone evolution after {} eruptions.png'</span><span style="color: #333333;">.</span>format(nerupts), dpi <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">600</span>)
</pre></div>
<p><br /></p><p>Gather the saved images and use a natural (human) sorting to order them from start to finish then save as a gif animation with the <a href="https://imageio.readthedocs.io/en/stable/">imageio</a> Python library. </p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">natural_key</span>(string_):
<span style="color: #dd4422;">"""See https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/"""</span>
<span style="color: #008800; font-weight: bold;">return</span> [<span style="color: #007020;">int</span>(s) <span style="color: #008800; font-weight: bold;">if</span> s<span style="color: #333333;">.</span>isdigit() <span style="color: #008800; font-weight: bold;">else</span> s <span style="color: #008800; font-weight: bold;">for</span> s <span style="color: black; font-weight: bold;">in</span> re<span style="color: #333333;">.</span>split(<span style="background-color: #fff0f0;">r'(\d+)'</span>, string_)]
images <span style="color: #333333;">=</span> <span style="color: #007020;">sorted</span>(<span style="color: #007020;">list</span>(<span style="color: #007020;">map</span>(<span style="color: #007020;">str</span>, Path()<span style="color: #333333;">.</span>glob(<span style="background-color: #fff0f0;">'*.png'</span>))), key<span style="color: #333333;">=</span>natural_key)
images <span style="color: #333333;">=</span> [x <span style="color: #008800; font-weight: bold;">for</span> x <span style="color: black; font-weight: bold;">in</span> images <span style="color: #008800; font-weight: bold;">if</span> <span style="color: black; font-weight: bold;">not</span> <span style="background-color: #fff0f0;">'Cinder'</span> <span style="color: black; font-weight: bold;">in</span> x]
images <span style="color: #333333;">=</span> [imageio<span style="color: #333333;">.</span>imread(i) <span style="color: #008800; font-weight: bold;">for</span> i <span style="color: black; font-weight: bold;">in</span> images]
imageio<span style="color: #333333;">.</span>mimsave(<span style="background-color: #fff0f0;">'eruption.gif'</span>,images,fps<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">3</span>)
</pre></div>
<p><br /></p><p>And now for the fun part, click on the video below to watch the resulting animation of cinder cone evolution and bomb trajectories plotted every 5000 eruptions:</p><p><br /></p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='586' height='488' src='https://www.blogger.com/video.g?token=AD6v5dzeTKwCmTbG7Fl3XgHv6xf72-EwXarrMLG5X2XWU-D9VcIDU-Xfu9-2cvmLdZgaWESuTQdNVy88Dla6SfXGmg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><br /><div><div class="separator" style="clear: both; text-align: center;"><br /></div></div>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-5933334897942687062021-11-07T22:54:00.051-08:002024-02-23T12:02:41.396-08:00A simple dehydrator build with temperature control
<div class="separator" style="display: none;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj0yIteKxhYxh_cxPBHrOsqOwgLwOUA5E4wCAS3mdntnQdYl_b4iMHRTfoObcR1z3CGYpP3Tw33-0m9JnFfW167MPvF1c8qZjtltIRrsu6r1uAur31YW5IoPtUMIMDV75qFSycRD1RMynCzEbPyOamnTq1Q85nGzRDtJrN03dICjKPj93i4fhOxOwS8Mg=w525-h700" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="255" data-original-width="255" height="255" src="https://blogger.googleusercontent.com/img/a/AVvXsEj0yIteKxhYxh_cxPBHrOsqOwgLwOUA5E4wCAS3mdntnQdYl_b4iMHRTfoObcR1z3CGYpP3Tw33-0m9JnFfW167MPvF1c8qZjtltIRrsu6r1uAur31YW5IoPtUMIMDV75qFSycRD1RMynCzEbPyOamnTq1Q85nGzRDtJrN03dICjKPj93i4fhOxOwS8Mg=w525-h700" width="255" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></div><p></p>
<p style="text-align: left;">Step-by-step process (with pictures) of how I built a large capacity food dehydrator, including optional thermostat control of a heating element and ventilation. Includes all parts and detailed instructions.</p><span><a name='more'></a></span><p style="text-align: left;">Recently after many weeks of successful mushroom hunting, I quickly had more mushrooms than I knew what to do with, and I would hate to throw them out. Our apple tree also had a massive amount of fruit this year. One could save time and buy a dehydrator, but after looking online at the various options and trying to decide on what to do with some old roof sheathing (plywood) I decided to build one. This post details the build process step-by-step and includes useful tips and links (note, affiliate links support this website and future content). This is an intermediate project that anyone can do, it is well worth the effort! </p><p style="text-align: left;"></p><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhSuQqTd89N2eh5hWaYUAkEuBnikp0ib4z3iEk1ntgvwM7Md97GwqMLwAbhPvVX4j9TgFJ7DPJzcvKADe3gEyAt98ms97by1PrT1dukp16JIV2IJkMjaG3nMO6ZrdsmDrO0KR8qc7KGOgYZ4LVYEB1UyKOEj75cM9skAOYlkOnnNmrUBu1eGq2Cs-iJYw=s3264" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="316" src="https://blogger.googleusercontent.com/img/a/AVvXsEhSuQqTd89N2eh5hWaYUAkEuBnikp0ib4z3iEk1ntgvwM7Md97GwqMLwAbhPvVX4j9TgFJ7DPJzcvKADe3gEyAt98ms97by1PrT1dukp16JIV2IJkMjaG3nMO6ZrdsmDrO0KR8qc7KGOgYZ4LVYEB1UyKOEj75cM9skAOYlkOnnNmrUBu1eGq2Cs-iJYw=w422-h316" width="422" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">A variety of wild picked mushrooms and garden peppers about to go into the dehydrator.</td></tr></tbody></table><p></p><p style="text-align: left;">This dehydrator has proven to be more useful and fun to use than I expected, we have used it to make home-made beef jerky (it can easily run over 180 deg. F!), apple chips, dried peaches, herbs, and others. After some research into similarly inspired projects I combined what I considered the best ideas into the design but kept it easy to make. It has a high capacity and can be used with different heating and ventilation units by simply plugging them into two outlets that are controlled by a built-in thermostat. I've also included some notes on modifying it to be more suitable for jerky with an internal fan. The total cost of this build for me was around $75. A list of materials used and links to purchase important parts and tools are provided. Hope you enjoy!</p><p style="text-align: left;"><b><br /></b></p><p style="text-align: left;"><b>Legal Disclaimer: </b><span style="font-weight: normal;">This project involved basic electrical wiring, e</span><span style="font-weight: normal;">ven simple electrical work has inherent safety risks and can result in serious injury or death. If you do not feel comfortable making electrical connections ask for help from a licensed electrician. subcriticalflow.com cannot be held responsible for any injuries you may incur from building or using this dehydrator.</span></p><h3 style="text-align: left;">The box</h3><div>The main task in building this dehydrator is construction of the frame which is simply a box made of plywood. Please feel free to modify the dimensions to suit your needs but the main points to consider when laying this out are:</div><div><ol style="text-align: left;"><li>What are the dimensions (length and width) of your trays you wish to use in your dehydrator?</li><li>What capacity or number of trays you do you need? </li></ol></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgcAGYnS-_V3KtgBc_70b1l_W-Yah7w5OqtwFV7I6Bov0yU_AQFJe85GBvqExVHt_G5-2UUkQTNO7V80MVOpuu7euhtcAyiMx6QsE0aY8YgGSzBJAO_EFwU5y7QdO0LtvBjR_k_l9rdmPKnlNlbaEyRltD6W8FomzuJBksWsawR6tj3-bsSfaL0DSDgZQ=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="685" src="https://blogger.googleusercontent.com/img/a/AVvXsEgcAGYnS-_V3KtgBc_70b1l_W-Yah7w5OqtwFV7I6Bov0yU_AQFJe85GBvqExVHt_G5-2UUkQTNO7V80MVOpuu7euhtcAyiMx6QsE0aY8YgGSzBJAO_EFwU5y7QdO0LtvBjR_k_l9rdmPKnlNlbaEyRltD6W8FomzuJBksWsawR6tj3-bsSfaL0DSDgZQ=w515-h685" width="515" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The dehydrator is a simple plywood box, with a hole on top for the exhaust fan and a series of holes on the bottom of the walls for incoming air.<br /></td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">Some things to keep in mind if you design your own box, the width and length of your trays will determine the width and length of the interior of your box. You will want to make your interior box width about 1/2" wider than the length of your trays or drying screens if you build your own so that they can slide in and out easily, they will be supported by 1/2" or so thick wood strips. As for the capacity question, if you only need to dehydrate a few pounds of food at a time (most foods dehydrate in 6 to 24 hours), then you can shorten your box. Just remember that if you greatly increase the size of your box the heating and insulation should also be bumped up a bit because you will have great heat loss. </div><h4 style="clear: both; text-align: left;">Overall dimensions</h4><div style="clear: both; text-align: left;">The box interior dimensions are 17" wide by 16" deep (front to back) and about 34 1/2" tall. </div><div style="clear: both; text-align: left;"><br />Again, the width and depth were determined by the dimensions of the stainless steel cooling racks I use as drying racks which are 16.5 x 11.5", I kept the extra 4 1/2" depth to be able to keep the food a bit away from the walls to improve the drying efficiency, I also wanted to experiment with adding a horizontal fan inside and have enough room without interfering with the drying racks, but this is optional you could reduce the depth of your box to be more inline with the size of your racks.</div><h4 style="clear: both; text-align: left;">A note on drying racks/material:</h4><div style="text-align: left;">I recommend stainless steel cooling racks because they are food safe and easy to clean, and will last forever unless you drop a sledge hammer on them (you could probably hammer them back into shape). After reading into this and considering building my own racks from wooden frames and screens I learned that aluminum or galvanized screen can discolor your food if it is acidic and may leach into it. Plastic screen (avoid fiberglass) like polypropylene can crack in high heat or tear easily, and I'm not fully comfortable with plastic material being in contact with food either. Some claim to be food safe you should research how they do with higher temperatures up to 200 degrees F. Save yourself some trouble and just get the stainless racks!</div><h3 style="clear: both; text-align: left;">Cut list:</h3><div>I used 3/4" plywood leftover from roof sheathing but recommend 1/2". I decided to use the 3/4" material because I had it laying around but it is overkill and makes the final unit a bit heavy although it works fine. Because it was a lower grade plywood I used an orbital sander, like this one, starting with 80 grit pads to smooth off the surfaces for a nicer finish. <i><b>Note</b>,</i> these dimensions are for 3/4" thick material, if you use 1/2" you will need to increase the width of the top and bottom pieces by 1/4" or so. </div><div><ul style="text-align: left;"><li>16" x 36" (2 pieces for side walls)</li><li>18 1/2" x 36" (back wall)</li><li>17 1/8" x 36" (door)</li><li>17 1/8" x 15 1/4" (2 pieces for top and bottom) </li><li>15 " x 3/4" x 5/8" (24 for for rack supports or your preference)</li></ul><div>Use a circular saw or a table saw to cut your pieces from the plywood. I used a circular saw and the Kreg rip cutting jig which is affordable, but use what you have. </div></div><h3 style="clear: both; text-align: left;">Assembly of the box</h3><div>If you have never built a wooden box don't worry it is not too difficult and this project doesn't require precision to be successful. If there are small gaps in your box seams once complete you can fill them with silicone caulk. </div><div><br /></div><div>Before assembling the box, cut out the ventilation fan hole (<a href="https://blogger.googleusercontent.com/img/a/AVvXsEhQCJ1qrpuPwMnZ7GUTqhNWURKz7UGWBgeexIBBSyPZZaqvS4AkLaoVNlUTB04MfcWTndjTtfkjBb1wG0lJFjfgfwR59nZAanKzjICviQ6UecZtLXze_w2VA5tqb5tJwgQzujn2e8JCxIDNUwCgBaNJJbhPx0-Gewe5uAs1qmFGX7i-7hOEa5vNDLx58Q=s3264">see image below</a>) in the top piece with a jigsaw and drill inlet holes in the walls. Find the center of the top piece and draw a 4 7/8" circle with a compass, note you may need to adjust this if you use a different fan. The fan should be able to slide into this how so it lays flat and does not fall through. </div><div><br /></div><div><br /></div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhQCJ1qrpuPwMnZ7GUTqhNWURKz7UGWBgeexIBBSyPZZaqvS4AkLaoVNlUTB04MfcWTndjTtfkjBb1wG0lJFjfgfwR59nZAanKzjICviQ6UecZtLXze_w2VA5tqb5tJwgQzujn2e8JCxIDNUwCgBaNJJbhPx0-Gewe5uAs1qmFGX7i-7hOEa5vNDLx58Q=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEhQCJ1qrpuPwMnZ7GUTqhNWURKz7UGWBgeexIBBSyPZZaqvS4AkLaoVNlUTB04MfcWTndjTtfkjBb1wG0lJFjfgfwR59nZAanKzjICviQ6UecZtLXze_w2VA5tqb5tJwgQzujn2e8JCxIDNUwCgBaNJJbhPx0-Gewe5uAs1qmFGX7i-7hOEa5vNDLx58Q=w640-h480" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">View of dehydrator box from above, the front door is at the bottom of the picture and covered in aluminum foil for reference.</td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;"><br /></div><p style="text-align: left;">Next, drill 1/2 or 3/4" inlet holes (about 2 inches from the bottom) in the side and back wall pieces every couple of inches angled slightly upwards from the outside in (<a href="https://blogger.googleusercontent.com/img/a/AVvXsEgwDx_uZM-NkiuclYbPJ6wVhW75T2iu2jaT_UF6vjyIiyJ8H-0IgEE-lzkA6aUFOAwuSlrwJBH7aQN4lGCDGG7CflE-BY9-yjYqr49wk9asVvbucsR0f4rPmBR_cjU4ZVf5hX0PQHwCOv4Klimw4uRUgl9y4C6Ibk3b_02KuZ2jOm5q09zD3YlDOfMHeQ=w400-h300">picture below</a>). You could also drill these holes in the bottom of the door but I didn't. Tip: put a piece of scrap material under your wall pieces to avoid tear out. </p><div style="text-align: left;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgwDx_uZM-NkiuclYbPJ6wVhW75T2iu2jaT_UF6vjyIiyJ8H-0IgEE-lzkA6aUFOAwuSlrwJBH7aQN4lGCDGG7CflE-BY9-yjYqr49wk9asVvbucsR0f4rPmBR_cjU4ZVf5hX0PQHwCOv4Klimw4uRUgl9y4C6Ibk3b_02KuZ2jOm5q09zD3YlDOfMHeQ=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="347" src="https://blogger.googleusercontent.com/img/a/AVvXsEgwDx_uZM-NkiuclYbPJ6wVhW75T2iu2jaT_UF6vjyIiyJ8H-0IgEE-lzkA6aUFOAwuSlrwJBH7aQN4lGCDGG7CflE-BY9-yjYqr49wk9asVvbucsR0f4rPmBR_cjU4ZVf5hX0PQHwCOv4Klimw4uRUgl9y4C6Ibk3b_02KuZ2jOm5q09zD3YlDOfMHeQ=w462-h347" width="462" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Side view of inlet holes near bottom of side walls and castors.</td></tr></tbody></table><p style="text-align: left;"><br />I used a pocket hole jig and screws without glue to assemble the box and it is very strong and square. It would also be fine to drill pilot holes and screw, or nail (with glue) the box together but the angled pocket holes gives a lot more strength to plywood joints because they avoid screwing directly into end grain. </p><p style="text-align: left;">If you use pocket holes, layout your screw locations on all the pieces after you label them (back, side, top, bottom) and drill all the holes about 6-8 inches apart. Start by laying the back wall piece on a table or work surface and attach one of the side walls, a brad nail gun or corner clamp may be useful to hold the pieces aligned while you screw. The back and side walls are the same length and should be aligned lengthwise and connected at 90 degrees with the side wall should sit on top of the back (when the back piece is lying down). Next you can attach the top and bottom pieces which fit inside the back and side walls and are flush with their outer ends. Now you should have the back and one side wall connected lengthwise and along the top and bottom pieces, now the other side wall can be attached to the back and the top and bottom pieces from the inside. Look at the pictures above to see how the pieces should fit together once complete. <i>Tip</i>: set your drill to a low torque to avoid over driving screws and striping the plywood.</p><p style="text-align: left;"><br />Now your box should look similar to the first <a href="https://blogger.googleusercontent.com/img/a/AVvXsEgcAGYnS-_V3KtgBc_70b1l_W-Yah7w5OqtwFV7I6Bov0yU_AQFJe85GBvqExVHt_G5-2UUkQTNO7V80MVOpuu7euhtcAyiMx6QsE0aY8YgGSzBJAO_EFwU5y7QdO0LtvBjR_k_l9rdmPKnlNlbaEyRltD6W8FomzuJBksWsawR6tj3-bsSfaL0DSDgZQ=w481-h640">picture</a> without the wood strips installed.</p><h3 style="text-align: left;">Cut and install drying rack supports</h3><div style="text-align: left;">I used some scrap pine for the drying rack supports, you could also use 2x building studs or whatever you have. If you have a table saw you can easily cut these, if not you can use quarter round or square molding from a hardware store. Once they are all cut clean off any rough or splintered edges with sand paper. Next determine the spacing you wish to have between the trays, I recommend 1 1/4" spacing. Cut a scrap piece of straight wood the same thickness of your spacing (1 1/4") that is about 15 inches or so long. Use this piece of wood to help place your tray supports and align them evenly on the inside of both side walls. All you need to do is lay down your box on its side and put the spacing piece up against the inside wall along the top of the box, now you can take a rack support strip so that the wider side (the 3/4" thick side) is laying down on the wall and attach it to the wall. I used a pneumatic nail gun with 1 inch brads with wood glue in between to attach the strips. Continue to use your spacer piece placed up against the previously installed support strip to install 12 strips on one side of your box then flip the box over and do the same on the other side starting from the top down. The result should be 24 perfectly aligned strips to support 12 drying racks and will look similar to what is shown in the first <a href="https://blogger.googleusercontent.com/img/a/AVvXsEgcAGYnS-_V3KtgBc_70b1l_W-Yah7w5OqtwFV7I6Bov0yU_AQFJe85GBvqExVHt_G5-2UUkQTNO7V80MVOpuu7euhtcAyiMx6QsE0aY8YgGSzBJAO_EFwU5y7QdO0LtvBjR_k_l9rdmPKnlNlbaEyRltD6W8FomzuJBksWsawR6tj3-bsSfaL0DSDgZQ=w481-h640">picture</a> above but note that I only used 12 strips in mine (6 on both sides), looking back I recommend 24 strips (to support 12 drying racks) in case you ever want more capacity. </div><div style="text-align: left;"><br /></div><h3 style="text-align: left;">Apply finish (optional)</h3><div>At this stage I applied some raw linseed oil to the entire dehydrator including the door to protect the wood. I wouldn't recommend boiled linseed oil because of some of the toxic additives that may release at higher temperatures? You could use other finishes, natural plant-based oils like raw linseed are typically safe, and if fully cured most finishes are safe but do your research on their heat resistance. You would even paint the box if you are comfortable with it. </div><div><br /></div><div>If you decide to use raw linseed oil I would recommend mixing it with mineral spirits at a 1:3 ratio, this will help it penetrate deeper, make it easier to apply, and might cure a bit faster. </div><div style="text-align: left;"><h3 style="text-align: left;">Connect the door</h3></div><div style="text-align: left;"><span style="font-family: inherit;">This is a good time to connect the door to the dehydrator. This is simply done using two piano-style hinges. Put the box, door side facing up, on a work table and lay the door inside its front. The door should fit fairly snugly in between the two side walls and flush with the top and bottom of the box. You can lightly clamp the door in place. Next lay the hinges on top of the edge of the box so that one half the hinge extends over the side wall and the other half over the door, putting one hinge at the top of the box and the other at the bottom. Keeping the hinges centers, mark and drill small pilot holes where each screw hole is located and then attach using the screws provided.</span></div><h3><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgLAxrWVBI5yWbQRDZtpXMwnDNMYQxjicSVb6W8k3xdL24Vf8LXDc761KrixXioPKpcULR8w7yLzjTQcfH44jSJIgdVEVBifs-VW-6P9AGfERUks7ZXcZTzfm_RYmsngKqf7aDl7wy3J5Xs1e-OEi8sIutnQr7jq1iCd2bHzfn20XMHbTLx-T8k-D5J1g=s3264" style="margin-left: auto; margin-right: auto;"><img alt="Piano hinge used to attach door to side wall." border="0" data-original-height="3264" data-original-width="2448" height="525" src="https://blogger.googleusercontent.com/img/a/AVvXsEgLAxrWVBI5yWbQRDZtpXMwnDNMYQxjicSVb6W8k3xdL24Vf8LXDc761KrixXioPKpcULR8w7yLzjTQcfH44jSJIgdVEVBifs-VW-6P9AGfERUks7ZXcZTzfm_RYmsngKqf7aDl7wy3J5Xs1e-OEi8sIutnQr7jq1iCd2bHzfn20XMHbTLx-T8k-D5J1g=w394-h525" width="394" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Piano hinges used to attach door.</td></tr></tbody></table></h3><h3>Install a door latch</h3><div style="text-align: left;">I built this door latch using a scrap piece of wood cut into an L shape that pulls the door in tightly when shut using a clamp latch on the side of the box. It easily moves into closing position by attaching it to the front of the door using a small hinge. I did this because it does not only pull the door closed by also pulls it horizontally towards the side of the box to minimize any gaps along the door which helps to keep heat in the dehydrator.</div><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-left: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjEfNknCBojbyTe_VujMO-Jsdy19JxZ8JS2LZ2dDjso0u88rpwzoe0kxUENNo-PztrbYS_GJx4CvdJfqsgU9ruY_LdZfUj8T4DdQudjAlMjQ4zOp2M4cFo_aHZXBv8N_3M_p3WBcRqEIRAYaWor_2lM1bFC_FQMMv0aSXk7Zl9dBhMowbpJ5vWpP7uH6Q=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="300" src="https://blogger.googleusercontent.com/img/a/AVvXsEjEfNknCBojbyTe_VujMO-Jsdy19JxZ8JS2LZ2dDjso0u88rpwzoe0kxUENNo-PztrbYS_GJx4CvdJfqsgU9ruY_LdZfUj8T4DdQudjAlMjQ4zOp2M4cFo_aHZXBv8N_3M_p3WBcRqEIRAYaWor_2lM1bFC_FQMMv0aSXk7Zl9dBhMowbpJ5vWpP7uH6Q=w400-h300" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">View of custom made door latch.</td></tr></tbody></table><div style="text-align: left;">This method of making the door latch is optional, you could design another method or buy a latching system. But if you decide to make this, simply cut out or use an L shaped piece of wood attach it to the front door so that when closed the L pulls the door tightly against the side wall using the small hinge. Align, pre-drill, and screw in a mounting block that runs parallel with the L-shaped wood on the outside of the adjoining side of the box which holds the other part of the latch, make sure when the L is closed there is an appropriate gap so that when the latch is tightened it pulls the door in flush but it is not too close or too far away. </div><div><br /></div><h3>Install wheels or bottom supports</h3><h3></h3><p style="font-size: medium; font-weight: 400; text-align: left;">You will need to put some sort of supports under the dehydrator, I used four 3" lockable castors which allow me to move the dehydrator easily but you could also use other supports. This is important because you will need some access under the box for the wiring to your heating element which will run outside and under the box up to the top where the thermostat is located. </p><h3 style="text-align: left;">Install electrical box and fixture for the heating element</h3><p style="text-align: left;"><span style="font-weight: normal;">Next, drill a 2" hole in the center of the bottom of your dehydrator using a hole saw or jig saw. This will be used to run wiring to an electrical box which will be used to hold the heating fixture (bulb fixture). The reason for the large diameter is to make it easy to connect a cable clamp to the electrical cable to the bottom of the electrical box so that it cannot be pulled loose accidentally, this is very important for safety! </span></p><p style="text-align: left;">You can use an old discarded extension cord for this like I did or buy a 14 gauge cord that is about 5 feet long and keep the male 3-pronged 120v plug attached. You will directly wire in the other end of the cable into the light fixture later. Install a 3/4" cable clamp into the bottom hole in a 4" electrical box and tighten it to the box leaving the cable clamp open. Next, attach the electrical box inside the dehydrator on the bottom using screws so that it is centered over the 2" hole. I recommend this 4" <a href="https://www.amazon.com/gp/product/B008RGAJBE/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B008RGAJBE&linkCode=as2&tag=subcritflow-20&linkId=d6726d5e97b2a693da1c6eb3e0c4da49" target="_blank">electrical box</a> which is safe in damp conditions and a porcelain light bulb fixture to hold your heating element. Now run your cord through the bottom hole of your dehydrator and through the electrical box through the clamp with about 4 inches of the wires out of the cable sheathing using a cable stripper. Also strip about 1/2 to 3/4" of bare wire from the ground, neutral, and hot wires with a wire stripper and attach them to the bulb fixture, this is typically done by bending a partial loop (using the small hole in the wire stripper) in the three wires and pinning them down with the screws inside the fixture, making sure to connect the ground screw in the correct location of the fixture. Once the connections are made, pull any slacking cable through the bottom of the box and attach the fixture to the top of the electrical box with the supplied screws. Now finish up by tightening the cable clamp from below the dehydrator which should be accessible via the 2" hole that was drilled. Hold the male plug end of your cord and make sure that it can reach at least 8" above the dehydrator so it can be plugged into the box holding the thermostat.</p><h3 style="text-align: left;">The thermostat box and wiring (optional)</h3><p style="text-align: left;">Before continuing, I think it is important to mention that installing this thermostat is optional. At this point you could plug a heating element, like a 250 watt infrared bulb into the bottom of your dehydrator and put the fan in the top and start dehydrating. From my experience this configuration will run at around 150-160 degrees F. with the fan on. You could experiment with different heating elements, a fan damper, etc to adjust your temperature and airflow manually. The neat thing about the thermostat setup is that it allows you to control the ventilation or heating element separately or in tandem, plus it tracks the temperature inside the dehydrator very accurately. For example you could plug your exhaust fan into the wall and the heating element into the thermostat so that the fan never stops running however the heating element will only kick on when the temperature falls below a certain level. When making beef jerky, I typically do the opposite using the thermostat, in other words I keep the heating element on and only turn the exhaust on if the temperature goes above say 175 degrees F. <br />Building the thermostat controller was a new thing for me and I found it enjoyable and will likely use this approach again if I ever need to control heating/cooling in other projects like a greenhouse. <br />The thermostat I used was the very affordable (about $16 dollars) Inkbird ITC-1000F which is commonly used by home brewers for their fermentation chambers. Hey, maybe after this project you can pick up a new hobby? I housed mine in a small electrical subpanel box simply because it was what I could find and was inexpensive. Although this works fine and is very sturdy, looking back I would recommend using a plastic "project box" because they are much easier to cut out the holes needed for inserting the thermostat and receptacle. </p><h4 style="text-align: left;">Steps:</h4><p style="text-align: left;">Once you have your project box, take the tightening latches off the Inkbird and draw a rectangle in the front of the box that the Inkbird can fit into but the front will not fall all the way through. Also, draw a rectangle that is about a half inch smaller than the front cover for a regular 15 amp two plug receptacle on the top of your electrical box. Next cut these holes out with a Dremel/rotary tool and a cut-off wheel. Also knock-out or drill the appropriate size hole for a cable clamp for the power supply cord and drill a small ~3/8" hole in the back of the box for the temperature sensor to exit the box. The wiring diagram provided on the Inkbird will not work for this approach and is more useful for direct wiring. </p><p style="text-align: left;"><br />Follow a good wiring diagram, here is the one I followed from the American Homebrewers Association: </p><div style="text-align: left;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy2BMqbTy-M8lm55KVazgUSSOpoMRPyN8Zpddg68svbvnoypZkAAGeV8ZCOJxXDgKFdVXWsBW1WkbahVNS-lBI_TurKgj3ru72of3nGNEhi8hyphenhyphen14ZrfinadcbHw6U-jeSNprVoPW84AsVq/" style="margin-left: auto; margin-right: auto;"><img data-original-height="614" data-original-width="616" height="637" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy2BMqbTy-M8lm55KVazgUSSOpoMRPyN8Zpddg68svbvnoypZkAAGeV8ZCOJxXDgKFdVXWsBW1WkbahVNS-lBI_TurKgj3ru72of3nGNEhi8hyphenhyphen14ZrfinadcbHw6U-jeSNprVoPW84AsVq/w640-h637/temp_schematic1.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Wiring diagram for connecting the Inkbird ITC 1000F (and other Inkbird 1000 series) to a receptacle for separate heating and cooling circuits. <br /></td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;"><br /></div>Here the black wire is the hot, white is neutral, and the green is the ground. <i><b>Important</b></i>, one key thing you need to do that is not shown in the diagram but is critical for this circuit to function is to remove one of the tabs on the receptacle with needle nose pliers (see image below), in this diagram it is the one the right side of the receptacle (when looking from the front), the side with only two screws- not the side with the ground connection screw. </div><div style="text-align: left;"><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilsKzoGv-jQ5ATVEZB-_-0PHlfeKIZdRb-4vNzp61i7fEr8phoIgMb0E-FVKFUYZtXhSasopxyizEAr5yjxXktNHE32yZWFDdnof0KgbTqrdRprqRlgeZ69AIypHNV3Fa14yeHVcLb2fqm/" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img alt="" data-original-height="863" data-original-width="600" height="411" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilsKzoGv-jQ5ATVEZB-_-0PHlfeKIZdRb-4vNzp61i7fEr8phoIgMb0E-FVKFUYZtXhSasopxyizEAr5yjxXktNHE32yZWFDdnof0KgbTqrdRprqRlgeZ69AIypHNV3Fa14yeHVcLb2fqm/w286-h411/temp-plug.jpg" width="286" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Side view of metal tab that needs to be removed <br />from one side of the receptacle with needle-nose pliers.</td></tr></tbody></table><p style="text-align: left;"><br />Once you have broken this tab, install your Inkbird into the front slot of your box, attach a cable clamp to the power supply hole you made and pull the power cable through it and into the box, separate a good amount of the individual cable wires (~ 6 inches) and strip the last 1/'2" or so. Also, from your spare cable, cut and strip 3 pieces of hot labeled wire that are about 6-8" and 4 neutrals, you can always shorten them later. Now follow the diagram to make the connections using appropriate sized wire nuts or locking connectors for the gauge wire you use in this box (typically 14 AWG). The connections to the thermostat itself are made by sliding the ends of the wires inside the terminals and pinning them down with screws that come with it.</p></div><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEim4q3-sM6Uh8jeYgr7ePMEGY_OOXC71KExdICJUy_ptRS0BKPfNZDdFn04RbZLqmvzssK6o1w75vyirPGwJoFHn6lNXnuD3-h0P4ZtZeDsKBPJBkZ4q8n9Kwm9F2wYLydtUk1jvLTevRDDsOlJ6eCIEU3o8O9S0maD3oMoKyHOPWeQICbtXqkrN5YXSw=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="320" src="https://blogger.googleusercontent.com/img/a/AVvXsEim4q3-sM6Uh8jeYgr7ePMEGY_OOXC71KExdICJUy_ptRS0BKPfNZDdFn04RbZLqmvzssK6o1w75vyirPGwJoFHn6lNXnuD3-h0P4ZtZeDsKBPJBkZ4q8n9Kwm9F2wYLydtUk1jvLTevRDDsOlJ6eCIEU3o8O9S0maD3oMoKyHOPWeQICbtXqkrN5YXSw=w240-h320" width="240" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">A view of the thermostat box after making the wire connections from above.</td></tr></tbody></table><p>At this point it would be useful to mark which end of the outlet is connected to the cooling circuit and which plug is for the heating circuit on the outside of your box lid. Don't forget to also connect the provided temperature sensor to the thermostat and run the probe out through the box. I attached the whole assembly to the top of the dehydrator directly with screws. It can be tricky but I tightened the receptacle to the electrical box simply by tightening the screw on the from cover of the receptacle and positioning the receptacle so that it extends under the box lid, then by tightening the cover screw it pulls the receptacle body up against the box lid. Finally, tighten the cable clamp that holds the power supply cord into the thermostat box (<a href="https://blogger.googleusercontent.com/img/a/AVvXsEg7qkaIdm92xAxzGMaGr3pSMHBGlQkslESqV8kTDinPOY0WyrmX9yqSv22ox2R4zkTYsx7wLIwMcC90IqIFoB6ynIqD6Ci8tP_OAPT4nV0JO-EMvkjMtSsJwQ2Uto6pabfEGWE3_Dr44uMboXaTksFcS2TXt1HxaDyTEgEJJv4uJO_g576OS9a3QSmk1A=w400-h300">image below</a>). </p></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-left: 1em; text-align: left;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEg7qkaIdm92xAxzGMaGr3pSMHBGlQkslESqV8kTDinPOY0WyrmX9yqSv22ox2R4zkTYsx7wLIwMcC90IqIFoB6ynIqD6Ci8tP_OAPT4nV0JO-EMvkjMtSsJwQ2Uto6pabfEGWE3_Dr44uMboXaTksFcS2TXt1HxaDyTEgEJJv4uJO_g576OS9a3QSmk1A=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="300" src="https://blogger.googleusercontent.com/img/a/AVvXsEg7qkaIdm92xAxzGMaGr3pSMHBGlQkslESqV8kTDinPOY0WyrmX9yqSv22ox2R4zkTYsx7wLIwMcC90IqIFoB6ynIqD6Ci8tP_OAPT4nV0JO-EMvkjMtSsJwQ2Uto6pabfEGWE3_Dr44uMboXaTksFcS2TXt1HxaDyTEgEJJv4uJO_g576OS9a3QSmk1A=w400-h300" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">View of thermostat box from the back and the cable clamp holding power supply.</td></tr></tbody></table><div><br /></div><div><br /></div><div>Drill a small hole in the middle of the back of the dehydrator to run the temperature probe and position the probe towards about one third of the way to the middle of the box (from the wall) and about two thirds of the way up, where most of the food will be. Now plug in your thermostat to make sure things are working and the temperature reading seems correct. Plug the heating element into the heating circuit, and it should turn on, next try setting the temperature below the ambient temperature and plug the fan into the cooling circuit and make sure it turns on. </div><div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgrkdbEMG_58I1VQcr9CTFQ6P79M5PMXEsfyT6wn3N-GZcmw-ftUTd7AEukIscei6DK0lgiVto4Zu6Q9YP3Ezw0q8XoewpsfLNFCOSmQr-mzn0R-qnXQcpqh6w7um7bw-_xHnviT2NZMWPrP5322VQkLwxkTOfjApGDkWFiEj9g8z5jWnob_AH20NnSjg=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="692" src="https://blogger.googleusercontent.com/img/a/AVvXsEgrkdbEMG_58I1VQcr9CTFQ6P79M5PMXEsfyT6wn3N-GZcmw-ftUTd7AEukIscei6DK0lgiVto4Zu6Q9YP3Ezw0q8XoewpsfLNFCOSmQr-mzn0R-qnXQcpqh6w7um7bw-_xHnviT2NZMWPrP5322VQkLwxkTOfjApGDkWFiEj9g8z5jWnob_AH20NnSjg=w519-h692" width="519" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Front view of finished dehydrator with thermostat installed.</td></tr></tbody></table></div><br /><br /></div><h3 style="text-align: left;">Final touches</h3><div>You could fire her up and start drying, however I highly recommend putting some sort of reflective or radiant barrier (e.g. aluminum foil) on the inside walls of the dehydrator to increase its efficiency and reduce the heating time. Even better would be a layer of insulation with radiant barrier outside of that, like the stuff they use in attics, or you could experiment with a thin layer of food sage insulation and cover it yourself with aluminum. </div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj0yIteKxhYxh_cxPBHrOsqOwgLwOUA5E4wCAS3mdntnQdYl_b4iMHRTfoObcR1z3CGYpP3Tw33-0m9JnFfW167MPvF1c8qZjtltIRrsu6r1uAur31YW5IoPtUMIMDV75qFSycRD1RMynCzEbPyOamnTq1Q85nGzRDtJrN03dICjKPj93i4fhOxOwS8Mg=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3264" data-original-width="2448" height="700" src="https://blogger.googleusercontent.com/img/a/AVvXsEj0yIteKxhYxh_cxPBHrOsqOwgLwOUA5E4wCAS3mdntnQdYl_b4iMHRTfoObcR1z3CGYpP3Tw33-0m9JnFfW167MPvF1c8qZjtltIRrsu6r1uAur31YW5IoPtUMIMDV75qFSycRD1RMynCzEbPyOamnTq1Q85nGzRDtJrN03dICjKPj93i4fhOxOwS8Mg=w525-h700" width="525" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">View of the inside of my finished dehydrator, I used HVAC tape to hold down aluminum foil inside but a much better insulation system could be used.</td></tr></tbody></table><br /><div><h3>Congratulations! </h3><div>I hope you enjoyed this post, please make a comment if you find it useful or have any questions, I'll do my best to answer any. If you decide to make one yourself I would like to hear about it, please share in the comments!</div></div><div><br /></div><h3 style="text-align: left;">Usage, experiments, and anecdotes </h3><div>I've experimented with a couple different incandescent light bulbs as heating elements as well as the big 250 watt infrared which can get the dehydrator over 180 deg. F! It seems like a 50-75 watt incandescent running constantly might be perfect for making Biltong because it runs around 80 deg with the fan running constantly. </div><div><br /></div><div>To improve airflow without adding more exhaust/cooling I experimented with mounting a small motor with a fan blade attached inside the dehydrator about halfway up on the back of the unit. This worked very well for making beef jerky as I was able to cover the ventilation hole on top with some foil and increase the temperature greatly (maybe too much) while still drying well. </div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEixpqGIwL1nb_-phBntayz8aOF2mfEUa_tnwpkMUJ_qb_gUucDi8zdPUjPilqMBeZncwTb80ETzYFm_-vN1ZAjEDZyf_1yjOde3KpGA_x942UqW4Z_RsobJ9M34y0R9F5kB7u3Uasz0hsFocX1bTEsA2oLAQbfYzyomYsxb3mSsUQq5YlaJekagaYZOLg=s3264" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2448" data-original-width="3264" height="480" src="https://blogger.googleusercontent.com/img/a/AVvXsEixpqGIwL1nb_-phBntayz8aOF2mfEUa_tnwpkMUJ_qb_gUucDi8zdPUjPilqMBeZncwTb80ETzYFm_-vN1ZAjEDZyf_1yjOde3KpGA_x942UqW4Z_RsobJ9M34y0R9F5kB7u3Uasz0hsFocX1bTEsA2oLAQbfYzyomYsxb3mSsUQq5YlaJekagaYZOLg=w640-h480" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Beef jerky made using the dehydrator with horizontal airflow fan attached inside.</td></tr></tbody></table><div><br /></div><p style="text-align: left;">The way I did this was I took a small ac motor (probably 5 volts or so) out of an old space heater someone threw away and mounted some cheap polycarbonate (heat resistant) R.C. airplane propellers to it, I couldn't use the fan blades provided because they were the wrong direction. You can see the red propeller blades in the back of the picture above if you squint. </p><div><h3 style="text-align: left;"><br /></h3></div><div><div style="text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><p></p></div>John Volkhttp://www.blogger.com/profile/08635472565551583944noreply@blogger.com2tag:blogger.com,1999:blog-4671541330977381429.post-52855061651403289562018-07-04T17:50:00.005-07:002021-11-17T09:33:13.808-08:00Thoughts from replacing a furnace and adding a split AC in a manufactured home<head>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 0.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<body>
<p>A detailed description of what I learned from replacing a mobile home furnace with a full size furnace and split AC unit.</p>
<span><a name='more'></a></span>
<p>
<i><strong>Disclaimer!</strong></i>
<br />
I take no responsibility for anything that you do and do not consider anything in this post as advice. I am not a licensed HVAC technician. Before doing any HVAC projects refer to your local building codes and permitting laws and consult a licensed professional. You may or may not be permitted to do any of this work yourself if you are not licensed. The goal of this post is to give you an idea of what it takes to do this sort of job and some things to keep in mind perhaps to help you make sure your contractor is doing an adequate job or at least so that you can follow along. Perhaps this information may help you save some money, but this is NOT a DIY how-to guide!
</p>
<p>
Not too long ago the furnace in my manufactured home had a gas build up that resulted in a small explosion and bending of the heat exchanger. Fortunately it did not cause a leak and we were able to shut off the gas for the season, it was 22 years old and it was time to replace it. The home also did not have air conditioning so it was a good time to put in a split system central air conditioning unit along with the new furnace. <!-I had several quotes from local contractors that ranged between around $7,500 to $9,200! So I looked into what it would take and how much I would save if I did some of the work myself. Turns out that some of this project is doable as a DIY project for anyone who has a bit of experience with basic tools and construction techniques, and a willingness to learn. I ended up saving over $5,000 and had a good time learning about HVAC. --> This post will run through the general process of removing the old furnace and the install of a new AC and furnace. The details of some steps are left vague as they were done by a contractor although I will mention all the major steps involved in the process.
</p>
<hr />
<h4>Tear-out the old furnace</h4>
<p>
Be sure that the electric power to your unit and gas flow are off. This typically involves switching your breaker and turning off your gas valve to your furnace and the home's main gas valve. A contractor will verify that these are off with a voltage detector and gas leak detector.
</p>
<p>
Removing the old furnace requires some elbow grease and patience. A crow bar and a drill are important tools here. In our case the furnace was located in a "closet" and was fastened securely to the flue and sealed to the floor with silicone. As such there was minimal open space on the sides of the unit- just a few inches. Ultimately the unit had to be removed slowly by disassembling it piece by piece until the empty frame could be lifted and hauled out. If your unit is not enclosed in a small space then you will have an easier time at this stage. You will likely need a truck or trailer to haul the waste material to the dump if your contractor does not do this for you. I ended up salvaging many sheet metal screws from the unit which have later been put to good use. You may also be able to get some cash from scrap metal or reuse sheet metal, etc. Of course, the blower fan and motor are of use for some DIY shop or home projects, for me this includes building a dust collector. Once torn out you can take the time to clean the supply plenum or duct to which your system outflows and then seal it from dust while the project is underway.
</p>
<h4>Make concrete slab for condenser</h4>
<p>
We had a small concrete slab made for the AC condenser just outside of the house in a location that is ideally as close as possible to the AC coil and blower inside. This may be something you can help with. In picking the slab location your contractor, the most critical things are that drain lines and the refrigerant line set for the AC will have no major obstacles while keeping the distance short to reduce the energy and heat loss of your system. It is important to use the appropriate concrete for small slabs, and it is a good idea to make it a bit larger than your condenser to protect it from soil and vegetation. Our slab was reinforced with steel mesh and lain over compacted angular gravel. As with any concrete work be sure to finish the surface and let it dry properly (not too fast) for maximum strength. Be sure that the slab forms and finished surface are level as well otherwise the condenser may not function properly.
</p>
<h4>Prepare connections and layout</h4>
<p>
The connection from your AC or furnace to your duct will vary, in our case the supply air flows into ducts that run beneath the home. From what I understand, this is common in manufactured homes. Other homes are designed based on climatic settings and architectural considerations and may have return air coming in from the bottom of the furnace/AC system and supply air leaving from the top of the system into ducts in the ceiling. In either case the connection will typically be a sheet metal plenum or some sheet metal ductwork. The condensate drains from the new furnace and AC will also need space if there was no prior drain, a PVC pipe with a trap installed will generally be threaded or glued to new high efficiency gas furnaces and all AC units to drain condensate water. In our case the drain runs beneath the floor joists and out the wall to drain above the ground. A refrigerant line set consists of two copper pipes, for return and supply flow, will need to run from the condenser outside on the slab that was created to the AC coil that is located downstream of your blower, In our case beneath the gas furnace. It is important that the copper pipes in the line set are not bent or have any serious kinks, therefore laying out the location of the line set path so that it does not contain sharp bends is important. Another thing to consider here is that line sets typically come in predetermined lengths if not specially ordered therefore you can save some money (and energy) by figuring out the shortest length that corresponds with one of these lengths (e.g. 25 ft) by determining the location for the condenser and connection path. It is important to lay this out before you move on to the installation.
</p>
<h4>Install return air grill</h4>
<p>
You may already have a return air plenum for your previous system. In our case we did not because the previous unit was a mobile home furnace that received combustion air from within the house from the front of the unit. We replaced this unit with a standard gas furnace that required a supply air connection of filtered air. What we did was install a return air grill in the non-load bearing wall behind the unit. This will later be attached to the return air intake on the furnace unit with a flexible insulated HVAC duct. The square shaped grill needed to be attached to a circular duct therefore we manufactured a small box from sheet metal to couple these together. Any skilled contractor can manufacture custom ductwork to fit these situations on the spot. Here it is important to refer to your units air flow to determine that size of return air filter and corresponding ductwork to attach to the furnace. If your return air filter and connecting ducts are too small this may greatly reduce the efficiency of the HVAC system!
</p>
<h4>Install coil, furnace/blower, and flue</h4>
<p>
Connecting the new units will depend on your system, in this case our system is downward flowing so the AC coil goes on the bottom and connects to the supply ducts while the furnace and blower are above. The top of the unit connects to the return air that was installed in the adjacent wall, in the upper portion. The top of the unit also has PVC connections to the roof flue for combustion air. The installation of the AC coil will attach to the supply air duct. HVAC silicone caulk is used to seal the furnace and AC units together, they need to be carefully aligned when they are stacked. After the AC and furnace are connected to the supply duct system/plenum and each other they will need to be connected to the ductwork that makes up your return air. In our case this was a 20 x 20" grill and insulated flexible duct. Be sure that any new ductwork is air tight on the return side to minimize dust entering the unit, small gaps in the flexible duct connections may be sealed with HVAC tape. Next the connections for the furnace combustion air need to be made, typically through a roof stack. If you need to run a new flue stack to the roof be sure that the contractor has experience and is able to correctly install flashing around the new flue without damaging the roof material. Otherwise you may be able to reuse the old flue stack by connecting into it from the bottom if you did not damage it when removing the original unit. As with the return air, it is critical to use the right size pipes (PVC in our case) for combustion and discharging outside air.
</p>
<h4>Run the refrigerant line set and drains</h4>
<p>
Now that all the units are in place it is time to connect the refrigerant line set to the coil and run condensate drains from the furnace and AC coil. The refrigerant line set runs from the AC coil to the location of the condenser slab, the location that it exits the home should be in line with the location of the connection on the condenser that you will put on the concrete slab later. Similarly, the layout for the line set should result in the connection coming into the home so that it does not need to be bent sharply and ends near the AC coil. Next the condensate drains from the furnace and coil need to run somewhere to drain, in our case they were connected using PVC pipe which ran beneath the sub floor where we placed a trap in the line and then ran out to the bottom of the siding in the skirting to drain a few inches from the foundation. The drain was attached to the bottom of the floor joists, it should not be left unsupported. Similarly for the line set, the high pressure in the system can cause the line set to move with the condenser pump activates and shuts off, therefore keep the line set away from any sharp surfaces that it may abrade into. Minimize damage in the homes siding by drilling the exit homes in strategic locations and use a small diameter bit to locate the spot before drilling the final large hole for the lines. The line set is insulated to keep energy loss to a minimum, the connection outside to the condenser should be as close as allowed to the home to also minimize energy loss. Any exposed part of the refrigerant line that flows cold fluid from the condenser should be wrapped in thick (e.g. 10 mil) HVAC line set tape. Lastly, seal with caulk or foam where the lines exit the home's exterior.
</p>
<h4>Electrical work for condenser, furnace, and brazing</h4>
<p>
A licensed electrician may need to add a dedicated circuit to your AC condenser if it is a new system as was my case. It is a good idea (if not required by your local code) that a separate shutoff switch is installed neat the condensor (outdoors) for the unit. Also, they should mount the wiring with the correct outdoor conduit. Similarly, electrical connections need to be made for the furnace and thermostat. Next the line set (which carries the refrigerant) needs to be connected to the AC coil and condenser. Typically copper connections are brazed using high temperature (e.g. from an oxygen acetylene torch) and flux. A good HVAC contractor who has read up on the newest and best methods will put a low pressure flow of nitrogen gas in the line set while brazing the connections in order to purge oxygen from inside the pipe. This practice reduces oxidation that occurs inside the pipe that would otherwise leave behind carbon particles and soot in the line that could damage the AC system or reduce its efficiency or durability. Next the system will be pressurized with refrigerant fluid to a certain level or pressure depending on the system and check for leaks by any drops in pressure using a gauge attached to the condenser. At this point the blower and AC system can usually be turned on and tested as the only thing left to do is connect the gas to the furnace.
</p>
<h4>Gas connection for furnace</h4>
<p>
The furnace needs to be reconnected to the gas line using the same diameter iron gas line that the home uses or larger. We had a safety vale installed that replaced our old simple gas valve before it connects to the gas furnace. Be sure that the contractor installs a trap in the gas line to reduce debris and dust that may otherwise enter the furnace. The threaded iron pipe should be well tighten and utilize gas joint pipe compound, and finally tested for leaks. Congratulations!
</p>
<h4>Other tips</h4>
<p>
You might be able to save money by working with your contractor and permitting office and doing some of these steps yourself- maybe not. Either way you can also save by asking contractors if you can help search for the best units to buy from a HVAC wholesaler.
</p>
</body>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com18United States37.09024 -95.712891-42.817205105173521 123.6671730106201 90 44.907044989379884tag:blogger.com,1999:blog-4671541330977381429.post-4720130462402508572016-10-10T16:54:00.002-07:002021-11-17T09:30:25.566-08:00Python, regex, and SymPy to automate custom text conversions to LaTeX<!DOCTYPE html>
<html>
<head><meta charset="utf-8" />
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<style type="text/css">
/*!
*
* Twitter Bootstrap
*
*/
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
mark {
background: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 1em 40px;
}
hr {
box-sizing: content-box;
height: 0;
}
pre {
overflow: auto;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
button,
input,
optgroup,
select,
textarea {
color: inherit;
font: inherit;
margin: 0;
}
button {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
}
button[disabled],
html input[disabled] {
cursor: default;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input {
line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
-webkit-appearance: textfield;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
}
optgroup {
font-weight: bold;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
@media print {
*,
*:before,
*:after {
background: transparent !important;
color: #000 !important;
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
a[href^="#"]:after,
a[href^="javascript:"]: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;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
.navbar {
display: none;
}
.btn > .caret,
.dropup > .btn > .caret {
border-top-color: #000 !important;
}
.label {
border: 1px solid #000;
}
.table {
border-collapse: collapse !important;
}
.table td,
.table th {
background-color: #fff !important;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #ddd !important;
}
}
@font-face {
font-family: 'Glyphicons Halflings';
src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.glyphicon-asterisk:before {
content: "\002a";
}
.glyphicon-plus:before {
content: "\002b";
}
.glyphicon-euro:before,
.glyphicon-eur:before {
content: "\20ac";
}
.glyphicon-minus:before {
content: "\2212";
}
.glyphicon-cloud:before {
content: "\2601";
}
.glyphicon-envelope:before {
content: "\2709";
}
.glyphicon-pencil:before {
content: "\270f";
}
.glyphicon-glass:before {
content: "\e001";
}
.glyphicon-music:before {
content: "\e002";
}
.glyphicon-search:before {
content: "\e003";
}
.glyphicon-heart:before {
content: "\e005";
}
.glyphicon-star:before {
content: "\e006";
}
.glyphicon-star-empty:before {
content: "\e007";
}
.glyphicon-user:before {
content: "\e008";
}
.glyphicon-film:before {
content: "\e009";
}
.glyphicon-th-large:before {
content: "\e010";
}
.glyphicon-th:before {
content: "\e011";
}
.glyphicon-th-list:before {
content: "\e012";
}
.glyphicon-ok:before {
content: "\e013";
}
.glyphicon-remove:before {
content: "\e014";
}
.glyphicon-zoom-in:before {
content: "\e015";
}
.glyphicon-zoom-out:before {
content: "\e016";
}
.glyphicon-off:before {
content: "\e017";
}
.glyphicon-signal:before {
content: "\e018";
}
.glyphicon-cog:before {
content: "\e019";
}
.glyphicon-trash:before {
content: "\e020";
}
.glyphicon-home:before {
content: "\e021";
}
.glyphicon-file:before {
content: "\e022";
}
.glyphicon-time:before {
content: "\e023";
}
.glyphicon-road:before {
content: "\e024";
}
.glyphicon-download-alt:before {
content: "\e025";
}
.glyphicon-download:before {
content: "\e026";
}
.glyphicon-upload:before {
content: "\e027";
}
.glyphicon-inbox:before {
content: "\e028";
}
.glyphicon-play-circle:before {
content: "\e029";
}
.glyphicon-repeat:before {
content: "\e030";
}
.glyphicon-refresh:before {
content: "\e031";
}
.glyphicon-list-alt:before {
content: "\e032";
}
.glyphicon-lock:before {
content: "\e033";
}
.glyphicon-flag:before {
content: "\e034";
}
.glyphicon-headphones:before {
content: "\e035";
}
.glyphicon-volume-off:before {
content: "\e036";
}
.glyphicon-volume-down:before {
content: "\e037";
}
.glyphicon-volume-up:before {
content: "\e038";
}
.glyphicon-qrcode:before {
content: "\e039";
}
.glyphicon-barcode:before {
content: "\e040";
}
.glyphicon-tag:before {
content: "\e041";
}
.glyphicon-tags:before {
content: "\e042";
}
.glyphicon-book:before {
content: "\e043";
}
.glyphicon-bookmark:before {
content: "\e044";
}
.glyphicon-print:before {
content: "\e045";
}
.glyphicon-camera:before {
content: "\e046";
}
.glyphicon-font:before {
content: "\e047";
}
.glyphicon-bold:before {
content: "\e048";
}
.glyphicon-italic:before {
content: "\e049";
}
.glyphicon-text-height:before {
content: "\e050";
}
.glyphicon-text-width:before {
content: "\e051";
}
.glyphicon-align-left:before {
content: "\e052";
}
.glyphicon-align-center:before {
content: "\e053";
}
.glyphicon-align-right:before {
content: "\e054";
}
.glyphicon-align-justify:before {
content: "\e055";
}
.glyphicon-list:before {
content: "\e056";
}
.glyphicon-indent-left:before {
content: "\e057";
}
.glyphicon-indent-right:before {
content: "\e058";
}
.glyphicon-facetime-video:before {
content: "\e059";
}
.glyphicon-picture:before {
content: "\e060";
}
.glyphicon-map-marker:before {
content: "\e062";
}
.glyphicon-adjust:before {
content: "\e063";
}
.glyphicon-tint:before {
content: "\e064";
}
.glyphicon-edit:before {
content: "\e065";
}
.glyphicon-share:before {
content: "\e066";
}
.glyphicon-check:before {
content: "\e067";
}
.glyphicon-move:before {
content: "\e068";
}
.glyphicon-step-backward:before {
content: "\e069";
}
.glyphicon-fast-backward:before {
content: "\e070";
}
.glyphicon-backward:before {
content: "\e071";
}
.glyphicon-play:before {
content: "\e072";
}
.glyphicon-pause:before {
content: "\e073";
}
.glyphicon-stop:before {
content: "\e074";
}
.glyphicon-forward:before {
content: "\e075";
}
.glyphicon-fast-forward:before {
content: "\e076";
}
.glyphicon-step-forward:before {
content: "\e077";
}
.glyphicon-eject:before {
content: "\e078";
}
.glyphicon-chevron-left:before {
content: "\e079";
}
.glyphicon-chevron-right:before {
content: "\e080";
}
.glyphicon-plus-sign:before {
content: "\e081";
}
.glyphicon-minus-sign:before {
content: "\e082";
}
.glyphicon-remove-sign:before {
content: "\e083";
}
.glyphicon-ok-sign:before {
content: "\e084";
}
.glyphicon-question-sign:before {
content: "\e085";
}
.glyphicon-info-sign:before {
content: "\e086";
}
.glyphicon-screenshot:before {
content: "\e087";
}
.glyphicon-remove-circle:before {
content: "\e088";
}
.glyphicon-ok-circle:before {
content: "\e089";
}
.glyphicon-ban-circle:before {
content: "\e090";
}
.glyphicon-arrow-left:before {
content: "\e091";
}
.glyphicon-arrow-right:before {
content: "\e092";
}
.glyphicon-arrow-up:before {
content: "\e093";
}
.glyphicon-arrow-down:before {
content: "\e094";
}
.glyphicon-share-alt:before {
content: "\e095";
}
.glyphicon-resize-full:before {
content: "\e096";
}
.glyphicon-resize-small:before {
content: "\e097";
}
.glyphicon-exclamation-sign:before {
content: "\e101";
}
.glyphicon-gift:before {
content: "\e102";
}
.glyphicon-leaf:before {
content: "\e103";
}
.glyphicon-fire:before {
content: "\e104";
}
.glyphicon-eye-open:before {
content: "\e105";
}
.glyphicon-eye-close:before {
content: "\e106";
}
.glyphicon-warning-sign:before {
content: "\e107";
}
.glyphicon-plane:before {
content: "\e108";
}
.glyphicon-calendar:before {
content: "\e109";
}
.glyphicon-random:before {
content: "\e110";
}
.glyphicon-comment:before {
content: "\e111";
}
.glyphicon-magnet:before {
content: "\e112";
}
.glyphicon-chevron-up:before {
content: "\e113";
}
.glyphicon-chevron-down:before {
content: "\e114";
}
.glyphicon-retweet:before {
content: "\e115";
}
.glyphicon-shopping-cart:before {
content: "\e116";
}
.glyphicon-folder-close:before {
content: "\e117";
}
.glyphicon-folder-open:before {
content: "\e118";
}
.glyphicon-resize-vertical:before {
content: "\e119";
}
.glyphicon-resize-horizontal:before {
content: "\e120";
}
.glyphicon-hdd:before {
content: "\e121";
}
.glyphicon-bullhorn:before {
content: "\e122";
}
.glyphicon-bell:before {
content: "\e123";
}
.glyphicon-certificate:before {
content: "\e124";
}
.glyphicon-thumbs-up:before {
content: "\e125";
}
.glyphicon-thumbs-down:before {
content: "\e126";
}
.glyphicon-hand-right:before {
content: "\e127";
}
.glyphicon-hand-left:before {
content: "\e128";
}
.glyphicon-hand-up:before {
content: "\e129";
}
.glyphicon-hand-down:before {
content: "\e130";
}
.glyphicon-circle-arrow-right:before {
content: "\e131";
}
.glyphicon-circle-arrow-left:before {
content: "\e132";
}
.glyphicon-circle-arrow-up:before {
content: "\e133";
}
.glyphicon-circle-arrow-down:before {
content: "\e134";
}
.glyphicon-globe:before {
content: "\e135";
}
.glyphicon-wrench:before {
content: "\e136";
}
.glyphicon-tasks:before {
content: "\e137";
}
.glyphicon-filter:before {
content: "\e138";
}
.glyphicon-briefcase:before {
content: "\e139";
}
.glyphicon-fullscreen:before {
content: "\e140";
}
.glyphicon-dashboard:before {
content: "\e141";
}
.glyphicon-paperclip:before {
content: "\e142";
}
.glyphicon-heart-empty:before {
content: "\e143";
}
.glyphicon-link:before {
content: "\e144";
}
.glyphicon-phone:before {
content: "\e145";
}
.glyphicon-pushpin:before {
content: "\e146";
}
.glyphicon-usd:before {
content: "\e148";
}
.glyphicon-gbp:before {
content: "\e149";
}
.glyphicon-sort:before {
content: "\e150";
}
.glyphicon-sort-by-alphabet:before {
content: "\e151";
}
.glyphicon-sort-by-alphabet-alt:before {
content: "\e152";
}
.glyphicon-sort-by-order:before {
content: "\e153";
}
.glyphicon-sort-by-order-alt:before {
content: "\e154";
}
.glyphicon-sort-by-attributes:before {
content: "\e155";
}
.glyphicon-sort-by-attributes-alt:before {
content: "\e156";
}
.glyphicon-unchecked:before {
content: "\e157";
}
.glyphicon-expand:before {
content: "\e158";
}
.glyphicon-collapse-down:before {
content: "\e159";
}
.glyphicon-collapse-up:before {
content: "\e160";
}
.glyphicon-log-in:before {
content: "\e161";
}
.glyphicon-flash:before {
content: "\e162";
}
.glyphicon-log-out:before {
content: "\e163";
}
.glyphicon-new-window:before {
content: "\e164";
}
.glyphicon-record:before {
content: "\e165";
}
.glyphicon-save:before {
content: "\e166";
}
.glyphicon-open:before {
content: "\e167";
}
.glyphicon-saved:before {
content: "\e168";
}
.glyphicon-import:before {
content: "\e169";
}
.glyphicon-export:before {
content: "\e170";
}
.glyphicon-send:before {
content: "\e171";
}
.glyphicon-floppy-disk:before {
content: "\e172";
}
.glyphicon-floppy-saved:before {
content: "\e173";
}
.glyphicon-floppy-remove:before {
content: "\e174";
}
.glyphicon-floppy-save:before {
content: "\e175";
}
.glyphicon-floppy-open:before {
content: "\e176";
}
.glyphicon-credit-card:before {
content: "\e177";
}
.glyphicon-transfer:before {
content: "\e178";
}
.glyphicon-cutlery:before {
content: "\e179";
}
.glyphicon-header:before {
content: "\e180";
}
.glyphicon-compressed:before {
content: "\e181";
}
.glyphicon-earphone:before {
content: "\e182";
}
.glyphicon-phone-alt:before {
content: "\e183";
}
.glyphicon-tower:before {
content: "\e184";
}
.glyphicon-stats:before {
content: "\e185";
}
.glyphicon-sd-video:before {
content: "\e186";
}
.glyphicon-hd-video:before {
content: "\e187";
}
.glyphicon-subtitles:before {
content: "\e188";
}
.glyphicon-sound-stereo:before {
content: "\e189";
}
.glyphicon-sound-dolby:before {
content: "\e190";
}
.glyphicon-sound-5-1:before {
content: "\e191";
}
.glyphicon-sound-6-1:before {
content: "\e192";
}
.glyphicon-sound-7-1:before {
content: "\e193";
}
.glyphicon-copyright-mark:before {
content: "\e194";
}
.glyphicon-registration-mark:before {
content: "\e195";
}
.glyphicon-cloud-download:before {
content: "\e197";
}
.glyphicon-cloud-upload:before {
content: "\e198";
}
.glyphicon-tree-conifer:before {
content: "\e199";
}
.glyphicon-tree-deciduous:before {
content: "\e200";
}
.glyphicon-cd:before {
content: "\e201";
}
.glyphicon-save-file:before {
content: "\e202";
}
.glyphicon-open-file:before {
content: "\e203";
}
.glyphicon-level-up:before {
content: "\e204";
}
.glyphicon-copy:before {
content: "\e205";
}
.glyphicon-paste:before {
content: "\e206";
}
.glyphicon-alert:before {
content: "\e209";
}
.glyphicon-equalizer:before {
content: "\e210";
}
.glyphicon-king:before {
content: "\e211";
}
.glyphicon-queen:before {
content: "\e212";
}
.glyphicon-pawn:before {
content: "\e213";
}
.glyphicon-bishop:before {
content: "\e214";
}
.glyphicon-knight:before {
content: "\e215";
}
.glyphicon-baby-formula:before {
content: "\e216";
}
.glyphicon-tent:before {
content: "\26fa";
}
.glyphicon-blackboard:before {
content: "\e218";
}
.glyphicon-bed:before {
content: "\e219";
}
.glyphicon-apple:before {
content: "\f8ff";
}
.glyphicon-erase:before {
content: "\e221";
}
.glyphicon-hourglass:before {
content: "\231b";
}
.glyphicon-lamp:before {
content: "\e223";
}
.glyphicon-duplicate:before {
content: "\e224";
}
.glyphicon-piggy-bank:before {
content: "\e225";
}
.glyphicon-scissors:before {
content: "\e226";
}
.glyphicon-bitcoin:before {
content: "\e227";
}
.glyphicon-btc:before {
content: "\e227";
}
.glyphicon-xbt:before {
content: "\e227";
}
.glyphicon-yen:before {
content: "\00a5";
}
.glyphicon-jpy:before {
content: "\00a5";
}
.glyphicon-ruble:before {
content: "\20bd";
}
.glyphicon-rub:before {
content: "\20bd";
}
.glyphicon-scale:before {
content: "\e230";
}
.glyphicon-ice-lolly:before {
content: "\e231";
}
.glyphicon-ice-lolly-tasted:before {
content: "\e232";
}
.glyphicon-education:before {
content: "\e233";
}
.glyphicon-option-horizontal:before {
content: "\e234";
}
.glyphicon-option-vertical:before {
content: "\e235";
}
.glyphicon-menu-hamburger:before {
content: "\e236";
}
.glyphicon-modal-window:before {
content: "\e237";
}
.glyphicon-oil:before {
content: "\e238";
}
.glyphicon-grain:before {
content: "\e239";
}
.glyphicon-sunglasses:before {
content: "\e240";
}
.glyphicon-text-size:before {
content: "\e241";
}
.glyphicon-text-color:before {
content: "\e242";
}
.glyphicon-text-background:before {
content: "\e243";
}
.glyphicon-object-align-top:before {
content: "\e244";
}
.glyphicon-object-align-bottom:before {
content: "\e245";
}
.glyphicon-object-align-horizontal:before {
content: "\e246";
}
.glyphicon-object-align-left:before {
content: "\e247";
}
.glyphicon-object-align-vertical:before {
content: "\e248";
}
.glyphicon-object-align-right:before {
content: "\e249";
}
.glyphicon-triangle-right:before {
content: "\e250";
}
.glyphicon-triangle-left:before {
content: "\e251";
}
.glyphicon-triangle-bottom:before {
content: "\e252";
}
.glyphicon-triangle-top:before {
content: "\e253";
}
.glyphicon-console:before {
content: "\e254";
}
.glyphicon-superscript:before {
content: "\e255";
}
.glyphicon-subscript:before {
content: "\e256";
}
.glyphicon-menu-left:before {
content: "\e257";
}
.glyphicon-menu-right:before {
content: "\e258";
}
.glyphicon-menu-down:before {
content: "\e259";
}
.glyphicon-menu-up:before {
content: "\e260";
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-size: 10px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 1.42857143;
color: #000;
background-color: #fff;
}
input,
button,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
a {
color: #337ab7;
text-decoration: none;
}
a:hover,
a:focus {
color: #23527c;
text-decoration: underline;
}
a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
figure {
margin: 0;
}
img {
vertical-align: middle;
}
.img-responsive,
.thumbnail > img,
.thumbnail a > img,
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
display: block;
max-width: 100%;
height: auto;
}
.img-rounded {
border-radius: 3px;
}
.img-thumbnail {
padding: 4px;
line-height: 1.42857143;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 2px;
-webkit-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
display: inline-block;
max-width: 100%;
height: auto;
}
.img-circle {
border-radius: 50%;
}
hr {
margin-top: 18px;
margin-bottom: 18px;
border: 0;
border-top: 1px solid #eeeeee;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
[role="button"] {
cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
font-family: inherit;
font-weight: 500;
line-height: 1.1;
color: inherit;
}
h1 small,
h2 small,
h3 small,
h4 small,
h5 small,
h6 small,
.h1 small,
.h2 small,
.h3 small,
.h4 small,
.h5 small,
.h6 small,
h1 .small,
h2 .small,
h3 .small,
h4 .small,
h5 .small,
h6 .small,
.h1 .small,
.h2 .small,
.h3 .small,
.h4 .small,
.h5 .small,
.h6 .small {
font-weight: normal;
line-height: 1;
color: #777777;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
margin-top: 18px;
margin-bottom: 9px;
}
h1 small,
.h1 small,
h2 small,
.h2 small,
h3 small,
.h3 small,
h1 .small,
.h1 .small,
h2 .small,
.h2 .small,
h3 .small,
.h3 .small {
font-size: 65%;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 9px;
margin-bottom: 9px;
}
h4 small,
.h4 small,
h5 small,
.h5 small,
h6 small,
.h6 small,
h4 .small,
.h4 .small,
h5 .small,
.h5 .small,
h6 .small,
.h6 .small {
font-size: 75%;
}
h1,
.h1 {
font-size: 33px;
}
h2,
.h2 {
font-size: 27px;
}
h3,
.h3 {
font-size: 23px;
}
h4,
.h4 {
font-size: 17px;
}
h5,
.h5 {
font-size: 13px;
}
h6,
.h6 {
font-size: 12px;
}
p {
margin: 0 0 9px;
}
.lead {
margin-bottom: 18px;
font-size: 14px;
font-weight: 300;
line-height: 1.4;
}
@media (min-width: 768px) {
.lead {
font-size: 19.5px;
}
}
small,
.small {
font-size: 92%;
}
mark,
.mark {
background-color: #fcf8e3;
padding: .2em;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.text-justify {
text-align: justify;
}
.text-nowrap {
white-space: nowrap;
}
.text-lowercase {
text-transform: lowercase;
}
.text-uppercase {
text-transform: uppercase;
}
.text-capitalize {
text-transform: capitalize;
}
.text-muted {
color: #777777;
}
.text-primary {
color: #337ab7;
}
a.text-primary:hover,
a.text-primary:focus {
color: #286090;
}
.text-success {
color: #3c763d;
}
a.text-success:hover,
a.text-success:focus {
color: #2b542c;
}
.text-info {
color: #31708f;
}
a.text-info:hover,
a.text-info:focus {
color: #245269;
}
.text-warning {
color: #8a6d3b;
}
a.text-warning:hover,
a.text-warning:focus {
color: #66512c;
}
.text-danger {
color: #a94442;
}
a.text-danger:hover,
a.text-danger:focus {
color: #843534;
}
.bg-primary {
color: #fff;
background-color: #337ab7;
}
a.bg-primary:hover,
a.bg-primary:focus {
background-color: #286090;
}
.bg-success {
background-color: #dff0d8;
}
a.bg-success:hover,
a.bg-success:focus {
background-color: #c1e2b3;
}
.bg-info {
background-color: #d9edf7;
}
a.bg-info:hover,
a.bg-info:focus {
background-color: #afd9ee;
}
.bg-warning {
background-color: #fcf8e3;
}
a.bg-warning:hover,
a.bg-warning:focus {
background-color: #f7ecb5;
}
.bg-danger {
background-color: #f2dede;
}
a.bg-danger:hover,
a.bg-danger:focus {
background-color: #e4b9b9;
}
.page-header {
padding-bottom: 8px;
margin: 36px 0 18px;
border-bottom: 1px solid #eeeeee;
}
ul,
ol {
margin-top: 0;
margin-bottom: 9px;
}
ul ul,
ol ul,
ul ol,
ol ol {
margin-bottom: 0;
}
.list-unstyled {
padding-left: 0;
list-style: none;
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.list-inline > li {
display: inline-block;
padding-left: 5px;
padding-right: 5px;
}
dl {
margin-top: 0;
margin-bottom: 18px;
}
dt,
dd {
line-height: 1.42857143;
}
dt {
font-weight: bold;
}
dd {
margin-left: 0;
}
@media (min-width: 541px) {
.dl-horizontal dt {
float: left;
width: 160px;
clear: left;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dl-horizontal dd {
margin-left: 180px;
}
}
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #777777;
}
.initialism {
font-size: 90%;
text-transform: uppercase;
}
blockquote {
padding: 9px 18px;
margin: 0 0 18px;
font-size: inherit;
border-left: 5px solid #eeeeee;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
margin-bottom: 0;
}
blockquote footer,
blockquote small,
blockquote .small {
display: block;
font-size: 80%;
line-height: 1.42857143;
color: #777777;
}
blockquote footer:before,
blockquote small:before,
blockquote .small:before {
content: '\2014 \00A0';
}
.blockquote-reverse,
blockquote.pull-right {
padding-right: 15px;
padding-left: 0;
border-right: 5px solid #eeeeee;
border-left: 0;
text-align: right;
}
.blockquote-reverse footer:before,
blockquote.pull-right footer:before,
.blockquote-reverse small:before,
blockquote.pull-right small:before,
.blockquote-reverse .small:before,
blockquote.pull-right .small:before {
content: '';
}
.blockquote-reverse footer:after,
blockquote.pull-right footer:after,
.blockquote-reverse small:after,
blockquote.pull-right small:after,
.blockquote-reverse .small:after,
blockquote.pull-right .small:after {
content: '\00A0 \2014';
}
address {
margin-bottom: 18px;
font-style: normal;
line-height: 1.42857143;
}
code,
kbd,
pre,
samp {
font-family: monospace;
}
code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
border-radius: 2px;
}
kbd {
padding: 2px 4px;
font-size: 90%;
color: #888;
background-color: transparent;
border-radius: 1px;
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
}
kbd kbd {
padding: 0;
font-size: 100%;
font-weight: bold;
box-shadow: none;
}
pre {
display: block;
padding: 8.5px;
margin: 0 0 9px;
font-size: 12px;
line-height: 1.42857143;
word-break: break-all;
word-wrap: break-word;
color: #333333;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 2px;
}
pre code {
padding: 0;
font-size: inherit;
color: inherit;
white-space: pre-wrap;
background-color: transparent;
border-radius: 0;
}
.pre-scrollable {
max-height: 340px;
overflow-y: scroll;
}
.container {
margin-right: auto;
margin-left: auto;
padding-left: 0px;
padding-right: 0px;
}
@media (min-width: 768px) {
.container {
width: 768px;
}
}
@media (min-width: 992px) {
.container {
width: 940px;
}
}
@media (min-width: 1200px) {
.container {
width: 1140px;
}
}
.container-fluid {
margin-right: auto;
margin-left: auto;
padding-left: 0px;
padding-right: 0px;
}
.row {
margin-left: 0px;
margin-right: 0px;
}
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
min-height: 1px;
padding-left: 0px;
padding-right: 0px;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
float: left;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
.col-xs-pull-12 {
right: 100%;
}
.col-xs-pull-11 {
right: 91.66666667%;
}
.col-xs-pull-10 {
right: 83.33333333%;
}
.col-xs-pull-9 {
right: 75%;
}
.col-xs-pull-8 {
right: 66.66666667%;
}
.col-xs-pull-7 {
right: 58.33333333%;
}
.col-xs-pull-6 {
right: 50%;
}
.col-xs-pull-5 {
right: 41.66666667%;
}
.col-xs-pull-4 {
right: 33.33333333%;
}
.col-xs-pull-3 {
right: 25%;
}
.col-xs-pull-2 {
right: 16.66666667%;
}
.col-xs-pull-1 {
right: 8.33333333%;
}
.col-xs-pull-0 {
right: auto;
}
.col-xs-push-12 {
left: 100%;
}
.col-xs-push-11 {
left: 91.66666667%;
}
.col-xs-push-10 {
left: 83.33333333%;
}
.col-xs-push-9 {
left: 75%;
}
.col-xs-push-8 {
left: 66.66666667%;
}
.col-xs-push-7 {
left: 58.33333333%;
}
.col-xs-push-6 {
left: 50%;
}
.col-xs-push-5 {
left: 41.66666667%;
}
.col-xs-push-4 {
left: 33.33333333%;
}
.col-xs-push-3 {
left: 25%;
}
.col-xs-push-2 {
left: 16.66666667%;
}
.col-xs-push-1 {
left: 8.33333333%;
}
.col-xs-push-0 {
left: auto;
}
.col-xs-offset-12 {
margin-left: 100%;
}
.col-xs-offset-11 {
margin-left: 91.66666667%;
}
.col-xs-offset-10 {
margin-left: 83.33333333%;
}
.col-xs-offset-9 {
margin-left: 75%;
}
.col-xs-offset-8 {
margin-left: 66.66666667%;
}
.col-xs-offset-7 {
margin-left: 58.33333333%;
}
.col-xs-offset-6 {
margin-left: 50%;
}
.col-xs-offset-5 {
margin-left: 41.66666667%;
}
.col-xs-offset-4 {
margin-left: 33.33333333%;
}
.col-xs-offset-3 {
margin-left: 25%;
}
.col-xs-offset-2 {
margin-left: 16.66666667%;
}
.col-xs-offset-1 {
margin-left: 8.33333333%;
}
.col-xs-offset-0 {
margin-left: 0%;
}
@media (min-width: 768px) {
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
float: left;
}
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-8 {
width: 66.66666667%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-2 {
width: 16.66666667%;
}
.col-sm-1 {
width: 8.33333333%;
}
.col-sm-pull-12 {
right: 100%;
}
.col-sm-pull-11 {
right: 91.66666667%;
}
.col-sm-pull-10 {
right: 83.33333333%;
}
.col-sm-pull-9 {
right: 75%;
}
.col-sm-pull-8 {
right: 66.66666667%;
}
.col-sm-pull-7 {
right: 58.33333333%;
}
.col-sm-pull-6 {
right: 50%;
}
.col-sm-pull-5 {
right: 41.66666667%;
}
.col-sm-pull-4 {
right: 33.33333333%;
}
.col-sm-pull-3 {
right: 25%;
}
.col-sm-pull-2 {
right: 16.66666667%;
}
.col-sm-pull-1 {
right: 8.33333333%;
}
.col-sm-pull-0 {
right: auto;
}
.col-sm-push-12 {
left: 100%;
}
.col-sm-push-11 {
left: 91.66666667%;
}
.col-sm-push-10 {
left: 83.33333333%;
}
.col-sm-push-9 {
left: 75%;
}
.col-sm-push-8 {
left: 66.66666667%;
}
.col-sm-push-7 {
left: 58.33333333%;
}
.col-sm-push-6 {
left: 50%;
}
.col-sm-push-5 {
left: 41.66666667%;
}
.col-sm-push-4 {
left: 33.33333333%;
}
.col-sm-push-3 {
left: 25%;
}
.col-sm-push-2 {
left: 16.66666667%;
}
.col-sm-push-1 {
left: 8.33333333%;
}
.col-sm-push-0 {
left: auto;
}
.col-sm-offset-12 {
margin-left: 100%;
}
.col-sm-offset-11 {
margin-left: 91.66666667%;
}
.col-sm-offset-10 {
margin-left: 83.33333333%;
}
.col-sm-offset-9 {
margin-left: 75%;
}
.col-sm-offset-8 {
margin-left: 66.66666667%;
}
.col-sm-offset-7 {
margin-left: 58.33333333%;
}
.col-sm-offset-6 {
margin-left: 50%;
}
.col-sm-offset-5 {
margin-left: 41.66666667%;
}
.col-sm-offset-4 {
margin-left: 33.33333333%;
}
.col-sm-offset-3 {
margin-left: 25%;
}
.col-sm-offset-2 {
margin-left: 16.66666667%;
}
.col-sm-offset-1 {
margin-left: 8.33333333%;
}
.col-sm-offset-0 {
margin-left: 0%;
}
}
@media (min-width: 992px) {
.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
float: left;
}
.col-md-12 {
width: 100%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-9 {
width: 75%;
}
.col-md-8 {
width: 66.66666667%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-6 {
width: 50%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-3 {
width: 25%;
}
.col-md-2 {
width: 16.66666667%;
}
.col-md-1 {
width: 8.33333333%;
}
.col-md-pull-12 {
right: 100%;
}
.col-md-pull-11 {
right: 91.66666667%;
}
.col-md-pull-10 {
right: 83.33333333%;
}
.col-md-pull-9 {
right: 75%;
}
.col-md-pull-8 {
right: 66.66666667%;
}
.col-md-pull-7 {
right: 58.33333333%;
}
.col-md-pull-6 {
right: 50%;
}
.col-md-pull-5 {
right: 41.66666667%;
}
.col-md-pull-4 {
right: 33.33333333%;
}
.col-md-pull-3 {
right: 25%;
}
.col-md-pull-2 {
right: 16.66666667%;
}
.col-md-pull-1 {
right: 8.33333333%;
}
.col-md-pull-0 {
right: auto;
}
.col-md-push-12 {
left: 100%;
}
.col-md-push-11 {
left: 91.66666667%;
}
.col-md-push-10 {
left: 83.33333333%;
}
.col-md-push-9 {
left: 75%;
}
.col-md-push-8 {
left: 66.66666667%;
}
.col-md-push-7 {
left: 58.33333333%;
}
.col-md-push-6 {
left: 50%;
}
.col-md-push-5 {
left: 41.66666667%;
}
.col-md-push-4 {
left: 33.33333333%;
}
.col-md-push-3 {
left: 25%;
}
.col-md-push-2 {
left: 16.66666667%;
}
.col-md-push-1 {
left: 8.33333333%;
}
.col-md-push-0 {
left: auto;
}
.col-md-offset-12 {
margin-left: 100%;
}
.col-md-offset-11 {
margin-left: 91.66666667%;
}
.col-md-offset-10 {
margin-left: 83.33333333%;
}
.col-md-offset-9 {
margin-left: 75%;
}
.col-md-offset-8 {
margin-left: 66.66666667%;
}
.col-md-offset-7 {
margin-left: 58.33333333%;
}
.col-md-offset-6 {
margin-left: 50%;
}
.col-md-offset-5 {
margin-left: 41.66666667%;
}
.col-md-offset-4 {
margin-left: 33.33333333%;
}
.col-md-offset-3 {
margin-left: 25%;
}
.col-md-offset-2 {
margin-left: 16.66666667%;
}
.col-md-offset-1 {
margin-left: 8.33333333%;
}
.col-md-offset-0 {
margin-left: 0%;
}
}
@media (min-width: 1200px) {
.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
float: left;
}
.col-lg-12 {
width: 100%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-8 {
width: 66.66666667%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-2 {
width: 16.66666667%;
}
.col-lg-1 {
width: 8.33333333%;
}
.col-lg-pull-12 {
right: 100%;
}
.col-lg-pull-11 {
right: 91.66666667%;
}
.col-lg-pull-10 {
right: 83.33333333%;
}
.col-lg-pull-9 {
right: 75%;
}
.col-lg-pull-8 {
right: 66.66666667%;
}
.col-lg-pull-7 {
right: 58.33333333%;
}
.col-lg-pull-6 {
right: 50%;
}
.col-lg-pull-5 {
right: 41.66666667%;
}
.col-lg-pull-4 {
right: 33.33333333%;
}
.col-lg-pull-3 {
right: 25%;
}
.col-lg-pull-2 {
right: 16.66666667%;
}
.col-lg-pull-1 {
right: 8.33333333%;
}
.col-lg-pull-0 {
right: auto;
}
.col-lg-push-12 {
left: 100%;
}
.col-lg-push-11 {
left: 91.66666667%;
}
.col-lg-push-10 {
left: 83.33333333%;
}
.col-lg-push-9 {
left: 75%;
}
.col-lg-push-8 {
left: 66.66666667%;
}
.col-lg-push-7 {
left: 58.33333333%;
}
.col-lg-push-6 {
left: 50%;
}
.col-lg-push-5 {
left: 41.66666667%;
}
.col-lg-push-4 {
left: 33.33333333%;
}
.col-lg-push-3 {
left: 25%;
}
.col-lg-push-2 {
left: 16.66666667%;
}
.col-lg-push-1 {
left: 8.33333333%;
}
.col-lg-push-0 {
left: auto;
}
.col-lg-offset-12 {
margin-left: 100%;
}
.col-lg-offset-11 {
margin-left: 91.66666667%;
}
.col-lg-offset-10 {
margin-left: 83.33333333%;
}
.col-lg-offset-9 {
margin-left: 75%;
}
.col-lg-offset-8 {
margin-left: 66.66666667%;
}
.col-lg-offset-7 {
margin-left: 58.33333333%;
}
.col-lg-offset-6 {
margin-left: 50%;
}
.col-lg-offset-5 {
margin-left: 41.66666667%;
}
.col-lg-offset-4 {
margin-left: 33.33333333%;
}
.col-lg-offset-3 {
margin-left: 25%;
}
.col-lg-offset-2 {
margin-left: 16.66666667%;
}
.col-lg-offset-1 {
margin-left: 8.33333333%;
}
.col-lg-offset-0 {
margin-left: 0%;
}
}
table {
background-color: transparent;
}
caption {
padding-top: 8px;
padding-bottom: 8px;
color: #777777;
text-align: left;
}
th {
text-align: left;
}
.table {
width: 100%;
max-width: 100%;
margin-bottom: 18px;
}
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
.table > thead > tr > th {
vertical-align: bottom;
border-bottom: 2px solid #ddd;
}
.table > caption + thead > tr:first-child > th,
.table > colgroup + thead > tr:first-child > th,
.table > thead:first-child > tr:first-child > th,
.table > caption + thead > tr:first-child > td,
.table > colgroup + thead > tr:first-child > td,
.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 > thead > tr > th,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > td {
padding: 5px;
}
.table-bordered {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
border-bottom-width: 2px;
}
.table-striped > tbody > tr:nth-of-type(odd) {
background-color: #f9f9f9;
}
.table-hover > tbody > tr:hover {
background-color: #f5f5f5;
}
table col[class*="col-"] {
position: static;
float: none;
display: table-column;
}
table td[class*="col-"],
table th[class*="col-"] {
position: static;
float: none;
display: table-cell;
}
.table > thead > tr > td.active,
.table > tbody > tr > td.active,
.table > tfoot > tr > td.active,
.table > thead > tr > th.active,
.table > tbody > tr > th.active,
.table > tfoot > tr > th.active,
.table > thead > tr.active > td,
.table > tbody > tr.active > td,
.table > tfoot > tr.active > td,
.table > thead > tr.active > th,
.table > tbody > tr.active > th,
.table > tfoot > tr.active > th {
background-color: #f5f5f5;
}
.table-hover > tbody > tr > td.active:hover,
.table-hover > tbody > tr > th.active:hover,
.table-hover > tbody > tr.active:hover > td,
.table-hover > tbody > tr:hover > .active,
.table-hover > tbody > tr.active:hover > th {
background-color: #e8e8e8;
}
.table > thead > tr > td.success,
.table > tbody > tr > td.success,
.table > tfoot > tr > td.success,
.table > thead > tr > th.success,
.table > tbody > tr > th.success,
.table > tfoot > tr > th.success,
.table > thead > tr.success > td,
.table > tbody > tr.success > td,
.table > tfoot > tr.success > td,
.table > thead > tr.success > th,
.table > tbody > tr.success > th,
.table > tfoot > tr.success > th {
background-color: #dff0d8;
}
.table-hover > tbody > tr > td.success:hover,
.table-hover > tbody > tr > th.success:hover,
.table-hover > tbody > tr.success:hover > td,
.table-hover > tbody > tr:hover > .success,
.table-hover > tbody > tr.success:hover > th {
background-color: #d0e9c6;
}
.table > thead > tr > td.info,
.table > tbody > tr > td.info,
.table > tfoot > tr > td.info,
.table > thead > tr > th.info,
.table > tbody > tr > th.info,
.table > tfoot > tr > th.info,
.table > thead > tr.info > td,
.table > tbody > tr.info > td,
.table > tfoot > tr.info > td,
.table > thead > tr.info > th,
.table > tbody > tr.info > th,
.table > tfoot > tr.info > th {
background-color: #d9edf7;
}
.table-hover > tbody > tr > td.info:hover,
.table-hover > tbody > tr > th.info:hover,
.table-hover > tbody > tr.info:hover > td,
.table-hover > tbody > tr:hover > .info,
.table-hover > tbody > tr.info:hover > th {
background-color: #c4e3f3;
}
.table > thead > tr > td.warning,
.table > tbody > tr > td.warning,
.table > tfoot > tr > td.warning,
.table > thead > tr > th.warning,
.table > tbody > tr > th.warning,
.table > tfoot > tr > th.warning,
.table > thead > tr.warning > td,
.table > tbody > tr.warning > td,
.table > tfoot > tr.warning > td,
.table > thead > tr.warning > th,
.table > tbody > tr.warning > th,
.table > tfoot > tr.warning > th {
background-color: #fcf8e3;
}
.table-hover > tbody > tr > td.warning:hover,
.table-hover > tbody > tr > th.warning:hover,
.table-hover > tbody > tr.warning:hover > td,
.table-hover > tbody > tr:hover > .warning,
.table-hover > tbody > tr.warning:hover > th {
background-color: #faf2cc;
}
.table > thead > tr > td.danger,
.table > tbody > tr > td.danger,
.table > tfoot > tr > td.danger,
.table > thead > tr > th.danger,
.table > tbody > tr > th.danger,
.table > tfoot > tr > th.danger,
.table > thead > tr.danger > td,
.table > tbody > tr.danger > td,
.table > tfoot > tr.danger > td,
.table > thead > tr.danger > th,
.table > tbody > tr.danger > th,
.table > tfoot > tr.danger > th {
background-color: #f2dede;
}
.table-hover > tbody > tr > td.danger:hover,
.table-hover > tbody > tr > th.danger:hover,
.table-hover > tbody > tr.danger:hover > td,
.table-hover > tbody > tr:hover > .danger,
.table-hover > tbody > tr.danger:hover > th {
background-color: #ebcccc;
}
.table-responsive {
overflow-x: auto;
min-height: 0.01%;
}
@media screen and (max-width: 767px) {
.table-responsive {
width: 100%;
margin-bottom: 13.5px;
overflow-y: hidden;
-ms-overflow-style: -ms-autohiding-scrollbar;
border: 1px solid #ddd;
}
.table-responsive > .table {
margin-bottom: 0;
}
.table-responsive > .table > thead > tr > th,
.table-responsive > .table > tbody > tr > th,
.table-responsive > .table > tfoot > tr > th,
.table-responsive > .table > thead > tr > td,
.table-responsive > .table > tbody > tr > td,
.table-responsive > .table > tfoot > tr > td {
white-space: nowrap;
}
.table-responsive > .table-bordered {
border: 0;
}
.table-responsive > .table-bordered > thead > tr > th:first-child,
.table-responsive > .table-bordered > tbody > tr > th:first-child,
.table-responsive > .table-bordered > tfoot > tr > th:first-child,
.table-responsive > .table-bordered > thead > tr > td:first-child,
.table-responsive > .table-bordered > tbody > tr > td:first-child,
.table-responsive > .table-bordered > tfoot > tr > td:first-child {
border-left: 0;
}
.table-responsive > .table-bordered > thead > tr > th:last-child,
.table-responsive > .table-bordered > tbody > tr > th:last-child,
.table-responsive > .table-bordered > tfoot > tr > th:last-child,
.table-responsive > .table-bordered > thead > tr > td:last-child,
.table-responsive > .table-bordered > tbody > tr > td:last-child,
.table-responsive > .table-bordered > tfoot > tr > td:last-child {
border-right: 0;
}
.table-responsive > .table-bordered > tbody > tr:last-child > th,
.table-responsive > .table-bordered > tfoot > tr:last-child > th,
.table-responsive > .table-bordered > tbody > tr:last-child > td,
.table-responsive > .table-bordered > tfoot > tr:last-child > td {
border-bottom: 0;
}
}
fieldset {
padding: 0;
margin: 0;
border: 0;
min-width: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: 18px;
font-size: 19.5px;
line-height: inherit;
color: #333333;
border: 0;
border-bottom: 1px solid #e5e5e5;
}
label {
display: inline-block;
max-width: 100%;
margin-bottom: 5px;
font-weight: bold;
}
input[type="search"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
input[type="radio"],
input[type="checkbox"] {
margin: 4px 0 0;
margin-top: 1px \9;
line-height: normal;
}
input[type="file"] {
display: block;
}
input[type="range"] {
display: block;
width: 100%;
}
select[multiple],
select[size] {
height: auto;
}
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
output {
display: block;
padding-top: 7px;
font-size: 13px;
line-height: 1.42857143;
color: #555555;
}
.form-control {
display: block;
width: 100%;
height: 32px;
padding: 6px 12px;
font-size: 13px;
line-height: 1.42857143;
color: #555555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 2px;
-webkit-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-color ease-in-out .15s, box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.form-control::-moz-placeholder {
color: #999;
opacity: 1;
}
.form-control:-ms-input-placeholder {
color: #999;
}
.form-control::-webkit-input-placeholder {
color: #999;
}
.form-control::-ms-expand {
border: 0;
background-color: transparent;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
background-color: #eeeeee;
opacity: 1;
}
.form-control[disabled],
fieldset[disabled] .form-control {
cursor: not-allowed;
}
textarea.form-control {
height: auto;
}
input[type="search"] {
-webkit-appearance: none;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control,
input[type="month"].form-control {
line-height: 32px;
}
input[type="date"].input-sm,
input[type="time"].input-sm,
input[type="datetime-local"].input-sm,
input[type="month"].input-sm,
.input-group-sm input[type="date"],
.input-group-sm input[type="time"],
.input-group-sm input[type="datetime-local"],
.input-group-sm input[type="month"] {
line-height: 30px;
}
input[type="date"].input-lg,
input[type="time"].input-lg,
input[type="datetime-local"].input-lg,
input[type="month"].input-lg,
.input-group-lg input[type="date"],
.input-group-lg input[type="time"],
.input-group-lg input[type="datetime-local"],
.input-group-lg input[type="month"] {
line-height: 45px;
}
}
.form-group {
margin-bottom: 15px;
}
.radio,
.checkbox {
position: relative;
display: block;
margin-top: 10px;
margin-bottom: 10px;
}
.radio label,
.checkbox label {
min-height: 18px;
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: absolute;
margin-left: -20px;
margin-top: 4px \9;
}
.radio + .radio,
.checkbox + .checkbox {
margin-top: -5px;
}
.radio-inline,
.checkbox-inline {
position: relative;
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
vertical-align: middle;
font-weight: normal;
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
margin-left: 10px;
}
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"].disabled,
input[type="checkbox"].disabled,
fieldset[disabled] input[type="radio"],
fieldset[disabled] input[type="checkbox"] {
cursor: not-allowed;
}
.radio-inline.disabled,
.checkbox-inline.disabled,
fieldset[disabled] .radio-inline,
fieldset[disabled] .checkbox-inline {
cursor: not-allowed;
}
.radio.disabled label,
.checkbox.disabled label,
fieldset[disabled] .radio label,
fieldset[disabled] .checkbox label {
cursor: not-allowed;
}
.form-control-static {
padding-top: 7px;
padding-bottom: 7px;
margin-bottom: 0;
min-height: 31px;
}
.form-control-static.input-lg,
.form-control-static.input-sm {
padding-left: 0;
padding-right: 0;
}
.input-sm {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
}
select.input-sm {
height: 30px;
line-height: 30px;
}
textarea.input-sm,
select[multiple].input-sm {
height: auto;
}
.form-group-sm .form-control {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
}
.form-group-sm select.form-control {
height: 30px;
line-height: 30px;
}
.form-group-sm textarea.form-control,
.form-group-sm select[multiple].form-control {
height: auto;
}
.form-group-sm .form-control-static {
height: 30px;
min-height: 30px;
padding: 6px 10px;
font-size: 12px;
line-height: 1.5;
}
.input-lg {
height: 45px;
padding: 10px 16px;
font-size: 17px;
line-height: 1.3333333;
border-radius: 3px;
}
select.input-lg {
height: 45px;
line-height: 45px;
}
textarea.input-lg,
select[multiple].input-lg {
height: auto;
}
.form-group-lg .form-control {
height: 45px;
padding: 10px 16px;
font-size: 17px;
line-height: 1.3333333;
border-radius: 3px;
}
.form-group-lg select.form-control {
height: 45px;
line-height: 45px;
}
.form-group-lg textarea.form-control,
.form-group-lg select[multiple].form-control {
height: auto;
}
.form-group-lg .form-control-static {
height: 45px;
min-height: 35px;
padding: 11px 16px;
font-size: 17px;
line-height: 1.3333333;
}
.has-feedback {
position: relative;
}
.has-feedback .form-control {
padding-right: 40px;
}
.form-control-feedback {
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: block;
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
pointer-events: none;
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback,
.form-group-lg .form-control + .form-control-feedback {
width: 45px;
height: 45px;
line-height: 45px;
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback,
.form-group-sm .form-control + .form-control-feedback {
width: 30px;
height: 30px;
line-height: 30px;
}
.has-success .help-block,
.has-success .control-label,
.has-success .radio,
.has-success .checkbox,
.has-success .radio-inline,
.has-success .checkbox-inline,
.has-success.radio label,
.has-success.checkbox label,
.has-success.radio-inline label,
.has-success.checkbox-inline label {
color: #3c763d;
}
.has-success .form-control {
border-color: #3c763d;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-success .form-control:focus {
border-color: #2b542c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
}
.has-success .input-group-addon {
color: #3c763d;
border-color: #3c763d;
background-color: #dff0d8;
}
.has-success .form-control-feedback {
color: #3c763d;
}
.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
.has-warning .checkbox,
.has-warning .radio-inline,
.has-warning .checkbox-inline,
.has-warning.radio label,
.has-warning.checkbox label,
.has-warning.radio-inline label,
.has-warning.checkbox-inline label {
color: #8a6d3b;
}
.has-warning .form-control {
border-color: #8a6d3b;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-warning .form-control:focus {
border-color: #66512c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
}
.has-warning .input-group-addon {
color: #8a6d3b;
border-color: #8a6d3b;
background-color: #fcf8e3;
}
.has-warning .form-control-feedback {
color: #8a6d3b;
}
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline,
.has-error.radio label,
.has-error.checkbox label,
.has-error.radio-inline label,
.has-error.checkbox-inline label {
color: #a94442;
}
.has-error .form-control {
border-color: #a94442;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-error .form-control:focus {
border-color: #843534;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
}
.has-error .input-group-addon {
color: #a94442;
border-color: #a94442;
background-color: #f2dede;
}
.has-error .form-control-feedback {
color: #a94442;
}
.has-feedback label ~ .form-control-feedback {
top: 23px;
}
.has-feedback label.sr-only ~ .form-control-feedback {
top: 0;
}
.help-block {
display: block;
margin-top: 5px;
margin-bottom: 10px;
color: #404040;
}
@media (min-width: 768px) {
.form-inline .form-group {
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.form-inline .form-control-static {
display: inline-block;
}
.form-inline .input-group {
display: inline-table;
vertical-align: middle;
}
.form-inline .input-group .input-group-addon,
.form-inline .input-group .input-group-btn,
.form-inline .input-group .form-control {
width: auto;
}
.form-inline .input-group > .form-control {
width: 100%;
}
.form-inline .control-label {
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .radio,
.form-inline .checkbox {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .radio label,
.form-inline .checkbox label {
padding-left: 0;
}
.form-inline .radio input[type="radio"],
.form-inline .checkbox input[type="checkbox"] {
position: relative;
margin-left: 0;
}
.form-inline .has-feedback .form-control-feedback {
top: 0;
}
}
.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
margin-top: 0;
margin-bottom: 0;
padding-top: 7px;
}
.form-horizontal .radio,
.form-horizontal .checkbox {
min-height: 25px;
}
.form-horizontal .form-group {
margin-left: 0px;
margin-right: 0px;
}
@media (min-width: 768px) {
.form-horizontal .control-label {
text-align: right;
margin-bottom: 0;
padding-top: 7px;
}
}
.form-horizontal .has-feedback .form-control-feedback {
right: 0px;
}
@media (min-width: 768px) {
.form-horizontal .form-group-lg .control-label {
padding-top: 11px;
font-size: 17px;
}
}
@media (min-width: 768px) {
.form-horizontal .form-group-sm .control-label {
padding-top: 6px;
font-size: 12px;
}
}
.btn {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
white-space: nowrap;
padding: 6px 12px;
font-size: 13px;
line-height: 1.42857143;
border-radius: 2px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn:hover,
.btn:focus,
.btn.focus {
color: #333;
text-decoration: none;
}
.btn:active,
.btn.active {
outline: 0;
background-image: none;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
cursor: not-allowed;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
a.btn.disabled,
fieldset[disabled] a.btn {
pointer-events: none;
}
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-default:focus,
.btn-default.focus {
color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
.btn-default:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.btn-default:active:hover,
.btn-default.active:hover,
.open > .dropdown-toggle.btn-default:hover,
.btn-default:active:focus,
.btn-default.active:focus,
.open > .dropdown-toggle.btn-default:focus,
.btn-default:active.focus,
.btn-default.active.focus,
.open > .dropdown-toggle.btn-default.focus {
color: #333;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
background-image: none;
}
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus {
background-color: #fff;
border-color: #ccc;
}
.btn-default .badge {
color: #fff;
background-color: #333;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary:focus,
.btn-primary.focus {
color: #fff;
background-color: #286090;
border-color: #122b40;
}
.btn-primary:hover {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active:hover,
.btn-primary.active:hover,
.open > .dropdown-toggle.btn-primary:hover,
.btn-primary:active:focus,
.btn-primary.active:focus,
.open > .dropdown-toggle.btn-primary:focus,
.btn-primary:active.focus,
.btn-primary.active.focus,
.open > .dropdown-toggle.btn-primary.focus {
color: #fff;
background-color: #204d74;
border-color: #122b40;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
background-image: none;
}
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus {
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary .badge {
color: #337ab7;
background-color: #fff;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-success:focus,
.btn-success.focus {
color: #fff;
background-color: #449d44;
border-color: #255625;
}
.btn-success:hover {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.btn-success:active:hover,
.btn-success.active:hover,
.open > .dropdown-toggle.btn-success:hover,
.btn-success:active:focus,
.btn-success.active:focus,
.open > .dropdown-toggle.btn-success:focus,
.btn-success:active.focus,
.btn-success.active.focus,
.open > .dropdown-toggle.btn-success.focus {
color: #fff;
background-color: #398439;
border-color: #255625;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
background-image: none;
}
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus {
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-success .badge {
color: #5cb85c;
background-color: #fff;
}
.btn-info {
color: #fff;
background-color: #5bc0de;
border-color: #46b8da;
}
.btn-info:focus,
.btn-info.focus {
color: #fff;
background-color: #31b0d5;
border-color: #1b6d85;
}
.btn-info:hover {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.btn-info:active:hover,
.btn-info.active:hover,
.open > .dropdown-toggle.btn-info:hover,
.btn-info:active:focus,
.btn-info.active:focus,
.open > .dropdown-toggle.btn-info:focus,
.btn-info:active.focus,
.btn-info.active.focus,
.open > .dropdown-toggle.btn-info.focus {
color: #fff;
background-color: #269abc;
border-color: #1b6d85;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
background-image: none;
}
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus {
background-color: #5bc0de;
border-color: #46b8da;
}
.btn-info .badge {
color: #5bc0de;
background-color: #fff;
}
.btn-warning {
color: #fff;
background-color: #f0ad4e;
border-color: #eea236;
}
.btn-warning:focus,
.btn-warning.focus {
color: #fff;
background-color: #ec971f;
border-color: #985f0d;
}
.btn-warning:hover {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.btn-warning:active:hover,
.btn-warning.active:hover,
.open > .dropdown-toggle.btn-warning:hover,
.btn-warning:active:focus,
.btn-warning.active:focus,
.open > .dropdown-toggle.btn-warning:focus,
.btn-warning:active.focus,
.btn-warning.active.focus,
.open > .dropdown-toggle.btn-warning.focus {
color: #fff;
background-color: #d58512;
border-color: #985f0d;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
background-image: none;
}
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus {
background-color: #f0ad4e;
border-color: #eea236;
}
.btn-warning .badge {
color: #f0ad4e;
background-color: #fff;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.btn-danger:focus,
.btn-danger.focus {
color: #fff;
background-color: #c9302c;
border-color: #761c19;
}
.btn-danger:hover {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-danger:active:hover,
.btn-danger.active:hover,
.open > .dropdown-toggle.btn-danger:hover,
.btn-danger:active:focus,
.btn-danger.active:focus,
.open > .dropdown-toggle.btn-danger:focus,
.btn-danger:active.focus,
.btn-danger.active.focus,
.open > .dropdown-toggle.btn-danger.focus {
color: #fff;
background-color: #ac2925;
border-color: #761c19;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
background-image: none;
}
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus {
background-color: #d9534f;
border-color: #d43f3a;
}
.btn-danger .badge {
color: #d9534f;
background-color: #fff;
}
.btn-link {
color: #337ab7;
font-weight: normal;
border-radius: 0;
}
.btn-link,
.btn-link:active,
.btn-link.active,
.btn-link[disabled],
fieldset[disabled] .btn-link {
background-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-link,
.btn-link:hover,
.btn-link:focus,
.btn-link:active {
border-color: transparent;
}
.btn-link:hover,
.btn-link:focus {
color: #23527c;
text-decoration: underline;
background-color: transparent;
}
.btn-link[disabled]:hover,
fieldset[disabled] .btn-link:hover,
.btn-link[disabled]:focus,
fieldset[disabled] .btn-link:focus {
color: #777777;
text-decoration: none;
}
.btn-lg,
.btn-group-lg > .btn {
padding: 10px 16px;
font-size: 17px;
line-height: 1.3333333;
border-radius: 3px;
}
.btn-sm,
.btn-group-sm > .btn {
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
}
.btn-xs,
.btn-group-xs > .btn {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
}
.btn-block {
display: block;
width: 100%;
}
.btn-block + .btn-block {
margin-top: 5px;
}
input[type="submit"].btn-block,
input[type="reset"].btn-block,
input[type="button"].btn-block {
width: 100%;
}
.fade {
opacity: 0;
-webkit-transition: opacity 0.15s linear;
-o-transition: opacity 0.15s linear;
transition: opacity 0.15s linear;
}
.fade.in {
opacity: 1;
}
.collapse {
display: none;
}
.collapse.in {
display: block;
}
tr.collapse.in {
display: table-row;
}
tbody.collapse.in {
display: table-row-group;
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
-webkit-transition-property: height, visibility;
transition-property: height, visibility;
-webkit-transition-duration: 0.35s;
transition-duration: 0.35s;
-webkit-transition-timing-function: ease;
transition-timing-function: ease;
}
.caret {
display: inline-block;
width: 0;
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: 4px dashed;
border-top: 4px solid \9;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
}
.dropup,
.dropdown {
position: relative;
}
.dropdown-toggle:focus {
outline: 0;
}
.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;
font-size: 13px;
text-align: left;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 2px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
}
.dropdown-menu.pull-right {
right: 0;
left: auto;
}
.dropdown-menu .divider {
height: 1px;
margin: 8px 0;
overflow: hidden;
background-color: #e5e5e5;
}
.dropdown-menu > li > a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.42857143;
color: #333333;
white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
text-decoration: none;
color: #262626;
background-color: #f5f5f5;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
color: #fff;
text-decoration: none;
outline: 0;
background-color: #337ab7;
}
.dropdown-menu > .disabled > a,
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
color: #777777;
}
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
text-decoration: none;
background-color: transparent;
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
cursor: not-allowed;
}
.open > .dropdown-menu {
display: block;
}
.open > a {
outline: 0;
}
.dropdown-menu-right {
left: auto;
right: 0;
}
.dropdown-menu-left {
left: 0;
right: auto;
}
.dropdown-header {
display: block;
padding: 3px 20px;
font-size: 12px;
line-height: 1.42857143;
color: #777777;
white-space: nowrap;
}
.dropdown-backdrop {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 990;
}
.pull-right > .dropdown-menu {
right: 0;
left: auto;
}
.dropup .caret,
.navbar-fixed-bottom .dropdown .caret {
border-top: 0;
border-bottom: 4px dashed;
border-bottom: 4px solid \9;
content: "";
}
.dropup .dropdown-menu,
.navbar-fixed-bottom .dropdown .dropdown-menu {
top: auto;
bottom: 100%;
margin-bottom: 2px;
}
@media (min-width: 541px) {
.navbar-right .dropdown-menu {
left: auto;
right: 0;
}
.navbar-right .dropdown-menu-left {
left: 0;
right: auto;
}
}
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-block;
vertical-align: middle;
}
.btn-group > .btn,
.btn-group-vertical > .btn {
position: relative;
float: left;
}
.btn-group > .btn:hover,
.btn-group-vertical > .btn:hover,
.btn-group > .btn:focus,
.btn-group-vertical > .btn:focus,
.btn-group > .btn:active,
.btn-group-vertical > .btn:active,
.btn-group > .btn.active,
.btn-group-vertical > .btn.active {
z-index: 2;
}
.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
.btn-group .btn-group + .btn,
.btn-group .btn-group + .btn-group {
margin-left: -1px;
}
.btn-toolbar {
margin-left: -5px;
}
.btn-toolbar .btn,
.btn-toolbar .btn-group,
.btn-toolbar .input-group {
float: left;
}
.btn-toolbar > .btn,
.btn-toolbar > .btn-group,
.btn-toolbar > .input-group {
margin-left: 5px;
}
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
border-radius: 0;
}
.btn-group > .btn:first-child {
margin-left: 0;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.btn-group > .btn-group {
float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
.btn-group > .btn + .dropdown-toggle {
padding-left: 8px;
padding-right: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
padding-left: 12px;
padding-right: 12px;
}
.btn-group.open .dropdown-toggle {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-group.open .dropdown-toggle.btn-link {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn .caret {
margin-left: 0;
}
.btn-lg .caret {
border-width: 5px 5px 0;
border-bottom-width: 0;
}
.dropup .btn-lg .caret {
border-width: 0 5px 5px;
}
.btn-group-vertical > .btn,
.btn-group-vertical > .btn-group,
.btn-group-vertical > .btn-group > .btn {
display: block;
float: none;
width: 100%;
max-width: 100%;
}
.btn-group-vertical > .btn-group > .btn {
float: none;
}
.btn-group-vertical > .btn + .btn,
.btn-group-vertical > .btn + .btn-group,
.btn-group-vertical > .btn-group + .btn,
.btn-group-vertical > .btn-group + .btn-group {
margin-top: -1px;
margin-left: 0;
}
.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
border-radius: 0;
}
.btn-group-vertical > .btn:first-child:not(:last-child) {
border-top-right-radius: 2px;
border-top-left-radius: 2px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn:last-child:not(:first-child) {
border-top-right-radius: 0;
border-top-left-radius: 0;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
}
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
border-top-right-radius: 0;
border-top-left-radius: 0;
}
.btn-group-justified {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: separate;
}
.btn-group-justified > .btn,
.btn-group-justified > .btn-group {
float: none;
display: table-cell;
width: 1%;
}
.btn-group-justified > .btn-group .btn {
width: 100%;
}
.btn-group-justified > .btn-group .dropdown-menu {
left: auto;
}
[data-toggle="buttons"] > .btn input[type="radio"],
[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
[data-toggle="buttons"] > .btn input[type="checkbox"],
[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
}
.input-group {
position: relative;
display: table;
border-collapse: separate;
}
.input-group[class*="col-"] {
float: none;
padding-left: 0;
padding-right: 0;
}
.input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
}
.input-group .form-control:focus {
z-index: 3;
}
.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
height: 45px;
padding: 10px 16px;
font-size: 17px;
line-height: 1.3333333;
border-radius: 3px;
}
select.input-group-lg > .form-control,
select.input-group-lg > .input-group-addon,
select.input-group-lg > .input-group-btn > .btn {
height: 45px;
line-height: 45px;
}
textarea.input-group-lg > .form-control,
textarea.input-group-lg > .input-group-addon,
textarea.input-group-lg > .input-group-btn > .btn,
select[multiple].input-group-lg > .form-control,
select[multiple].input-group-lg > .input-group-addon,
select[multiple].input-group-lg > .input-group-btn > .btn {
height: auto;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
}
select.input-group-sm > .form-control,
select.input-group-sm > .input-group-addon,
select.input-group-sm > .input-group-btn > .btn {
height: 30px;
line-height: 30px;
}
textarea.input-group-sm > .form-control,
textarea.input-group-sm > .input-group-addon,
textarea.input-group-sm > .input-group-btn > .btn,
select[multiple].input-group-sm > .form-control,
select[multiple].input-group-sm > .input-group-addon,
select[multiple].input-group-sm > .input-group-btn > .btn {
height: auto;
}
.input-group-addon,
.input-group-btn,
.input-group .form-control {
display: table-cell;
}
.input-group-addon:not(:first-child):not(:last-child),
.input-group-btn:not(:first-child):not(:last-child),
.input-group .form-control:not(:first-child):not(:last-child) {
border-radius: 0;
}
.input-group-addon,
.input-group-btn {
width: 1%;
white-space: nowrap;
vertical-align: middle;
}
.input-group-addon {
padding: 6px 12px;
font-size: 13px;
font-weight: normal;
line-height: 1;
color: #555555;
text-align: center;
background-color: #eeeeee;
border: 1px solid #ccc;
border-radius: 2px;
}
.input-group-addon.input-sm {
padding: 5px 10px;
font-size: 12px;
border-radius: 1px;
}
.input-group-addon.input-lg {
padding: 10px 16px;
font-size: 17px;
border-radius: 3px;
}
.input-group-addon input[type="radio"],
.input-group-addon input[type="checkbox"] {
margin-top: 0;
}
.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.input-group-addon:first-child {
border-right: 0;
}
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.input-group-addon:last-child {
border-left: 0;
}
.input-group-btn {
position: relative;
font-size: 0;
white-space: nowrap;
}
.input-group-btn > .btn {
position: relative;
}
.input-group-btn > .btn + .btn {
margin-left: -1px;
}
.input-group-btn > .btn:hover,
.input-group-btn > .btn:focus,
.input-group-btn > .btn:active {
z-index: 2;
}
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group {
margin-right: -1px;
}
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group {
z-index: 2;
margin-left: -1px;
}
.nav {
margin-bottom: 0;
padding-left: 0;
list-style: none;
}
.nav > li {
position: relative;
display: block;
}
.nav > li > a {
position: relative;
display: block;
padding: 10px 15px;
}
.nav > li > a:hover,
.nav > li > a:focus {
text-decoration: none;
background-color: #eeeeee;
}
.nav > li.disabled > a {
color: #777777;
}
.nav > li.disabled > a:hover,
.nav > li.disabled > a:focus {
color: #777777;
text-decoration: none;
background-color: transparent;
cursor: not-allowed;
}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
background-color: #eeeeee;
border-color: #337ab7;
}
.nav .nav-divider {
height: 1px;
margin: 8px 0;
overflow: hidden;
background-color: #e5e5e5;
}
.nav > li > a > img {
max-width: none;
}
.nav-tabs {
border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
float: left;
margin-bottom: -1px;
}
.nav-tabs > li > a {
margin-right: 2px;
line-height: 1.42857143;
border: 1px solid transparent;
border-radius: 2px 2px 0 0;
}
.nav-tabs > li > a:hover {
border-color: #eeeeee #eeeeee #ddd;
}
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
color: #555555;
background-color: #fff;
border: 1px solid #ddd;
border-bottom-color: transparent;
cursor: default;
}
.nav-tabs.nav-justified {
width: 100%;
border-bottom: 0;
}
.nav-tabs.nav-justified > li {
float: none;
}
.nav-tabs.nav-justified > li > a {
text-align: center;
margin-bottom: 5px;
}
.nav-tabs.nav-justified > .dropdown .dropdown-menu {
top: auto;
left: auto;
}
@media (min-width: 768px) {
.nav-tabs.nav-justified > li {
display: table-cell;
width: 1%;
}
.nav-tabs.nav-justified > li > a {
margin-bottom: 0;
}
}
.nav-tabs.nav-justified > li > a {
margin-right: 0;
border-radius: 2px;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs.nav-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 2px 2px 0 0;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
border-bottom-color: #fff;
}
}
.nav-pills > li {
float: left;
}
.nav-pills > li > a {
border-radius: 2px;
}
.nav-pills > li + li {
margin-left: 2px;
}
.nav-pills > li.active > a,
.nav-pills > li.active > a:hover,
.nav-pills > li.active > a:focus {
color: #fff;
background-color: #337ab7;
}
.nav-stacked > li {
float: none;
}
.nav-stacked > li + li {
margin-top: 2px;
margin-left: 0;
}
.nav-justified {
width: 100%;
}
.nav-justified > li {
float: none;
}
.nav-justified > li > a {
text-align: center;
margin-bottom: 5px;
}
.nav-justified > .dropdown .dropdown-menu {
top: auto;
left: auto;
}
@media (min-width: 768px) {
.nav-justified > li {
display: table-cell;
width: 1%;
}
.nav-justified > li > a {
margin-bottom: 0;
}
}
.nav-tabs-justified {
border-bottom: 0;
}
.nav-tabs-justified > li > a {
margin-right: 0;
border-radius: 2px;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 2px 2px 0 0;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
border-bottom-color: #fff;
}
}
.tab-content > .tab-pane {
display: none;
}
.tab-content > .active {
display: block;
}
.nav-tabs .dropdown-menu {
margin-top: -1px;
border-top-right-radius: 0;
border-top-left-radius: 0;
}
.navbar {
position: relative;
min-height: 30px;
margin-bottom: 18px;
border: 1px solid transparent;
}
@media (min-width: 541px) {
.navbar {
border-radius: 2px;
}
}
@media (min-width: 541px) {
.navbar-header {
float: left;
}
}
.navbar-collapse {
overflow-x: visible;
padding-right: 0px;
padding-left: 0px;
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
-webkit-overflow-scrolling: touch;
}
.navbar-collapse.in {
overflow-y: auto;
}
@media (min-width: 541px) {
.navbar-collapse {
width: auto;
border-top: 0;
box-shadow: none;
}
.navbar-collapse.collapse {
display: block !important;
height: auto !important;
padding-bottom: 0;
overflow: visible !important;
}
.navbar-collapse.in {
overflow-y: visible;
}
.navbar-fixed-top .navbar-collapse,
.navbar-static-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
padding-left: 0;
padding-right: 0;
}
}
.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
max-height: 340px;
}
@media (max-device-width: 540px) and (orientation: landscape) {
.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
max-height: 200px;
}
}
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
margin-right: 0px;
margin-left: 0px;
}
@media (min-width: 541px) {
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
margin-right: 0;
margin-left: 0;
}
}
.navbar-static-top {
z-index: 1000;
border-width: 0 0 1px;
}
@media (min-width: 541px) {
.navbar-static-top {
border-radius: 0;
}
}
.navbar-fixed-top,
.navbar-fixed-bottom {
position: fixed;
right: 0;
left: 0;
z-index: 1030;
}
@media (min-width: 541px) {
.navbar-fixed-top,
.navbar-fixed-bottom {
border-radius: 0;
}
}
.navbar-fixed-top {
top: 0;
border-width: 0 0 1px;
}
.navbar-fixed-bottom {
bottom: 0;
margin-bottom: 0;
border-width: 1px 0 0;
}
.navbar-brand {
float: left;
padding: 6px 0px;
font-size: 17px;
line-height: 18px;
height: 30px;
}
.navbar-brand:hover,
.navbar-brand:focus {
text-decoration: none;
}
.navbar-brand > img {
display: block;
}
@media (min-width: 541px) {
.navbar > .container .navbar-brand,
.navbar > .container-fluid .navbar-brand {
margin-left: 0px;
}
}
.navbar-toggle {
position: relative;
float: right;
margin-right: 0px;
padding: 9px 10px;
margin-top: -2px;
margin-bottom: -2px;
background-color: transparent;
background-image: none;
border: 1px solid transparent;
border-radius: 2px;
}
.navbar-toggle:focus {
outline: 0;
}
.navbar-toggle .icon-bar {
display: block;
width: 22px;
height: 2px;
border-radius: 1px;
}
.navbar-toggle .icon-bar + .icon-bar {
margin-top: 4px;
}
@media (min-width: 541px) {
.navbar-toggle {
display: none;
}
}
.navbar-nav {
margin: 3px 0px;
}
.navbar-nav > li > a {
padding-top: 10px;
padding-bottom: 10px;
line-height: 18px;
}
@media (max-width: 540px) {
.navbar-nav .open .dropdown-menu {
position: static;
float: none;
width: auto;
margin-top: 0;
background-color: transparent;
border: 0;
box-shadow: none;
}
.navbar-nav .open .dropdown-menu > li > a,
.navbar-nav .open .dropdown-menu .dropdown-header {
padding: 5px 15px 5px 25px;
}
.navbar-nav .open .dropdown-menu > li > a {
line-height: 18px;
}
.navbar-nav .open .dropdown-menu > li > a:hover,
.navbar-nav .open .dropdown-menu > li > a:focus {
background-image: none;
}
}
@media (min-width: 541px) {
.navbar-nav {
float: left;
margin: 0;
}
.navbar-nav > li {
float: left;
}
.navbar-nav > li > a {
padding-top: 6px;
padding-bottom: 6px;
}
}
.navbar-form {
margin-left: 0px;
margin-right: 0px;
padding: 10px 0px;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
margin-top: -1px;
margin-bottom: -1px;
}
@media (min-width: 768px) {
.navbar-form .form-group {
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
}
.navbar-form .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.navbar-form .form-control-static {
display: inline-block;
}
.navbar-form .input-group {
display: inline-table;
vertical-align: middle;
}
.navbar-form .input-group .input-group-addon,
.navbar-form .input-group .input-group-btn,
.navbar-form .input-group .form-control {
width: auto;
}
.navbar-form .input-group > .form-control {
width: 100%;
}
.navbar-form .control-label {
margin-bottom: 0;
vertical-align: middle;
}
.navbar-form .radio,
.navbar-form .checkbox {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
}
.navbar-form .radio label,
.navbar-form .checkbox label {
padding-left: 0;
}
.navbar-form .radio input[type="radio"],
.navbar-form .checkbox input[type="checkbox"] {
position: relative;
margin-left: 0;
}
.navbar-form .has-feedback .form-control-feedback {
top: 0;
}
}
@media (max-width: 540px) {
.navbar-form .form-group {
margin-bottom: 5px;
}
.navbar-form .form-group:last-child {
margin-bottom: 0;
}
}
@media (min-width: 541px) {
.navbar-form {
width: auto;
border: 0;
margin-left: 0;
margin-right: 0;
padding-top: 0;
padding-bottom: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
}
.navbar-nav > li > .dropdown-menu {
margin-top: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
}
.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
margin-bottom: 0;
border-top-right-radius: 2px;
border-top-left-radius: 2px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.navbar-btn {
margin-top: -1px;
margin-bottom: -1px;
}
.navbar-btn.btn-sm {
margin-top: 0px;
margin-bottom: 0px;
}
.navbar-btn.btn-xs {
margin-top: 4px;
margin-bottom: 4px;
}
.navbar-text {
margin-top: 6px;
margin-bottom: 6px;
}
@media (min-width: 541px) {
.navbar-text {
float: left;
margin-left: 0px;
margin-right: 0px;
}
}
@media (min-width: 541px) {
.navbar-left {
float: left !important;
float: left;
}
.navbar-right {
float: right !important;
float: right;
margin-right: 0px;
}
.navbar-right ~ .navbar-right {
margin-right: 0;
}
}
.navbar-default {
background-color: #f8f8f8;
border-color: #e7e7e7;
}
.navbar-default .navbar-brand {
color: #777;
}
.navbar-default .navbar-brand:hover,
.navbar-default .navbar-brand:focus {
color: #5e5e5e;
background-color: transparent;
}
.navbar-default .navbar-text {
color: #777;
}
.navbar-default .navbar-nav > li > a {
color: #777;
}
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus {
color: #333;
background-color: transparent;
}
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > .active > a:hover,
.navbar-default .navbar-nav > .active > a:focus {
color: #555;
background-color: #e7e7e7;
}
.navbar-default .navbar-nav > .disabled > a,
.navbar-default .navbar-nav > .disabled > a:hover,
.navbar-default .navbar-nav > .disabled > a:focus {
color: #ccc;
background-color: transparent;
}
.navbar-default .navbar-toggle {
border-color: #ddd;
}
.navbar-default .navbar-toggle:hover,
.navbar-default .navbar-toggle:focus {
background-color: #ddd;
}
.navbar-default .navbar-toggle .icon-bar {
background-color: #888;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
border-color: #e7e7e7;
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .open > a:hover,
.navbar-default .navbar-nav > .open > a:focus {
background-color: #e7e7e7;
color: #555;
}
@media (max-width: 540px) {
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
color: #777;
}
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
color: #333;
background-color: transparent;
}
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #555;
background-color: #e7e7e7;
}
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
color: #ccc;
background-color: transparent;
}
}
.navbar-default .navbar-link {
color: #777;
}
.navbar-default .navbar-link:hover {
color: #333;
}
.navbar-default .btn-link {
color: #777;
}
.navbar-default .btn-link:hover,
.navbar-default .btn-link:focus {
color: #333;
}
.navbar-default .btn-link[disabled]:hover,
fieldset[disabled] .navbar-default .btn-link:hover,
.navbar-default .btn-link[disabled]:focus,
fieldset[disabled] .navbar-default .btn-link:focus {
color: #ccc;
}
.navbar-inverse {
background-color: #222;
border-color: #080808;
}
.navbar-inverse .navbar-brand {
color: #9d9d9d;
}
.navbar-inverse .navbar-brand:hover,
.navbar-inverse .navbar-brand:focus {
color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-text {
color: #9d9d9d;
}
.navbar-inverse .navbar-nav > li > a {
color: #9d9d9d;
}
.navbar-inverse .navbar-nav > li > a:hover,
.navbar-inverse .navbar-nav > li > a:focus {
color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
color: #fff;
background-color: #080808;
}
.navbar-inverse .navbar-nav > .disabled > a,
.navbar-inverse .navbar-nav > .disabled > a:hover,
.navbar-inverse .navbar-nav > .disabled > a:focus {
color: #444;
background-color: transparent;
}
.navbar-inverse .navbar-toggle {
border-color: #333;
}
.navbar-inverse .navbar-toggle:hover,
.navbar-inverse .navbar-toggle:focus {
background-color: #333;
}
.navbar-inverse .navbar-toggle .icon-bar {
background-color: #fff;
}
.navbar-inverse .navbar-collapse,
.navbar-inverse .navbar-form {
border-color: #101010;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .open > a:hover,
.navbar-inverse .navbar-nav > .open > a:focus {
background-color: #080808;
color: #fff;
}
@media (max-width: 540px) {
.navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
border-color: #080808;
}
.navbar-inverse .navbar-nav .open .dropdown-menu .divider {
background-color: #080808;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
color: #9d9d9d;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-color: #080808;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
color: #444;
background-color: transparent;
}
}
.navbar-inverse .navbar-link {
color: #9d9d9d;
}
.navbar-inverse .navbar-link:hover {
color: #fff;
}
.navbar-inverse .btn-link {
color: #9d9d9d;
}
.navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link:focus {
color: #fff;
}
.navbar-inverse .btn-link[disabled]:hover,
fieldset[disabled] .navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link[disabled]:focus,
fieldset[disabled] .navbar-inverse .btn-link:focus {
color: #444;
}
.breadcrumb {
padding: 8px 15px;
margin-bottom: 18px;
list-style: none;
background-color: #f5f5f5;
border-radius: 2px;
}
.breadcrumb > li {
display: inline-block;
}
.breadcrumb > li + li:before {
content: "/\00a0";
padding: 0 5px;
color: #5e5e5e;
}
.breadcrumb > .active {
color: #777777;
}
.pagination {
display: inline-block;
padding-left: 0;
margin: 18px 0;
border-radius: 2px;
}
.pagination > li {
display: inline;
}
.pagination > li > a,
.pagination > li > span {
position: relative;
float: left;
padding: 6px 12px;
line-height: 1.42857143;
text-decoration: none;
color: #337ab7;
background-color: #fff;
border: 1px solid #ddd;
margin-left: -1px;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
margin-left: 0;
border-bottom-left-radius: 2px;
border-top-left-radius: 2px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
border-bottom-right-radius: 2px;
border-top-right-radius: 2px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
z-index: 2;
color: #23527c;
background-color: #eeeeee;
border-color: #ddd;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus {
z-index: 3;
color: #fff;
background-color: #337ab7;
border-color: #337ab7;
cursor: default;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
color: #777777;
background-color: #fff;
border-color: #ddd;
cursor: not-allowed;
}
.pagination-lg > li > a,
.pagination-lg > li > span {
padding: 10px 16px;
font-size: 17px;
line-height: 1.3333333;
}
.pagination-lg > li:first-child > a,
.pagination-lg > li:first-child > span {
border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
}
.pagination-lg > li:last-child > a,
.pagination-lg > li:last-child > span {
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
}
.pagination-sm > li > a,
.pagination-sm > li > span {
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
}
.pagination-sm > li:first-child > a,
.pagination-sm > li:first-child > span {
border-bottom-left-radius: 1px;
border-top-left-radius: 1px;
}
.pagination-sm > li:last-child > a,
.pagination-sm > li:last-child > span {
border-bottom-right-radius: 1px;
border-top-right-radius: 1px;
}
.pager {
padding-left: 0;
margin: 18px 0;
list-style: none;
text-align: center;
}
.pager li {
display: inline;
}
.pager li > a,
.pager li > span {
display: inline-block;
padding: 5px 14px;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 15px;
}
.pager li > a:hover,
.pager li > a:focus {
text-decoration: none;
background-color: #eeeeee;
}
.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: #777777;
background-color: #fff;
cursor: not-allowed;
}
.label {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: bold;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
}
a.label:hover,
a.label:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
.label:empty {
display: none;
}
.btn .label {
position: relative;
top: -1px;
}
.label-default {
background-color: #777777;
}
.label-default[href]:hover,
.label-default[href]:focus {
background-color: #5e5e5e;
}
.label-primary {
background-color: #337ab7;
}
.label-primary[href]:hover,
.label-primary[href]:focus {
background-color: #286090;
}
.label-success {
background-color: #5cb85c;
}
.label-success[href]:hover,
.label-success[href]:focus {
background-color: #449d44;
}
.label-info {
background-color: #5bc0de;
}
.label-info[href]:hover,
.label-info[href]:focus {
background-color: #31b0d5;
}
.label-warning {
background-color: #f0ad4e;
}
.label-warning[href]:hover,
.label-warning[href]:focus {
background-color: #ec971f;
}
.label-danger {
background-color: #d9534f;
}
.label-danger[href]:hover,
.label-danger[href]:focus {
background-color: #c9302c;
}
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: 12px;
font-weight: bold;
color: #fff;
line-height: 1;
vertical-align: middle;
white-space: nowrap;
text-align: center;
background-color: #777777;
border-radius: 10px;
}
.badge:empty {
display: none;
}
.btn .badge {
position: relative;
top: -1px;
}
.btn-xs .badge,
.btn-group-xs > .btn .badge {
top: 0;
padding: 1px 5px;
}
a.badge:hover,
a.badge:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
.list-group-item.active > .badge,
.nav-pills > .active > a > .badge {
color: #337ab7;
background-color: #fff;
}
.list-group-item > .badge {
float: right;
}
.list-group-item > .badge + .badge {
margin-right: 5px;
}
.nav-pills > li > a > .badge {
margin-left: 3px;
}
.jumbotron {
padding-top: 30px;
padding-bottom: 30px;
margin-bottom: 30px;
color: inherit;
background-color: #eeeeee;
}
.jumbotron h1,
.jumbotron .h1 {
color: inherit;
}
.jumbotron p {
margin-bottom: 15px;
font-size: 20px;
font-weight: 200;
}
.jumbotron > hr {
border-top-color: #d5d5d5;
}
.container .jumbotron,
.container-fluid .jumbotron {
border-radius: 3px;
padding-left: 0px;
padding-right: 0px;
}
.jumbotron .container {
max-width: 100%;
}
@media screen and (min-width: 768px) {
.jumbotron {
padding-top: 48px;
padding-bottom: 48px;
}
.container .jumbotron,
.container-fluid .jumbotron {
padding-left: 60px;
padding-right: 60px;
}
.jumbotron h1,
.jumbotron .h1 {
font-size: 59px;
}
}
.thumbnail {
display: block;
padding: 4px;
margin-bottom: 18px;
line-height: 1.42857143;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 2px;
-webkit-transition: border 0.2s ease-in-out;
-o-transition: border 0.2s ease-in-out;
transition: border 0.2s ease-in-out;
}
.thumbnail > img,
.thumbnail a > img {
margin-left: auto;
margin-right: auto;
}
a.thumbnail:hover,
a.thumbnail:focus,
a.thumbnail.active {
border-color: #337ab7;
}
.thumbnail .caption {
padding: 9px;
color: #000;
}
.alert {
padding: 15px;
margin-bottom: 18px;
border: 1px solid transparent;
border-radius: 2px;
}
.alert h4 {
margin-top: 0;
color: inherit;
}
.alert .alert-link {
font-weight: bold;
}
.alert > p,
.alert > ul {
margin-bottom: 0;
}
.alert > p + p {
margin-top: 5px;
}
.alert-dismissable,
.alert-dismissible {
padding-right: 35px;
}
.alert-dismissable .close,
.alert-dismissible .close {
position: relative;
top: -2px;
right: -21px;
color: inherit;
}
.alert-success {
background-color: #dff0d8;
border-color: #d6e9c6;
color: #3c763d;
}
.alert-success hr {
border-top-color: #c9e2b3;
}
.alert-success .alert-link {
color: #2b542c;
}
.alert-info {
background-color: #d9edf7;
border-color: #bce8f1;
color: #31708f;
}
.alert-info hr {
border-top-color: #a6e1ec;
}
.alert-info .alert-link {
color: #245269;
}
.alert-warning {
background-color: #fcf8e3;
border-color: #faebcc;
color: #8a6d3b;
}
.alert-warning hr {
border-top-color: #f7e1b5;
}
.alert-warning .alert-link {
color: #66512c;
}
.alert-danger {
background-color: #f2dede;
border-color: #ebccd1;
color: #a94442;
}
.alert-danger hr {
border-top-color: #e4b9c0;
}
.alert-danger .alert-link {
color: #843534;
}
@-webkit-keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
@keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
.progress {
overflow: hidden;
height: 18px;
margin-bottom: 18px;
background-color: #f5f5f5;
border-radius: 2px;
-webkit-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;
line-height: 18px;
color: #fff;
text-align: center;
background-color: #337ab7;
-webkit-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-transition: width 0.6s ease;
-o-transition: width 0.6s ease;
transition: width 0.6s ease;
}
.progress-striped .progress-bar,
.progress-bar-striped {
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: -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);
background-size: 40px 40px;
}
.progress.active .progress-bar,
.progress-bar.active {
-webkit-animation: progress-bar-stripes 2s linear infinite;
-o-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
.progress-bar-success {
background-color: #5cb85c;
}
.progress-striped .progress-bar-success {
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: -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-bar-info {
background-color: #5bc0de;
}
.progress-striped .progress-bar-info {
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: -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-bar-warning {
background-color: #f0ad4e;
}
.progress-striped .progress-bar-warning {
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: -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-bar-danger {
background-color: #d9534f;
}
.progress-striped .progress-bar-danger {
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: -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);
}
.media {
margin-top: 15px;
}
.media:first-child {
margin-top: 0;
}
.media,
.media-body {
zoom: 1;
overflow: hidden;
}
.media-body {
width: 10000px;
}
.media-object {
display: block;
}
.media-object.img-thumbnail {
max-width: none;
}
.media-right,
.media > .pull-right {
padding-left: 10px;
}
.media-left,
.media > .pull-left {
padding-right: 10px;
}
.media-left,
.media-right,
.media-body {
display: table-cell;
vertical-align: top;
}
.media-middle {
vertical-align: middle;
}
.media-bottom {
vertical-align: bottom;
}
.media-heading {
margin-top: 0;
margin-bottom: 5px;
}
.media-list {
padding-left: 0;
list-style: none;
}
.list-group {
margin-bottom: 20px;
padding-left: 0;
}
.list-group-item {
position: relative;
display: block;
padding: 10px 15px;
margin-bottom: -1px;
background-color: #fff;
border: 1px solid #ddd;
}
.list-group-item:first-child {
border-top-right-radius: 2px;
border-top-left-radius: 2px;
}
.list-group-item:last-child {
margin-bottom: 0;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
}
a.list-group-item,
button.list-group-item {
color: #555;
}
a.list-group-item .list-group-item-heading,
button.list-group-item .list-group-item-heading {
color: #333;
}
a.list-group-item:hover,
button.list-group-item:hover,
a.list-group-item:focus,
button.list-group-item:focus {
text-decoration: none;
color: #555;
background-color: #f5f5f5;
}
button.list-group-item {
width: 100%;
text-align: left;
}
.list-group-item.disabled,
.list-group-item.disabled:hover,
.list-group-item.disabled:focus {
background-color: #eeeeee;
color: #777777;
cursor: not-allowed;
}
.list-group-item.disabled .list-group-item-heading,
.list-group-item.disabled:hover .list-group-item-heading,
.list-group-item.disabled:focus .list-group-item-heading {
color: inherit;
}
.list-group-item.disabled .list-group-item-text,
.list-group-item.disabled:hover .list-group-item-text,
.list-group-item.disabled:focus .list-group-item-text {
color: #777777;
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
z-index: 2;
color: #fff;
background-color: #337ab7;
border-color: #337ab7;
}
.list-group-item.active .list-group-item-heading,
.list-group-item.active:hover .list-group-item-heading,
.list-group-item.active:focus .list-group-item-heading,
.list-group-item.active .list-group-item-heading > small,
.list-group-item.active:hover .list-group-item-heading > small,
.list-group-item.active:focus .list-group-item-heading > small,
.list-group-item.active .list-group-item-heading > .small,
.list-group-item.active:hover .list-group-item-heading > .small,
.list-group-item.active:focus .list-group-item-heading > .small {
color: inherit;
}
.list-group-item.active .list-group-item-text,
.list-group-item.active:hover .list-group-item-text,
.list-group-item.active:focus .list-group-item-text {
color: #c7ddef;
}
.list-group-item-success {
color: #3c763d;
background-color: #dff0d8;
}
a.list-group-item-success,
button.list-group-item-success {
color: #3c763d;
}
a.list-group-item-success .list-group-item-heading,
button.list-group-item-success .list-group-item-heading {
color: inherit;
}
a.list-group-item-success:hover,
button.list-group-item-success:hover,
a.list-group-item-success:focus,
button.list-group-item-success:focus {
color: #3c763d;
background-color: #d0e9c6;
}
a.list-group-item-success.active,
button.list-group-item-success.active,
a.list-group-item-success.active:hover,
button.list-group-item-success.active:hover,
a.list-group-item-success.active:focus,
button.list-group-item-success.active:focus {
color: #fff;
background-color: #3c763d;
border-color: #3c763d;
}
.list-group-item-info {
color: #31708f;
background-color: #d9edf7;
}
a.list-group-item-info,
button.list-group-item-info {
color: #31708f;
}
a.list-group-item-info .list-group-item-heading,
button.list-group-item-info .list-group-item-heading {
color: inherit;
}
a.list-group-item-info:hover,
button.list-group-item-info:hover,
a.list-group-item-info:focus,
button.list-group-item-info:focus {
color: #31708f;
background-color: #c4e3f3;
}
a.list-group-item-info.active,
button.list-group-item-info.active,
a.list-group-item-info.active:hover,
button.list-group-item-info.active:hover,
a.list-group-item-info.active:focus,
button.list-group-item-info.active:focus {
color: #fff;
background-color: #31708f;
border-color: #31708f;
}
.list-group-item-warning {
color: #8a6d3b;
background-color: #fcf8e3;
}
a.list-group-item-warning,
button.list-group-item-warning {
color: #8a6d3b;
}
a.list-group-item-warning .list-group-item-heading,
button.list-group-item-warning .list-group-item-heading {
color: inherit;
}
a.list-group-item-warning:hover,
button.list-group-item-warning:hover,
a.list-group-item-warning:focus,
button.list-group-item-warning:focus {
color: #8a6d3b;
background-color: #faf2cc;
}
a.list-group-item-warning.active,
button.list-group-item-warning.active,
a.list-group-item-warning.active:hover,
button.list-group-item-warning.active:hover,
a.list-group-item-warning.active:focus,
button.list-group-item-warning.active:focus {
color: #fff;
background-color: #8a6d3b;
border-color: #8a6d3b;
}
.list-group-item-danger {
color: #a94442;
background-color: #f2dede;
}
a.list-group-item-danger,
button.list-group-item-danger {
color: #a94442;
}
a.list-group-item-danger .list-group-item-heading,
button.list-group-item-danger .list-group-item-heading {
color: inherit;
}
a.list-group-item-danger:hover,
button.list-group-item-danger:hover,
a.list-group-item-danger:focus,
button.list-group-item-danger:focus {
color: #a94442;
background-color: #ebcccc;
}
a.list-group-item-danger.active,
button.list-group-item-danger.active,
a.list-group-item-danger.active:hover,
button.list-group-item-danger.active:hover,
a.list-group-item-danger.active:focus,
button.list-group-item-danger.active:focus {
color: #fff;
background-color: #a94442;
border-color: #a94442;
}
.list-group-item-heading {
margin-top: 0;
margin-bottom: 5px;
}
.list-group-item-text {
margin-bottom: 0;
line-height: 1.3;
}
.panel {
margin-bottom: 18px;
background-color: #fff;
border: 1px solid transparent;
border-radius: 2px;
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
.panel-body {
padding: 15px;
}
.panel-heading {
padding: 10px 15px;
border-bottom: 1px solid transparent;
border-top-right-radius: 1px;
border-top-left-radius: 1px;
}
.panel-heading > .dropdown .dropdown-toggle {
color: inherit;
}
.panel-title {
margin-top: 0;
margin-bottom: 0;
font-size: 15px;
color: inherit;
}
.panel-title > a,
.panel-title > small,
.panel-title > .small,
.panel-title > small > a,
.panel-title > .small > a {
color: inherit;
}
.panel-footer {
padding: 10px 15px;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
border-bottom-right-radius: 1px;
border-bottom-left-radius: 1px;
}
.panel > .list-group,
.panel > .panel-collapse > .list-group {
margin-bottom: 0;
}
.panel > .list-group .list-group-item,
.panel > .panel-collapse > .list-group .list-group-item {
border-width: 1px 0;
border-radius: 0;
}
.panel > .list-group:first-child .list-group-item:first-child,
.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
border-top: 0;
border-top-right-radius: 1px;
border-top-left-radius: 1px;
}
.panel > .list-group:last-child .list-group-item:last-child,
.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
border-bottom: 0;
border-bottom-right-radius: 1px;
border-bottom-left-radius: 1px;
}
.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
border-top-right-radius: 0;
border-top-left-radius: 0;
}
.panel-heading + .list-group .list-group-item:first-child {
border-top-width: 0;
}
.list-group + .panel-footer {
border-top-width: 0;
}
.panel > .table,
.panel > .table-responsive > .table,
.panel > .panel-collapse > .table {
margin-bottom: 0;
}
.panel > .table caption,
.panel > .table-responsive > .table caption,
.panel > .panel-collapse > .table caption {
padding-left: 15px;
padding-right: 15px;
}
.panel > .table:first-child,
.panel > .table-responsive:first-child > .table:first-child {
border-top-right-radius: 1px;
border-top-left-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
border-top-left-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
border-top-right-radius: 1px;
}
.panel > .table:last-child,
.panel > .table-responsive:last-child > .table:last-child {
border-bottom-right-radius: 1px;
border-bottom-left-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
border-bottom-left-radius: 1px;
border-bottom-right-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
border-bottom-left-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
border-bottom-right-radius: 1px;
}
.panel > .panel-body + .table,
.panel > .panel-body + .table-responsive,
.panel > .table + .panel-body,
.panel > .table-responsive + .panel-body {
border-top: 1px solid #ddd;
}
.panel > .table > tbody:first-child > tr:first-child th,
.panel > .table > tbody:first-child > tr:first-child td {
border-top: 0;
}
.panel > .table-bordered,
.panel > .table-responsive > .table-bordered {
border: 0;
}
.panel > .table-bordered > thead > tr > th:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
.panel > .table-bordered > tbody > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
.panel > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-bordered > thead > tr > td:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
.panel > .table-bordered > tbody > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
.panel > .table-bordered > tfoot > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
border-left: 0;
}
.panel > .table-bordered > thead > tr > th:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
.panel > .table-bordered > tbody > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
.panel > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-bordered > thead > tr > td:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
.panel > .table-bordered > tbody > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
.panel > .table-bordered > tfoot > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
border-right: 0;
}
.panel > .table-bordered > thead > tr:first-child > td,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
.panel > .table-bordered > tbody > tr:first-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
.panel > .table-bordered > thead > tr:first-child > th,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
.panel > .table-bordered > tbody > tr:first-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
border-bottom: 0;
}
.panel > .table-bordered > tbody > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
.panel > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-bordered > tbody > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
.panel > .table-bordered > tfoot > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
border-bottom: 0;
}
.panel > .table-responsive {
border: 0;
margin-bottom: 0;
}
.panel-group {
margin-bottom: 18px;
}
.panel-group .panel {
margin-bottom: 0;
border-radius: 2px;
}
.panel-group .panel + .panel {
margin-top: 5px;
}
.panel-group .panel-heading {
border-bottom: 0;
}
.panel-group .panel-heading + .panel-collapse > .panel-body,
.panel-group .panel-heading + .panel-collapse > .list-group {
border-top: 1px solid #ddd;
}
.panel-group .panel-footer {
border-top: 0;
}
.panel-group .panel-footer + .panel-collapse .panel-body {
border-bottom: 1px solid #ddd;
}
.panel-default {
border-color: #ddd;
}
.panel-default > .panel-heading {
color: #333333;
background-color: #f5f5f5;
border-color: #ddd;
}
.panel-default > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #ddd;
}
.panel-default > .panel-heading .badge {
color: #f5f5f5;
background-color: #333333;
}
.panel-default > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #ddd;
}
.panel-primary {
border-color: #337ab7;
}
.panel-primary > .panel-heading {
color: #fff;
background-color: #337ab7;
border-color: #337ab7;
}
.panel-primary > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #337ab7;
}
.panel-primary > .panel-heading .badge {
color: #337ab7;
background-color: #fff;
}
.panel-primary > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #337ab7;
}
.panel-success {
border-color: #d6e9c6;
}
.panel-success > .panel-heading {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.panel-success > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #d6e9c6;
}
.panel-success > .panel-heading .badge {
color: #dff0d8;
background-color: #3c763d;
}
.panel-success > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #d6e9c6;
}
.panel-info {
border-color: #bce8f1;
}
.panel-info > .panel-heading {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
.panel-info > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #bce8f1;
}
.panel-info > .panel-heading .badge {
color: #d9edf7;
background-color: #31708f;
}
.panel-info > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #bce8f1;
}
.panel-warning {
border-color: #faebcc;
}
.panel-warning > .panel-heading {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
.panel-warning > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #faebcc;
}
.panel-warning > .panel-heading .badge {
color: #fcf8e3;
background-color: #8a6d3b;
}
.panel-warning > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #faebcc;
}
.panel-danger {
border-color: #ebccd1;
}
.panel-danger > .panel-heading {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
.panel-danger > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #ebccd1;
}
.panel-danger > .panel-heading .badge {
color: #f2dede;
background-color: #a94442;
}
.panel-danger > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #ebccd1;
}
.embed-responsive {
position: relative;
display: block;
height: 0;
padding: 0;
overflow: hidden;
}
.embed-responsive .embed-responsive-item,
.embed-responsive iframe,
.embed-responsive embed,
.embed-responsive object,
.embed-responsive video {
position: absolute;
top: 0;
left: 0;
bottom: 0;
height: 100%;
width: 100%;
border: 0;
}
.embed-responsive-16by9 {
padding-bottom: 56.25%;
}
.embed-responsive-4by3 {
padding-bottom: 75%;
}
.well {
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
border-radius: 2px;
-webkit-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-lg {
padding: 24px;
border-radius: 3px;
}
.well-sm {
padding: 9px;
border-radius: 1px;
}
.close {
float: right;
font-size: 19.5px;
font-weight: bold;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
opacity: 0.2;
filter: alpha(opacity=20);
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
opacity: 0.5;
filter: alpha(opacity=50);
}
button.close {
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
}
.modal-open {
overflow: hidden;
}
.modal {
display: none;
overflow: hidden;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
-webkit-overflow-scrolling: touch;
outline: 0;
}
.modal.fade .modal-dialog {
-webkit-transform: translate(0, -25%);
-ms-transform: translate(0, -25%);
-o-transform: translate(0, -25%);
transform: translate(0, -25%);
-webkit-transition: -webkit-transform 0.3s ease-out;
-moz-transition: -moz-transform 0.3s ease-out;
-o-transition: -o-transform 0.3s ease-out;
transition: transform 0.3s ease-out;
}
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
.modal-open .modal {
overflow-x: hidden;
overflow-y: auto;
}
.modal-dialog {
position: relative;
width: auto;
margin: 10px;
}
.modal-content {
position: relative;
background-color: #fff;
border: 1px solid #999;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 3px;
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
background-clip: padding-box;
outline: 0;
}
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1040;
background-color: #000;
}
.modal-backdrop.fade {
opacity: 0;
filter: alpha(opacity=0);
}
.modal-backdrop.in {
opacity: 0.5;
filter: alpha(opacity=50);
}
.modal-header {
padding: 15px;
border-bottom: 1px solid #e5e5e5;
}
.modal-header .close {
margin-top: -2px;
}
.modal-title {
margin: 0;
line-height: 1.42857143;
}
.modal-body {
position: relative;
padding: 15px;
}
.modal-footer {
padding: 15px;
text-align: right;
border-top: 1px solid #e5e5e5;
}
.modal-footer .btn + .btn {
margin-left: 5px;
margin-bottom: 0;
}
.modal-footer .btn-group .btn + .btn {
margin-left: -1px;
}
.modal-footer .btn-block + .btn-block {
margin-left: 0;
}
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
@media (min-width: 768px) {
.modal-dialog {
width: 600px;
margin: 30px auto;
}
.modal-content {
-webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
}
.modal-sm {
width: 300px;
}
}
@media (min-width: 992px) {
.modal-lg {
width: 900px;
}
}
.tooltip {
position: absolute;
z-index: 1070;
display: block;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
font-size: 12px;
opacity: 0;
filter: alpha(opacity=0);
}
.tooltip.in {
opacity: 0.9;
filter: alpha(opacity=90);
}
.tooltip.top {
margin-top: -3px;
padding: 5px 0;
}
.tooltip.right {
margin-left: 3px;
padding: 0 5px;
}
.tooltip.bottom {
margin-top: 3px;
padding: 5px 0;
}
.tooltip.left {
margin-left: -3px;
padding: 0 5px;
}
.tooltip-inner {
max-width: 200px;
padding: 3px 8px;
color: #fff;
text-align: center;
background-color: #000;
border-radius: 2px;
}
.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-width: 5px 5px 0;
border-top-color: #000;
}
.tooltip.top-left .tooltip-arrow {
bottom: 0;
right: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0;
border-top-color: #000;
}
.tooltip.top-right .tooltip-arrow {
bottom: 0;
left: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0;
border-top-color: #000;
}
.tooltip.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -5px;
border-width: 5px 5px 5px 0;
border-right-color: #000;
}
.tooltip.left .tooltip-arrow {
top: 50%;
right: 0;
margin-top: -5px;
border-width: 5px 0 5px 5px;
border-left-color: #000;
}
.tooltip.bottom .tooltip-arrow {
top: 0;
left: 50%;
margin-left: -5px;
border-width: 0 5px 5px;
border-bottom-color: #000;
}
.tooltip.bottom-left .tooltip-arrow {
top: 0;
right: 5px;
margin-top: -5px;
border-width: 0 5px 5px;
border-bottom-color: #000;
}
.tooltip.bottom-right .tooltip-arrow {
top: 0;
left: 5px;
margin-top: -5px;
border-width: 0 5px 5px;
border-bottom-color: #000;
}
.popover {
position: absolute;
top: 0;
left: 0;
z-index: 1060;
display: none;
max-width: 276px;
padding: 1px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
font-size: 13px;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 3px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.popover.top {
margin-top: -10px;
}
.popover.right {
margin-left: 10px;
}
.popover.bottom {
margin-top: 10px;
}
.popover.left {
margin-left: -10px;
}
.popover-title {
margin: 0;
padding: 8px 14px;
font-size: 13px;
background-color: #f7f7f7;
border-bottom: 1px solid #ebebeb;
border-radius: 2px 2px 0 0;
}
.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: 11px;
}
.popover > .arrow:after {
border-width: 10px;
content: "";
}
.popover.top > .arrow {
left: 50%;
margin-left: -11px;
border-bottom-width: 0;
border-top-color: #999999;
border-top-color: rgba(0, 0, 0, 0.25);
bottom: -11px;
}
.popover.top > .arrow:after {
content: " ";
bottom: 1px;
margin-left: -10px;
border-bottom-width: 0;
border-top-color: #fff;
}
.popover.right > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
border-left-width: 0;
border-right-color: #999999;
border-right-color: rgba(0, 0, 0, 0.25);
}
.popover.right > .arrow:after {
content: " ";
left: 1px;
bottom: -10px;
border-left-width: 0;
border-right-color: #fff;
}
.popover.bottom > .arrow {
left: 50%;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999999;
border-bottom-color: rgba(0, 0, 0, 0.25);
top: -11px;
}
.popover.bottom > .arrow:after {
content: " ";
top: 1px;
margin-left: -10px;
border-top-width: 0;
border-bottom-color: #fff;
}
.popover.left > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
border-right-width: 0;
border-left-color: #999999;
border-left-color: rgba(0, 0, 0, 0.25);
}
.popover.left > .arrow:after {
content: " ";
right: 1px;
border-right-width: 0;
border-left-color: #fff;
bottom: -10px;
}
.carousel {
position: relative;
}
.carousel-inner {
position: relative;
overflow: hidden;
width: 100%;
}
.carousel-inner > .item {
display: none;
position: relative;
-webkit-transition: 0.6s ease-in-out left;
-o-transition: 0.6s ease-in-out left;
transition: 0.6s ease-in-out left;
}
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
line-height: 1;
}
@media all and (transform-3d), (-webkit-transform-3d) {
.carousel-inner > .item {
-webkit-transition: -webkit-transform 0.6s ease-in-out;
-moz-transition: -moz-transform 0.6s ease-in-out;
-o-transition: -o-transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
perspective: 1000px;
}
.carousel-inner > .item.next,
.carousel-inner > .item.active.right {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
left: 0;
}
.carousel-inner > .item.prev,
.carousel-inner > .item.active.left {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
left: 0;
}
.carousel-inner > .item.next.left,
.carousel-inner > .item.prev.right,
.carousel-inner > .item.active {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
left: 0;
}
}
.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: 0;
left: 0;
bottom: 0;
width: 15%;
opacity: 0.5;
filter: alpha(opacity=50);
font-size: 20px;
color: #fff;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
background-color: rgba(0, 0, 0, 0);
}
.carousel-control.left {
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
}
.carousel-control.right {
left: auto;
right: 0;
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
}
.carousel-control:hover,
.carousel-control:focus {
outline: 0;
color: #fff;
text-decoration: none;
opacity: 0.9;
filter: alpha(opacity=90);
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
position: absolute;
top: 50%;
margin-top: -10px;
z-index: 5;
display: inline-block;
}
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
left: 50%;
margin-left: -10px;
}
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-right {
right: 50%;
margin-right: -10px;
}
.carousel-control .icon-prev,
.carousel-control .icon-next {
width: 20px;
height: 20px;
line-height: 1;
font-family: serif;
}
.carousel-control .icon-prev:before {
content: '\2039';
}
.carousel-control .icon-next:before {
content: '\203a';
}
.carousel-indicators {
position: absolute;
bottom: 10px;
left: 50%;
z-index: 15;
width: 60%;
margin-left: -30%;
padding-left: 0;
list-style: none;
text-align: center;
}
.carousel-indicators li {
display: inline-block;
width: 10px;
height: 10px;
margin: 1px;
text-indent: -999px;
border: 1px solid #fff;
border-radius: 10px;
cursor: pointer;
background-color: #000 \9;
background-color: rgba(0, 0, 0, 0);
}
.carousel-indicators .active {
margin: 0;
width: 12px;
height: 12px;
background-color: #fff;
}
.carousel-caption {
position: absolute;
left: 15%;
right: 15%;
bottom: 20px;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
color: #fff;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.carousel-caption .btn {
text-shadow: none;
}
@media screen and (min-width: 768px) {
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right,
.carousel-control .icon-prev,
.carousel-control .icon-next {
width: 30px;
height: 30px;
margin-top: -10px;
font-size: 30px;
}
.carousel-control .glyphicon-chevron-left,
.carousel-control .icon-prev {
margin-left: -10px;
}
.carousel-control .glyphicon-chevron-right,
.carousel-control .icon-next {
margin-right: -10px;
}
.carousel-caption {
left: 20%;
right: 20%;
padding-bottom: 30px;
}
.carousel-indicators {
bottom: 20px;
}
}
.clearfix:before,
.clearfix:after,
.dl-horizontal dd:before,
.dl-horizontal dd:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after,
.form-horizontal .form-group:before,
.form-horizontal .form-group:after,
.btn-toolbar:before,
.btn-toolbar:after,
.btn-group-vertical > .btn-group:before,
.btn-group-vertical > .btn-group:after,
.nav:before,
.nav:after,
.navbar:before,
.navbar:after,
.navbar-header:before,
.navbar-header:after,
.navbar-collapse:before,
.navbar-collapse:after,
.pager:before,
.pager:after,
.panel-body:before,
.panel-body:after,
.modal-header:before,
.modal-header:after,
.modal-footer:before,
.modal-footer:after,
.item_buttons:before,
.item_buttons:after {
content: " ";
display: table;
}
.clearfix:after,
.dl-horizontal dd:after,
.container:after,
.container-fluid:after,
.row:after,
.form-horizontal .form-group:after,
.btn-toolbar:after,
.btn-group-vertical > .btn-group:after,
.nav:after,
.navbar:after,
.navbar-header:after,
.navbar-collapse:after,
.pager:after,
.panel-body:after,
.modal-header:after,
.modal-footer:after,
.item_buttons:after {
clear: both;
}
.center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
.pull-right {
float: right !important;
}
.pull-left {
float: left !important;
}
.hide {
display: none !important;
}
.show {
display: block !important;
}
.invisible {
visibility: hidden;
}
.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.hidden {
display: none !important;
}
.affix {
position: fixed;
}
@-ms-viewport {
width: device-width;
}
.visible-xs,
.visible-sm,
.visible-md,
.visible-lg {
display: none !important;
}
.visible-xs-block,
.visible-xs-inline,
.visible-xs-inline-block,
.visible-sm-block,
.visible-sm-inline,
.visible-sm-inline-block,
.visible-md-block,
.visible-md-inline,
.visible-md-inline-block,
.visible-lg-block,
.visible-lg-inline,
.visible-lg-inline-block {
display: none !important;
}
@media (max-width: 767px) {
.visible-xs {
display: block !important;
}
table.visible-xs {
display: table !important;
}
tr.visible-xs {
display: table-row !important;
}
th.visible-xs,
td.visible-xs {
display: table-cell !important;
}
}
@media (max-width: 767px) {
.visible-xs-block {
display: block !important;
}
}
@media (max-width: 767px) {
.visible-xs-inline {
display: inline !important;
}
}
@media (max-width: 767px) {
.visible-xs-inline-block {
display: inline-block !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm {
display: block !important;
}
table.visible-sm {
display: table !important;
}
tr.visible-sm {
display: table-row !important;
}
th.visible-sm,
td.visible-sm {
display: table-cell !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-block {
display: block !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-inline {
display: inline !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-inline-block {
display: inline-block !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md {
display: block !important;
}
table.visible-md {
display: table !important;
}
tr.visible-md {
display: table-row !important;
}
th.visible-md,
td.visible-md {
display: table-cell !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-block {
display: block !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-inline {
display: inline !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-inline-block {
display: inline-block !important;
}
}
@media (min-width: 1200px) {
.visible-lg {
display: block !important;
}
table.visible-lg {
display: table !important;
}
tr.visible-lg {
display: table-row !important;
}
th.visible-lg,
td.visible-lg {
display: table-cell !important;
}
}
@media (min-width: 1200px) {
.visible-lg-block {
display: block !important;
}
}
@media (min-width: 1200px) {
.visible-lg-inline {
display: inline !important;
}
}
@media (min-width: 1200px) {
.visible-lg-inline-block {
display: inline-block !important;
}
}
@media (max-width: 767px) {
.hidden-xs {
display: none !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.hidden-sm {
display: none !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.hidden-md {
display: none !important;
}
}
@media (min-width: 1200px) {
.hidden-lg {
display: none !important;
}
}
.visible-print {
display: none !important;
}
@media print {
.visible-print {
display: block !important;
}
table.visible-print {
display: table !important;
}
tr.visible-print {
display: table-row !important;
}
th.visible-print,
td.visible-print {
display: table-cell !important;
}
}
.visible-print-block {
display: none !important;
}
@media print {
.visible-print-block {
display: block !important;
}
}
.visible-print-inline {
display: none !important;
}
@media print {
.visible-print-inline {
display: inline !important;
}
}
.visible-print-inline-block {
display: none !important;
}
@media print {
.visible-print-inline-block {
display: inline-block !important;
}
}
@media print {
.hidden-print {
display: none !important;
}
}
/*!
*
* Font Awesome
*
*/
/*!
* Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
/* FONT PATH
* -------------------------- */
@font-face {
font-family: 'FontAwesome';
src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.2.0');
src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../components/font-awesome/fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../components/font-awesome/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
.fa {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* makes the font 33% larger relative to the icon container */
.fa-lg {
font-size: 1.33333333em;
line-height: 0.75em;
vertical-align: -15%;
}
.fa-2x {
font-size: 2em;
}
.fa-3x {
font-size: 3em;
}
.fa-4x {
font-size: 4em;
}
.fa-5x {
font-size: 5em;
}
.fa-fw {
width: 1.28571429em;
text-align: center;
}
.fa-ul {
padding-left: 0;
margin-left: 2.14285714em;
list-style-type: none;
}
.fa-ul > li {
position: relative;
}
.fa-li {
position: absolute;
left: -2.14285714em;
width: 2.14285714em;
top: 0.14285714em;
text-align: center;
}
.fa-li.fa-lg {
left: -1.85714286em;
}
.fa-border {
padding: .2em .25em .15em;
border: solid 0.08em #eee;
border-radius: .1em;
}
.pull-right {
float: right;
}
.pull-left {
float: left;
}
.fa.pull-left {
margin-right: .3em;
}
.fa.pull-right {
margin-left: .3em;
}
.fa-spin {
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
}
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.fa-rotate-90 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
.fa-rotate-180 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.fa-rotate-270 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg);
}
.fa-flip-horizontal {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
-webkit-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.fa-flip-vertical {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
-webkit-transform: scale(1, -1);
-ms-transform: scale(1, -1);
transform: scale(1, -1);
}
:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical {
filter: none;
}
.fa-stack {
position: relative;
display: inline-block;
width: 2em;
height: 2em;
line-height: 2em;
vertical-align: middle;
}
.fa-stack-1x,
.fa-stack-2x {
position: absolute;
left: 0;
width: 100%;
text-align: center;
}
.fa-stack-1x {
line-height: inherit;
}
.fa-stack-2x {
font-size: 2em;
}
.fa-inverse {
color: #fff;
}
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
readers do not read off random characters that represent icons */
.fa-glass:before {
content: "\f000";
}
.fa-music:before {
content: "\f001";
}
.fa-search:before {
content: "\f002";
}
.fa-envelope-o:before {
content: "\f003";
}
.fa-heart:before {
content: "\f004";
}
.fa-star:before {
content: "\f005";
}
.fa-star-o:before {
content: "\f006";
}
.fa-user:before {
content: "\f007";
}
.fa-film:before {
content: "\f008";
}
.fa-th-large:before {
content: "\f009";
}
.fa-th:before {
content: "\f00a";
}
.fa-th-list:before {
content: "\f00b";
}
.fa-check:before {
content: "\f00c";
}
.fa-remove:before,
.fa-close:before,
.fa-times:before {
content: "\f00d";
}
.fa-search-plus:before {
content: "\f00e";
}
.fa-search-minus:before {
content: "\f010";
}
.fa-power-off:before {
content: "\f011";
}
.fa-signal:before {
content: "\f012";
}
.fa-gear:before,
.fa-cog:before {
content: "\f013";
}
.fa-trash-o:before {
content: "\f014";
}
.fa-home:before {
content: "\f015";
}
.fa-file-o:before {
content: "\f016";
}
.fa-clock-o:before {
content: "\f017";
}
.fa-road:before {
content: "\f018";
}
.fa-download:before {
content: "\f019";
}
.fa-arrow-circle-o-down:before {
content: "\f01a";
}
.fa-arrow-circle-o-up:before {
content: "\f01b";
}
.fa-inbox:before {
content: "\f01c";
}
.fa-play-circle-o:before {
content: "\f01d";
}
.fa-rotate-right:before,
.fa-repeat:before {
content: "\f01e";
}
.fa-refresh:before {
content: "\f021";
}
.fa-list-alt:before {
content: "\f022";
}
.fa-lock:before {
content: "\f023";
}
.fa-flag:before {
content: "\f024";
}
.fa-headphones:before {
content: "\f025";
}
.fa-volume-off:before {
content: "\f026";
}
.fa-volume-down:before {
content: "\f027";
}
.fa-volume-up:before {
content: "\f028";
}
.fa-qrcode:before {
content: "\f029";
}
.fa-barcode:before {
content: "\f02a";
}
.fa-tag:before {
content: "\f02b";
}
.fa-tags:before {
content: "\f02c";
}
.fa-book:before {
content: "\f02d";
}
.fa-bookmark:before {
content: "\f02e";
}
.fa-print:before {
content: "\f02f";
}
.fa-camera:before {
content: "\f030";
}
.fa-font:before {
content: "\f031";
}
.fa-bold:before {
content: "\f032";
}
.fa-italic:before {
content: "\f033";
}
.fa-text-height:before {
content: "\f034";
}
.fa-text-width:before {
content: "\f035";
}
.fa-align-left:before {
content: "\f036";
}
.fa-align-center:before {
content: "\f037";
}
.fa-align-right:before {
content: "\f038";
}
.fa-align-justify:before {
content: "\f039";
}
.fa-list:before {
content: "\f03a";
}
.fa-dedent:before,
.fa-outdent:before {
content: "\f03b";
}
.fa-indent:before {
content: "\f03c";
}
.fa-video-camera:before {
content: "\f03d";
}
.fa-photo:before,
.fa-image:before,
.fa-picture-o:before {
content: "\f03e";
}
.fa-pencil:before {
content: "\f040";
}
.fa-map-marker:before {
content: "\f041";
}
.fa-adjust:before {
content: "\f042";
}
.fa-tint:before {
content: "\f043";
}
.fa-edit:before,
.fa-pencil-square-o:before {
content: "\f044";
}
.fa-share-square-o:before {
content: "\f045";
}
.fa-check-square-o:before {
content: "\f046";
}
.fa-arrows:before {
content: "\f047";
}
.fa-step-backward:before {
content: "\f048";
}
.fa-fast-backward:before {
content: "\f049";
}
.fa-backward:before {
content: "\f04a";
}
.fa-play:before {
content: "\f04b";
}
.fa-pause:before {
content: "\f04c";
}
.fa-stop:before {
content: "\f04d";
}
.fa-forward:before {
content: "\f04e";
}
.fa-fast-forward:before {
content: "\f050";
}
.fa-step-forward:before {
content: "\f051";
}
.fa-eject:before {
content: "\f052";
}
.fa-chevron-left:before {
content: "\f053";
}
.fa-chevron-right:before {
content: "\f054";
}
.fa-plus-circle:before {
content: "\f055";
}
.fa-minus-circle:before {
content: "\f056";
}
.fa-times-circle:before {
content: "\f057";
}
.fa-check-circle:before {
content: "\f058";
}
.fa-question-circle:before {
content: "\f059";
}
.fa-info-circle:before {
content: "\f05a";
}
.fa-crosshairs:before {
content: "\f05b";
}
.fa-times-circle-o:before {
content: "\f05c";
}
.fa-check-circle-o:before {
content: "\f05d";
}
.fa-ban:before {
content: "\f05e";
}
.fa-arrow-left:before {
content: "\f060";
}
.fa-arrow-right:before {
content: "\f061";
}
.fa-arrow-up:before {
content: "\f062";
}
.fa-arrow-down:before {
content: "\f063";
}
.fa-mail-forward:before,
.fa-share:before {
content: "\f064";
}
.fa-expand:before {
content: "\f065";
}
.fa-compress:before {
content: "\f066";
}
.fa-plus:before {
content: "\f067";
}
.fa-minus:before {
content: "\f068";
}
.fa-asterisk:before {
content: "\f069";
}
.fa-exclamation-circle:before {
content: "\f06a";
}
.fa-gift:before {
content: "\f06b";
}
.fa-leaf:before {
content: "\f06c";
}
.fa-fire:before {
content: "\f06d";
}
.fa-eye:before {
content: "\f06e";
}
.fa-eye-slash:before {
content: "\f070";
}
.fa-warning:before,
.fa-exclamation-triangle:before {
content: "\f071";
}
.fa-plane:before {
content: "\f072";
}
.fa-calendar:before {
content: "\f073";
}
.fa-random:before {
content: "\f074";
}
.fa-comment:before {
content: "\f075";
}
.fa-magnet:before {
content: "\f076";
}
.fa-chevron-up:before {
content: "\f077";
}
.fa-chevron-down:before {
content: "\f078";
}
.fa-retweet:before {
content: "\f079";
}
.fa-shopping-cart:before {
content: "\f07a";
}
.fa-folder:before {
content: "\f07b";
}
.fa-folder-open:before {
content: "\f07c";
}
.fa-arrows-v:before {
content: "\f07d";
}
.fa-arrows-h:before {
content: "\f07e";
}
.fa-bar-chart-o:before,
.fa-bar-chart:before {
content: "\f080";
}
.fa-twitter-square:before {
content: "\f081";
}
.fa-facebook-square:before {
content: "\f082";
}
.fa-camera-retro:before {
content: "\f083";
}
.fa-key:before {
content: "\f084";
}
.fa-gears:before,
.fa-cogs:before {
content: "\f085";
}
.fa-comments:before {
content: "\f086";
}
.fa-thumbs-o-up:before {
content: "\f087";
}
.fa-thumbs-o-down:before {
content: "\f088";
}
.fa-star-half:before {
content: "\f089";
}
.fa-heart-o:before {
content: "\f08a";
}
.fa-sign-out:before {
content: "\f08b";
}
.fa-linkedin-square:before {
content: "\f08c";
}
.fa-thumb-tack:before {
content: "\f08d";
}
.fa-external-link:before {
content: "\f08e";
}
.fa-sign-in:before {
content: "\f090";
}
.fa-trophy:before {
content: "\f091";
}
.fa-github-square:before {
content: "\f092";
}
.fa-upload:before {
content: "\f093";
}
.fa-lemon-o:before {
content: "\f094";
}
.fa-phone:before {
content: "\f095";
}
.fa-square-o:before {
content: "\f096";
}
.fa-bookmark-o:before {
content: "\f097";
}
.fa-phone-square:before {
content: "\f098";
}
.fa-twitter:before {
content: "\f099";
}
.fa-facebook:before {
content: "\f09a";
}
.fa-github:before {
content: "\f09b";
}
.fa-unlock:before {
content: "\f09c";
}
.fa-credit-card:before {
content: "\f09d";
}
.fa-rss:before {
content: "\f09e";
}
.fa-hdd-o:before {
content: "\f0a0";
}
.fa-bullhorn:before {
content: "\f0a1";
}
.fa-bell:before {
content: "\f0f3";
}
.fa-certificate:before {
content: "\f0a3";
}
.fa-hand-o-right:before {
content: "\f0a4";
}
.fa-hand-o-left:before {
content: "\f0a5";
}
.fa-hand-o-up:before {
content: "\f0a6";
}
.fa-hand-o-down:before {
content: "\f0a7";
}
.fa-arrow-circle-left:before {
content: "\f0a8";
}
.fa-arrow-circle-right:before {
content: "\f0a9";
}
.fa-arrow-circle-up:before {
content: "\f0aa";
}
.fa-arrow-circle-down:before {
content: "\f0ab";
}
.fa-globe:before {
content: "\f0ac";
}
.fa-wrench:before {
content: "\f0ad";
}
.fa-tasks:before {
content: "\f0ae";
}
.fa-filter:before {
content: "\f0b0";
}
.fa-briefcase:before {
content: "\f0b1";
}
.fa-arrows-alt:before {
content: "\f0b2";
}
.fa-group:before,
.fa-users:before {
content: "\f0c0";
}
.fa-chain:before,
.fa-link:before {
content: "\f0c1";
}
.fa-cloud:before {
content: "\f0c2";
}
.fa-flask:before {
content: "\f0c3";
}
.fa-cut:before,
.fa-scissors:before {
content: "\f0c4";
}
.fa-copy:before,
.fa-files-o:before {
content: "\f0c5";
}
.fa-paperclip:before {
content: "\f0c6";
}
.fa-save:before,
.fa-floppy-o:before {
content: "\f0c7";
}
.fa-square:before {
content: "\f0c8";
}
.fa-navicon:before,
.fa-reorder:before,
.fa-bars:before {
content: "\f0c9";
}
.fa-list-ul:before {
content: "\f0ca";
}
.fa-list-ol:before {
content: "\f0cb";
}
.fa-strikethrough:before {
content: "\f0cc";
}
.fa-underline:before {
content: "\f0cd";
}
.fa-table:before {
content: "\f0ce";
}
.fa-magic:before {
content: "\f0d0";
}
.fa-truck:before {
content: "\f0d1";
}
.fa-pinterest:before {
content: "\f0d2";
}
.fa-pinterest-square:before {
content: "\f0d3";
}
.fa-google-plus-square:before {
content: "\f0d4";
}
.fa-google-plus:before {
content: "\f0d5";
}
.fa-money:before {
content: "\f0d6";
}
.fa-caret-down:before {
content: "\f0d7";
}
.fa-caret-up:before {
content: "\f0d8";
}
.fa-caret-left:before {
content: "\f0d9";
}
.fa-caret-right:before {
content: "\f0da";
}
.fa-columns:before {
content: "\f0db";
}
.fa-unsorted:before,
.fa-sort:before {
content: "\f0dc";
}
.fa-sort-down:before,
.fa-sort-desc:before {
content: "\f0dd";
}
.fa-sort-up:before,
.fa-sort-asc:before {
content: "\f0de";
}
.fa-envelope:before {
content: "\f0e0";
}
.fa-linkedin:before {
content: "\f0e1";
}
.fa-rotate-left:before,
.fa-undo:before {
content: "\f0e2";
}
.fa-legal:before,
.fa-gavel:before {
content: "\f0e3";
}
.fa-dashboard:before,
.fa-tachometer:before {
content: "\f0e4";
}
.fa-comment-o:before {
content: "\f0e5";
}
.fa-comments-o:before {
content: "\f0e6";
}
.fa-flash:before,
.fa-bolt:before {
content: "\f0e7";
}
.fa-sitemap:before {
content: "\f0e8";
}
.fa-umbrella:before {
content: "\f0e9";
}
.fa-paste:before,
.fa-clipboard:before {
content: "\f0ea";
}
.fa-lightbulb-o:before {
content: "\f0eb";
}
.fa-exchange:before {
content: "\f0ec";
}
.fa-cloud-download:before {
content: "\f0ed";
}
.fa-cloud-upload:before {
content: "\f0ee";
}
.fa-user-md:before {
content: "\f0f0";
}
.fa-stethoscope:before {
content: "\f0f1";
}
.fa-suitcase:before {
content: "\f0f2";
}
.fa-bell-o:before {
content: "\f0a2";
}
.fa-coffee:before {
content: "\f0f4";
}
.fa-cutlery:before {
content: "\f0f5";
}
.fa-file-text-o:before {
content: "\f0f6";
}
.fa-building-o:before {
content: "\f0f7";
}
.fa-hospital-o:before {
content: "\f0f8";
}
.fa-ambulance:before {
content: "\f0f9";
}
.fa-medkit:before {
content: "\f0fa";
}
.fa-fighter-jet:before {
content: "\f0fb";
}
.fa-beer:before {
content: "\f0fc";
}
.fa-h-square:before {
content: "\f0fd";
}
.fa-plus-square:before {
content: "\f0fe";
}
.fa-angle-double-left:before {
content: "\f100";
}
.fa-angle-double-right:before {
content: "\f101";
}
.fa-angle-double-up:before {
content: "\f102";
}
.fa-angle-double-down:before {
content: "\f103";
}
.fa-angle-left:before {
content: "\f104";
}
.fa-angle-right:before {
content: "\f105";
}
.fa-angle-up:before {
content: "\f106";
}
.fa-angle-down:before {
content: "\f107";
}
.fa-desktop:before {
content: "\f108";
}
.fa-laptop:before {
content: "\f109";
}
.fa-tablet:before {
content: "\f10a";
}
.fa-mobile-phone:before,
.fa-mobile:before {
content: "\f10b";
}
.fa-circle-o:before {
content: "\f10c";
}
.fa-quote-left:before {
content: "\f10d";
}
.fa-quote-right:before {
content: "\f10e";
}
.fa-spinner:before {
content: "\f110";
}
.fa-circle:before {
content: "\f111";
}
.fa-mail-reply:before,
.fa-reply:before {
content: "\f112";
}
.fa-github-alt:before {
content: "\f113";
}
.fa-folder-o:before {
content: "\f114";
}
.fa-folder-open-o:before {
content: "\f115";
}
.fa-smile-o:before {
content: "\f118";
}
.fa-frown-o:before {
content: "\f119";
}
.fa-meh-o:before {
content: "\f11a";
}
.fa-gamepad:before {
content: "\f11b";
}
.fa-keyboard-o:before {
content: "\f11c";
}
.fa-flag-o:before {
content: "\f11d";
}
.fa-flag-checkered:before {
content: "\f11e";
}
.fa-terminal:before {
content: "\f120";
}
.fa-code:before {
content: "\f121";
}
.fa-mail-reply-all:before,
.fa-reply-all:before {
content: "\f122";
}
.fa-star-half-empty:before,
.fa-star-half-full:before,
.fa-star-half-o:before {
content: "\f123";
}
.fa-location-arrow:before {
content: "\f124";
}
.fa-crop:before {
content: "\f125";
}
.fa-code-fork:before {
content: "\f126";
}
.fa-unlink:before,
.fa-chain-broken:before {
content: "\f127";
}
.fa-question:before {
content: "\f128";
}
.fa-info:before {
content: "\f129";
}
.fa-exclamation:before {
content: "\f12a";
}
.fa-superscript:before {
content: "\f12b";
}
.fa-subscript:before {
content: "\f12c";
}
.fa-eraser:before {
content: "\f12d";
}
.fa-puzzle-piece:before {
content: "\f12e";
}
.fa-microphone:before {
content: "\f130";
}
.fa-microphone-slash:before {
content: "\f131";
}
.fa-shield:before {
content: "\f132";
}
.fa-calendar-o:before {
content: "\f133";
}
.fa-fire-extinguisher:before {
content: "\f134";
}
.fa-rocket:before {
content: "\f135";
}
.fa-maxcdn:before {
content: "\f136";
}
.fa-chevron-circle-left:before {
content: "\f137";
}
.fa-chevron-circle-right:before {
content: "\f138";
}
.fa-chevron-circle-up:before {
content: "\f139";
}
.fa-chevron-circle-down:before {
content: "\f13a";
}
.fa-html5:before {
content: "\f13b";
}
.fa-css3:before {
content: "\f13c";
}
.fa-anchor:before {
content: "\f13d";
}
.fa-unlock-alt:before {
content: "\f13e";
}
.fa-bullseye:before {
content: "\f140";
}
.fa-ellipsis-h:before {
content: "\f141";
}
.fa-ellipsis-v:before {
content: "\f142";
}
.fa-rss-square:before {
content: "\f143";
}
.fa-play-circle:before {
content: "\f144";
}
.fa-ticket:before {
content: "\f145";
}
.fa-minus-square:before {
content: "\f146";
}
.fa-minus-square-o:before {
content: "\f147";
}
.fa-level-up:before {
content: "\f148";
}
.fa-level-down:before {
content: "\f149";
}
.fa-check-square:before {
content: "\f14a";
}
.fa-pencil-square:before {
content: "\f14b";
}
.fa-external-link-square:before {
content: "\f14c";
}
.fa-share-square:before {
content: "\f14d";
}
.fa-compass:before {
content: "\f14e";
}
.fa-toggle-down:before,
.fa-caret-square-o-down:before {
content: "\f150";
}
.fa-toggle-up:before,
.fa-caret-square-o-up:before {
content: "\f151";
}
.fa-toggle-right:before,
.fa-caret-square-o-right:before {
content: "\f152";
}
.fa-euro:before,
.fa-eur:before {
content: "\f153";
}
.fa-gbp:before {
content: "\f154";
}
.fa-dollar:before,
.fa-usd:before {
content: "\f155";
}
.fa-rupee:before,
.fa-inr:before {
content: "\f156";
}
.fa-cny:before,
.fa-rmb:before,
.fa-yen:before,
.fa-jpy:before {
content: "\f157";
}
.fa-ruble:before,
.fa-rouble:before,
.fa-rub:before {
content: "\f158";
}
.fa-won:before,
.fa-krw:before {
content: "\f159";
}
.fa-bitcoin:before,
.fa-btc:before {
content: "\f15a";
}
.fa-file:before {
content: "\f15b";
}
.fa-file-text:before {
content: "\f15c";
}
.fa-sort-alpha-asc:before {
content: "\f15d";
}
.fa-sort-alpha-desc:before {
content: "\f15e";
}
.fa-sort-amount-asc:before {
content: "\f160";
}
.fa-sort-amount-desc:before {
content: "\f161";
}
.fa-sort-numeric-asc:before {
content: "\f162";
}
.fa-sort-numeric-desc:before {
content: "\f163";
}
.fa-thumbs-up:before {
content: "\f164";
}
.fa-thumbs-down:before {
content: "\f165";
}
.fa-youtube-square:before {
content: "\f166";
}
.fa-youtube:before {
content: "\f167";
}
.fa-xing:before {
content: "\f168";
}
.fa-xing-square:before {
content: "\f169";
}
.fa-youtube-play:before {
content: "\f16a";
}
.fa-dropbox:before {
content: "\f16b";
}
.fa-stack-overflow:before {
content: "\f16c";
}
.fa-instagram:before {
content: "\f16d";
}
.fa-flickr:before {
content: "\f16e";
}
.fa-adn:before {
content: "\f170";
}
.fa-bitbucket:before {
content: "\f171";
}
.fa-bitbucket-square:before {
content: "\f172";
}
.fa-tumblr:before {
content: "\f173";
}
.fa-tumblr-square:before {
content: "\f174";
}
.fa-long-arrow-down:before {
content: "\f175";
}
.fa-long-arrow-up:before {
content: "\f176";
}
.fa-long-arrow-left:before {
content: "\f177";
}
.fa-long-arrow-right:before {
content: "\f178";
}
.fa-apple:before {
content: "\f179";
}
.fa-windows:before {
content: "\f17a";
}
.fa-android:before {
content: "\f17b";
}
.fa-linux:before {
content: "\f17c";
}
.fa-dribbble:before {
content: "\f17d";
}
.fa-skype:before {
content: "\f17e";
}
.fa-foursquare:before {
content: "\f180";
}
.fa-trello:before {
content: "\f181";
}
.fa-female:before {
content: "\f182";
}
.fa-male:before {
content: "\f183";
}
.fa-gittip:before {
content: "\f184";
}
.fa-sun-o:before {
content: "\f185";
}
.fa-moon-o:before {
content: "\f186";
}
.fa-archive:before {
content: "\f187";
}
.fa-bug:before {
content: "\f188";
}
.fa-vk:before {
content: "\f189";
}
.fa-weibo:before {
content: "\f18a";
}
.fa-renren:before {
content: "\f18b";
}
.fa-pagelines:before {
content: "\f18c";
}
.fa-stack-exchange:before {
content: "\f18d";
}
.fa-arrow-circle-o-right:before {
content: "\f18e";
}
.fa-arrow-circle-o-left:before {
content: "\f190";
}
.fa-toggle-left:before,
.fa-caret-square-o-left:before {
content: "\f191";
}
.fa-dot-circle-o:before {
content: "\f192";
}
.fa-wheelchair:before {
content: "\f193";
}
.fa-vimeo-square:before {
content: "\f194";
}
.fa-turkish-lira:before,
.fa-try:before {
content: "\f195";
}
.fa-plus-square-o:before {
content: "\f196";
}
.fa-space-shuttle:before {
content: "\f197";
}
.fa-slack:before {
content: "\f198";
}
.fa-envelope-square:before {
content: "\f199";
}
.fa-wordpress:before {
content: "\f19a";
}
.fa-openid:before {
content: "\f19b";
}
.fa-institution:before,
.fa-bank:before,
.fa-university:before {
content: "\f19c";
}
.fa-mortar-board:before,
.fa-graduation-cap:before {
content: "\f19d";
}
.fa-yahoo:before {
content: "\f19e";
}
.fa-google:before {
content: "\f1a0";
}
.fa-reddit:before {
content: "\f1a1";
}
.fa-reddit-square:before {
content: "\f1a2";
}
.fa-stumbleupon-circle:before {
content: "\f1a3";
}
.fa-stumbleupon:before {
content: "\f1a4";
}
.fa-delicious:before {
content: "\f1a5";
}
.fa-digg:before {
content: "\f1a6";
}
.fa-pied-piper:before {
content: "\f1a7";
}
.fa-pied-piper-alt:before {
content: "\f1a8";
}
.fa-drupal:before {
content: "\f1a9";
}
.fa-joomla:before {
content: "\f1aa";
}
.fa-language:before {
content: "\f1ab";
}
.fa-fax:before {
content: "\f1ac";
}
.fa-building:before {
content: "\f1ad";
}
.fa-child:before {
content: "\f1ae";
}
.fa-paw:before {
content: "\f1b0";
}
.fa-spoon:before {
content: "\f1b1";
}
.fa-cube:before {
content: "\f1b2";
}
.fa-cubes:before {
content: "\f1b3";
}
.fa-behance:before {
content: "\f1b4";
}
.fa-behance-square:before {
content: "\f1b5";
}
.fa-steam:before {
content: "\f1b6";
}
.fa-steam-square:before {
content: "\f1b7";
}
.fa-recycle:before {
content: "\f1b8";
}
.fa-automobile:before,
.fa-car:before {
content: "\f1b9";
}
.fa-cab:before,
.fa-taxi:before {
content: "\f1ba";
}
.fa-tree:before {
content: "\f1bb";
}
.fa-spotify:before {
content: "\f1bc";
}
.fa-deviantart:before {
content: "\f1bd";
}
.fa-soundcloud:before {
content: "\f1be";
}
.fa-database:before {
content: "\f1c0";
}
.fa-file-pdf-o:before {
content: "\f1c1";
}
.fa-file-word-o:before {
content: "\f1c2";
}
.fa-file-excel-o:before {
content: "\f1c3";
}
.fa-file-powerpoint-o:before {
content: "\f1c4";
}
.fa-file-photo-o:before,
.fa-file-picture-o:before,
.fa-file-image-o:before {
content: "\f1c5";
}
.fa-file-zip-o:before,
.fa-file-archive-o:before {
content: "\f1c6";
}
.fa-file-sound-o:before,
.fa-file-audio-o:before {
content: "\f1c7";
}
.fa-file-movie-o:before,
.fa-file-video-o:before {
content: "\f1c8";
}
.fa-file-code-o:before {
content: "\f1c9";
}
.fa-vine:before {
content: "\f1ca";
}
.fa-codepen:before {
content: "\f1cb";
}
.fa-jsfiddle:before {
content: "\f1cc";
}
.fa-life-bouy:before,
.fa-life-buoy:before,
.fa-life-saver:before,
.fa-support:before,
.fa-life-ring:before {
content: "\f1cd";
}
.fa-circle-o-notch:before {
content: "\f1ce";
}
.fa-ra:before,
.fa-rebel:before {
content: "\f1d0";
}
.fa-ge:before,
.fa-empire:before {
content: "\f1d1";
}
.fa-git-square:before {
content: "\f1d2";
}
.fa-git:before {
content: "\f1d3";
}
.fa-hacker-news:before {
content: "\f1d4";
}
.fa-tencent-weibo:before {
content: "\f1d5";
}
.fa-qq:before {
content: "\f1d6";
}
.fa-wechat:before,
.fa-weixin:before {
content: "\f1d7";
}
.fa-send:before,
.fa-paper-plane:before {
content: "\f1d8";
}
.fa-send-o:before,
.fa-paper-plane-o:before {
content: "\f1d9";
}
.fa-history:before {
content: "\f1da";
}
.fa-circle-thin:before {
content: "\f1db";
}
.fa-header:before {
content: "\f1dc";
}
.fa-paragraph:before {
content: "\f1dd";
}
.fa-sliders:before {
content: "\f1de";
}
.fa-share-alt:before {
content: "\f1e0";
}
.fa-share-alt-square:before {
content: "\f1e1";
}
.fa-bomb:before {
content: "\f1e2";
}
.fa-soccer-ball-o:before,
.fa-futbol-o:before {
content: "\f1e3";
}
.fa-tty:before {
content: "\f1e4";
}
.fa-binoculars:before {
content: "\f1e5";
}
.fa-plug:before {
content: "\f1e6";
}
.fa-slideshare:before {
content: "\f1e7";
}
.fa-twitch:before {
content: "\f1e8";
}
.fa-yelp:before {
content: "\f1e9";
}
.fa-newspaper-o:before {
content: "\f1ea";
}
.fa-wifi:before {
content: "\f1eb";
}
.fa-calculator:before {
content: "\f1ec";
}
.fa-paypal:before {
content: "\f1ed";
}
.fa-google-wallet:before {
content: "\f1ee";
}
.fa-cc-visa:before {
content: "\f1f0";
}
.fa-cc-mastercard:before {
content: "\f1f1";
}
.fa-cc-discover:before {
content: "\f1f2";
}
.fa-cc-amex:before {
content: "\f1f3";
}
.fa-cc-paypal:before {
content: "\f1f4";
}
.fa-cc-stripe:before {
content: "\f1f5";
}
.fa-bell-slash:before {
content: "\f1f6";
}
.fa-bell-slash-o:before {
content: "\f1f7";
}
.fa-trash:before {
content: "\f1f8";
}
.fa-copyright:before {
content: "\f1f9";
}
.fa-at:before {
content: "\f1fa";
}
.fa-eyedropper:before {
content: "\f1fb";
}
.fa-paint-brush:before {
content: "\f1fc";
}
.fa-birthday-cake:before {
content: "\f1fd";
}
.fa-area-chart:before {
content: "\f1fe";
}
.fa-pie-chart:before {
content: "\f200";
}
.fa-line-chart:before {
content: "\f201";
}
.fa-lastfm:before {
content: "\f202";
}
.fa-lastfm-square:before {
content: "\f203";
}
.fa-toggle-off:before {
content: "\f204";
}
.fa-toggle-on:before {
content: "\f205";
}
.fa-bicycle:before {
content: "\f206";
}
.fa-bus:before {
content: "\f207";
}
.fa-ioxhost:before {
content: "\f208";
}
.fa-angellist:before {
content: "\f209";
}
.fa-cc:before {
content: "\f20a";
}
.fa-shekel:before,
.fa-sheqel:before,
.fa-ils:before {
content: "\f20b";
}
.fa-meanpath:before {
content: "\f20c";
}
/*!
*
* IPython base
*
*/
.modal.fade .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
code {
color: #000;
}
pre {
font-size: inherit;
line-height: inherit;
}
label {
font-weight: normal;
}
/* Make the page background atleast 100% the height of the view port */
/* Make the page itself atleast 70% the height of the view port */
.border-box-sizing {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.corner-all {
border-radius: 2px;
}
.no-padding {
padding: 0px;
}
/* Flexible box model classes */
/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
/* This file is a compatability layer. It allows the usage of flexible box
model layouts accross multiple browsers, including older browsers. The newest,
universal implementation of the flexible box model is used when available (see
`Modern browsers` comments below). Browsers that are known to implement this
new spec completely include:
Firefox 28.0+
Chrome 29.0+
Internet Explorer 11+
Opera 17.0+
Browsers not listed, including Safari, are supported via the styling under the
`Old browsers` comments below.
*/
.hbox {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
}
.hbox > * {
/* Old browsers */
-webkit-box-flex: 0;
-moz-box-flex: 0;
box-flex: 0;
/* Modern browsers */
flex: none;
}
.vbox {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
}
.vbox > * {
/* Old browsers */
-webkit-box-flex: 0;
-moz-box-flex: 0;
box-flex: 0;
/* Modern browsers */
flex: none;
}
.hbox.reverse,
.vbox.reverse,
.reverse {
/* Old browsers */
-webkit-box-direction: reverse;
-moz-box-direction: reverse;
box-direction: reverse;
/* Modern browsers */
flex-direction: row-reverse;
}
.hbox.box-flex0,
.vbox.box-flex0,
.box-flex0 {
/* Old browsers */
-webkit-box-flex: 0;
-moz-box-flex: 0;
box-flex: 0;
/* Modern browsers */
flex: none;
width: auto;
}
.hbox.box-flex1,
.vbox.box-flex1,
.box-flex1 {
/* Old browsers */
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
/* Modern browsers */
flex: 1;
}
.hbox.box-flex,
.vbox.box-flex,
.box-flex {
/* Old browsers */
/* Old browsers */
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
/* Modern browsers */
flex: 1;
}
.hbox.box-flex2,
.vbox.box-flex2,
.box-flex2 {
/* Old browsers */
-webkit-box-flex: 2;
-moz-box-flex: 2;
box-flex: 2;
/* Modern browsers */
flex: 2;
}
.box-group1 {
/* Deprecated */
-webkit-box-flex-group: 1;
-moz-box-flex-group: 1;
box-flex-group: 1;
}
.box-group2 {
/* Deprecated */
-webkit-box-flex-group: 2;
-moz-box-flex-group: 2;
box-flex-group: 2;
}
.hbox.start,
.vbox.start,
.start {
/* Old browsers */
-webkit-box-pack: start;
-moz-box-pack: start;
box-pack: start;
/* Modern browsers */
justify-content: flex-start;
}
.hbox.end,
.vbox.end,
.end {
/* Old browsers */
-webkit-box-pack: end;
-moz-box-pack: end;
box-pack: end;
/* Modern browsers */
justify-content: flex-end;
}
.hbox.center,
.vbox.center,
.center {
/* Old browsers */
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
/* Modern browsers */
justify-content: center;
}
.hbox.baseline,
.vbox.baseline,
.baseline {
/* Old browsers */
-webkit-box-pack: baseline;
-moz-box-pack: baseline;
box-pack: baseline;
/* Modern browsers */
justify-content: baseline;
}
.hbox.stretch,
.vbox.stretch,
.stretch {
/* Old browsers */
-webkit-box-pack: stretch;
-moz-box-pack: stretch;
box-pack: stretch;
/* Modern browsers */
justify-content: stretch;
}
.hbox.align-start,
.vbox.align-start,
.align-start {
/* Old browsers */
-webkit-box-align: start;
-moz-box-align: start;
box-align: start;
/* Modern browsers */
align-items: flex-start;
}
.hbox.align-end,
.vbox.align-end,
.align-end {
/* Old browsers */
-webkit-box-align: end;
-moz-box-align: end;
box-align: end;
/* Modern browsers */
align-items: flex-end;
}
.hbox.align-center,
.vbox.align-center,
.align-center {
/* Old browsers */
-webkit-box-align: center;
-moz-box-align: center;
box-align: center;
/* Modern browsers */
align-items: center;
}
.hbox.align-baseline,
.vbox.align-baseline,
.align-baseline {
/* Old browsers */
-webkit-box-align: baseline;
-moz-box-align: baseline;
box-align: baseline;
/* Modern browsers */
align-items: baseline;
}
.hbox.align-stretch,
.vbox.align-stretch,
.align-stretch {
/* Old browsers */
-webkit-box-align: stretch;
-moz-box-align: stretch;
box-align: stretch;
/* Modern browsers */
align-items: stretch;
}
div.error {
margin: 2em;
text-align: center;
}
div.error > h1 {
font-size: 500%;
line-height: normal;
}
div.error > p {
font-size: 200%;
line-height: normal;
}
div.traceback-wrapper {
text-align: left;
max-width: 800px;
margin: auto;
}
/**
* Primary styles
*
* Author: Jupyter Development Team
*/
body {
background-color: #fff;
/* This makes sure that the body covers the entire window and needs to
be in a different element than the display: box in wrapper below */
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
overflow: visible;
}
body > #header {
/* Initially hidden to prevent FLOUC */
display: none;
background-color: #fff;
/* Display over codemirror */
position: relative;
z-index: 100;
}
body > #header #header-container {
padding-bottom: 5px;
padding-top: 5px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
body > #header .header-bar {
width: 100%;
height: 1px;
background: #e7e7e7;
margin-bottom: -1px;
}
@media print {
body > #header {
display: none !important;
}
}
#header-spacer {
width: 100%;
visibility: hidden;
}
@media print {
#header-spacer {
display: none;
}
}
#ipython_notebook {
padding-left: 0px;
padding-top: 1px;
padding-bottom: 1px;
}
@media (max-width: 991px) {
#ipython_notebook {
margin-left: 10px;
}
}
#noscript {
width: auto;
padding-top: 16px;
padding-bottom: 16px;
text-align: center;
font-size: 22px;
color: red;
font-weight: bold;
}
#ipython_notebook img {
height: 28px;
}
#site {
width: 100%;
display: none;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
overflow: auto;
}
@media print {
#site {
height: auto !important;
}
}
/* Smaller buttons */
.ui-button .ui-button-text {
padding: 0.2em 0.8em;
font-size: 77%;
}
input.ui-button {
padding: 0.3em 0.9em;
}
span#login_widget {
float: right;
}
span#login_widget > .button,
#logout {
color: #333;
background-color: #fff;
border-color: #ccc;
}
span#login_widget > .button:focus,
#logout:focus,
span#login_widget > .button.focus,
#logout.focus {
color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
span#login_widget > .button:hover,
#logout:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
span#login_widget > .button:active,
#logout:active,
span#login_widget > .button.active,
#logout.active,
.open > .dropdown-togglespan#login_widget > .button,
.open > .dropdown-toggle#logout {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
span#login_widget > .button:active:hover,
#logout:active:hover,
span#login_widget > .button.active:hover,
#logout.active:hover,
.open > .dropdown-togglespan#login_widget > .button:hover,
.open > .dropdown-toggle#logout:hover,
span#login_widget > .button:active:focus,
#logout:active:focus,
span#login_widget > .button.active:focus,
#logout.active:focus,
.open > .dropdown-togglespan#login_widget > .button:focus,
.open > .dropdown-toggle#logout:focus,
span#login_widget > .button:active.focus,
#logout:active.focus,
span#login_widget > .button.active.focus,
#logout.active.focus,
.open > .dropdown-togglespan#login_widget > .button.focus,
.open > .dropdown-toggle#logout.focus {
color: #333;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
span#login_widget > .button:active,
#logout:active,
span#login_widget > .button.active,
#logout.active,
.open > .dropdown-togglespan#login_widget > .button,
.open > .dropdown-toggle#logout {
background-image: none;
}
span#login_widget > .button.disabled:hover,
#logout.disabled:hover,
span#login_widget > .button[disabled]:hover,
#logout[disabled]:hover,
fieldset[disabled] span#login_widget > .button:hover,
fieldset[disabled] #logout:hover,
span#login_widget > .button.disabled:focus,
#logout.disabled:focus,
span#login_widget > .button[disabled]:focus,
#logout[disabled]:focus,
fieldset[disabled] span#login_widget > .button:focus,
fieldset[disabled] #logout:focus,
span#login_widget > .button.disabled.focus,
#logout.disabled.focus,
span#login_widget > .button[disabled].focus,
#logout[disabled].focus,
fieldset[disabled] span#login_widget > .button.focus,
fieldset[disabled] #logout.focus {
background-color: #fff;
border-color: #ccc;
}
span#login_widget > .button .badge,
#logout .badge {
color: #fff;
background-color: #333;
}
.nav-header {
text-transform: none;
}
#header > span {
margin-top: 10px;
}
.modal_stretch .modal-dialog {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
min-height: 80vh;
}
.modal_stretch .modal-dialog .modal-body {
max-height: calc(100vh - 200px);
overflow: auto;
flex: 1;
}
@media (min-width: 768px) {
.modal .modal-dialog {
width: 700px;
}
}
@media (min-width: 768px) {
select.form-control {
margin-left: 12px;
margin-right: 12px;
}
}
/*!
*
* IPython auth
*
*/
.center-nav {
display: inline-block;
margin-bottom: -4px;
}
/*!
*
* IPython tree view
*
*/
/* We need an invisible input field on top of the sentense*/
/* "Drag file onto the list ..." */
.alternate_upload {
background-color: none;
display: inline;
}
.alternate_upload.form {
padding: 0;
margin: 0;
}
.alternate_upload input.fileinput {
text-align: center;
vertical-align: middle;
display: inline;
opacity: 0;
z-index: 2;
width: 12ex;
margin-right: -12ex;
}
.alternate_upload .btn-upload {
height: 22px;
}
/**
* Primary styles
*
* Author: Jupyter Development Team
*/
ul#tabs {
margin-bottom: 4px;
}
ul#tabs a {
padding-top: 6px;
padding-bottom: 4px;
}
ul.breadcrumb a:focus,
ul.breadcrumb a:hover {
text-decoration: none;
}
ul.breadcrumb i.icon-home {
font-size: 16px;
margin-right: 4px;
}
ul.breadcrumb span {
color: #5e5e5e;
}
.list_toolbar {
padding: 4px 0 4px 0;
vertical-align: middle;
}
.list_toolbar .tree-buttons {
padding-top: 1px;
}
.dynamic-buttons {
padding-top: 3px;
display: inline-block;
}
.list_toolbar [class*="span"] {
min-height: 24px;
}
.list_header {
font-weight: bold;
background-color: #EEE;
}
.list_placeholder {
font-weight: bold;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 7px;
padding-right: 7px;
}
.list_container {
margin-top: 4px;
margin-bottom: 20px;
border: 1px solid #ddd;
border-radius: 2px;
}
.list_container > div {
border-bottom: 1px solid #ddd;
}
.list_container > div:hover .list-item {
background-color: red;
}
.list_container > div:last-child {
border: none;
}
.list_item:hover .list_item {
background-color: #ddd;
}
.list_item a {
text-decoration: none;
}
.list_item:hover {
background-color: #fafafa;
}
.list_header > div,
.list_item > div {
padding-top: 4px;
padding-bottom: 4px;
padding-left: 7px;
padding-right: 7px;
line-height: 22px;
}
.list_header > div input,
.list_item > div input {
margin-right: 7px;
margin-left: 14px;
vertical-align: baseline;
line-height: 22px;
position: relative;
top: -1px;
}
.list_header > div .item_link,
.list_item > div .item_link {
margin-left: -1px;
vertical-align: baseline;
line-height: 22px;
}
.new-file input[type=checkbox] {
visibility: hidden;
}
.item_name {
line-height: 22px;
height: 24px;
}
.item_icon {
font-size: 14px;
color: #5e5e5e;
margin-right: 7px;
margin-left: 7px;
line-height: 22px;
vertical-align: baseline;
}
.item_buttons {
line-height: 1em;
margin-left: -5px;
}
.item_buttons .btn,
.item_buttons .btn-group,
.item_buttons .input-group {
float: left;
}
.item_buttons > .btn,
.item_buttons > .btn-group,
.item_buttons > .input-group {
margin-left: 5px;
}
.item_buttons .btn {
min-width: 13ex;
}
.item_buttons .running-indicator {
padding-top: 4px;
color: #5cb85c;
}
.item_buttons .kernel-name {
padding-top: 4px;
color: #5bc0de;
margin-right: 7px;
float: left;
}
.toolbar_info {
height: 24px;
line-height: 24px;
}
.list_item input:not([type=checkbox]) {
padding-top: 3px;
padding-bottom: 3px;
height: 22px;
line-height: 14px;
margin: 0px;
}
.highlight_text {
color: blue;
}
#project_name {
display: inline-block;
padding-left: 7px;
margin-left: -2px;
}
#project_name > .breadcrumb {
padding: 0px;
margin-bottom: 0px;
background-color: transparent;
font-weight: bold;
}
#tree-selector {
padding-right: 0px;
}
#button-select-all {
min-width: 50px;
}
#select-all {
margin-left: 7px;
margin-right: 2px;
}
.menu_icon {
margin-right: 2px;
}
.tab-content .row {
margin-left: 0px;
margin-right: 0px;
}
.folder_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f114";
}
.folder_icon:before.pull-left {
margin-right: .3em;
}
.folder_icon:before.pull-right {
margin-left: .3em;
}
.notebook_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f02d";
position: relative;
top: -1px;
}
.notebook_icon:before.pull-left {
margin-right: .3em;
}
.notebook_icon:before.pull-right {
margin-left: .3em;
}
.running_notebook_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f02d";
position: relative;
top: -1px;
color: #5cb85c;
}
.running_notebook_icon:before.pull-left {
margin-right: .3em;
}
.running_notebook_icon:before.pull-right {
margin-left: .3em;
}
.file_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f016";
position: relative;
top: -2px;
}
.file_icon:before.pull-left {
margin-right: .3em;
}
.file_icon:before.pull-right {
margin-left: .3em;
}
#notebook_toolbar .pull-right {
padding-top: 0px;
margin-right: -1px;
}
ul#new-menu {
left: auto;
right: 0;
}
.kernel-menu-icon {
padding-right: 12px;
width: 24px;
content: "\f096";
}
.kernel-menu-icon:before {
content: "\f096";
}
.kernel-menu-icon-current:before {
content: "\f00c";
}
#tab_content {
padding-top: 20px;
}
#running .panel-group .panel {
margin-top: 3px;
margin-bottom: 1em;
}
#running .panel-group .panel .panel-heading {
background-color: #EEE;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 7px;
padding-right: 7px;
line-height: 22px;
}
#running .panel-group .panel .panel-heading a:focus,
#running .panel-group .panel .panel-heading a:hover {
text-decoration: none;
}
#running .panel-group .panel .panel-body {
padding: 0px;
}
#running .panel-group .panel .panel-body .list_container {
margin-top: 0px;
margin-bottom: 0px;
border: 0px;
border-radius: 0px;
}
#running .panel-group .panel .panel-body .list_container .list_item {
border-bottom: 1px solid #ddd;
}
#running .panel-group .panel .panel-body .list_container .list_item:last-child {
border-bottom: 0px;
}
.delete-button {
display: none;
}
.duplicate-button {
display: none;
}
.rename-button {
display: none;
}
.shutdown-button {
display: none;
}
.dynamic-instructions {
display: inline-block;
padding-top: 4px;
}
/*!
*
* IPython text editor webapp
*
*/
.selected-keymap i.fa {
padding: 0px 5px;
}
.selected-keymap i.fa:before {
content: "\f00c";
}
#mode-menu {
overflow: auto;
max-height: 20em;
}
.edit_app #header {
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
.edit_app #menubar .navbar {
/* Use a negative 1 bottom margin, so the border overlaps the border of the
header */
margin-bottom: -1px;
}
.dirty-indicator {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 20px;
}
.dirty-indicator.pull-left {
margin-right: .3em;
}
.dirty-indicator.pull-right {
margin-left: .3em;
}
.dirty-indicator-dirty {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 20px;
}
.dirty-indicator-dirty.pull-left {
margin-right: .3em;
}
.dirty-indicator-dirty.pull-right {
margin-left: .3em;
}
.dirty-indicator-clean {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 20px;
}
.dirty-indicator-clean.pull-left {
margin-right: .3em;
}
.dirty-indicator-clean.pull-right {
margin-left: .3em;
}
.dirty-indicator-clean:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f00c";
}
.dirty-indicator-clean:before.pull-left {
margin-right: .3em;
}
.dirty-indicator-clean:before.pull-right {
margin-left: .3em;
}
#filename {
font-size: 16pt;
display: table;
padding: 0px 5px;
}
#current-mode {
padding-left: 5px;
padding-right: 5px;
}
#texteditor-backdrop {
padding-top: 20px;
padding-bottom: 20px;
}
@media not print {
#texteditor-backdrop {
background-color: #EEE;
}
}
@media print {
#texteditor-backdrop #texteditor-container .CodeMirror-gutter,
#texteditor-backdrop #texteditor-container .CodeMirror-gutters {
background-color: #fff;
}
}
@media not print {
#texteditor-backdrop #texteditor-container .CodeMirror-gutter,
#texteditor-backdrop #texteditor-container .CodeMirror-gutters {
background-color: #fff;
}
}
@media not print {
#texteditor-backdrop #texteditor-container {
padding: 0px;
background-color: #fff;
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
}
/*!
*
* IPython notebook
*
*/
/* CSS font colors for translated ANSI colors. */
.ansibold {
font-weight: bold;
}
/* use dark versions for foreground, to improve visibility */
.ansiblack {
color: black;
}
.ansired {
color: darkred;
}
.ansigreen {
color: darkgreen;
}
.ansiyellow {
color: #c4a000;
}
.ansiblue {
color: darkblue;
}
.ansipurple {
color: darkviolet;
}
.ansicyan {
color: steelblue;
}
.ansigray {
color: gray;
}
/* and light for background, for the same reason */
.ansibgblack {
background-color: black;
}
.ansibgred {
background-color: red;
}
.ansibggreen {
background-color: green;
}
.ansibgyellow {
background-color: yellow;
}
.ansibgblue {
background-color: blue;
}
.ansibgpurple {
background-color: magenta;
}
.ansibgcyan {
background-color: cyan;
}
.ansibggray {
background-color: gray;
}
div.cell {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
border-radius: 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
border-width: 1px;
border-style: solid;
border-color: transparent;
width: 100%;
padding: 5px;
/* This acts as a spacer between cells, that is outside the border */
margin: 0px;
outline: none;
border-left-width: 1px;
padding-left: 5px;
background: linear-gradient(to right, transparent -40px, transparent 1px, transparent 1px, transparent 100%);
}
div.cell.jupyter-soft-selected {
border-left-color: #90CAF9;
border-left-color: #E3F2FD;
border-left-width: 1px;
padding-left: 5px;
border-right-color: #E3F2FD;
border-right-width: 1px;
background: #E3F2FD;
}
@media print {
div.cell.jupyter-soft-selected {
border-color: transparent;
}
}
div.cell.selected {
border-color: #ababab;
border-left-width: 0px;
padding-left: 6px;
background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 5px, transparent 5px, transparent 100%);
}
@media print {
div.cell.selected {
border-color: transparent;
}
}
div.cell.selected.jupyter-soft-selected {
border-left-width: 0;
padding-left: 6px;
background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 7px, #E3F2FD 7px, #E3F2FD 100%);
}
.edit_mode div.cell.selected {
border-color: #66BB6A;
border-left-width: 0px;
padding-left: 6px;
background: linear-gradient(to right, #66BB6A -40px, #66BB6A 5px, transparent 5px, transparent 100%);
}
@media print {
.edit_mode div.cell.selected {
border-color: transparent;
}
}
.prompt {
/* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
min-width: 14ex;
/* This padding is tuned to match the padding on the CodeMirror editor. */
padding: 0.4em;
margin: 0px;
font-family: monospace;
text-align: right;
/* This has to match that of the the CodeMirror class line-height below */
line-height: 1.21429em;
/* Don't highlight prompt number selection */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Use default cursor */
cursor: default;
}
@media (max-width: 540px) {
.prompt {
text-align: left;
}
}
div.inner_cell {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
/* Old browsers */
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
/* Modern browsers */
flex: 1;
}
@-moz-document url-prefix() {
div.inner_cell {
overflow-x: hidden;
}
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_area {
border: 1px solid #cfcfcf;
border-radius: 2px;
background: #f7f7f7;
line-height: 1.21429em;
}
/* This is needed so that empty prompt areas can collapse to zero height when there
is no content in the output_subarea and the prompt. The main purpose of this is
to make sure that empty JavaScript output_subareas have no height. */
div.prompt:empty {
padding-top: 0;
padding-bottom: 0;
}
div.unrecognized_cell {
padding: 5px 5px 5px 0px;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
}
div.unrecognized_cell .inner_cell {
border-radius: 2px;
padding: 5px;
font-weight: bold;
color: red;
border: 1px solid #cfcfcf;
background: #eaeaea;
}
div.unrecognized_cell .inner_cell a {
color: inherit;
text-decoration: none;
}
div.unrecognized_cell .inner_cell a:hover {
color: inherit;
text-decoration: none;
}
@media (max-width: 540px) {
div.unrecognized_cell > div.prompt {
display: none;
}
}
div.code_cell {
/* avoid page breaking on code cells when printing */
}
@media print {
div.code_cell {
page-break-inside: avoid;
}
}
/* any special styling for code cells that are currently running goes here */
div.input {
page-break-inside: avoid;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
}
@media (max-width: 540px) {
div.input {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
}
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_prompt {
color: #303F9F;
border-top: 1px solid transparent;
}
div.input_area > div.highlight {
margin: 0.4em;
border: none;
padding: 0px;
background-color: transparent;
}
div.input_area > div.highlight > pre {
margin: 0px;
border: none;
padding: 0px;
background-color: transparent;
}
/* The following gets added to the <head> if it is detected that the user has a
* monospace font with inconsistent normal/bold/italic height. See
* notebookmain.js. Such fonts will have keywords vertically offset with
* respect to the rest of the text. The user should select a better font.
* See: https://github.com/ipython/ipython/issues/1503
*
* .CodeMirror span {
* vertical-align: bottom;
* }
*/
.CodeMirror {
line-height: 1.21429em;
/* Changed from 1em to our global default */
font-size: 14px;
height: auto;
/* Changed to auto to autogrow */
background: none;
/* Changed from white to allow our bg to show through */
}
.CodeMirror-scroll {
/* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
/* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
overflow-y: hidden;
overflow-x: auto;
}
.CodeMirror-lines {
/* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
/* we have set a different line-height and want this to scale with that. */
padding: 0.4em;
}
.CodeMirror-linenumber {
padding: 0 8px 0 4px;
}
.CodeMirror-gutters {
border-bottom-left-radius: 2px;
border-top-left-radius: 2px;
}
.CodeMirror pre {
/* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
/* .CodeMirror-lines */
padding: 0;
border: 0;
border-radius: 0;
}
/*
Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
Adapted from GitHub theme
*/
.highlight-base {
color: #000;
}
.highlight-variable {
color: #000;
}
.highlight-variable-2 {
color: #1a1a1a;
}
.highlight-variable-3 {
color: #333333;
}
.highlight-string {
color: #BA2121;
}
.highlight-comment {
color: #408080;
font-style: italic;
}
.highlight-number {
color: #080;
}
.highlight-atom {
color: #88F;
}
.highlight-keyword {
color: #008000;
font-weight: bold;
}
.highlight-builtin {
color: #008000;
}
.highlight-error {
color: #f00;
}
.highlight-operator {
color: #AA22FF;
font-weight: bold;
}
.highlight-meta {
color: #AA22FF;
}
/* previously not defined, copying from default codemirror */
.highlight-def {
color: #00f;
}
.highlight-string-2 {
color: #f50;
}
.highlight-qualifier {
color: #555;
}
.highlight-bracket {
color: #997;
}
.highlight-tag {
color: #170;
}
.highlight-attribute {
color: #00c;
}
.highlight-header {
color: blue;
}
.highlight-quote {
color: #090;
}
.highlight-link {
color: #00c;
}
/* apply the same style to codemirror */
.cm-s-ipython span.cm-keyword {
color: #008000;
font-weight: bold;
}
.cm-s-ipython span.cm-atom {
color: #88F;
}
.cm-s-ipython span.cm-number {
color: #080;
}
.cm-s-ipython span.cm-def {
color: #00f;
}
.cm-s-ipython span.cm-variable {
color: #000;
}
.cm-s-ipython span.cm-operator {
color: #AA22FF;
font-weight: bold;
}
.cm-s-ipython span.cm-variable-2 {
color: #1a1a1a;
}
.cm-s-ipython span.cm-variable-3 {
color: #333333;
}
.cm-s-ipython span.cm-comment {
color: #408080;
font-style: italic;
}
.cm-s-ipython span.cm-string {
color: #BA2121;
}
.cm-s-ipython span.cm-string-2 {
color: #f50;
}
.cm-s-ipython span.cm-meta {
color: #AA22FF;
}
.cm-s-ipython span.cm-qualifier {
color: #555;
}
.cm-s-ipython span.cm-builtin {
color: #008000;
}
.cm-s-ipython span.cm-bracket {
color: #997;
}
.cm-s-ipython span.cm-tag {
color: #170;
}
.cm-s-ipython span.cm-attribute {
color: #00c;
}
.cm-s-ipython span.cm-header {
color: blue;
}
.cm-s-ipython span.cm-quote {
color: #090;
}
.cm-s-ipython span.cm-link {
color: #00c;
}
.cm-s-ipython span.cm-error {
color: #f00;
}
.cm-s-ipython span.cm-tab {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
background-position: right;
background-repeat: no-repeat;
}
div.output_wrapper {
/* this position must be relative to enable descendents to be absolute within it */
position: relative;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
z-index: 1;
}
/* class for the output area when it should be height-limited */
div.output_scroll {
/* ideally, this would be max-height, but FF barfs all over that */
height: 24em;
/* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
width: 100%;
overflow: auto;
border-radius: 2px;
-webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
display: block;
}
/* output div while it is collapsed */
div.output_collapsed {
margin: 0px;
padding: 0px;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
}
div.out_prompt_overlay {
height: 100%;
padding: 0px 0.4em;
position: absolute;
border-radius: 2px;
}
div.out_prompt_overlay:hover {
/* use inner shadow to get border that is computed the same on WebKit/FF */
-webkit-box-shadow: inset 0 0 1px #000;
box-shadow: inset 0 0 1px #000;
background: rgba(240, 240, 240, 0.5);
}
div.output_prompt {
color: #D84315;
}
/* This class is the outer container of all output sections. */
div.output_area {
padding: 0px;
page-break-inside: avoid;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
}
div.output_area .MathJax_Display {
text-align: left !important;
}
div.output_area .rendered_html table {
margin-left: 0;
margin-right: 0;
}
div.output_area .rendered_html img {
margin-left: 0;
margin-right: 0;
}
div.output_area img,
div.output_area svg {
max-width: 100%;
height: auto;
}
div.output_area img.unconfined,
div.output_area svg.unconfined {
max-width: none;
}
/* This is needed to protect the pre formating from global settings such
as that of bootstrap */
.output {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
}
@media (max-width: 540px) {
div.output_area {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-align: stretch;
display: box;
box-orient: vertical;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: column;
align-items: stretch;
}
}
div.output_area pre {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
color: black;
background-color: transparent;
border-radius: 0;
}
/* This class is for the output subarea inside the output_area and after
the prompt div. */
div.output_subarea {
overflow-x: auto;
padding: 0.4em;
/* Old browsers */
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
/* Modern browsers */
flex: 1;
max-width: calc(100% - 14ex);
}
div.output_scroll div.output_subarea {
overflow-x: visible;
}
/* The rest of the output_* classes are for special styling of the different
output types */
/* all text output has this class: */
div.output_text {
text-align: left;
color: #000;
/* This has to match that of the the CodeMirror class line-height below */
line-height: 1.21429em;
}
/* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
div.output_stderr {
background: #fdd;
/* very light red background for stderr */
}
div.output_latex {
text-align: left;
}
/* Empty output_javascript divs should have no height */
div.output_javascript:empty {
padding: 0;
}
.js-error {
color: darkred;
}
/* raw_input styles */
div.raw_input_container {
line-height: 1.21429em;
padding-top: 5px;
}
pre.raw_input_prompt {
/* nothing needed here. */
}
input.raw_input {
font-family: monospace;
font-size: inherit;
color: inherit;
width: auto;
/* make sure input baseline aligns with prompt */
vertical-align: baseline;
/* padding + margin = 0.5em between prompt and cursor */
padding: 0em 0.25em;
margin: 0em 0.25em;
}
input.raw_input:focus {
box-shadow: none;
}
p.p-space {
margin-bottom: 10px;
}
div.output_unrecognized {
padding: 5px;
font-weight: bold;
color: red;
}
div.output_unrecognized a {
color: inherit;
text-decoration: none;
}
div.output_unrecognized a:hover {
color: inherit;
text-decoration: none;
}
.rendered_html {
color: #000;
/* any extras will just be numbers: */
}
.rendered_html em {
font-style: italic;
}
.rendered_html strong {
font-weight: bold;
}
.rendered_html u {
text-decoration: underline;
}
.rendered_html :link {
text-decoration: underline;
}
.rendered_html :visited {
text-decoration: underline;
}
.rendered_html h1 {
font-size: 185.7%;
margin: 1.08em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h2 {
font-size: 157.1%;
margin: 1.27em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h3 {
font-size: 128.6%;
margin: 1.55em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h4 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h5 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
font-style: italic;
}
.rendered_html h6 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
font-style: italic;
}
.rendered_html h1:first-child {
margin-top: 0.538em;
}
.rendered_html h2:first-child {
margin-top: 0.636em;
}
.rendered_html h3:first-child {
margin-top: 0.777em;
}
.rendered_html h4:first-child {
margin-top: 1em;
}
.rendered_html h5:first-child {
margin-top: 1em;
}
.rendered_html h6:first-child {
margin-top: 1em;
}
.rendered_html ul {
list-style: disc;
margin: 0em 2em;
padding-left: 0px;
}
.rendered_html ul ul {
list-style: square;
margin: 0em 2em;
}
.rendered_html ul ul ul {
list-style: circle;
margin: 0em 2em;
}
.rendered_html ol {
list-style: decimal;
margin: 0em 2em;
padding-left: 0px;
}
.rendered_html ol ol {
list-style: upper-alpha;
margin: 0em 2em;
}
.rendered_html ol ol ol {
list-style: lower-alpha;
margin: 0em 2em;
}
.rendered_html ol ol ol ol {
list-style: lower-roman;
margin: 0em 2em;
}
.rendered_html ol ol ol ol ol {
list-style: decimal;
margin: 0em 2em;
}
.rendered_html * + ul {
margin-top: 1em;
}
.rendered_html * + ol {
margin-top: 1em;
}
.rendered_html hr {
color: black;
background-color: black;
}
.rendered_html pre {
margin: 1em 2em;
}
.rendered_html pre,
.rendered_html code {
border: 0;
background-color: #fff;
color: #000;
font-size: 100%;
padding: 0px;
}
.rendered_html blockquote {
margin: 1em 2em;
}
.rendered_html table {
margin-left: auto;
margin-right: auto;
border: 1px solid black;
border-collapse: collapse;
}
.rendered_html tr,
.rendered_html th,
.rendered_html td {
border: 1px solid black;
border-collapse: collapse;
margin: 1em 2em;
}
.rendered_html td,
.rendered_html th {
text-align: left;
vertical-align: middle;
padding: 4px;
}
.rendered_html th {
font-weight: bold;
}
.rendered_html * + table {
margin-top: 1em;
}
.rendered_html p {
text-align: left;
}
.rendered_html * + p {
margin-top: 1em;
}
.rendered_html img {
display: block;
margin-left: auto;
margin-right: auto;
}
.rendered_html * + img {
margin-top: 1em;
}
.rendered_html img,
.rendered_html svg {
max-width: 100%;
height: auto;
}
.rendered_html img.unconfined,
.rendered_html svg.unconfined {
max-width: none;
}
div.text_cell {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
}
@media (max-width: 540px) {
div.text_cell > div.prompt {
display: none;
}
}
div.text_cell_render {
/*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
outline: none;
resize: none;
width: inherit;
border-style: none;
padding: 0.5em 0.5em 0.5em 0.4em;
color: #000;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
a.anchor-link:link {
text-decoration: none;
padding: 0px 20px;
visibility: hidden;
}
h1:hover .anchor-link,
h2:hover .anchor-link,
h3:hover .anchor-link,
h4:hover .anchor-link,
h5:hover .anchor-link,
h6:hover .anchor-link {
visibility: visible;
}
.text_cell.rendered .input_area {
display: none;
}
.text_cell.rendered .rendered_html {
overflow-x: auto;
overflow-y: hidden;
}
.text_cell.unrendered .text_cell_render {
display: none;
}
.cm-header-1,
.cm-header-2,
.cm-header-3,
.cm-header-4,
.cm-header-5,
.cm-header-6 {
font-weight: bold;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.cm-header-1 {
font-size: 185.7%;
}
.cm-header-2 {
font-size: 157.1%;
}
.cm-header-3 {
font-size: 128.6%;
}
.cm-header-4 {
font-size: 110%;
}
.cm-header-5 {
font-size: 100%;
font-style: italic;
}
.cm-header-6 {
font-size: 100%;
font-style: italic;
}
/*!
*
* IPython notebook webapp
*
*/
@media (max-width: 767px) {
.notebook_app {
padding-left: 0px;
padding-right: 0px;
}
}
#ipython-main-app {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 100%;
}
div#notebook_panel {
margin: 0px;
padding: 0px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 100%;
}
div#notebook {
font-size: 14px;
line-height: 20px;
overflow-y: hidden;
overflow-x: auto;
width: 100%;
/* This spaces the page away from the edge of the notebook area */
padding-top: 20px;
margin: 0px;
outline: none;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
min-height: 100%;
}
@media not print {
#notebook-container {
padding: 15px;
background-color: #fff;
min-height: 0;
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
}
@media print {
#notebook-container {
width: 100%;
}
}
div.ui-widget-content {
border: 1px solid #ababab;
outline: none;
}
pre.dialog {
background-color: #f7f7f7;
border: 1px solid #ddd;
border-radius: 2px;
padding: 0.4em;
padding-left: 2em;
}
p.dialog {
padding: 0.2em;
}
/* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
*/
pre,
code,
kbd,
samp {
white-space: pre-wrap;
}
#fonttest {
font-family: monospace;
}
p {
margin-bottom: 0;
}
.end_space {
min-height: 100px;
transition: height .2s ease;
}
.notebook_app > #header {
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
@media not print {
.notebook_app {
background-color: #EEE;
}
}
kbd {
border-style: solid;
border-width: 1px;
box-shadow: none;
margin: 2px;
padding-left: 2px;
padding-right: 2px;
padding-top: 1px;
padding-bottom: 1px;
}
/* CSS for the cell toolbar */
.celltoolbar {
border: thin solid #CFCFCF;
border-bottom: none;
background: #EEE;
border-radius: 2px 2px 0px 0px;
width: 100%;
height: 29px;
padding-right: 4px;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
/* Old browsers */
-webkit-box-pack: end;
-moz-box-pack: end;
box-pack: end;
/* Modern browsers */
justify-content: flex-end;
display: -webkit-flex;
}
@media print {
.celltoolbar {
display: none;
}
}
.ctb_hideshow {
display: none;
vertical-align: bottom;
}
/* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
Cell toolbars are only shown when the ctb_global_show class is also set.
*/
.ctb_global_show .ctb_show.ctb_hideshow {
display: block;
}
.ctb_global_show .ctb_show + .input_area,
.ctb_global_show .ctb_show + div.text_cell_input,
.ctb_global_show .ctb_show ~ div.text_cell_render {
border-top-right-radius: 0px;
border-top-left-radius: 0px;
}
.ctb_global_show .ctb_show ~ div.text_cell_render {
border: 1px solid #cfcfcf;
}
.celltoolbar {
font-size: 87%;
padding-top: 3px;
}
.celltoolbar select {
display: block;
width: 100%;
height: 32px;
padding: 6px 12px;
font-size: 13px;
line-height: 1.42857143;
color: #555555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 2px;
-webkit-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-color ease-in-out .15s, box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 1px;
width: inherit;
font-size: inherit;
height: 22px;
padding: 0px;
display: inline-block;
}
.celltoolbar select:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.celltoolbar select::-moz-placeholder {
color: #999;
opacity: 1;
}
.celltoolbar select:-ms-input-placeholder {
color: #999;
}
.celltoolbar select::-webkit-input-placeholder {
color: #999;
}
.celltoolbar select::-ms-expand {
border: 0;
background-color: transparent;
}
.celltoolbar select[disabled],
.celltoolbar select[readonly],
fieldset[disabled] .celltoolbar select {
background-color: #eeeeee;
opacity: 1;
}
.celltoolbar select[disabled],
fieldset[disabled] .celltoolbar select {
cursor: not-allowed;
}
textarea.celltoolbar select {
height: auto;
}
select.celltoolbar select {
height: 30px;
line-height: 30px;
}
textarea.celltoolbar select,
select[multiple].celltoolbar select {
height: auto;
}
.celltoolbar label {
margin-left: 5px;
margin-right: 5px;
}
.completions {
position: absolute;
z-index: 110;
overflow: hidden;
border: 1px solid #ababab;
border-radius: 2px;
-webkit-box-shadow: 0px 6px 10px -1px #adadad;
box-shadow: 0px 6px 10px -1px #adadad;
line-height: 1;
}
.completions select {
background: white;
outline: none;
border: none;
padding: 0px;
margin: 0px;
overflow: auto;
font-family: monospace;
font-size: 110%;
color: #000;
width: auto;
}
.completions select option.context {
color: #286090;
}
#kernel_logo_widget {
float: right !important;
float: right;
}
#kernel_logo_widget .current_kernel_logo {
display: none;
margin-top: -1px;
margin-bottom: -1px;
width: 32px;
height: 32px;
}
#menubar {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
margin-top: 1px;
}
#menubar .navbar {
border-top: 1px;
border-radius: 0px 0px 2px 2px;
margin-bottom: 0px;
}
#menubar .navbar-toggle {
float: left;
padding-top: 7px;
padding-bottom: 7px;
border: none;
}
#menubar .navbar-collapse {
clear: left;
}
.nav-wrapper {
border-bottom: 1px solid #e7e7e7;
}
i.menu-icon {
padding-top: 4px;
}
ul#help_menu li a {
overflow: hidden;
padding-right: 2.2em;
}
ul#help_menu li a i {
margin-right: -1.2em;
}
.dropdown-submenu {
position: relative;
}
.dropdown-submenu > .dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
}
.dropdown-submenu:hover > .dropdown-menu {
display: block;
}
.dropdown-submenu > a:after {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: block;
content: "\f0da";
float: right;
color: #333333;
margin-top: 2px;
margin-right: -10px;
}
.dropdown-submenu > a:after.pull-left {
margin-right: .3em;
}
.dropdown-submenu > a:after.pull-right {
margin-left: .3em;
}
.dropdown-submenu:hover > a:after {
color: #262626;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left > .dropdown-menu {
left: -100%;
margin-left: 10px;
}
#notification_area {
float: right !important;
float: right;
z-index: 10;
}
.indicator_area {
float: right !important;
float: right;
color: #777;
margin-left: 5px;
margin-right: 5px;
width: 11px;
z-index: 10;
text-align: center;
width: auto;
}
#kernel_indicator {
float: right !important;
float: right;
color: #777;
margin-left: 5px;
margin-right: 5px;
width: 11px;
z-index: 10;
text-align: center;
width: auto;
border-left: 1px solid;
}
#kernel_indicator .kernel_indicator_name {
padding-left: 5px;
padding-right: 5px;
}
#modal_indicator {
float: right !important;
float: right;
color: #777;
margin-left: 5px;
margin-right: 5px;
width: 11px;
z-index: 10;
text-align: center;
width: auto;
}
#readonly-indicator {
float: right !important;
float: right;
color: #777;
margin-left: 5px;
margin-right: 5px;
width: 11px;
z-index: 10;
text-align: center;
width: auto;
margin-top: 2px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
display: none;
}
.modal_indicator:before {
width: 1.28571429em;
text-align: center;
}
.edit_mode .modal_indicator:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f040";
}
.edit_mode .modal_indicator:before.pull-left {
margin-right: .3em;
}
.edit_mode .modal_indicator:before.pull-right {
margin-left: .3em;
}
.command_mode .modal_indicator:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: ' ';
}
.command_mode .modal_indicator:before.pull-left {
margin-right: .3em;
}
.command_mode .modal_indicator:before.pull-right {
margin-left: .3em;
}
.kernel_idle_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f10c";
}
.kernel_idle_icon:before.pull-left {
margin-right: .3em;
}
.kernel_idle_icon:before.pull-right {
margin-left: .3em;
}
.kernel_busy_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f111";
}
.kernel_busy_icon:before.pull-left {
margin-right: .3em;
}
.kernel_busy_icon:before.pull-right {
margin-left: .3em;
}
.kernel_dead_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f1e2";
}
.kernel_dead_icon:before.pull-left {
margin-right: .3em;
}
.kernel_dead_icon:before.pull-right {
margin-left: .3em;
}
.kernel_disconnected_icon:before {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: "\f127";
}
.kernel_disconnected_icon:before.pull-left {
margin-right: .3em;
}
.kernel_disconnected_icon:before.pull-right {
margin-left: .3em;
}
.notification_widget {
color: #777;
z-index: 10;
background: rgba(240, 240, 240, 0.5);
margin-right: 4px;
color: #333;
background-color: #fff;
border-color: #ccc;
}
.notification_widget:focus,
.notification_widget.focus {
color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
.notification_widget:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.notification_widget:active,
.notification_widget.active,
.open > .dropdown-toggle.notification_widget {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.notification_widget:active:hover,
.notification_widget.active:hover,
.open > .dropdown-toggle.notification_widget:hover,
.notification_widget:active:focus,
.notification_widget.active:focus,
.open > .dropdown-toggle.notification_widget:focus,
.notification_widget:active.focus,
.notification_widget.active.focus,
.open > .dropdown-toggle.notification_widget.focus {
color: #333;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
.notification_widget:active,
.notification_widget.active,
.open > .dropdown-toggle.notification_widget {
background-image: none;
}
.notification_widget.disabled:hover,
.notification_widget[disabled]:hover,
fieldset[disabled] .notification_widget:hover,
.notification_widget.disabled:focus,
.notification_widget[disabled]:focus,
fieldset[disabled] .notification_widget:focus,
.notification_widget.disabled.focus,
.notification_widget[disabled].focus,
fieldset[disabled] .notification_widget.focus {
background-color: #fff;
border-color: #ccc;
}
.notification_widget .badge {
color: #fff;
background-color: #333;
}
.notification_widget.warning {
color: #fff;
background-color: #f0ad4e;
border-color: #eea236;
}
.notification_widget.warning:focus,
.notification_widget.warning.focus {
color: #fff;
background-color: #ec971f;
border-color: #985f0d;
}
.notification_widget.warning:hover {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.notification_widget.warning:active,
.notification_widget.warning.active,
.open > .dropdown-toggle.notification_widget.warning {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.notification_widget.warning:active:hover,
.notification_widget.warning.active:hover,
.open > .dropdown-toggle.notification_widget.warning:hover,
.notification_widget.warning:active:focus,
.notification_widget.warning.active:focus,
.open > .dropdown-toggle.notification_widget.warning:focus,
.notification_widget.warning:active.focus,
.notification_widget.warning.active.focus,
.open > .dropdown-toggle.notification_widget.warning.focus {
color: #fff;
background-color: #d58512;
border-color: #985f0d;
}
.notification_widget.warning:active,
.notification_widget.warning.active,
.open > .dropdown-toggle.notification_widget.warning {
background-image: none;
}
.notification_widget.warning.disabled:hover,
.notification_widget.warning[disabled]:hover,
fieldset[disabled] .notification_widget.warning:hover,
.notification_widget.warning.disabled:focus,
.notification_widget.warning[disabled]:focus,
fieldset[disabled] .notification_widget.warning:focus,
.notification_widget.warning.disabled.focus,
.notification_widget.warning[disabled].focus,
fieldset[disabled] .notification_widget.warning.focus {
background-color: #f0ad4e;
border-color: #eea236;
}
.notification_widget.warning .badge {
color: #f0ad4e;
background-color: #fff;
}
.notification_widget.success {
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.notification_widget.success:focus,
.notification_widget.success.focus {
color: #fff;
background-color: #449d44;
border-color: #255625;
}
.notification_widget.success:hover {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.notification_widget.success:active,
.notification_widget.success.active,
.open > .dropdown-toggle.notification_widget.success {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.notification_widget.success:active:hover,
.notification_widget.success.active:hover,
.open > .dropdown-toggle.notification_widget.success:hover,
.notification_widget.success:active:focus,
.notification_widget.success.active:focus,
.open > .dropdown-toggle.notification_widget.success:focus,
.notification_widget.success:active.focus,
.notification_widget.success.active.focus,
.open > .dropdown-toggle.notification_widget.success.focus {
color: #fff;
background-color: #398439;
border-color: #255625;
}
.notification_widget.success:active,
.notification_widget.success.active,
.open > .dropdown-toggle.notification_widget.success {
background-image: none;
}
.notification_widget.success.disabled:hover,
.notification_widget.success[disabled]:hover,
fieldset[disabled] .notification_widget.success:hover,
.notification_widget.success.disabled:focus,
.notification_widget.success[disabled]:focus,
fieldset[disabled] .notification_widget.success:focus,
.notification_widget.success.disabled.focus,
.notification_widget.success[disabled].focus,
fieldset[disabled] .notification_widget.success.focus {
background-color: #5cb85c;
border-color: #4cae4c;
}
.notification_widget.success .badge {
color: #5cb85c;
background-color: #fff;
}
.notification_widget.info {
color: #fff;
background-color: #5bc0de;
border-color: #46b8da;
}
.notification_widget.info:focus,
.notification_widget.info.focus {
color: #fff;
background-color: #31b0d5;
border-color: #1b6d85;
}
.notification_widget.info:hover {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.notification_widget.info:active,
.notification_widget.info.active,
.open > .dropdown-toggle.notification_widget.info {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.notification_widget.info:active:hover,
.notification_widget.info.active:hover,
.open > .dropdown-toggle.notification_widget.info:hover,
.notification_widget.info:active:focus,
.notification_widget.info.active:focus,
.open > .dropdown-toggle.notification_widget.info:focus,
.notification_widget.info:active.focus,
.notification_widget.info.active.focus,
.open > .dropdown-toggle.notification_widget.info.focus {
color: #fff;
background-color: #269abc;
border-color: #1b6d85;
}
.notification_widget.info:active,
.notification_widget.info.active,
.open > .dropdown-toggle.notification_widget.info {
background-image: none;
}
.notification_widget.info.disabled:hover,
.notification_widget.info[disabled]:hover,
fieldset[disabled] .notification_widget.info:hover,
.notification_widget.info.disabled:focus,
.notification_widget.info[disabled]:focus,
fieldset[disabled] .notification_widget.info:focus,
.notification_widget.info.disabled.focus,
.notification_widget.info[disabled].focus,
fieldset[disabled] .notification_widget.info.focus {
background-color: #5bc0de;
border-color: #46b8da;
}
.notification_widget.info .badge {
color: #5bc0de;
background-color: #fff;
}
.notification_widget.danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.notification_widget.danger:focus,
.notification_widget.danger.focus {
color: #fff;
background-color: #c9302c;
border-color: #761c19;
}
.notification_widget.danger:hover {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.notification_widget.danger:active,
.notification_widget.danger.active,
.open > .dropdown-toggle.notification_widget.danger {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.notification_widget.danger:active:hover,
.notification_widget.danger.active:hover,
.open > .dropdown-toggle.notification_widget.danger:hover,
.notification_widget.danger:active:focus,
.notification_widget.danger.active:focus,
.open > .dropdown-toggle.notification_widget.danger:focus,
.notification_widget.danger:active.focus,
.notification_widget.danger.active.focus,
.open > .dropdown-toggle.notification_widget.danger.focus {
color: #fff;
background-color: #ac2925;
border-color: #761c19;
}
.notification_widget.danger:active,
.notification_widget.danger.active,
.open > .dropdown-toggle.notification_widget.danger {
background-image: none;
}
.notification_widget.danger.disabled:hover,
.notification_widget.danger[disabled]:hover,
fieldset[disabled] .notification_widget.danger:hover,
.notification_widget.danger.disabled:focus,
.notification_widget.danger[disabled]:focus,
fieldset[disabled] .notification_widget.danger:focus,
.notification_widget.danger.disabled.focus,
.notification_widget.danger[disabled].focus,
fieldset[disabled] .notification_widget.danger.focus {
background-color: #d9534f;
border-color: #d43f3a;
}
.notification_widget.danger .badge {
color: #d9534f;
background-color: #fff;
}
div#pager {
background-color: #fff;
font-size: 14px;
line-height: 20px;
overflow: hidden;
display: none;
position: fixed;
bottom: 0px;
width: 100%;
max-height: 50%;
padding-top: 8px;
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
/* Display over codemirror */
z-index: 100;
/* Hack which prevents jquery ui resizable from changing top. */
top: auto !important;
}
div#pager pre {
line-height: 1.21429em;
color: #000;
background-color: #f7f7f7;
padding: 0.4em;
}
div#pager #pager-button-area {
position: absolute;
top: 8px;
right: 20px;
}
div#pager #pager-contents {
position: relative;
overflow: auto;
width: 100%;
height: 100%;
}
div#pager #pager-contents #pager-container {
position: relative;
padding: 15px 0px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
div#pager .ui-resizable-handle {
top: 0px;
height: 8px;
background: #f7f7f7;
border-top: 1px solid #cfcfcf;
border-bottom: 1px solid #cfcfcf;
/* This injects handle bars (a short, wide = symbol) for
the resize handle. */
}
div#pager .ui-resizable-handle::after {
content: '';
top: 2px;
left: 50%;
height: 3px;
width: 30px;
margin-left: -15px;
position: absolute;
border-top: 1px solid #cfcfcf;
}
.quickhelp {
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-align: stretch;
display: box;
box-orient: horizontal;
box-align: stretch;
/* Modern browsers */
display: flex;
flex-direction: row;
align-items: stretch;
line-height: 1.8em;
}
.shortcut_key {
display: inline-block;
width: 20ex;
text-align: right;
font-family: monospace;
}
.shortcut_descr {
display: inline-block;
/* Old browsers */
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
/* Modern browsers */
flex: 1;
}
span.save_widget {
margin-top: 6px;
}
span.save_widget span.filename {
height: 1em;
line-height: 1em;
padding: 3px;
margin-left: 16px;
border: none;
font-size: 146.5%;
border-radius: 2px;
}
span.save_widget span.filename:hover {
background-color: #e6e6e6;
}
span.checkpoint_status,
span.autosave_status {
font-size: small;
}
@media (max-width: 767px) {
span.save_widget {
font-size: small;
}
span.checkpoint_status,
span.autosave_status {
display: none;
}
}
@media (min-width: 768px) and (max-width: 991px) {
span.checkpoint_status {
display: none;
}
span.autosave_status {
font-size: x-small;
}
}
.toolbar {
padding: 0px;
margin-left: -5px;
margin-top: 2px;
margin-bottom: 5px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.toolbar select,
.toolbar label {
width: auto;
vertical-align: middle;
margin-right: 2px;
margin-bottom: 0px;
display: inline;
font-size: 92%;
margin-left: 0.3em;
margin-right: 0.3em;
padding: 0px;
padding-top: 3px;
}
.toolbar .btn {
padding: 2px 8px;
}
.toolbar .btn-group {
margin-top: 0px;
margin-left: 5px;
}
#maintoolbar {
margin-bottom: -3px;
margin-top: -8px;
border: 0px;
min-height: 27px;
margin-left: 0px;
padding-top: 11px;
padding-bottom: 3px;
}
#maintoolbar .navbar-text {
float: none;
vertical-align: middle;
text-align: right;
margin-left: 5px;
margin-right: 0px;
margin-top: 0px;
}
.select-xs {
height: 24px;
}
.pulse,
.dropdown-menu > li > a.pulse,
li.pulse > a.dropdown-toggle,
li.pulse.open > a.dropdown-toggle {
background-color: #F37626;
color: white;
}
/**
* Primary styles
*
* Author: Jupyter Development Team
*/
/** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
* of chance of beeing generated from the ../less/[samename].less file, you can
* try to get back the less file by reverting somme commit in history
**/
/*
* We'll try to get something pretty, so we
* have some strange css to have the scroll bar on
* the left with fix button on the top right of the tooltip
*/
@-moz-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-webkit-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-moz-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/*properties of tooltip after "expand"*/
.bigtooltip {
overflow: auto;
height: 200px;
-webkit-transition-property: height;
-webkit-transition-duration: 500ms;
-moz-transition-property: height;
-moz-transition-duration: 500ms;
transition-property: height;
transition-duration: 500ms;
}
/*properties of tooltip before "expand"*/
.smalltooltip {
-webkit-transition-property: height;
-webkit-transition-duration: 500ms;
-moz-transition-property: height;
-moz-transition-duration: 500ms;
transition-property: height;
transition-duration: 500ms;
text-overflow: ellipsis;
overflow: hidden;
height: 80px;
}
.tooltipbuttons {
position: absolute;
padding-right: 15px;
top: 0px;
right: 0px;
}
.tooltiptext {
/*avoid the button to overlap on some docstring*/
padding-right: 30px;
}
.ipython_tooltip {
max-width: 700px;
/*fade-in animation when inserted*/
-webkit-animation: fadeOut 400ms;
-moz-animation: fadeOut 400ms;
animation: fadeOut 400ms;
-webkit-animation: fadeIn 400ms;
-moz-animation: fadeIn 400ms;
animation: fadeIn 400ms;
vertical-align: middle;
background-color: #f7f7f7;
overflow: visible;
border: #ababab 1px solid;
outline: none;
padding: 3px;
margin: 0px;
padding-left: 7px;
font-family: monospace;
min-height: 50px;
-moz-box-shadow: 0px 6px 10px -1px #adadad;
-webkit-box-shadow: 0px 6px 10px -1px #adadad;
box-shadow: 0px 6px 10px -1px #adadad;
border-radius: 2px;
position: absolute;
z-index: 1000;
}
.ipython_tooltip a {
float: right;
}
.ipython_tooltip .tooltiptext pre {
border: 0;
border-radius: 0;
font-size: 100%;
background-color: #f7f7f7;
}
.pretooltiparrow {
left: 0px;
margin: 0px;
top: -16px;
width: 40px;
height: 16px;
overflow: hidden;
position: absolute;
}
.pretooltiparrow:before {
background-color: #f7f7f7;
border: 1px #ababab solid;
z-index: 11;
content: "";
position: absolute;
left: 15px;
top: 10px;
width: 25px;
height: 25px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
}
ul.typeahead-list i {
margin-left: -10px;
width: 18px;
}
ul.typeahead-list {
max-height: 80vh;
overflow: auto;
}
ul.typeahead-list > li > a {
/** Firefox bug **/
/* see https://github.com/jupyter/notebook/issues/559 */
white-space: normal;
}
.cmd-palette .modal-body {
padding: 7px;
}
.cmd-palette form {
background: white;
}
.cmd-palette input {
outline: none;
}
.no-shortcut {
display: none;
}
.command-shortcut:before {
content: "(command)";
padding-right: 3px;
color: #777777;
}
.edit-shortcut:before {
content: "(edit)";
padding-right: 3px;
color: #777777;
}
#find-and-replace #replace-preview .match,
#find-and-replace #replace-preview .insert {
background-color: #BBDEFB;
border-color: #90CAF9;
border-style: solid;
border-width: 1px;
border-radius: 0px;
}
#find-and-replace #replace-preview .replace .match {
background-color: #FFCDD2;
border-color: #EF9A9A;
border-radius: 0px;
}
#find-and-replace #replace-preview .replace .insert {
background-color: #C8E6C9;
border-color: #A5D6A7;
border-radius: 0px;
}
#find-and-replace #replace-preview {
max-height: 60vh;
overflow: auto;
}
#find-and-replace #replace-preview pre {
padding: 5px 10px;
}
.terminal-app {
background: #EEE;
}
.terminal-app #header {
background: #fff;
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
.terminal-app .terminal {
float: left;
font-family: monospace;
color: white;
background: black;
padding: 0.4em;
border-radius: 2px;
-webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
}
.terminal-app .terminal,
.terminal-app .terminal dummy-screen {
line-height: 1em;
font-size: 14px;
}
.terminal-app .terminal-cursor {
color: black;
background: white;
}
.terminal-app #terminado-container {
margin-top: 20px;
}
/*# sourceMappingURL=style.min.css.map */
</style>
<style type="text/css">
.highlight .hll { background-color: #ffffcc }
.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 .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.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: #888888 } /* 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: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.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 .mb { color: #666666 } /* Literal.Number.Bin */
.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 */
</style>
<style type="text/css">
/* Temporary definitions which will become obsolete with Notebook release 5.0 */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }
.ansi-bold { font-weight: bold; }
</style>
<style type="text/css">
h1 span {
font-size: 18px;
color: gray;
font-weight: bold;
font-style: italic;
}
p.blog {
font-size: 16px;
}
li{
line-height: 1.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
</style>
<style type="text/css">
/* Overrides of notebook CSS for static HTML export */
body {
overflow: visible;
padding: 8px;
}
div#notebook {
overflow: visible;
border-top: none;
}
@media print {
div.cell {
display: block;
page-break-inside: avoid;
}
div.output_wrapper {
display: block;
page-break-inside: avoid;
}
div.output {
display: block;
page-break-inside: avoid;
}
}
</style>
<!-- Custom stylesheet, it must be in the same directory as the html file -->
<link rel="stylesheet" href="custom.css">
<!-- Loading mathjax macro -->
<!-- Load mathjax -->
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
<!-- MathJax configuration -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true,
processEnvironments: true
},
// Center justify equations in code and markdown cells. Elsewhere
// we use CSS to left justify single line equations in code cells.
displayAlign: 'center',
"HTML-CSS": {
styles: {'.MathJax_Display': {"margin": 0}},
linebreaks: { automatic: true }
}
});
</script>
<!-- End of mathjax configuration --></head>
<body>
<p>A Jupyter Notebook that details the use of SymPy to create LaTeX formatted equations.</p>
<span></span><span><a name='more'></a></span>
<div tabindex="-1" id="notebook" class="border-box-sizing">
<div class="container" id="notebook-container">
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [1]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="sd">"""</span>
<span class="sd">Author: John Volk</span>
<span class="sd">Date: 10/10/2016</span>
<span class="sd">"""</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
<span class="kn">from</span> <span class="nn">sympy.parsing.sympy_parser</span> <span class="k">import</span> <span class="p">(</span><span class="n">parse_expr</span><span class="p">,</span> <span class="n">standard_transformations</span><span class="p">,</span> <span class="n">implicit_multiplication</span><span class="p">,</span>\
<span class="n">implicit_application</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">sympy</span>
<span class="kn">import</span> <span class="nn">re</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Python,-regex,-and-SymPy-to-automate-custom-text-conversions-to-LaTeX">Python, regex, and SymPy to automate custom text conversions to LaTeX<a class="anchor-link" href="#Python,-regex,-and-SymPy-to-automate-custom-text-conversions-to-LaTeX">¶</a></h1><p><strong>This post includes examples on how to:</strong></p>
<ul>
<li><p class="blog">Convert text equation in bad format for Python and SymPy </li>
<li><p class="blog">Convert normal Python mathematical experssion into a suitable form for SymPy's LaTeX printer </li>
<li><p class="blog">Use sympy to produce LaTeX output</li>
<li><p class="blog">Create functions and data structures to make the process reusable and efficient to fit your needs</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Lets-start-with-the-following-string-that-we-assign-to-the-variable-text-that-represents-a-mathematical-model-but-in-poor-printing-form:">Lets start with the following string that we assign to the variable <span>text</span> that represents a mathematical model but in poor printing form:<a class="anchor-link" href="#Lets-start-with-the-following-string-that-we-assign-to-the-variable-text-that-represents-a-mathematical-model-but-in-poor-printing-form:">¶</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [2]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">text</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">Ln(Y) = a0 + a1 LnQ + a2 LnQ^2 + a3 Sin(2 pi dtime) + a4 Cos(2 pi dtime)</span>
<span class="s2">+ a5 dtime + a6 dtime^2"""</span>
<span class="n">text</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[2]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>'\nLn(Y) = a0 + a1 LnQ + a2 LnQ^2 + a3 Sin(2 pi dtime) + a4 Cos(2 pi dtime)\n+ a5 dtime + a6 dtime^2'</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="However,-we-want-this-expression-to-look-like:">However, we want this expression to look like:<a class="anchor-link" href="#However,-we-want-this-expression-to-look-like:">¶</a></h1><p>$ \log{\left (Y \right )} = a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi dtime \right )} + a_{4} \cos{\left (2 \pi dtime \right )} + a_{5} dtime + a_{6} dtime^{2} $</p>
<h1 id="Observe-the-following-differences-between-text-and-valid-LateX:">Observe the following differences between <span>text</span> and valid LateX:<a class="anchor-link" href="#Observe-the-following-differences-between-text-and-valid-LateX:">¶</a></h1><ul>
<li><p class="blog">Some variables and functions are concatenated, i.e.: LnQ, correct latex would be \log{Q}</p></li>
<li><p class="blog">Functions are not in proper latex form (e.g. Sin = \sin, Ln = \log, ...)</p></li>
<li><p class="blog">Missing subscripts: a0 = a_0</p></li>
<li><p class="blog">Newline characters need to be removed</p></li>
<li><p class="blog">Some symbols need to be replaced: dtime = t</p></li>
</ul>
<h1 id="Python's-symbolic-math-pacakge-SymPy-can-automate-some-of-the-transformations-that-we-need,-and-SymPy-has-built-in-LaTeX-printing-capabilities.">Python's symbolic math pacakge <a href="http://www.sympy.org/en/index.html" target="_blank">SymPy</a> can automate some of the transformations that we need, and SymPy has built in LaTeX printing capabilities.<a class="anchor-link" href="#Python's-symbolic-math-pacakge-SymPy-can-automate-some-of-the-transformations-that-we-need,-and-SymPy-has-built-in-LaTeX-printing-capabilities.">¶</a></h1><p class="blog">
If you are not familiar with SymPy you should take some time to familiarize yourself with it; it takes some time to get used to its syntax. Check out the well done documentation for Sympy <a target="_blank" href="http://docs.sympy.org/latest/index.html">here.</a> </p><hr>
<h1 id="First-we-need-to-convert-the-string-(text)-into-valid-SymPy-input">First we need to convert the string <span>(text)</span> into valid SymPy input<a class="anchor-link" href="#First-we-need-to-convert-the-string-(text)-into-valid-SymPy-input">¶</a></h1><ul>
<li><p class="blog">Valid sympy input includes valid python math expressions with added recognition of math operations. For example the following expression can be parsed by SymPy without error:</p></li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [3]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">exp</span> <span class="o">=</span> <span class="s2">"(x + 4) * (x + sin(x**3) + log(x + 5*x) + 3*x - sqrt(y))"</span>
<span class="n">sympy</span><span class="o">.</span><span class="n">expand</span><span class="p">(</span><span class="n">exp</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[3]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>4*x**2 - x*sqrt(y) + x*log(x) + x*sin(x**3) + x*log(6) + 16*x - 4*sqrt(y) + 4*log(x) + 4*sin(x**3) + 4*log(6)</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="To-convert-a-valid-SymPy-expression-like-t-above-into-LaTeX-is-easy:">To convert a valid SymPy expression like <span>t</span> above into LaTeX is easy:<a class="anchor-link" href="#To-convert-a-valid-SymPy-expression-like-t-above-into-LaTeX-is-easy:">¶</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [4]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">latex</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">expand</span><span class="p">(</span><span class="n">exp</span><span class="p">)))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>4 x^{2} - x \sqrt{y} + x \log{\left (x \right )} + x \sin{\left (x^{3} \right )} + x \log{\left (6 \right )} + 16 x - 4 \sqrt{y} + 4 \log{\left (x \right )} + 4 \sin{\left (x^{3} \right )} + 4 \log{\left (6 \right )}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Which,-when-rendered-as-LaTeX-is">Which, when rendered as LaTeX is<a class="anchor-link" href="#Which,-when-rendered-as-LaTeX-is">¶</a></h1><p>$4 x^{2} - x \sqrt{y} + x \log{\left (x \right )} + x \sin{\left (x^{3} \right )} + x \log{\left (6 \right )} + 16 x - 4 \sqrt{y} + 4 \log{\left (x \right )} + 4 \sin{\left (x^{3} \right )} + 4 \log{\left (6 \right )}$</p>
<h1 id="SymPly-Beautiful!!!">SymPly Beautiful!!!<a class="anchor-link" href="#SymPly-Beautiful!!!">¶</a></h1><hr>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Now-back-to-our-original-text-that-we-want-to-convert,-we-need-to-make-some-simple-adjustments-to-make-the-string-a-valid-SymPy-expression">Now back to our original <span>text</span> that we want to convert, we need to make some simple adjustments to make the string a valid SymPy expression<a class="anchor-link" href="#Now-back-to-our-original-text-that-we-want-to-convert,-we-need-to-make-some-simple-adjustments-to-make-the-string-a-valid-SymPy-expression">¶</a></h1><p class="blog">You have several options here, in this case I choose to use regular expressions (regex) to do basic string pattern substitutions. You will likely need to modify these operations or create alrenative regex to prepare your text. If you do not know regex you can probably get by without using basic Python string methods.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [5]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## Note, I removed the LHS and the equal sign from the equation- SymPy requires special syntac for equations</span>
<span class="c1">## further explanation below</span>
<span class="n">text</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">a0 + a1 LnQ + a2 LnQ^2 + a3 Sin(2 pi dtime) + a4 Cos(2 pi dtime)</span>
<span class="s2">+ a5 dtime + a6 dtime^2"""</span>
<span class="c1">## Make a dictionary to map our strings to standard python math or symbols as needed</span>
<span class="n">symbol_map</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'^'</span><span class="p">:</span> <span class="s1">'**'</span><span class="p">,</span>
<span class="s1">'Ln'</span><span class="p">:</span> <span class="s1">'log '</span><span class="p">,</span>
<span class="s1">'Sin'</span><span class="p">:</span> <span class="s1">'sin '</span><span class="p">,</span>
<span class="s1">'Cos'</span><span class="p">:</span> <span class="s1">'cos '</span><span class="p">,</span>
<span class="s1">'dtime'</span><span class="p">:</span> <span class="s1">'t'</span>
<span class="p">}</span>
<span class="c1">## use the dictionary to compile a regex on the keys</span>
<span class="c1">## escape regex characters because ^ is one of the keys, (^ is a regex special character)</span>
<span class="n">to_symbols</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">symbol_map</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
<span class="c1"># run through the text looking for keys (regex) and replacing them with the values from the dict</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">to_symbols</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">symbol_map</span><span class="p">[</span><span class="n">x</span><span class="o">.</span><span class="n">group</span><span class="p">()],</span> <span class="n">text</span><span class="p">)</span>
<span class="n">text</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[5]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>'\na0 + a1 log Q + a2 log Q**2 + a3 sin (2 pi t) + a4 cos (2 pi t)\n+ a5 t + a6 t**2'</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [6]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## remove new line characters from the text </span>
<span class="n">text</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">' '</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="n">text</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[6]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>' a0 + a1 log Q + a2 log Q**2 + a3 sin (2 pi t) + a4 cos (2 pi t) + a5 t + a6 t**2'</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [7]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## regex to replace coefficients a0, a1, ... with their equivalents with subscripts e.g. a0 = a_0</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">r"\s+a(\d)"</span><span class="p">,</span> <span class="s2">r"a_\1"</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="n">text</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[7]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>'a_0 +a_1 log Q +a_2 log Q**2 +a_3 sin (2 pi t) +a_4 cos (2 pi t) +a_5 t +a_6 t**2'</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="At-this-point-text-is-almost-ready-for-LaTeX...">At this point <span>text</span> is almost ready for LaTeX...<a class="anchor-link" href="#At-this-point-text-is-almost-ready-for-LaTeX...">¶</a></h1><h1 id="The-remaining-issues-are-sufficiently-difficult-string-manipulations,-SymPy's-Parser--is-perfect-for-the-remaining-conversions:">The remaining issues are sufficiently difficult string manipulations, <a href="http://docs.sympy.org/dev/modules/parsing.html" target="_blank">SymPy's Parser</a> is perfect for the remaining conversions:<a class="anchor-link" href="#The-remaining-issues-are-sufficiently-difficult-string-manipulations,-SymPy's-Parser--is-perfect-for-the-remaining-conversions:">¶</a></h1>
<p class="blog">Instead of trying to figure out how to place asterisks everywhere that multiplication is implied and parenthesis where functions are implied, e.g. log Q**2 should be log(Q**2) we can use SymPy's Parser that is quite powerful.</p>
<p>We use implicit multiplication (self-explantory) and implicit application for function applications that are mising parenthesis, both of these are transformations provided by the SymPy Parser. Remember the parser will still follow mathematical order of operations (PEMDAS) when doing implicit application. The parser can handle additional cases as well such as function exponentiation. Check the handy examples at the documentation link above.
</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [8]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## get the transformations we need (imported above) and place into a tuple that is required for the parser</span>
<span class="n">transformations</span> <span class="o">=</span> <span class="n">standard_transformations</span> <span class="o">+</span> <span class="p">(</span><span class="n">implicit_multiplication</span><span class="p">,</span> <span class="n">implicit_application</span><span class="p">,</span> <span class="p">)</span>
<span class="c1">## parse the text by applying implicit multiplication and implicit (math function) appplication</span>
<span class="n">expr</span> <span class="o">=</span> <span class="n">parse_expr</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">transformations</span><span class="o">=</span><span class="n">transformations</span><span class="p">)</span>
<span class="n">expr</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[8]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>a_0 + a_1*log(Q) + a_2*log(Q**2) + a_3*sin(2*pi*t) + a_4*cos(2*pi*t) + a_5*t + a_6*t**2</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="We're-done,-just-print-using-SymPy's-latex-printer!">We're done, just print using SymPy's latex printer!<a class="anchor-link" href="#We're-done,-just-print-using-SymPy's-latex-printer!">¶</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [9]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">latex</span><span class="p">(</span><span class="n">expr</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi t \right )} + a_{4} \cos{\left (2 \pi t \right )} + a_{5} t + a_{6} t^{2}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="SymPly-amazing!!">SymPly amazing!!<a class="anchor-link" href="#SymPly-amazing!!">¶</a></h1><p>$a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi t \right )} + a_{4} \cos{\left (2 \pi t \right )} + a_{5} t + a_{6} t^{2} $</p>
<hr>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Now-let's-put-this-all-together-into-a-function:">Now let's put this all together into a function:<a class="anchor-link" href="#Now-let's-put-this-all-together-into-a-function:">¶</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [10]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## global variables for the function</span>
<span class="n">symbol_map</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'^'</span><span class="p">:</span> <span class="s1">'**'</span><span class="p">,</span>
<span class="s1">'Ln'</span><span class="p">:</span> <span class="s1">'log '</span><span class="p">,</span>
<span class="s1">'Sin'</span><span class="p">:</span> <span class="s1">'sin '</span><span class="p">,</span>
<span class="s1">'Cos'</span><span class="p">:</span> <span class="s1">'cos '</span><span class="p">,</span>
<span class="s1">'dtime'</span><span class="p">:</span> <span class="s1">'t'</span>
<span class="p">}</span>
<span class="n">transformations</span> <span class="o">=</span> <span class="n">standard_transformations</span> <span class="o">+</span> <span class="p">(</span><span class="n">implicit_multiplication</span><span class="p">,</span> <span class="n">implicit_application</span><span class="p">,</span> <span class="p">)</span>
<span class="c1">## the function</span>
<span class="k">def</span> <span class="nf">translate</span><span class="p">(</span><span class="n">bad_text</span><span class="p">):</span>
<span class="sd">"""My custom string-to-LaTeX-ready SymPy expression translation function</span>
<span class="sd"> </span>
<span class="sd"> Arguments:</span>
<span class="sd"> bad_text (str): text that is in some bad format that requires string manipulation</span>
<span class="sd"> including custom string modifications to math functions, symbols, and operators</span>
<span class="sd"> defined by the global symbol_map dictionary (for substitutions), and the regexs </span>
<span class="sd"> compiled herein. More advanced manipulations providied by SymPy are defined by </span>
<span class="sd"> the global variable `transformations` are inputs to the SymPy parser</span>
<span class="sd"> Returns:</span>
<span class="sd"> expr (sympy expression): A SymPy expresion created by the SymPy expression parser</span>
<span class="sd"> after first doing custom string modifications to math functions, symbols, and operators</span>
<span class="sd"> """</span>
<span class="n">to_symbols</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">symbol_map</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
<span class="n">bad_text</span> <span class="o">=</span> <span class="n">to_symbols</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">symbol_map</span><span class="p">[</span><span class="n">x</span><span class="o">.</span><span class="n">group</span><span class="p">()],</span> <span class="n">bad_text</span><span class="p">)</span>
<span class="n">bad_text</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="n">bad_text</span><span class="p">)</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">r"\s+a(\d)"</span><span class="p">,</span> <span class="s2">r"a_\1"</span><span class="p">,</span> <span class="n">bad_text</span><span class="p">)</span>
<span class="n">expr</span> <span class="o">=</span> <span class="n">parse_expr</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">transformations</span><span class="o">=</span><span class="n">transformations</span><span class="p">)</span>
<span class="k">return</span> <span class="n">expr</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [11]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## very handy, now we just have to convert to TeX and print</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">latex</span><span class="p">(</span><span class="n">translate</span><span class="p">(</span><span class="n">text</span><span class="p">)))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi t \right )} + a_{4} \cos{\left (2 \pi t \right )} + a_{5} t + a_{6} t^{2}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="What-about-the-original-text-?-It-was-an-equation-with-a-left-hand-side:">What about the original <span>text</span> ? It was an equation with a left-hand-side:<a class="anchor-link" href="#What-about-the-original-text-?-It-was-an-equation-with-a-left-hand-side:">¶</a></h1><ul>
<li><p class="blog">Parse both the LHS and RHS separately and combine with SymPy's Equation method</p></li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [12]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">text</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">Ln(Y) = a0 + a1 LnQ + a2 LnQ^2 + a3 Sin(2 pi dtime) + a4 Cos(2 pi dtime)</span>
<span class="s2">+ a5 dtime + a6 dtime^2"""</span>
<span class="c1"># split on the equal sign</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'='</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">t2</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'='</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [13]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## Use sympy.Eq(LHS,RHS)</span>
<span class="n">LHS</span> <span class="o">=</span> <span class="n">translate</span><span class="p">(</span><span class="n">t1</span><span class="p">)</span>
<span class="n">RHS</span> <span class="o">=</span> <span class="n">translate</span><span class="p">(</span><span class="n">t2</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">latex</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">Eq</span><span class="p">(</span><span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">)))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>\log{\left (Y \right )} = a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi t \right )} + a_{4} \cos{\left (2 \pi t \right )} + a_{5} t + a_{6} t^{2}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>$\log{\left (Load \right )} = a_{0} + a_{1} \log{\left (Q \right )} + a_{2} \log{\left (Q^{2} \right )} + a_{3} \sin{\left (2 \pi t \right )} + a_{4} \cos{\left (2 \pi t \right )} + a_{5} t + a_{6} t^{2} $</p>
<h1 id="SymPly-fantastic!!!">SymPly fantastic!!!<a class="anchor-link" href="#SymPly-fantastic!!!">¶</a></h1><hr>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="SymPy's-power-can-now-be-used-to-modify-our-LaTeX-expression">SymPy's power can now be used to modify our LaTeX expression<a class="anchor-link" href="#SymPy's-power-can-now-be-used-to-modify-our-LaTeX-expression">¶</a></h1><h1 id="One-quick-example:-let's-plug-in-random-values-for-the-following-variables:">One quick example: let's plug in random values for the following variables:<a class="anchor-link" href="#One-quick-example:-let's-plug-in-random-values-for-the-following-variables:">¶</a></h1>$$\large{a_0, a_1, a_2, a_3, a_4, a_5, ~\text{and}~ a_6 }$$
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [14]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## extract SymPy symbols from both sides of eqn</span>
<span class="n">LHS_symbols</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">LHS</span><span class="o">.</span><span class="n">atoms</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">symbol</span><span class="o">.</span><span class="n">Symbol</span><span class="p">)]</span>
<span class="n">RHS_symbols</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">RHS</span><span class="o">.</span><span class="n">atoms</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">symbol</span><span class="o">.</span><span class="n">Symbol</span><span class="p">)]</span>
<span class="n">LHS_symbols</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[14]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>['Y']</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [15]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">RHS_symbols</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[15]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>['a_0', 'Q', 'a_5', 'a_6', 'a_2', 'a_3', 'a_1', 'a_4', 't']</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [16]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## remove Q and t from the RHS list because we do not want to plug values in for them</span>
<span class="n">RHS_symbols</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">RHS_symbols</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">))</span>
<span class="n">RHS_symbols</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">RHS_symbols</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">'t'</span><span class="p">));</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [17]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## create a dictionary assigning each symbol to random variables</span>
<span class="n">plug_in_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">RHS_symbols</span> <span class="p">}</span>
<span class="nb">print</span><span class="p">(</span><span class="n">plug_in_dict</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>{'a_6': 4, 'a_5': 7, 'a_4': 5, 'a_3': 0, 'a_2': 1, 'a_1': 0, 'a_0': 6}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [18]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="c1">## now plug in our values and let sympy simplyfy! Note, the variables we changed only appear on the RHS</span>
<span class="n">RHS</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">plug_in_dict</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt output_prompt">Out[18]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>4*t**2 + 7*t + log(Q**2) + 5*cos(2*pi*t) + 6</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Using-our-function-above,-let's-convert-and-render-the-modified-expression-in-TeX">Using our function above, let's convert and render the modified expression in TeX<a class="anchor-link" href="#Using-our-function-above,-let's-convert-and-render-the-modified-expression-in-TeX">¶</a></h1><h1 id="Where:">Where:<a class="anchor-link" href="#Where:">¶</a></h1><div class="highlight"><pre><span></span><span class="n">a_6</span> <span class="o">=</span> <span class="mi">4</span>
<span class="n">a_5</span> <span class="o">=</span> <span class="mi">7</span>
<span class="n">a_4</span> <span class="o">=</span> <span class="mi">5</span>
<span class="n">a_3</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">a_2</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">a_1</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">a_0</span> <span class="o">=</span> <span class="mi">6</span>
</pre></div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [19]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">latex</span><span class="p">(</span><span class="n">sympy</span><span class="o">.</span><span class="n">Eq</span><span class="p">(</span><span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">plug_in_dict</span><span class="p">))))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>\log{\left (Y \right )} = 4 t^{2} + 7 t + \log{\left (Q^{2} \right )} + 5 \cos{\left (2 \pi t \right )} + 6
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>$\log{\left (Y \right )} = 4 t^{2} + 7 t + \log{\left (Q^{2} \right )} + 5 \cos{\left (2 \pi t \right )} + 6 $</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Remarks">Remarks<a class="anchor-link" href="#Remarks">¶</a></h1><p class="blog">I hope this was useful to anyone trying to use Python to batch process strings into mathematical expressions and LaTeX. In my case I needed to process many of these types of strings that were output from a computer code that fits regression models to input data. As you can see, if you work with mathematical expressions of any kind and already know basic Python, SymPy is undoubtedly useful. If you liked this or have experimented with your own implementations of Python, regex, and/or SymPy to do cool and useful things please share in the comments below. </p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-73180210646693034882015-11-16T22:37:00.001-08:002021-11-17T09:35:17.465-08:00Computing zonal and weighted statistics from NetCDF data with NCO<head>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 1.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<p>An in depth tutorial on using command line NetCDF tools for computing weighted statistics.</p>
<span><a name='more'></a></span>
<body>
<p>This post is a sequel to <a href="http://www.subcriticalflow.com/2015/09/NetCDF-NCO-ncrcat-ncecat-ncra-ncrea-concatenate-average.html">Concatenate and average NetCDFs</a> where I introduced NCO (NetCDF operators), how to install NCO, and provided examples for the essential operations of record and ensemble concatenation and averaging of variables across multiple NetCDF files. If you are new to NCO I suggest familiarizing yourself with that post and experimenting with some NetCDF files as well as reading the <a href="http://nco.sourceforge.net/nco.html">NCO user manual</a>. This post explains how to calculate weighted and non-weighted zonal statistics on variables over different dimensions (e.g. temporal and spatial averages) using the ncwa command line tool. Including several examples as well as information regarding open-source tools for visualizing NetCDF variables and NCO commands for accessing NetCDF metadata. These tools and examples will aid you in your work flow as they did for me!
<hr />
<h4>Calculate zonal means using <strong>ncwa</strong></h4>
<p>In the previous NCO <a href="http://www.subcriticalflow.com/2015/09/NetCDF-NCO-ncrcat-ncecat-ncra-ncrea-concatenate-average.html">post</a> we used the record averager (ncra) command to average variables over multiple files over their record dimension, typically time. But what if we need to average or use other aggregating statistics on a variable over space, time, or any other combination of dimensions we desire? The NetCDF weighted averager is just the right tool for the task.
</p>
<p>Let's say we have 12 NetCDF files that each hold monthly model output for the water year 1992, in this case they contain simulation results from the <a href="http://www.cesm.ucar.edu/">Community Earth System Model</a>:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ls
model_out_1991-10.nc model_out_1992-02.nc model_out_1992-06.nc
model_out_1991-11.nc model_out_1992-03.nc model_out_1992-07.nc
model_out_1991-12.nc model_out_1992-04.nc model_out_1992-08.nc
model_out_1992-01.nc model_out_1992-05.nc model_out_1992-09.nc
</pre></div>
<br />
<div style="width: 90%;align: center;margin: 0 auto;">
<h3 align="center">Side Note: visualizing data in NetCDFs!</h3>
<hr>
<p>Any NetCDF file can be viewed quickly with the free tool ncview which you can easily get through the aptitude repository:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>sudo apt-get install ncview</pre></div>
<p>Using ncview is simple</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncview NetCDF_File_To_view</pre></div>
<p>Alternatively you could use the NASA's free <a href="http://www.giss.nasa.gov/tools/panoply/">Panoply software</a> to view and create custom high quality figures from your NetCDF files. Panoply has a lot of options and is great for publication plots but I prefer ncview for taking quick views of a NetCDF file on the fly while doing analysis. The figures below were created with Panoply.
</p>
<hr >
</div>
<br />
<p>For example, here is a plot of simulated ground temperature in the model_out_1992-06.nc file (June ground temperature).
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCpUPDE4Yi0l_yucl-Y6pY2eh_An4sqgok9OfTCgRPFgoAKP30P6u41Rxt4oh4QrmzpJeLa-QV9xoM7srS8lSpDOB9xc7oly0gi5Ns_yrUm720wMTBseM1J__H2BOH28EyRT8ZYwqYGRs/s1600/TG+in+model_out_1992-06.png" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCpUPDE4Yi0l_yucl-Y6pY2eh_An4sqgok9OfTCgRPFgoAKP30P6u41Rxt4oh4QrmzpJeLa-QV9xoM7srS8lSpDOB9xc7oly0gi5Ns_yrUm720wMTBseM1J__H2BOH28EyRT8ZYwqYGRs/s1600/TG+in+model_out_1992-06.png"></a></div>
<p>Now, before we do any weighted averaging lets concatenate the monthly output files along the record dimension (time) using ncrcat to make one NetCDF file TG_concated.nc which contains a time series of the monthly data. For simplicity let's only consider the variable ground temperature (TG) shown above. We can specify the variable we want to subset using the <i>-v</i> option with ncrcat. Alternatively we could have averaged the variables across their record dimension using ncra but then we would no longer have the time dimension in the output file.
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%">ncrcat -O -v TG model_out_*.nc TG_concated.nc
</pre></div>
<p>The resulting file now only contains the TG variable, <i>-O</i> just says to overwrite the output file if it already exists. We can get useful information about the ground temperature variable with NCO as well using ncinfo:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncinfo -v TG TG_concated.nc
<<span style="color: #007020">type</span> <span style="color: #4070a0">'netCDF4._netCDF4.Variable'</span>>
float32 TG<span style="color: #666666">(</span><span style="color: #007020">time</span>, lat, lon<span style="color: #666666">)</span>
long_name: ground temperature
units: K
cell_methods: <span style="color: #007020">time</span>: mean
_FillValue: 1e+36
missing_value: 1e+36
unlimited dimensions: <span style="color: #007020">time</span>
current <span style="color: #bb60d5">shape</span> <span style="color: #666666">=</span> <span style="color: #666666">(</span>12, 192, 288<span style="color: #666666">)</span>
filling off
</pre></div>
<p>We can see TG is a 3D variable in time, latitude, and longitude with a corresponding array shape of (12, 192, 288) (months, latitude nodes, longitude nodes). We can leverage this information if we need to aggregate and reduce the dimensionality for plotting or analysis.
</p>
<br />
<div style="width: 90%;align: center;margin: 0 auto;">
<h3 align="center">Side Note: viewing metadata of NetCDFs!</h3>
<hr>
<p>You might be wondering how to view meta data of NetCDF files-- there are several different ways: 1) <code>ncinfo netcdf_file </code> will print most basic and important information of the contents such as all variables, dimensions, file history, etc.; 2) <code>ncdump -h netcdf_file </code> provides more detailed info for each variable; 3) <code>ncks -m <i>or</i> -M netcdf_file </code> will produce output pertaining to dimensions, -m is useful for finding length and units of dimensions and you can pass it variables as well with <i>-v</i>. The <i>-M</i> option will print out information regarding global attributes. Experiment with these as they are all super useful!
</p>
<hr>
</div>
<br />
<p>As we viewed using ncinfo our variable of interest is 3 dimensional in time, latitude, and longitude so we can average over these dimensions using ncwa (NetCDF weighted averager) thus reducing its dimensionality, actually the default behaviour of ncwa is to average over all dimensions thus reducing the variable to a scalar. For example just calling ncwa on TG_concated.nc:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncwa -O TG_concated.nc out.nc
<span style="color: #bb60d5">$ </span>ncks -v TG out.nc
TG: <span style="color: #007020">type </span>NC_FLOAT, <span style="color: #40a070">0</span> dimensions, <span style="color: #40a070">5</span> attributes, chunked? no, compressed? no, packed? no
TG size <span style="color: #666666">(</span>RAM<span style="color: #666666">)</span> <span style="color: #666666">=</span> 1*sizeof<span style="color: #666666">(</span>NC_FLOAT<span style="color: #666666">)</span> <span style="color: #666666">=</span> 1*4 <span style="color: #666666">=</span> <span style="color: #40a070">4</span> bytes
TG attribute 0: long_name, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">18</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> ground temperature
TG attribute 1: units, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">1</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> K
TG attribute 2: cell_methods, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">31</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> <span style="color: #007020">time</span>: mean <span style="color: #007020">time</span>, lat, lon: mean
TG attribute 3: _FillValue, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">1</span> NC_FLOAT, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> 1e+36
TG attribute 4: missing_value, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">1</span> NC_FLOAT, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> 1e+36
<span style="color: #bb60d5">TG</span> <span style="color: #666666">=</span> 267.074 K
</pre></div>
<p>The resulting scalar value for TG in the output file of 267.074 Kelvin is the global average ground temperature over the 12 months. To avoid averaging over all dimensions you must use the <i>-a</i> option followed by the dimensions you want to average over. If you used ncwa -a followed by the record dimension of the input file this would be equivalent to the default behaviour of the NCO record averager ncra. By specifying dimensions with <i>-a</i> we can get the latitudinal zonal mean ground temperature as a function of time by only averaging over the longitudinal axis:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncwa -O -v TG -a lon,time TG_concated.nc lat_zonal_mean.nc
<span style="color: #bb60d5">$ </span>ncinfo -v TG lat_zonal_mean.nc
<<span style="color: #007020">type</span> <span style="color: #4070a0">'netCDF4._netCDF4.Variable'</span>>
float32 TG<span style="color: #666666">(</span>lat<span style="color: #666666">)</span>
long_name: ground temperature
units: K
cell_methods: <span style="color: #007020">time</span>: mean <span style="color: #007020">time</span>, lon: mean
_FillValue: 1e+36
missing_value: 1e+36
unlimited dimensions:
current <span style="color: #bb60d5">shape</span> <span style="color: #666666">=</span> <span style="color: #666666">(</span>192,<span style="color: #666666">)</span>
filling off
</pre></div>
<p>The new shape of lat_zonal_mean.nc is 192 which is the size of the latitude array in the original file. What we have created is a file with ground temperature that has been averaged over 12 months and over every longitude cell resulting in a singular value for each latitude node. This output file is useful for making a latitudinal zonal mean plot of mean ground temperature:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1pLXMjG6XdHYoaF1ny4zap2Yi-KRTk_n2oN_7nxLBQntl7xho3p6aVyd7CHy4CgaF7sCWIxBCcX61nl6EbV_4l5EAMp8K3-oYumhx5X6ET2vzCMRBo_jrBfDYBLLUSCU6S31c3c2-Ww0/s1600/TG+in+lat_zonal_mean.png" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1pLXMjG6XdHYoaF1ny4zap2Yi-KRTk_n2oN_7nxLBQntl7xho3p6aVyd7CHy4CgaF7sCWIxBCcX61nl6EbV_4l5EAMp8K3-oYumhx5X6ET2vzCMRBo_jrBfDYBLLUSCU6S31c3c2-Ww0/s1600/TG+in+lat_zonal_mean.png"></a></div>
<p>It is not an error that the line breaks around -60 degrees latitude, this is because there is no land in this stretch of the world and remember we are viewing <i>ground</i> temperature.
</p>
<p>The NCO weighted average operator ncwa also supports sub-setting the domain of operation over one or more dimensions using the syntax <code>ncwa -d dim,[min],[max],[stride] -d dim,[min],[max],[stride] -d dim,[min],[max],[stride] in.nc out.nc</code>. The resulting output file will have the weighted average only for the desired dimensional domain. If stride is not given then all data between min and max are included, a stride of 2 will select every other value of the dimension (e.g. every other day if dim is time), 3 every third and so on. You need to include one of the values or both from the min and max parameters, using a comma for an open ended range. There is no limit on how many dimensions and ranges of dimensions you can subset over. For example, say we wanted to calculate the latitudinal zonal mean as before but only for latitudes above the equator and say we wanted to see how the zonal average evolved through time:
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncwa -O -v TG -a lon -d lat,0.,90. TG_concated.nc lat_zonal_mean_0_to_90_degrees.nc
</pre></div>
<p>The resulting output contains the latitudinal zonal mean over the twelve months of data, the resulting 2D plot shows the mean ground temperature over the latitudinal axis (x axis) versus time (y axis).
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi_82pQfndS5Exj1XtYuNFZu9p3xIwFVGWRDHeLZS-uXelA7Xh9DDg1q583A31KI5UfulPwVbYBkbN6TSVTtmNS9H52ZDPNqcKsts3mXiHJR7H84NFiQsLCt6T12MizoWyXlwQvNHVDIc/s1600/TG+in+lat_zonal_mean_0_to_90_degrees.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi_82pQfndS5Exj1XtYuNFZu9p3xIwFVGWRDHeLZS-uXelA7Xh9DDg1q583A31KI5UfulPwVbYBkbN6TSVTtmNS9H52ZDPNqcKsts3mXiHJR7H84NFiQsLCt6T12MizoWyXlwQvNHVDIc/s1600/TG+in+lat_zonal_mean_0_to_90_degrees.png"></a></div>
<p>The global monthly temperature from the model is out of phase because the order of the concatenated files that we started with was in water year order, that is October through September. I chose not to interpolate the monthly data in the plot, as a result you can see 12 distinct bands for each month starting with October. That is not to say that the concatenation did not keep track of the dates correctly- it did, but this example shows that you have flexibility on which date you would like the time series to start from.
</p>
<h4>Masking with logical conditionals</h4>
<p>In addition to being able to subset our domain of operation by dimensions, ncwa supports using logical conditional statements for selection based on a variable's value and a relational operator ($=, \ne, \gt, \lt, \ge, \le$). There are two methods to do this: the long hard way:) <code>ncwa -m mask_variable -M mask_value -T Fortran_relational in.nc out.nc</code>; or the short simple way:) <code>ncwa -B 'mask_variable relational mask_value' in.nc out.nc</code>. Where <i>-m</i> proceeds the variable used for the masking; <i>-T</i> proceeds a Fortran relational operator ($eq, ne, gt, lt, ge, le$) which correspond to ($=, \ne, \gt, \lt, \ge, \le$) in Fortran; <i>-M</i> proceeds the masking value; and if you use the <i>-B</i> option the valid relational operators are ==, !=, >, <, >=, <=. You should make sure to enclose the conditional expression after <i>-B</i> in quotes.
</p>
<p>For example lets say we wanted to look at two variables from the model: soil evaporation rate (QSOIL) and plant transpiration rate (QVEGT). With ncwa we could calculate the evaporation for locations where the transpiration is high or vice versa just to see how this NCO operation works. This will require three steps: first we will concatenate the monthly files this time keeping these two variables, second we will calculate the global mean transpiration, and last we will calculate the mean global mean evaporation for locations where transpiration is above the global mean and plot our results.
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncrcat -O -v QSOIL,QVEGT model_out_199*.nc ET_concated.nc
<span style="color: #bb60d5">$ </span>ncwa -O ET_concated.nc global_avg_ET.nc
<span style="color: #bb60d5">$ </span>ncks -v QVEGT global_avg_ET.nc QVEGT: <span style="color: #007020">type </span>NC_FLOAT, <span style="color: #40a070">0</span> dimensions, <span style="color: #40a070">5</span> attributes, chunked? no, compressed? no, packed? no
QVEGT size <span style="color: #666666">(</span>RAM<span style="color: #666666">)</span> <span style="color: #666666">=</span> 1*sizeof<span style="color: #666666">(</span>NC_FLOAT<span style="color: #666666">)</span> <span style="color: #666666">=</span> 1*4 <span style="color: #666666">=</span> <span style="color: #40a070">4</span> bytes
QVEGT attribute 0: long_name, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">20</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> canopy transpiration
QVEGT attribute 1: units, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">4</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> mm/s
QVEGT attribute 2: cell_methods, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">31</span> NC_CHAR, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> <span style="color: #007020">time</span>: mean <span style="color: #007020">time</span>, lat, lon: mean
QVEGT attribute 3: _FillValue, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">1</span> NC_FLOAT, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> 1e+36
QVEGT attribute 4: missing_value, <span style="color: #bb60d5">size</span> <span style="color: #666666">=</span> <span style="color: #40a070">1</span> NC_FLOAT, <span style="color: #bb60d5">value</span> <span style="color: #666666">=</span> 1e+36
<span style="color: #bb60d5">QVEGT</span> <span style="color: #666666">=</span> 9.58266e-06 mm/s
<span style="color: #bb60d5">$ </span>ncwa -O -a <span style="color: #007020">time</span> -B <span style="color: #4070a0">'QVEGT > 9.58266e-06'</span> ET_concated.nc out.nc
</pre></div>
<p>The resulting plot of soil evaporation (QSOIL) in the output file looks like:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5rCq0tRHGBPfqtzvRHzHvqvBJPlJ_T8ArDHMBTW7lFHnUEKHGiM6RXo-T4MgRApIjeOyEhILXxrJEcEFT8yDuLKSHeJBzNFxRM9iZJofzveNmVc5M-MHKdGaB1jfZwnsXdeFJ-vZes-c/s1600/Annual+mean+QSOIL+in+out.nc+where+QVEGT+%253E+mean%2528QVEGT%2529.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5rCq0tRHGBPfqtzvRHzHvqvBJPlJ_T8ArDHMBTW7lFHnUEKHGiM6RXo-T4MgRApIjeOyEhILXxrJEcEFT8yDuLKSHeJBzNFxRM9iZJofzveNmVc5M-MHKdGaB1jfZwnsXdeFJ-vZes-c/s1600/Annual+mean+QSOIL+in+out.nc+where+QVEGT+%253E+mean%2528QVEGT%2529.png"></a></div>
<p>The logical indexing resulting from <code>-B 'QVEGT > 9.58266e-06'</code> appears to have masked the worlds largest deserts in the output file. This is an obvious result considering there is a dearth vegetation in these regions; although this example does not clearly illustrate the relationship between evaporation and transpiration (which I expect would be a dynamic relationship seasonally as well), with a well thought-out plan the masking option can be quite useful for scientific data analysis.
</p>
<h4>Weighted averaging</h4>
<p>You might be wondering by now how to calculate <i>weighted</i> averages with ncwa, after all ncwa stands for NetCDF weighted averager! Well it's simple the only extra switch that is required is <i>-w</i> followed by the variable to use for the weights. Sometimes it is useful to include the <i>-N</i> option which tells ncwa to only use the numerator of the weights, i.e. integrating the variable over the selected weighting variable such as grid cell area. It is often that variables (at least from model output) will be area-weighted to begin with, if so <code>-w area</code> without <code>-N</code> will produce the same output as would not weighting by area in the first place. However if you use <code>-N -w area -v var</code> ncwa will calculate the area$\times$var product in each cell without ever dividing by the sum of the areas thus integrating the variable over area. Here are two examples to clarify.
</p>
<p>For the first example we will calculate the annual mean leaf area index (LAI) as simulated by the Community Earth System Model. For comparison we will calculate the same mean weighted by simulated plant transpiration (QVEGT). The result from the latter will cause grid cells that have high LAI and high QVEGT to stand out while lessening the value of LAI where QVEGT is below average.
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncrcat -O model_out_199*.nc concated.nc
<span style="color: #bb60d5">$ </span>ncwa -O -a <span style="color: #007020">time </span>concated.nc not_weighted.nc
<span style="color: #bb60d5">$ </span>ncwa -O -w QVEGT -a <span style="color: #007020">time </span>concated.nc QVEGT_weighted.nc
</pre></div>
<p>Here is the corresponding plot for the non-weighted mean LAI:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLnckhNXSESlMYbzn1riDaW7RIKaAqcHsI84NfCxYoQrB4BCrOg6J6jlGzl1TVRyBIFPYFg1kB3UhSI7InKN3hU9N8hCyzYbzQkxfZsoQ4S9InJTyIx4SLrIDLj7Bympf7WTjI1wZb3Ms/s1600/LAI+in+not_weighted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLnckhNXSESlMYbzn1riDaW7RIKaAqcHsI84NfCxYoQrB4BCrOg6J6jlGzl1TVRyBIFPYFg1kB3UhSI7InKN3hU9N8hCyzYbzQkxfZsoQ4S9InJTyIx4SLrIDLj7Bympf7WTjI1wZb3Ms/s1600/LAI+in+not_weighted.png"></a></div>
<p>And here is the corresponding plot for the mean LAI weighted by QVEGT:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmYo7Y3k9-N0alB6LXjIvZd5eZm_Zi8j_gBiMK-PafmH4sY1nDr4mIx5N6YNFJ47b5Uw4r4UXpVtGmBjh1hl4xZxPqAPC4AAUCK_LEfvuH5InLujVAKzugp27H0lghN2BrTIM0JJ3ysO8/s1600/LAI+in+QVEGT_weighted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmYo7Y3k9-N0alB6LXjIvZd5eZm_Zi8j_gBiMK-PafmH4sY1nDr4mIx5N6YNFJ47b5Uw4r4UXpVtGmBjh1hl4xZxPqAPC4AAUCK_LEfvuH5InLujVAKzugp27H0lghN2BrTIM0JJ3ysO8/s1600/LAI+in+QVEGT_weighted.png"></a></div>
<p>There are clear differences between the weighted and non-weighted LAI maps, weighting allows us to visualize the locations where both vegetation is dense and where vegetation is transpiring. One observation I made by viewing both plots is there are large regions in northern North America and Asia that transpire quite a bit yet they do not correspond to the highest LAI, most of this region is home to the Boreal or Taiga coniferous forests. Perhaps the Boreal forests are transpiring significantly but are not as dense as say the tropical rainforests of the world. We could of seen the impact of transpiration on LAI more clearly by simply differencing these two plots however I wanted to keep the interpretation of the weighting operation as simple as possible.
</p>
<p>Just to clarify the use of the <i>-N</i> option this example shows how to integrate a variable over grid cell area and time. This is straightforward.
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncwa -O -N -w area -a <span style="color: #007020">time </span>concated.nc Area_integrated.nc
</pre></div>
<p>Now let's take a look at the familiar LAI variable after it has been integrated with respect to grid cell area and time:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGcQPqx55SRe4hpKGmwu4YuijGDncUsp_0iMla_g8PmtLn0fTWRTaRdq69O2XE0l-yw7O49VMGCLa1NUj1BlsTZgg-3qxuKCf6Gcb8WO8YObF4u1_M_STF4RaQ5G7yKnT84j3vMmRgMJ4/s1600/LAISUN+in+Area_integrated.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGcQPqx55SRe4hpKGmwu4YuijGDncUsp_0iMla_g8PmtLn0fTWRTaRdq69O2XE0l-yw7O49VMGCLa1NUj1BlsTZgg-3qxuKCf6Gcb8WO8YObF4u1_M_STF4RaQ5G7yKnT84j3vMmRgMJ4/s1600/LAISUN+in+Area_integrated.png"></a></div>
<p>By integrating with respect to grid cell area (km$^2$) and time the values of LAI are now very huge and not meaningful, to be precise the values are simply the product of LAI and the grid cell area summed over the time length-12 months: $$\mbox{Values for each grid cell above}~=~ \sum_{n=1}^{12} LAI_{i,j}\times GCA_{i,j}$$ where $GCA_{i,j}$ is the grid cell area (km$^2$) for the cell at the $i^{th}$ latitude index and the $j^{th}$ longitude index on the model grid which is 1$^\circ$ resolution. We see that by doing this the values near the equator increased and as we move towards the poles the LAI values decreased as compared to the non-weighted plot of LAI above. This is simply a result of the spherical grid that the model utilizes which has much higher grid cell areas near the equator.
</p>
<p>The <i>-N</i> option is equivalent to <i>-y ttl</i> which tells ncwa to take the sum as opposed to the mean over the specified dimensions after <i>-a</i> and since area is not a dimension in the files we are working with we needed to list area as the weight variable. Note, integrating some variables may or may not make sense depending on what you are trying to accomplish and remember some variables may have already been area weighted and take special care to understand what units you are dealing with. For example QVEGT above has units of mm/s. If you weighted QVEGT by grid cell area (which happens to be in $km^2$) and summed over time as shown above for LAI you would get units of $12\cdot mm\cdot km^2/s$. You could then calculate the average volumetric flux by dividing by 12 and converting the $km^2$ to $mm^2$.
</p>
<h4>Computing other aggregating statistics besides averaging</h4>
<p>The ncwa averages by default but also allows additional aggregating statistic calculations by stating them after the <i>-y</i> option. These methods also work for ncra, ncea, and nces. The ncra (NetCDF record averager) is a less sophisticated version of ncwa, you can find more about it and ncea (NetCDF ensemble averager) <a href="http://www.subcriticalflow.com/2015/09/NetCDF-NCO-ncrcat-ncecat-ncra-ncrea-concatenate-average.html">here</a>. As mentioned the <i>-N</i> option is the equivalent to <i>-y ttl</i> and tells ncwa to sum over the specified dimensions listed after the <i>-a</i> option. Here is a list of all the statistics that ncwa, ncra, ncea, and nces support with the operation keyword followed by a colon and then its description:
</p>
<ul>
<li><code>avg</code> : mean value</li>
<li><code>ttl</code> : sum of values</li>
<li><code>sqravg</code> : square of mean</li>
<li><code>sqrt</code> : square root of the mean</li>
<li><code>avgsqr</code> : mean of sum of squares</li>
<li><code>max</code> : maximum value</li>
<li><code>min</code> : minimum value</li>
<li><code>mabs</code> : maximum absolute value</li>
<li><code>mebs</code> : mean of absolute value</li>
<li><code>mibs</code> : minimum absolute value</li>
<li><code>rms</code> : root-mean-square (normalized by N)</li>
<li><code>rmssdn</code> : root-mean-square (normalized by N-1)</li>
</ul>
<p>For example,
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>ncwa -O -v QVEGT -a <span style="color: #007020">time</span> -d lat,-60.,15. -d lon,280.,330. -y max concated.nc out.nc
</pre></div>
<p>Will calculate the max of the monthly simulated QVEGT for the rectangular region around South America.
</p>
<hr />
<h4>Final remarks</h4>
<p>As we saw the NCO command line tool for weighted averaging (ncwa) is powerful and flexible, it is not limited to weighted averaging but can do a range of aggregating statistics, with or without weights, including subsetting and logical indexing or masking. This makes ncwa one of my favorite NCO tools because it can do so many jobs. Once you get familiar with it I think you will prefer using it over opening NetCDF files in your language of choice and doing the operations there. This is because the NCO syntax is succinct and the inner workings are optimized for speed and efficient memory use. Once you couple NCO with a scripting language of your choice it becomes even more powerful. If you enjoyed this post or have suggestions please comment like subscribe and keep visiting! Cheers and happy NetCDF-ing :)
</p>
</body>
John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-87388828521948625952015-10-27T14:44:00.009-07:002021-11-17T09:42:16.959-08:00Scale independent hydrologic metrics<head>
<title></title>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 0.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
table{
border-collapse: collapse;
font-family:bookman;
font-size:110%;
}
.firstLine th{
border-bottom: 1px solid black;
font-size:120%;
}
.blank_row
{
height: 10px !important; /* Overwrite any previous rules */
background-color: #FFFFFF;
}
</style>
<script type="text/x-mathjax-config">
//<![CDATA[
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": { availableFonts: ["TeX"] }
});
//]]>
</script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript">
</script>
</head>
<body>
<p>A short discussion of common metrics used to characterize the hydrology of watersheds.</p>
<span><a name='more'></a></span>
<p>
Scale independent hydrologic metrics, or sometimes called hydrologic signatures, are quantities that capture watershed hydrologic responses or characteristics that do not depend on the size of the watershed. Put another, way they are useful ways to measure hydrologic response that do not scale with watershed area. However, even these metrics generally breakdown when used at the very fine or large scales (and definiately at pore or continental scales!). Such metrics are useful in relating hydrologically similar watersheds of different extent to one another to identify fundamental hydrologic properties of a watershed. For example the relation between storage and discharge of a watershed can be described using scale invariant recession metrics. Below is a table I put together of four basic and well known scale independent hydrologic metrics that can be calculated for a watershed using commonly available data like streamflow, precipitation, and temperature.
</p>
<br />
<center>
<table style="width:75%">
<col width="75">
<col width="75">
<col width="280">
<tr class="firstLine">
<th>Metric name</th>
<th>Quantity</th>
<th>Description</th>
</tr>
<tr>
<td><strong>Runoff ratio</strong></td>
<td align='center'>$\huge{\frac{\overline{Q}}{\overline{P}}}$</td>
<td>$\overline{Q}$ and $\overline{P}$ are long-term average streamflow and precipitation for the watershed. The runoff ratio represents the fraction of precipitation that has contributed to streamflow in a watershed assuming the only hydrologic input is direct precipitation. Depending on the time period used to calculate the runoff ratio it can be an indicator of surface properties in a watershed (impervious to highly permeable) or over longer periods it indicates losses to evapotranspiration.</td>
</tr>
<tr class="blank_row">
<td colspan="3"></td>
</tr>
<tr>
<td><strong>Snowfall/Precipitaion-day ratio</strong></td>
<td align='center'>$\huge{\frac{N_{S}}{N_{P}}}$</td>
<td>$N_{S}$ is the number of days in a given year that had snowfall and $N_P$ is number of days that exhibited precipitation. Sometimes these are measured using a threshold amount of of snow or precipitation e.g. number of days with snowfall above 1 cm or rainfall above 1 mm, $N_S$ may also be calculated as the number of days when the temperature was below freezing. Also called the snow day ratio this metric quantifies the dominance of snow as the major form of precipitation for a watershed.</td>
</tr>
<tr class="blank_row">
<td colspan="3"></td>
</tr>
<tr>
<td><strong>Streamflow elasticity</strong></td>
<td align='center'><i>median</i>$\huge{\left(\frac {\frac{dQ}{\overline{Q}}} {\frac{dP}{\overline{P}}} \right)}$</td>
<td>$\overline{Q}$ and $\overline{P}$ are long-term average streamflow and precipitation for the catchment. The derivative of $Q$ or $P$ is likely not available due to the non-continuous measurements of these variables and these quantities are estimated by differencing each day from the previous day's value, alternatively the difference can calculated by subtracting each day by the annual mean value. Streamflow elasticity indicates how sensitive the watershed is to precipitation, that is for a given change in $P$ how much will $Q$ change. A high value indicates an elastic or sensitive watershed whereas a low vaule indicates an inelastic or insensitive watershed.</td>
</tr>
<tr class="blank_row">
<td colspan="3"></td>
</tr>
<tr>
<td><strong>Baseflow index</strong></td>
<td align='center'>$\huge{ \frac{\overline{Q_{bf}}} {\overline{Q_{sf}}} }$</td>
<td>$\overline{Q_{bf}}$ is long-term average of the baseflow component of streamflow, usually estimated using a digital filter and $\overline{Q_{sf}}$ is the long-term average streamflow for the catchment. Baseflow index or BFI represents the long-term average proportion of the baseflow component (i.e. groundwater discharge) of total streamflow in a stream. A BFI close to one means that nearly all flow is from slow subsurface discharge to a stream whereas a BFI near zero means that the stream gets most of its input from fast overland flow or preferential flow from precipitation events. Thus the BFI can be related to land cover, soil/aquifer permeability, and other watershed characteristics. </td>
</tr>
</table>
</center>
<br />
<p>
The concept of scale independent metrics for hydrology is important; they can give insight into fundamental hydrologic processes in a watershed. This is an abbreviated list of straightforward metrics that can easily be calculated for a gaged watershed. Using scale independent metrics to investigate hydrologic change and variability is important because the metrics relate to key hydrologic processes or important watershed characteristics. They are also commonly used to classify hydrologically similar watersheds. Can you think of other scale independent metrics? Feel free to post your thoughts in the comments.
</p>
</body>
<script type="text/javascript">MathJax.Hub.Queue(["Typeset",MathJax.Hub]);</script>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com1tag:blogger.com,1999:blog-4671541330977381429.post-72660698368063504002015-10-07T01:55:00.004-07:002021-11-17T09:41:58.468-08:00Why you should learn Python's multiprocessing module<head>
<title></title>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 0.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<body>
<p>A brief introduction to the Python multiprocessing library.</p>
<span><a name='more'></a></span>
<p>
This post is not an in depth guide to multiprocessing in Python or even a brief intro. Rather it is intended to give you motivation to bother learning it. When I recently experimented with Python's cross-platform <a href="https://docs.python.org/2/library/multiprocessing.html">multiprocessing</a> module I was pleasantly surprised on how easy it was to use. I was able to quickly parallelize iterative tasks in Python. For example I have a script that runs the same text parsing on files in multiple directories. Using a simple tool from the multiprocessing module allowed me to easily run the text processing in multiple directories simultaneously. This saved a lot of time since the alternative was looping over the list of directories and running the same command in each directory one at a time. You might have heard that Python is not a good language for parallel processing due to the Global Interpreter Lock issue but the multiprocessing module enables bypassing the lock.
</p>
<hr />
<br />
<h4>Simple example using Pool</h4>
<p>
The multiprocessing module has several objects that may be useful for you; one that stands out is the pool class. Pool allows you to utilize multiple processors to run a set of independent tasks quite efficiently (small amount of code) in parallel. To use pool first create a pool object and then simply call its map method which maps a python data collection e.g. a list or dictionary to a single parameter function. In other words map applies the function you pass it to every element in a collection you also must pass to it as input. Check it out,
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">multiprocessing</span> <span style="color: #007020; font-weight: bold">as</span> <span style="color: #0e84b5; font-weight: bold">mp</span>
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">time</span>
a_list <span style="color: #666666">=</span> <span style="color: #007020">range</span>(<span style="color: #40a070">8</span>)
<span style="color: #007020; font-weight: bold">def</span> <span style="color: #06287e">f</span>(x):
time<span style="color: #666666">.</span>sleep(<span style="color: #40a070">5</span>)
<span style="color: #007020; font-weight: bold">print</span> x
pool <span style="color: #666666">=</span> mp<span style="color: #666666">.</span>Pool(processes<span style="color: #666666">=</span><span style="color: #40a070">8</span>)
pool<span style="color: #666666">.</span>map(f,a_list)
</pre></div>
<p>
When run produces,
</p>
<div style="background: #f0f0f0; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.8em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #bb60d5">$ </span>python mp.py
2
1
0
3
4
5
6
7
</pre></div>
<p>
In this arbitrary and simple example the last two lines of code do all the work. These two lines create the pool object and apply the function "f" to each element in "a_list" simultaneously on 8 cpu threads. The pool map method is analogous to the built in Python map function. Also notice that f simply prints the input parameter x but when run the output is not in the original order of a_list. This is the expected result because it is running 8 processes in parallel. Pool.map does not apply the function to the elements in the collection you pass it in any order. This means that the tasks you assign to pool must be completely independent from one another.
</p>
<p>
You can easily extend this example to fit more complicated workflows and as you can see it is incredibly simple. Chances are you have access to a multi-core/hyper-threaded processor that you are under-utilizing. So don't be scared any more, this Python module allows anyone to utilize multiprocessing in a very simple way. Any time you invest learning this module will greatly reward you by saving your runtime later. Cheers
</p>
</body>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com1tag:blogger.com,1999:blog-4671541330977381429.post-89042320474231601892015-09-26T02:09:00.005-07:002022-02-21T12:19:51.760-08:00Concatenate and average NetCDFs<head>
<title></title>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 0.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<body>
<p>An quick tutorial on installing command line NetCDF tools and using them for basic variable concatenation and averaging.</p>
<span><a name='more'></a></span>
<p>Network Common Data Form AKA NetCDF files are commonly used to hold multidimensional scientific data, the NetCDF project was started in the 80's and is maintained by <a href="http://www.unidata.ucar.edu/"> Unidata</a>. If you work with netCDF files on a routine basis you probably already have a method for merging or aggregating data across multiple netCDF files. Conversely, if you are new to netCDF files this lesson is a good starting point for basic commands that aid in aggregating data across multiple netCDF files. Ultimately, learning NCO should save you a lot of time developing your own methods to work with NetCDF files from scratch. This is a basic introduction to a few basic NCO operators with examples. Everything in this post should work for Debian based Linux distributions and with slight modifications on any system.</p>
<hr />
<h3>NetCDF Operators (NCO) toolkit</h3>
<ul style="list-style-type: disc;">
<li>Command line tools for essential data wrangling tasks on netCDF, HDF, and DAP files</li>
<li>Fast optimized algorithms, Open Source</li>
<li>Flexible syntax, shell wildcard expansion and extended regex compatibility</li>
<li>Can seem like a lot to learn at first- start simple</li>
</ul>
<h3>Get NCO for Debian systems</h3>
<p>Get the newest full distribution from a compressed tarfile <a href="http://sf.net/projects/nco"><strong>here</strong></a>. I installed via the aptitude repository and recommend it:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">sudo apt-get update
sudo apt-get install nco
</pre></div>
<br />
<h4>Concatenating</h4>
<br />
<h3>Concatenate data that extends multiple files using <strong>ncrcat</strong></h3>
<p>Commonly when working with netCDF files you will have a sequence of files that correspond to the same record. Commonly time series data that spans multiple files.
For example you may have temperature data from a station that records every 15 minutes and each file has one year of data. Lets say you have a netCDF file of this data for every year from 1990 to 2010:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;"><span style="color: #bb60d5;">$ </span>ls
temp_1990.nc
temp_1991.nc
temp_1992.nc
temp_1993.nc
temp_1994.nc
temp_1995.nc
temp_1996.nc
temp_1997.nc
temp_1998.nc
temp_1999.nc
temp_2000.nc
temp_2001.nc
temp_2002.nc
temp_2003.nc
temp_2004.nc
temp_2005.nc
temp_2006.nc
temp_2007.nc
temp_2008.nc
temp_2009.nc
temp_2010.nc
</pre></div>
<p>To concatenate these files such that the time series values from each file flow together in one file. This is simply done using the <strong>ncrcat</strong> command which concatenates multiple files along a record dimension- commonly time. All NCO command line operations follow the general syntax: <code>operator -options [option_params] input_file(s) output_file(s)</code>. We can run ncrcat to concatenate all the temperature files using the standard shell * wildcard which matches any character any number of times.</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncrcat temp_*.nc temp_full_record.nc
</pre></div>
<p>The resulting <i>temp_full_record.nc</i> NetCDF file will contain a complete time series of all data variables indexed to their record dimensions. The alternative to using the * glob expansion wildcard would be to list each input file one by one space delimited. Example: </p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncrcat temp_2000.nc temp_2001.nc temp_2002.nc temp_2000-2002.nc
</pre></div>
<p>Some time you may be working with very large files or a large number of files and to save resources and time you may only want to concatenate one or a few variables from the files, this is easily done using the <i>-v</i> or --variable (long name) option of ncrcat. For example if the temp NetCDF files contained variables such as humidity, tmax, tmin, dewpoint, solrad, and windspeed and we are only interested in the humidity and windspeed then the following command would do concatenate just these two variables as well as maintaining any associated dimensions or coordinates (e.g. time, latitude, longitude, vertical layers, etc.).</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncrcat -v humidity,windspeed temp_*.nc humidity_wind.nc
</pre></div>
<p><strong><i>Note</i></strong> the variables listed after the -v option must be listed as comma delimited without any white space. Another useful option that complements -v is the exclude option <strong>--exclude</strong> or <strong>-x</strong> which will exclude the specified variables from the output file while maintaining all others found in the input files.
<h3>Ensemble Concatenation using ncecat</h3>
<p>Another useful NCO operator <strong>ncecat</strong> will concatenate multiple NetCDF files that have the same length record dimension and the same variables. For example, you may have output from five climate model realizations (from the same model) that all ran for the same time period and all have the same dimensions, coordinates, and variables. If you want all of them in one file with variables side by side then use ncecat. A disadvantage is ncecat does require that all the files be of the same length and dimension for each variable and all the files must contain the same variables (names of variables and dimensions as well as values of dimensions must match exactly). In this example we have output files from five model realizations:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;"><span style="color: #bb60d5;">$ </span>ls
scenario_00.nc
scenario_01.nc
scenario_02.nc
scenario_03.nc
scenario_04.nc
</pre></div>
<p>In a similar way that we used ncrcat above, we can place the variables in each of these files in one file. This time ncecat will place the same variables from each file side by side because each file has the same record dimensions (time is a common record dimension). Do <i>not</i> use ncrcat for concatenating files that have the same record dimensions. If we wanted to concatenate all data from the files for scenario two through four inclusive we could use ncecat with the [] glob expansion:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncecat scenario_0<span style="color: #666666;">[</span>234<span style="color: #666666;">]</span>.nc scenarios_02_to_04.nc
</pre></div>
<br />
<h4>Averaging</h4>
<br />
<h3>Average data that extends multiple files using ncra</h3>
<p>To average multiple NetCDF files that contain the same variables over the same record dimension (usually time) ncra can be used in an analogous way as ncrcat. It is easy to remember these two because their abbreviations: ncrcat "NetCDF record concatenator" and ncra: "NetCDF record averager". Using the same ten temperature files as shown above, to average all variables in these files over the record 1990-2010 simply run ncra on all the input files:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncra temp_*.nc temp_full_record.nc
</pre></div>
<p>A useful option <strong>-d</strong> or long version <strong>--dimension</strong> allows us to take a subset (hyperslab) of data based on a dimensional range of that data. For example you may want to know the 20 year average of the data variables recorded (humidity, tmax, tmin, dewpoint, solrad, and windspeed) for all points north of 45 degrees latitude. This can de done via:</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncra -d lat,45.,90. temp_*.nc temp_full_record.nc
</pre></div>
<p>The general syntax for sub-setting is <code>-d dim,[min],[max]</code>. Note that there are no spaces between the dimension name (lat) and min (45.) and max (90.) latitude values. The above example output file will have the record average (usually time) for each variable in the file for only the spatial coordinates above the 45th latitude. Do not confuse this with averaging all the variable values above the 45th latitude. Concatenating operators ncrcat and ncecat can also use this option but for combinations of subsets based on two or more dimensions, e.g. averaging over latitude and longitude you will either need to use the NetCDF kitchen sink (ncks) operator first using the syntax <code>ncks -d dim,[min],[max],[stride] -d dim,[min],[max],[stride] -d dim,[min],[max],[stride] in.nc out.nc</code>. The resulting output file will have the desired dimensional domain. If stride is not given then all data between min and max are included, a stride of 2 will select every other value of the dimension (e.g. every other day if dim is time), 3 every third and so on. With ncks there is no limit on how many dimensions and ranges of dimensions you can subset over. See multislab-- section 3.9 in the NCO user's guide for more info, also in this specific case you would use the ncwa (weighted averager) listing multiple dimensional ranges.
</p>
<h3>Ensemble averaging using <strong>ncea</strong></h3>
<p>Recall the example on ensemble concatenation where ncecat combined data of the same record dimension from five model realizations into one NetCDF file. In a similar way ncea will perform an ensemble average over the various model output files. We can take a scenario ensemble average of humidity from the five climate scenarios, the output would be something like a singe spatial array of humidity. Remember humidity is a variable in the climate NetCDF files that were output from the climate model.
</p>
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid white; overflow: auto; padding: .8em .6em; width: auto;"><pre style="line-height: 125%; margin: 0;">ncea -v humidity scenario_*.nc ensemble_avg_humidity.nc
</pre></div>
<br />
<h3>Final remarks</h3>
<p>These NCO operators are useful, fast, and free so use them! This post went over the basics of concatenating and averaging data from multiple NetCDF files and some of their fundamentally important options. It is a good start. However, there are more operators and there is much more that the NCO operators can do and even the operators described here offer more advanced options and functionality. For example, many times you might want to average over different dimensions as opposed to time (which is the typical record dimension) and for that the NetCDF weighted averager (ncra) is the tool you want. To learn more about advanced averaging methods using NCO including subsetting, conditional masking, and weighted statistics check out this <a href="http://www.subcriticalflow.com/2015/11/computing-zonal-and-weighted-statistics.html">post</a>. </p>
<br />
<h3>Useful links</h3>
<p>NCO's homepage: <a href="http://nco.sourceforge.net/">http://nco.sourceforge.net/</a> </p>
<p>NCO User's Manual: <a href="http://nco.sourceforge.net/nco.html">http://nco.sourceforge.net/nco.html</a></p>
</p></body>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-22974062679502544552015-09-19T18:05:00.002-07:002021-11-17T09:44:36.097-08:00Getting WhatPulse installed on Linux<head>
<title></title>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
li{
line-height: 0.5em;
margin-top: 1px 0;
margin-bottom: 1px 0;
font-family:bookman;
font-size:110%;
}
hr {
border-color: #908d6a
}
</style>
</head>
<body>
<p>A short post aimed at helping anyone who is having issues installing the "WhatPulse" app on Linux.</p>
<span><a name='more'></a></span>
<p>If you are having issues installing WhatPulse on a Debian based Linux system, hopefully this post will help. If you don't know what WhatPulse is then check it out at the <a href="https://whatpulse.org/">official site</a> but it is a sweet little <i>free</i> app that tracks your keyboard and mouse usage and gives you fun statistics like which keys you click the most or time series plots of how much you type over time, including application specific stats. You can also compare yourself to global user's stats, I like it because it keeps me active and motivated to write. If you decide you want to give it a try you can <a href="http://whatpulse.org/ref/597115/">register a free WhatPulse account</a> first (note this is my referral link-unpaid and my WhatPulse ID is darcyslaw). There is generally less documentation for Linux installation so I decided to share what worked for me here.
</p>
<hr>
<h3>Install dependencies</h3>
<p>There are quite a few libraries required for whatpulse, namely the QT platform that whatpulse was built on.
</p>
<p>A list of these dependencies is given on a support document from whatpulse:
<ul>
<li>libQtCore</li>
<li>libQtWebKit</li>
<li>libqt4-sql</li>
<li>libqt4-sql-sqlite</li>
<li>openssl-devel (libssl-dev)</li>
<li>libQtScript</li>
</ul>
<p>To get these libraries the easiest way is to use the aptitude repository, I found the current names of these packages so you can try just copy and pasting:</p>
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">sudo apt-get update
sudo apt-get install libqtcore4 libqtwebkit4 libqt4-sql libqt4-sql-sqlite libssl-dev libqtscript4-core
</pre></div>
<br />
<h3>Download and setup</h3>
<p>Next you will want to download the correct compressed file for your Linux distribution and cpu here: <a href="https://whatpulse.org/downloads/">https://whatpulse.org/downloads/</a></p>
<p>Extract the <i>.tar.gz</i> file you can use:</p>
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">tar -zxvf whatpulse-linux-YOUR-VERSION.tar.gz
</pre></div>
<p>Now the last step is to give WhatPulse the ability to access your keyboard and mouse input and other privileges. Change directory into the extracted WhatPulse directory wherever you put it and run the supplied shell script <i>setup-input-permissions.sh</i> as root:</p>
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid white;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">sudo ./setup-input-permissions.sh
</pre></div>
<p>Hit return and you will prompted for the user you would like to give WhatPulse permission for. That is the user on your Linux machine e.g. "john" in my case. That's it, you should be done and next time you reboot your system WhatPulse should start!
</p>
</body>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-9808424949010927822015-09-13T22:24:00.008-07:002021-11-17T09:45:42.026-08:00Write and compile your first Fortran 95 program on Linux<head>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<p>Quick guide to writing, compiling, and executing a "Hello World" program in Fortran.</p>
<span><a name='more'></a></span>
<div class="separator" style="display:none;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhoiUp1kK1z8FnCIy3uLjXKSvF77wuyIcUjJQwQWKiRNkyiM4qyu5ZTmCGowifoHzFGe2K114XVkCbNANCwOJ2Nm20oPbZ-1QFvbEWdZ60OngYo6FDW3RJ3WNkBw3_jdSjQoczS6x8fxm6jvLYzJCpYDfniFT_KXDu5Y4yUWOgj0nYnm3Tr495TotwzpA=s255" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="255" data-original-width="255" height="255" src="https://blogger.googleusercontent.com/img/a/AVvXsEhoiUp1kK1z8FnCIy3uLjXKSvF77wuyIcUjJQwQWKiRNkyiM4qyu5ZTmCGowifoHzFGe2K114XVkCbNANCwOJ2Nm20oPbZ-1QFvbEWdZ60OngYo6FDW3RJ3WNkBw3_jdSjQoczS6x8fxm6jvLYzJCpYDfniFT_KXDu5Y4yUWOgj0nYnm3Tr495TotwzpA" width="255" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></div><p></p>
<p>
Fortran is a compiled programming language commonly used in scientific and numerical computations. It is one of the oldest (if not the oldest) machine independent programming languages, created by IBM in the early 50's. Many optimized numerical libraries were written in Fortran and are used by modern high level languages such as Python's numerical library <a href="https://numpy.org/" target="_blank">NumPy</a>. Scientific numerical models of physical phenomena such as weather and climate models are commonly written in Fortran, they often utilize parallel processing and run on the worlds most powerful supercomputers.
</p>
<p>
It may sound intimidating, but writing simple Fortran programs is not too difficult particularly if you have other programming experience. If you are a scientist or engineer that is running computationally extensive analysese in scripting languages such as Python, R, or MATLAB, it might be worth it to learn Fortran or C/C++ to give a performance boost to your work. This is not a tutorial but just a short snippet to help the very beginner compile a Fortran program that prints text to the shell.
</p>
<hr />
<h3>Get the gfortran compiler</h3>
<p>Learn how to write a simple Fortran 95 program and compile it on Linux. I am using a Debian based system- Linux Mint and compiling with gfortran. If you already have gfortran installed skip down to "write the program",
if you are not sure if you have gfortran installed you can run:</p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;">gfortran --version
</pre>
</div>
<p> If gfortran is installed you should see something like:</p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;">GNU Fortran <span style="color: #666666;">(</span>Ubuntu 4.8.4-2ubuntu1~14.04<span style="color: #666666;">)</span> 4.8.4
Copyright <span style="color: #666666;">(</span>C<span style="color: #666666;">)</span> 2013 Free Software Foundation, Inc.
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING
</pre>
</div>
<p>If you do not have gfortran installed you can run the following to install it from the apt repository:</p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;">sudo apt-get update
sudo apt-get install gfortran
</pre>
</div>
<p><i><b>Note,</b></i> you have the option to install different versions of gfortran as opposed to the newest version in your repository.
You might want to check out this <a href="http://askubuntu.com/questions/358907/how-do-i-install-gfortran">StackExchange post</a> if you're having trouble installing gfortran.
</p>
<h3>Write the program</h3>
<p>Once you have installed gfortran we can create and compile and then run our first Fortran 95 program. yay!
This part is easy, go ahead and create an empty file called first.f95 with your preferred text editor and then type
the following Fortran source code: </p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;"><span style="color: #408080; font-style: italic;">!my first Fortran program ever written</span>
<span style="color: green; font-weight: bold;">program </span><span style="color: #19177c;">first</span>
<span style="color: green; font-weight: bold;">IMPLICIT NONE</span>
<span style="color: green; font-weight: bold;">print</span> <span style="color: #666666;">*</span>,<span style="color: #ba2121;">'Hello World!'</span>
<span style="color: green; font-weight: bold;">print</span> <span style="color: #666666;">*</span>,<span style="color: #ba2121;">'This is my first Fortran 95 program ever.'</span>
<span style="color: green; font-weight: bold;">end program </span><span style="color: #19177c;">first</span>
</pre>
</div>
<p>Save and close your file, be sure to save is as first.f95 if you did not create it with a name yet.</p>
<h3>Compile and run!</h3>
<p>At the Linux command prompt within the same directory as first.f95 we can now compile our source code with gfortran:</p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;">gfortran first.f95 -o first
</pre>
</div>
<p><b><i>Note,</i></b> here we used the <b>-o</b> option so that we could name our executable, otherwise the default executable from gfortran will be a.out.
Finally we need to test our new program, we can run it just like any other executable file on Linux by typing ./ in front of its name. With any luck you should get the following output:</p>
<!--HTML generated using hilite.me--><div style="background: rgb(248, 248, 248); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">./first
Hello World!
This is my first Fortran 95 program ever.
</pre></div>
<p>Congratulations! you just successfully wrote, compiled, and ran a simple Fortran program on Linux. More to come on Fortran in future posts! </p>
John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com0tag:blogger.com,1999:blog-4671541330977381429.post-72644917219070292922015-09-07T22:22:00.006-07:002021-11-17T09:47:37.005-08:00How to highlight source code for displaying in HTML<head>
<style>
p {
color:black;
font-family:bookman;
font-size:110%;
}
</style>
</head>
<p>A useful online app that allows you to easily create fully formatted HTML to display highlighed code.</p>
<span><a name='more'></a></span>
<p>
I just want to share with you a useful <a href="http://hilite.me/" target="_blank">web tool</a> created by <a href="http://kojevnikov.com/" target="_blank">Alexander Kojevnikov</a> (thank you) that allows you to quickly and conveniently convert your source code to highlighted HTML so that you can place it on your website or blog.<br />
</p><hr />
<p>
Lets say you have some Python code snippet:<br />
<br />
def convert(x):<br />
return(x*2.54) <br />
## list of values to convert<br />
vals = [31,24,15,6.3] <br />
for each in vals:<br />
print convert(each) <br />
<br />
</p>
<p>However, what you <i>really</i> want is HT<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;">ML</span></span></span></span></span></span></span></span></span></span></span></span> that displays your source code as it appears in your development environment or code editor (e.g. spyder, jupyter, pycharm, vim, etc.). For example with highlighted keywords like:
</p>
<!--HTML generated using hilite.me--><br />
<div style="background: rgb(248, 248, 248); border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0px;"><span style="color: green; font-weight: bold;">def</span> <span style="color: blue;">convert</span>(x):
<span style="color: green; font-weight: bold;">return</span>(x<span style="color: #666666;">*2.54</span>)
<span style="color: #408080; font-style: italic;">## list of values to convert</span>
vals <span style="color: #666666;">=</span> [<span style="color: #666666;">31</span>,<span style="color: #666666;">24</span>,<span style="color: #666666;">15</span>,<span style="color: #666666;">6.3</span>]
<span style="color: green; font-weight: bold;">for</span> each <span style="color: #aa22ff; font-weight: bold;">in</span> vals:
<span style="color: green; font-weight: bold;">print</span> convert(each)
</pre>
</div>
<br />
<h3>Try it</h3>
<p>
<span style="font-family: inherit;">Just go the the web app at <a href="http://hilite.me/">http://hilite.me/</a> and type your source code in the box on the left<span style="font-family: inherit;">, select the language of the <span style="font-family: inherit;">source <span style="font-family: inherit;">code<span style="font-family: inherit;"> and the output style<span style="font-family: inherit;"><span style="font-family: inherit;">, then press "Highlight!"</span>. You will get output </span></span></span></span></span></span><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;">HTML</span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"> <span style="font-family: inherit;">for <span style="font-family: inherit;">displaying your source code <span style="font-family: inherit;">for many different languages. </span></span></span></span>The <span style="font-family: inherit;">screen shot below shows an example using</span></span></span></span></span></span></span><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"> the Python snippe<span style="font-family: inherit;">t above<span style="font-family: inherit;"> as it would be displayed in </span>the vim text editor (my favorite) using vim's default color scheme<span style="font-family: inherit;">. <span style="font-family: inherit;">You also have the option to <span style="font-family: inherit;">display line numbers in the <span style="font-family: inherit;">HTML. </span></span></span></span></span></span></span></span></span></span></span></span><br />
</p>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyjtiBQPEj9ThsqD3fttDf57TM8OSnZGZTXhaudnOfbFUV8UZaY8xSeiy0-l-_X9U66ZJ0BhtUttEnKGgh8cNnRKWNwBgN1l0KY8X99aioV1L77Ixcs56ymVVDuuhHsC_9-q4ZT_xcg-U/s1600/ss_highlitme.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="529" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyjtiBQPEj9ThsqD3fttDf57TM8OSnZGZTXhaudnOfbFUV8UZaY8xSeiy0-l-_X9U66ZJ0BhtUttEnKGgh8cNnRKWNwBgN1l0KY8X99aioV1L77Ixcs56ymVVDuuhHsC_9-q4ZT_xcg-U/s640/ss_highlitme.png" width="640" /></a></div>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: inherit;"> </span></span></span></span></span></span></span> </span>
<br />
<pre style="line-height: 125%; margin: 0px;"> </pre>
<p>Hilite.me is a useful web tool that you can easily use in a quick fashion to highlight and style source code of varying type to output in HTML, markdown, LaTeX, and others. With a bit of research you will find that everything done on the tool can easily be done on your system using the <a href="http://pygments.org/">Pygments</a> Python package. This may be worth learning if you commonly have workflows converting source code to readable HTML or produce documentation. Or if you do not have internet access. If there is interest in how to use Pygments in a workflow it will be a future post. </p>
<p></p>John Volkhttp://www.blogger.com/profile/04032976542767724390noreply@blogger.com1