<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>paradoxxx zero</title>
    <description>Random interesting things</description>
    <link>http://paradoxxxzero.github.io</link>
    <atom:link href="http://paradoxxxzero.github.io/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>wdb 3.0 material style</title>
        <description>&lt;p&gt;The future is here! wdb 3.0 is out get it while it’s hot (and certainly bugged)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/4cd1a4503682803966e706dec1de84b0d178da29/68747470733a2f2f7261772e6769746875622e636f6d2f4b6f7a65612f7764622f6d61737465722f7764622e706e67&quot; alt=&quot;Material wdb&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;changes&quot;&gt;Changes&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;A whole new material design lite interface (a bit responsive)&lt;/li&gt;
  &lt;li&gt;Clickable icons instead of hotkeys only&lt;/li&gt;
  &lt;li&gt;Visual distinction between stepping, post_mortem and shell&lt;/li&gt;
  &lt;li&gt;An actually readable help (you can get by clicking on the help icons)&lt;/li&gt;
  &lt;li&gt;A code mirror prompt with syntaxic coloration and more classic completion&lt;/li&gt;
  &lt;li&gt;New commands (open current file in external editor, respawn current process…)&lt;/li&gt;
  &lt;li&gt;A far better post mortem interaction when using ext and wdb is disabled.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;importmagic&lt;/code&gt; suggestions on NameError&lt;/li&gt;
  &lt;li&gt;Use of &lt;code class=&quot;highlighter-rouge&quot;&gt;uncompyle6&lt;/code&gt; to get python source when only byte-code is available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information about wdb, see &lt;a href=&quot;/2014/05/12/wdb-2.html&quot;&gt;previous post&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Jun 2016 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2016/06/08/wdb-3.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2016/06/08/wdb-3.html</guid>
      </item>
    
      <item>
        <title>Announcing butterfly 2.0</title>
        <description>&lt;p&gt;After 1 year and a half of waiting butterfly 2.0 is finally here!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/butterfly_2.0_1.gif&quot; alt=&quot;butterfly screen cast&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For those who don’t know butterfly is an open source in-browser nix terminal written in coffeescript (yeah I know, maybe I will port it to ES7 but you know… braces) and backed up by a python tornado server.&lt;/p&gt;

&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;

&lt;p&gt;Its feature list keep on growing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;xterm compatible (support a lot of unused features!)&lt;/li&gt;
  &lt;li&gt;Native browser scroll and search&lt;/li&gt;
  &lt;li&gt;Theming in css / sass &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly-themes&quot;&gt;(18 preset themes)&lt;/a&gt; endless possibilities!&lt;/li&gt;
  &lt;li&gt;HTML in your terminal! cat images and use &amp;lt;table&amp;gt;&lt;/li&gt;
  &lt;li&gt;Multiple sessions support (à la screen -x) to simultaneously access a terminal from several places on the planet!&lt;/li&gt;
  &lt;li&gt;Secure authentication with X509 certificates!&lt;/li&gt;
  &lt;li&gt;16,777,216 colors support!&lt;/li&gt;
  &lt;li&gt;Keyboard text selection!&lt;/li&gt;
  &lt;li&gt;Desktop notifications on terminal output!&lt;/li&gt;
  &lt;li&gt;Geolocation from browser!&lt;/li&gt;
  &lt;li&gt;May work on firefox too!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;give-it-a-shot&quot;&gt;Give it a shot&lt;/h2&gt;

&lt;p&gt;It’s even easier to try it now, just:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install butterfly
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install libsass  &lt;span class=&quot;c&quot;&gt;# If you want to use themes&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;butterfly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A new tab should appear in your browser. Then type&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;butterfly &lt;span class=&quot;nb&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To get an overview of butterfly features.&lt;/p&gt;

&lt;p&gt;For everyday use, it’s better to use a server see below.&lt;/p&gt;

&lt;h2 id=&quot;moar&quot;&gt;Moar&lt;/h2&gt;

&lt;p&gt;Go to the &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly&quot;&gt;github page&lt;/a&gt; for more informations, like setting up a server using systemd (I know I know) or why not contributing!&lt;/p&gt;

&lt;p&gt;Take a look at existing themes at &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly-themes&quot;&gt;butterfly-themes&lt;/a&gt; and current demos showing the butterfly potential at &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly-demos&quot;&gt;butterfly-demos&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;end&quot;&gt;End&lt;/h3&gt;

&lt;p&gt;We are in 2015, we can finally display images and html in a terminal and use 16M colors, what a world we are living in.&lt;/p&gt;
</description>
        <pubDate>Fri, 30 Oct 2015 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2015/10/30/butterfly_2.0.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2015/10/30/butterfly_2.0.html</guid>
      </item>
    
      <item>
        <title>Cutter</title>
        <description>&lt;p&gt;Today I finally wrote a readme for my little python tool &lt;a href=&quot;https://github.com/paradoxxxzero/cutter/&quot;&gt;cutter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is something that I use daily in conjuction of &lt;a href=&quot;https://github.com/Kozea/wdb&quot;&gt;wdb&lt;/a&gt; for debugging python code.&lt;/p&gt;

&lt;p&gt;Here’s the readme, I hope you will find it as useful as I am:&lt;/p&gt;

&lt;h1 id=&quot;readme&quot;&gt;Readme&lt;/h1&gt;

&lt;p&gt;Cutter is a small python module that add some sugar on top of list like objects to ease list traversal.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cutter&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'one'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'three'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'un'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'trois'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'uno'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tre'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Take the second element of every sublist&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Take the third letter of every second element of every sublist&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'o'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Idem&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'o'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Upper case the third letter of every second element of every sublist&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'O'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'U'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'E'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Flatten the list for one level&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'one'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'three'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'un'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'trois'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'uno'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tre'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# First letter of every elements&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'o'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;syntaxic-sugars&quot;&gt;Syntaxic sugars&lt;/h2&gt;

&lt;p&gt;There are two syntaxic sugars for an even easier use:&lt;/p&gt;

&lt;h3 id=&quot;the-_-syntax&quot;&gt;The |_ syntax&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cutter&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'O'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'U'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'E'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'one'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'three'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'un'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'trois'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'uno'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tre'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'o'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;the--syntax&quot;&gt;The ! syntax&lt;/h3&gt;
&lt;p&gt;This syntax is meant for use in shells.&lt;/p&gt;

&lt;p&gt;It is for example used in &lt;a href=&quot;https://github.com/Kozea/wdb&quot;&gt;wdb&lt;/a&gt; and the bundled cut.py interpreter.&lt;/p&gt;

&lt;p&gt;Cutter provide a &lt;code class=&quot;highlighter-rouge&quot;&gt;bang_compile&lt;/code&gt; function which is a wrapper of the python builtin &lt;code class=&quot;highlighter-rouge&quot;&gt;compile&lt;/code&gt; function.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# This code muste be compiled with cutter.utils.bang_compile&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'O'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'U'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'E'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'one'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'two'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'three'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'un'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'deux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'trois'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'uno'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'due'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tre'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'o'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'u'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'t'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This syntax use the python tokenizer and ast to make it work. This is really useful when debugging to inspect list content.&lt;/p&gt;

&lt;h3 id=&quot;more&quot;&gt;More&lt;/h3&gt;

&lt;p&gt;Cutter works with dictionaries too:&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'key'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;slices:&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For more examples see the test files : &lt;a href=&quot;https://github.com/paradoxxxzero/cutter/tree/master/test&quot;&gt;test&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cutter is compatible with at least: python 2.6, 2.7, 3.2, 3.3, 3.4 and pypy and is licensed under &lt;a href=&quot;http://www.gnu.org/licenses/lgpl.html&quot;&gt;lgpl v3&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 13 May 2015 15:04:42 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2015/05/13/cutter.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2015/05/13/cutter.html</guid>
      </item>
    
      <item>
        <title>wdb 2.1 new features and a new clean theme</title>
        <description>&lt;p&gt;Hi everybody!&lt;/p&gt;

&lt;p&gt;wdb 2.1 is here with a new more serious light theme:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/wdb21_light.png&quot; alt=&quot;wdb light theme&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and some new features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;New completion mechanism, should complete a lot better&lt;/li&gt;
  &lt;li&gt;Experimental object tree search (&lt;code class=&quot;highlighter-rouge&quot;&gt;.f&lt;/code&gt; command) to look for a key or a value condition in an object&lt;/li&gt;
  &lt;li&gt;Media display in debugger (&lt;code class=&quot;highlighter-rouge&quot;&gt;.i&lt;/code&gt; command)&lt;/li&gt;
  &lt;li&gt;New diff function to print differences between string / obj / files (&lt;code class=&quot;highlighter-rouge&quot;&gt;.x&lt;/code&gt; command)&lt;/li&gt;
  &lt;li&gt;Timing for expression evaluation (remote and local)&lt;/li&gt;
  &lt;li&gt;Prompt exception inspection (click on it)&lt;/li&gt;
  &lt;li&gt;A new shell mode and an executable &lt;code class=&quot;highlighter-rouge&quot;&gt;wdb&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;A new multiline prompt mode triggered by &lt;code class=&quot;highlighter-rouge&quot;&gt;[ctrl]&lt;/code&gt; + &lt;code class=&quot;highlighter-rouge&quot;&gt;[enter]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;And a lot of bug fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more features see the &lt;a href=&quot;/2014/05/12/wdb-2.html&quot;&gt;last wdb 2.0 post&lt;/a&gt; and the &lt;a href=&quot;https://github.com/Kozea/wdb&quot;&gt;github readme page&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 07 May 2015 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2015/05/07/wdb-2.1.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2015/05/07/wdb-2.1.html</guid>
      </item>
    
      <item>
        <title>wdb 2.0 the python debugger in your web browser</title>
        <description>&lt;p&gt;I released wdb 2.0 this morning with a lot of fixes and features added.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/wdb.gif&quot; alt=&quot;wdb screen cast&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;wdb-debugging-itself-colors-are-awful-due-to-gif-compression&quot;&gt;&lt;strong&gt;wdb&lt;/strong&gt; debugging itself &lt;small&gt;(colors are awful due to gif compression)&lt;/small&gt;&lt;/h4&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;For those who don’t know the project, &lt;strong&gt;wdb&lt;/strong&gt; is a python debugger like &lt;a href=&quot;https://docs.python.org/3/library/pdb.html&quot;&gt;pdb&lt;/a&gt;, but with a slick web front-end and a lot of additional features, such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Source syntax highlighting&lt;/li&gt;
  &lt;li&gt;Visual breakpoints&lt;/li&gt;
  &lt;li&gt;Interactive code completion using &lt;a href=&quot;http://jedi.jedidjah.ch/&quot;&gt;jedi&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Persistent breakpoints&lt;/li&gt;
  &lt;li&gt;Deep objects inspection using mouse&lt;/li&gt;
  &lt;li&gt;Multithreading / Multiprocessing support&lt;/li&gt;
  &lt;li&gt;Remote debugging&lt;/li&gt;
  &lt;li&gt;Watch expressions&lt;/li&gt;
  &lt;li&gt;In debugger code edition&lt;/li&gt;
  &lt;li&gt;Popular web servers integration to break on error&lt;/li&gt;
  &lt;li&gt;In exception breaking during trace (not post-mortem) in contrary to the werkzeug debugger for instance&lt;/li&gt;
  &lt;li&gt;Breaking in currently running programs through code injection (on supported systems)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project started because I wanted to improve the werkzeug debugger and it ended up as a whole project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;wdb&lt;/strong&gt; supports python 2.6, 2.7, 3.2, 3.3, 3.4 and pypy.&lt;/p&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;p&gt;Enough with the introduction, let’s just try it.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install wdb.server      &lt;span class=&quot;c&quot;&gt;# Install both debugging client and server&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wdb.server.py &amp;amp;             &lt;span class=&quot;c&quot;&gt;# Start the server as a background process&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; wdb your_file.py  &lt;span class=&quot;c&quot;&gt;# Start debugging your_file.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the last command, your default web browser should open with the debugger paused at the first executable line of your file. You can get some help by typing &lt;code class=&quot;highlighter-rouge&quot;&gt;.h&lt;/code&gt; in the prompt. But for the basic commands:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.s or [Ctrl] + [↓] or [F11]&lt;/code&gt; : Step into&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.n or [Ctrl] + [→] or [F10]&lt;/code&gt; : Step over (Next)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.r or [Ctrl] + [↑] or [F9] &lt;/code&gt; : Step out (Return)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.c or [Ctrl] + [←] or [F8] &lt;/code&gt; : Continue&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.u or [F7]                 &lt;/code&gt; : Until (Next over loops)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.h                         &lt;/code&gt; : Get some help&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.q                         &lt;/code&gt; : Quit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the server is running, you can access the following url &lt;a href=&quot;http://localhost:1984/&quot;&gt;localhost:1984/&lt;/a&gt; to have an overview of currently opened debugging sessions, global breakpoints and running python process (which you may pause see &lt;a href=&quot;https://github.com/Kozea/wdb#wdb-server&quot;&gt;here&lt;/a&gt; for more information).&lt;/p&gt;

&lt;p&gt;Wdb can also be used just like pdb, by putting:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;wdb&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;wdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;anywhere in your code, where you want it to pause.&lt;/p&gt;

&lt;h2 id=&quot;upgrade-from-v1x&quot;&gt;Upgrade from v1.x&lt;/h2&gt;

&lt;p&gt;To upgrade to wdb 2.0 you need to run:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install wdb.server
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install &lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt; wdb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is because now the package is split between the server and the debugging client to avoid unneeded dependencies installed in virtualenvs or other python versions (once the server is installed and running you just have to install &lt;code class=&quot;highlighter-rouge&quot;&gt;wdb&lt;/code&gt; in your virtualenvs).&lt;/p&gt;

&lt;h2 id=&quot;more&quot;&gt;More&lt;/h2&gt;

&lt;p&gt;For more detailed instructions and other features please read the &lt;code class=&quot;highlighter-rouge&quot;&gt;README.md&lt;/code&gt; on the github page: &lt;a href=&quot;https://github.com/Kozea/wdb&quot;&gt;github.com/Kozea/wdb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, you are more than welcome to contribute to the project (GPLv3), by adding new features, creating themes or supporting me financially see &lt;a href=&quot;/about/&quot;&gt;about page&lt;/a&gt; &lt;em&gt;(Encouraged!)&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 12 May 2014 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2014/05/12/wdb-2.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2014/05/12/wdb-2.html</guid>
      </item>
    
      <item>
        <title>butterfly now with ssl authentication</title>
        <description>&lt;p&gt;First of all thanks for all your feedback on butterfly, I never expected this to have such success (wow).
Google Analytics says about 50k visits in 2 days scattered among 164 countries. That’s a lot and this led to a fair amount of constructive criticism (and obviously a huge amount of destructive criticism too).&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;

&lt;p&gt;Security was a major topic among all discussions and therefore several security breaches were fixed. That’s why starting with the new 1.4.0 release, the SSL secure mode will now be enabled by default. This works by creating a certificate and a client authentication file (&lt;a href=&quot;http://en.wikipedia.org/wiki/Transport_Layer_Security&quot;&gt;More info&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This is a boring process so I added some options in butterfly to make your life easier.&lt;/p&gt;

&lt;p&gt;NB: Before going into the details, be aware that the previous behavior is still available using the &lt;code class=&quot;highlighter-rouge&quot;&gt;--unsecure&lt;/code&gt; option.&lt;/p&gt;

&lt;h3 id=&quot;use-butterfly--140&quot;&gt;Use butterfly &amp;gt; 1.4.0&lt;/h3&gt;

&lt;p&gt;As you launch &lt;code class=&quot;highlighter-rouge&quot;&gt;butterfly.server.py&lt;/code&gt; you will see that it can’t start without generating certificates. So let’s make them!&lt;/p&gt;

&lt;h4 id=&quot;generating-certificates-files&quot;&gt;Generating certificates files&lt;/h4&gt;
&lt;p&gt;In this example I suppose you run the server as root, you want to access it as user &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt; on a local network and your ip address on this network is &lt;code class=&quot;highlighter-rouge&quot;&gt;192.168.0.1&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;butterfly.server.py &lt;span class=&quot;nt&quot;&gt;--generate-certs&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;192.168.0.1&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Generate the root certificate for running on local network&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;butterfly.server.py &lt;span class=&quot;nt&quot;&gt;--generate-user-pkcs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;foo              &lt;span class=&quot;c&quot;&gt;# Generate PKCS#12 auth file for user foo&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you run as root the certificates will be placed in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/buttefly/ssl/&lt;/code&gt;, as user in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.butterfly/ssl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once generated, you will have to configure your browser to accept your self signed certificate and the PKCS#12 file (which contains a private key for your user to log in).&lt;/p&gt;

&lt;h4 id=&quot;importing-the-root-certificate-in-google-chrome&quot;&gt;Importing the root certificate in Google Chrome&lt;/h4&gt;

&lt;p&gt;Under Google Chrome go to &lt;em&gt;Settings &amp;gt; Show advanced settings… &amp;gt; HTTPS/SSL &amp;gt; Manage certificates… &amp;gt; Authorities &amp;gt; Import…&lt;/em&gt; and specify the &lt;code class=&quot;highlighter-rouge&quot;&gt;butterfly_ca.crt&lt;/code&gt; file.&lt;/p&gt;

&lt;h4 id=&quot;importing-the-root-certificate-in-firefox&quot;&gt;Importing the root certificate in Firefox&lt;/h4&gt;

&lt;p&gt;Under Firefox go to &lt;em&gt;Edit &amp;gt; Preferences &amp;gt; Advanced &amp;gt; View Certificates &amp;gt; Authorities &amp;gt; Import…&lt;/em&gt; and specify the &lt;code class=&quot;highlighter-rouge&quot;&gt;butterfly_ca.crt&lt;/code&gt; file.&lt;/p&gt;

&lt;h4 id=&quot;importing-the-user-client-authentication-file&quot;&gt;Importing the user client authentication file&lt;/h4&gt;
&lt;p&gt;For the PKCS#12 you will have to change the file ownership before importing it since this file is a secured file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;cp /etc/butterfly/ssl/foo.p12 /tmp &lt;span class=&quot;c&quot;&gt;# Copy it in /tmp&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;chown foo /tmp/foo.p12             &lt;span class=&quot;c&quot;&gt;# Make it readable to the browser&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then go to the &lt;em&gt;Your Certificates&lt;/em&gt; tab (for both Google Chrome and Firefox) and import it from &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp&lt;/code&gt;. If you set a password during the creation you will have to type it otherwise leave it blank. Some browsers don’t seem to appreciate blank passwords, if this doesn’t work retry &lt;code class=&quot;highlighter-rouge&quot;&gt;--generate-user-pkcs&lt;/code&gt; with a password.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;butterfly.server.py &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;192.168.0.1&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Run the server&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now point your browser at &lt;a href=&quot;https://192.168.0.1:57575/&quot;&gt;&lt;strong&gt;https://&lt;/strong&gt;192.168.0.1:57575/&lt;/a&gt; and you are done without typing any password (The authentication informations are contained in the PKCS#12 file).&lt;/p&gt;

&lt;p&gt;You will have to run &lt;code class=&quot;highlighter-rouge&quot;&gt;--generate-certs&lt;/code&gt; every time you want to use a different &lt;code class=&quot;highlighter-rouge&quot;&gt;--host&lt;/code&gt;, the PKCS#12 will still work though since both host and user files comes from the same CA.&lt;/p&gt;

&lt;h4 id=&quot;other-browsers&quot;&gt;Other browsers&lt;/h4&gt;

&lt;p&gt;For Safari under Mac OS X, you will have to go to the Keychain Access application to import the certificate and the user PKCS#12 files. Sadly Safari seems to have some issues with WebSockets and self-signed certificates and I didn’t manage to make it work but I’m far from being an Apple tech and if anyone has succeeded in making it work I’m really interested in your procedure, otherwise file a bug to Apple. It works with the previous browsers in Mac OS though.&lt;/p&gt;

&lt;p&gt;For other platforms, search for the browser / OS specific way to import certificates and pray for X509 client auth support. If it’s unavailable, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;--unsecure&lt;/code&gt; option and use ssh tunnels.&lt;/p&gt;

&lt;h2 id=&quot;changes&quot;&gt;Changes&lt;/h2&gt;

&lt;p&gt;Since the previous post, a lot of effort has been put into making butterfly safer by removing the HTML escapes for now and by checking websocket origin but also into making it run on more operating systems (FreeBSD, Mac OS, Cygwin, …).&lt;/p&gt;

&lt;p&gt;Incoming changes are listed &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly/issues?labels=enhancement&amp;amp;page=1&amp;amp;state=open&quot;&gt;on the github page&lt;/a&gt;. Please feel free to discuss them.&lt;/p&gt;

&lt;p&gt;Have fun and if you want to support my free work go to the &lt;a href=&quot;/about/&quot;&gt;about page&lt;/a&gt; (Encouraged!)&lt;/p&gt;
</description>
        <pubDate>Fri, 21 Mar 2014 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2014/03/21/butterfly-with-ssl-auth.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2014/03/21/butterfly-with-ssl-auth.html</guid>
      </item>
    
      <item>
        <title>butterfly your everyday terminal in your web browser</title>
        <description>&lt;p&gt;There’s something I’ve been working on recently, at start just for fun but it turned out I use it everyday, so here it is:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/butterfly_1.gif&quot; alt=&quot;butterfly screen cast&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;butterfly-your-everyday-terminal-right-in-your-browser&quot;&gt;&lt;strong&gt;butterfly&lt;/strong&gt; your everyday terminal right in your browser&lt;/h4&gt;

&lt;h1 id=&quot;version-20-has-been-released-please-see-here&quot;&gt;&lt;a href=&quot;/2015/10/30/butterfly_2.0.html&quot;&gt;Version 2.0 has been released please see here&lt;/a&gt;&lt;/h1&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;p&gt;To try it, it’s as simple as:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;pip install butterfly      &lt;span class=&quot;c&quot;&gt;# Install butterfly&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;butterfly.server.py &lt;span class=&quot;nt&quot;&gt;--unsecure&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Launch the web server unsecure&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then all you have to do is go to : &lt;a href=&quot;http://localhost:57575&quot;&gt;localhost:57575&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;use-it&quot;&gt;Use it&lt;/h2&gt;

&lt;h3 id=&quot;server-side&quot;&gt;Server side&lt;/h3&gt;

&lt;h4 id=&quot;run-at-start-up-with-systemd&quot;&gt;Run at start-up with systemd&lt;/h4&gt;

&lt;p&gt;As it relies on a server running in background, you can download the systemd file from here &lt;a href=&quot;https://github.com/paradoxxxzero/butterfly/raw/master/butterfly.service&quot;&gt;butterfly.service&lt;/a&gt; put it in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/systemd/system/&lt;/code&gt; or equivalent and:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;butterfly&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start butterfly&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now the server will always be running.&lt;/p&gt;

&lt;h4 id=&quot;running-as-root-and-multiple-users&quot;&gt;Running as root and multiple users&lt;/h4&gt;

&lt;p&gt;butterfly is made to work as the terminal user and as root. When running as root the privileges are dropped to the user that initiated the connection, i.e. the user that opened the web page. You can change the terminal user by going to  &lt;a href=&quot;http://localhost:57575/user/user&quot;&gt;localhost:57575/user/&amp;lt;user&amp;gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;access-from-a-remote-machine&quot;&gt;Access from a remote machine&lt;/h4&gt;

&lt;p&gt;You can set the bind host with &lt;code class=&quot;highlighter-rouge&quot;&gt;butterfly.server.py --host=&quot;0.0.0.0&quot;&lt;/code&gt; which will allow other users to connect to your terminal.
A password will be asked but IT IS NOT SECURE! So it’s recommended as of now to run this only on local network for testing purposes.&lt;/p&gt;

&lt;h4 id=&quot;run-a-specific-shell&quot;&gt;Run a specific shell&lt;/h4&gt;

&lt;p&gt;Use the &lt;strong&gt;shell&lt;/strong&gt; command line option: &lt;code class=&quot;highlighter-rouge&quot;&gt;butterfly.server.py --shell=/bin/fish&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;client-side&quot;&gt;Client side&lt;/h3&gt;

&lt;p&gt;butterfly works like any other terminal but it has some specific features.&lt;/p&gt;

&lt;h4 id=&quot;enter-browser-shortcuts&quot;&gt;Enter browser shortcuts&lt;/h4&gt;

&lt;p&gt;When the terminal is focused all the hot-keys are caught (except from those the browser prevent to catch).
If you want to access the address bar with &lt;strong&gt;CTRL + L&lt;/strong&gt; it won’t work. That why the &lt;strong&gt;ALT + Z&lt;/strong&gt; combination is here to tell butterfly that the next key combination must not be caught. In other word accessing the address bar is done by doing &lt;strong&gt;ALT + Z&lt;/strong&gt; then &lt;strong&gt;CTRL + L&lt;/strong&gt;. (If your browser support css3 filters the screen will turn sepia).&lt;/p&gt;

&lt;h4 id=&quot;quick-selection-of-history-text&quot;&gt;Quick selection of history text&lt;/h4&gt;

&lt;p&gt;This is a feature I’ve always wanted to find in a terminal, quick history selection. I’ve started to implement some ideas you can try by hitting &lt;strong&gt;CTRL + SHIFT + up&lt;/strong&gt; and then navigating the selection with &lt;strong&gt;CTRL + SHIFT + up/down&lt;/strong&gt; and the arrow keys. When you got it right, hit &lt;strong&gt;ENTER&lt;/strong&gt; and butterfly will enter the selection right into the prompt:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/butterfly_2.gif&quot; alt=&quot;butterfly selection&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;other-features&quot;&gt;Other features&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The visual style is done using css so it’s entirely editable.&lt;/li&gt;
  &lt;li&gt;You can easily extend the in-browser terminal behavior by writing javascript (like it’s done for the quick selection).&lt;/li&gt;
  &lt;li&gt;As apparently it’s trendy to use a “modern” text editor based on a browser, so…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/butterfly_3.gif&quot; alt=&quot;butterfly modern editors&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;missing-features&quot;&gt;Missing features&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The scroll-back is actually limited to 100 000 lines as of now in order to limit the memory footprint. It would be a good idea to store the scroll-back on the disk using the server.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Embedding html directly into the terminal is possible and &lt;strong&gt;edit: not supported anymore&lt;/strong&gt; with the &lt;code class=&quot;highlighter-rouge&quot;&gt;ESC]99;&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;BELL&lt;/code&gt; command for security reasons.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;16.7 millions of color is not yet supported but it’s one hack away using the &lt;code class=&quot;highlighter-rouge&quot;&gt;ESC[38;2;r;g;bm&lt;/code&gt; escape.&lt;/li&gt;
  &lt;li&gt;An in-terminal css/js editing options with why not a package repository for theme and extensions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;thats-all&quot;&gt;That’s all&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/paradoxxxzero/butterfly&quot;&gt;The repository is hosted on github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So let me know what do you think of it, I had a lot of fun writing it anyway.&lt;/p&gt;
</description>
        <pubDate>Fri, 28 Feb 2014 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2014/02/28/butterfly.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2014/02/28/butterfly.html</guid>
      </item>
    
      <item>
        <title>wsreload 2.0 technical details</title>
        <description>&lt;p&gt;Following to the last post about &lt;a href=&quot;/2013/11/29/wsreload.html&quot;&gt;wsreload&lt;/a&gt;, I will now explain how I implemented the reload mechanism.&lt;/p&gt;

&lt;p&gt;Most existing browser reloaders use dirty X hacks like &lt;code class=&quot;highlighter-rouge&quot;&gt;xdotool&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;xvkbd&lt;/code&gt; to send the &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt; key to the browser window. This doesn’t work reliably. No really. There’s also other solutions, like launching your browser with a debug backdoor (&lt;code class=&quot;highlighter-rouge&quot;&gt;--remote-shell-port&lt;/code&gt;) but it kinda mess up everything else.&lt;/p&gt;

&lt;p&gt;So to avoid these dirty hacks wsreload ships with a browser extension which role is to tell the browser to reload the page directly from the extension API with the added bonus of bypassing the cache.&lt;/p&gt;

&lt;p&gt;But this does not solve the shell &amp;lt;-&amp;gt; browser communication problem, for that I used a python websocket server: the well known &lt;a href=&quot;http://www.tornadoweb.org/&quot;&gt;tornado server&lt;/a&gt;.
The server is used to relay reload requests from the command line client to the listening extension in the browser all through websockets.&lt;/p&gt;

&lt;p&gt;It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kozea.github.io/umlaut/#N4IgdghgtgpiBcIBiAbA9gdwMIAsICcAXEAGhEIEtCU5EMBnfGdCAEwAI0A3GfLimBlIgUFMAGt6hAJ40EILAFc+cMgC80aKAlD0AxhDnwAjGUL4IYeigiFaAbQC0x4wAYSADgAsAXQC+ZMwwsGCE9Aj2oJCw8lhooRBivMIAHggAbABMAKxk0ghu7iAYFKyEOAiZrgDsZDgwFADmOMTwmW5k+GiEthTxCEV2Ka3FjMxobAB09Lw8+JMADvlkAGYUKTCsCCuGM2S25uHwwH4BUdC0CvE9SfipGTl5CNmPxaXlCF5eAJx1Dc2tTJVTrdXr9eCDGDDeQAIS6DGSq3Wm22uxg+0Ihx0pxI5xiiDiCVu9zar3yJmyRRKZQqJmqRXqTRaBVcRS6PUo4Mh0LoYxYrEWyxAaw2W3gOxQexAB3wRxOZ3AF3kAGVFAAjAAKXT0MHo4TIaXgWVyIHJlKp71pYEUKBQfyZrWttpBHL6YAGZihIzhmBm+HYXpgVjdwhFKPFaIxWOOOLxlwAImg9IoQsQDQ8TeT0qyyNSPvAnXaQIyAQhCy6we6IZ6eSAfQj/T01aHkWKJVKZXLY4r8SBVZrtbr9SBDcanvBKbnLWWbUWS8yC7OK5yq9yRmJuhQVkKw23I9LMbLsQropctUmhySgZmCtUTXmrUvi/8F+WQOzKx7yF75AwmPz2D0UQgzTYVW1RSV0QPaN5VxHtLgACQIVh4woehxBJMdTQQABmV4HxnZ1nwdQiiw/FcCkmbJ6Wqb50jw9JaK8Dw6PSGsRgAdRgNV6CTcQYFA3cII7Q8uxPJVEAASQAeUwslb3vadFyI+dHSfciQ2rb9awAFTQfBIFYNB2Awbi/TmFtRWEqDO2PODT3kJD8BQtCMPTeAvHkulFJpUj7VLZSyNBCitKGTizL4gTLPDdsbNEuy43keNbAgNUIBmElPJvCcLV8wL/NfdTgs0td5CQCgaHoaQpGCaK90gqMjxjcTe0TZNU0yu9x2zXL8zfVS/PfYquXY2F4T9dgmzq6zGrE+yJJANqUxAklqi67CjRzN48v6l81KIjSRu071xt4SbUumiMGugpr5R8MhRAkI5Ingsr0CEMheOUHUMjMAhGii+BfhAL78B1AB9Sw9BwfSvx6fAAcISGwGh2H4BwyZjC8Yxsm+TJ0myHDshY2icNG44QbQb7LmEeHEfkEAAhuubEsQVBMGEUGfvRv6EcBlxPqpsGYGR1G7hMKiaLohimJY9I2PIf6BNFmHxa8SZqmMTIcI8FiPFcHWvHSYGwp0SnqYZ3n6cQRnZoS162fezmhe5snFb51ovEF6mVbR4xJZqaX8dl1ireVqHVc+DWtZ1vWDe8Y3yd0F2abDkZbeZ+2HMdjnveFhBand623a5kWI7RwYlaR8u1ej7Xde+fXDcT46zdLy2i8BkAM9simCHhG4UHkAA5fSoEMRmWsudmPvN/Oec71otbziGa8o6jA/o4PvmY0PF992vNfruPm5Nn8Kfbm204Zpne9g1nkCdlfaBNquEA8Z+D7hquv/y1uL5Th3OmXce7xWavNXsM9nYW3gIXYBrQP5z1XijSO6NMbY1xvjQmxNvikzTr/f2G9aJb0YjvOWCtTYAJgd3a+Ntb5gNAP3TAg8R5jwnvsfA8J6hsFYfgceQ9uzZ0frnJBtATTwPfp/NeEsiFB1IbveW+DpFvkocnahtM350LtuAh+UDn7PFoR0URv8MZYxxnjAmRMSbfDdvA3+pUqHzxoYvG+2i7qrH0tzWKfggAA&quot;&gt;&lt;img src=&quot;data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnICB4bWxuczp4bGluaz0naHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycgd2lkdGg9JzgyOS41JyBoZWlnaHQ9Jzc5MCc+PCEtLUdlbmVyYXRlZCB3aXRoIHVtbGF1dCAoaHR0cDovL2tvemVhLmdpdGh1Yi5pby91bWxhdXQvKSAoYykgTW91bmllciBGbG9yaWFuIEtvemVhIDIwMTMgb24gVHVlIERlYyAwMyAyMDEzIDE4OjE1OjM0IEdNVCswMTAwIChDRVQpLS0+PGRlZnM+PHBhdHRlcm4gaWQ9ImdyaWQiIHZpZXdCb3g9IjAgMCAxMCAxMCIgeD0iMCIgeT0iMCIgd2lkdGg9IjI1IiBoZWlnaHQ9IjI1IiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBwYXR0ZXJuVHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTExMCw4NClzY2FsZSgxKSI+PHBhdGggZD0iTSAxMCAwIEwgMCAwIEwgMCAxMCI+PC9wYXRoPjwvcGF0dGVybj48bWFya2VyIGlkPSJOb25lIiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9Ik5vbmVPcGVuIiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9Ik5vbmVTdGFydCIgY2xhc3M9Im1hcmtlciBmaWxsLWZnIHN0cm9rZS1mZyIgdmlld0JveD0iMCAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIj48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iTm9uZU9wZW5TdGFydCIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iMCAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIj48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iVmVlIiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIC0yMCAtMTAgTCAtNi42NjY2NjY2NjY2NjY2NjcgMCBMIC0yMCAxMCB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iVmVlT3BlbiIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iLTIzIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAtMjAgLTEwIEwgLTYuNjY2NjY2NjY2NjY2NjY3IDAgTCAtMjAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IlZlZVN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAyMCAtMTAgTCA2LjY2NjY2NjY2NjY2NjY2NyAwIEwgMjAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IlZlZU9wZW5TdGFydCIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iMCAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMjAgLTEwIEwgNi42NjY2NjY2NjY2NjY2NjcgMCBMIDIwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJDcm93IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwIEwgLTIwIDAgTCAwIDEwIEwgLTEzLjMzMzMzMzMzMzMzMzMzNCAwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJDcm93T3BlbiIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iLTIzIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIC0xMCBMIC0yMCAwIEwgMCAxMCBMIC0xMy4zMzMzMzMzMzMzMzMzMzQgMCB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iQ3Jvd1N0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIC0xMCBMIDIwIDAgTCAwIDEwIEwgMTMuMzMzMzMzMzMzMzMzMzM0IDAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkNyb3dPcGVuU3RhcnQiIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9IjAgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwIEwgMjAgMCBMIDAgMTAgTCAxMy4zMzMzMzMzMzMzMzMzMzQgMCB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iTm9ybWFsIiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIC0yMCAtMTAgTCAtMjAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9Ik5vcm1hbE9wZW4iIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9Ii0yMyAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgLTIwIC0xMCBMIC0yMCAxMCB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iTm9ybWFsU3RhcnQiIGNsYXNzPSJtYXJrZXIgZmlsbC1mZyBzdHJva2UtZmciIHZpZXdCb3g9IjAgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDIwIC0xMCBMIDIwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJOb3JtYWxPcGVuU3RhcnQiIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9IjAgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDIwIC0xMCBMIDIwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJJbnYiIGNsYXNzPSJtYXJrZXIgZmlsbC1mZyBzdHJva2UtZmciIHZpZXdCb3g9Ii0yMyAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAtMTAgTCAtMjAgMCBMIDAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9Ikludk9wZW4iIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9Ii0yMyAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAtMTAgTCAtMjAgMCBMIDAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkludlN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIC0xMCBMIDIwIDAgTCAwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJJbnZPcGVuU3RhcnQiIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9IjAgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwIEwgMjAgMCBMIDAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkRpYW1vbmQiIGNsYXNzPSJtYXJrZXIgZmlsbC1mZyBzdHJva2UtZmciIHZpZXdCb3g9Ii00MyAtMTMgNDYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjQwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgLTIwIC0xMCBMIC00MCAwIEwgLTIwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJEaWFtb25kT3BlbiIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iLTQzIC0xMyA0NiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iNDAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAtMjAgLTEwIEwgLTQwIDAgTCAtMjAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkRpYW1vbmRTdGFydCIgY2xhc3M9Im1hcmtlciBmaWxsLWZnIHN0cm9rZS1mZyIgdmlld0JveD0iMCAtMTMgNDYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjQwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMjAgLTEwIEwgNDAgMCBMIDIwIDEwIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJEaWFtb25kT3BlblN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyA0NiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iNDAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAyMCAtMTAgTCA0MCAwIEwgMjAgMTAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkRvdCIgY2xhc3M9Im1hcmtlciBmaWxsLWZnIHN0cm9rZS1mZyIgdmlld0JveD0iLTIzIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgICAgICAgICBBIDEwIDEwIDAgMSAxIC0yMCAwICAgICAgICAgQSAxMCAxMCAwIDEgMSAwIDAiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJEb3RPcGVuIiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCAgICAgICAgIEEgMTAgMTAgMCAxIDEgLTIwIDAgICAgICAgICBBIDEwIDEwIDAgMSAxIDAgMCI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IkRvdFN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgICAgICAgICBBIC0xMCAxMCAwIDEgMSAyMCAwICAgICAgICAgQSAtMTAgMTAgMCAxIDEgMCAwIj48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iRG90T3BlblN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAyNiAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iMjAiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgICAgICAgICBBIC0xMCAxMCAwIDEgMSAyMCAwICAgICAgICAgQSAtMTAgMTAgMCAxIDEgMCAwIj48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iQm94IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwICAgICAgICAgTCAwIDEwICAgICAgICAgTCAtMjAgMTAgICAgICAgICBMIC0yMCAtMTAgICAgICAgIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJCb3hPcGVuIiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMjMgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwICAgICAgICAgTCAwIDEwICAgICAgICAgTCAtMjAgMTAgICAgICAgICBMIC0yMCAtMTAgICAgICAgIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJCb3hTdGFydCIgY2xhc3M9Im1hcmtlciBmaWxsLWZnIHN0cm9rZS1mZyIgdmlld0JveD0iMCAtMTMgMjYgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjIwIiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAtMTAgICAgICAgICBMIDAgMTAgICAgICAgICBMIDIwIDEwICAgICAgICAgTCAyMCAtMTAgICAgICAgIHoiPjwvcGF0aD48L21hcmtlcj48bWFya2VyIGlkPSJCb3hPcGVuU3RhcnQiIGNsYXNzPSJtYXJrZXIgZmlsbC1iZyBzdHJva2UtZmciIHZpZXdCb3g9IjAgLTEzIDI2IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSIyMCIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwICAgICAgICAgTCAwIDEwICAgICAgICAgTCAyMCAxMCAgICAgICAgIEwgMjAgLTEwICAgICAgICB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iVGVlIiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSItMTAuNSAtMTMgMTMuNSAyNiIgbWFya2VyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBtYXJrZXJXaWR0aD0iNy41IiBtYXJrZXJIZWlnaHQ9IjIwIiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAtMTAgICAgICAgICBMIDAgMTAgICAgICAgICBMIC03LjUgMTAgICAgICAgICBMIC03LjUgLTEwICAgICAgICB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iVGVlT3BlbiIgY2xhc3M9Im1hcmtlciBmaWxsLWJnIHN0cm9rZS1mZyIgdmlld0JveD0iLTEwLjUgLTEzIDEzLjUgMjYiIG1hcmtlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgbWFya2VyV2lkdGg9IjcuNSIgbWFya2VySGVpZ2h0PSIyMCIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgLTEwICAgICAgICAgTCAwIDEwICAgICAgICAgTCAtNy41IDEwICAgICAgICAgTCAtNy41IC0xMCAgICAgICAgeiI+PC9wYXRoPjwvbWFya2VyPjxtYXJrZXIgaWQ9IlRlZVN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtZmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAxMy41IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSI3LjUiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIC0xMCAgICAgICAgIEwgMCAxMCAgICAgICAgIEwgNy41IDEwICAgICAgICAgTCA3LjUgLTEwICAgICAgICB6Ij48L3BhdGg+PC9tYXJrZXI+PG1hcmtlciBpZD0iVGVlT3BlblN0YXJ0IiBjbGFzcz0ibWFya2VyIGZpbGwtYmcgc3Ryb2tlLWZnIiB2aWV3Qm94PSIwIC0xMyAxMy41IDI2IiBtYXJrZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIG1hcmtlcldpZHRoPSI3LjUiIG1hcmtlckhlaWdodD0iMjAiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIC0xMCAgICAgICAgIEwgMCAxMCAgICAgICAgIEwgNy41IDEwICAgICAgICAgTCA3LjUgLTEwICAgICAgICB6Ij48L3BhdGg+PC9tYXJrZXI+PHN0eWxlPi5maWxsLWJnIHsgZmlsbDogI2ZmZmZmZjsgfS5maWxsLWZnIHsgZmlsbDogIzAwMDAwMDsgfS5maWxsLW5vbmUgeyBmaWxsOiByZ2JhKDAsIDAsIDAsIDApOyB9LnN0cm9rZS1iZyB7IHN0cm9rZTogI2ZmZmZmZjsgfS5zdHJva2UtZmcgeyBzdHJva2U6ICMwMDAwMDA7IH0uc3Ryb2tlLW5vbmUgeyBzdHJva2U6IHJnYmEoMCwgMCwgMCwgMCk7IH0jdGl0bGUgeyB0ZXh0LWFuY2hvcjogbWlkZGxlOyBmb250LXNpemU6IDI4cHg7IH0jZ3JpZCBwYXRoIHsgZmlsbDogcmdiYSgwLCAwLCAwLCAwKTsgc3Ryb2tlOiByZ2JhKDAsIDAsIDI1NSwgMC4xMTc2NDcwNTg4MjM1Mjk0MSk7IH0uYmFja2dyb3VuZC5tb3ZlIHsgY3Vyc29yOiBtb3ZlOyB9dGV4dCB7IHRleHQtYW5jaG9yOiBtaWRkbGU7IGZvbnQtZmFtaWx5OiBzYW5zOyBmb250LXNpemU6IDE0cHg7IH0ubGluayAuZGFzaGVkIHsgc3Ryb2tlLWRhc2hhcnJheTogNXB4LCA1cHg7IH0ubGluayAuZ2hvc3QgeyBmaWxsOiBub25lOyBzdHJva2Utd2lkdGg6IDMwcHg7IHN0cm9rZTogcmdiYSgwLCAwLCAyNTUsIDApOyB9Lmdyb3VwIC5naG9zdCB7IGN1cnNvcjogY3Jvc3NoYWlyOyB9LnNoYXBlIHsgc3Ryb2tlOiAjMDAwMDAwOyBzdHJva2Utd2lkdGg6IDEuM3B4OyB9LnNlbGVjdGVkIC5zaGFwZSB7IHN0cm9rZTogIzAwMDBmZjsgfS5zZWxlY3RlZC5tb3ZpbmcgLnNoYXBlIHsgc3Ryb2tlOiAjZmYwMGZmOyB9Lm1vdmluZyAuc2hhcGUgeyBzdHJva2U6ICNmZjAwMDA7IH0ubGluayAuc2hhcGUgeyBmaWxsOiBub25lOyB9LmxpbmsgdGV4dCB7IGZpbGw6ICMwMDAwMDA7IHN0cm9rZTogbm9uZTsgfS5lbGVtZW50LCAuZ3JvdXAgeyBjdXJzb3I6IG1vdmU7IH0uZWxlbWVudCAuZ2hvc3QsIC5ncm91cCAuZ2hvc3QgeyBmaWxsOiByZ2JhKDAsIDAsIDAsIDApOyBzdHJva2U6IG5vbmU7IH0uZWxlbWVudCAuaGFuZGxlLk5XLCAuZ3JvdXAgLmhhbmRsZS5OVyB7IGN1cnNvcjogbnctcmVzaXplOyB9LmVsZW1lbnQgLmhhbmRsZS5ORSwgLmdyb3VwIC5oYW5kbGUuTkUgeyBjdXJzb3I6IG5lLXJlc2l6ZTsgfS5lbGVtZW50IC5oYW5kbGUuU1csIC5ncm91cCAuaGFuZGxlLlNXIHsgY3Vyc29yOiBzdy1yZXNpemU7IH0uZWxlbWVudCAuaGFuZGxlLlNFLCAuZ3JvdXAgLmhhbmRsZS5TRSB7IGN1cnNvcjogc2UtcmVzaXplOyB9LmVsZW1lbnQgLmhhbmRsZS5PLCAuZ3JvdXAgLmhhbmRsZS5PIHsgY3Vyc29yOiBjcm9zc2hhaXI7IH0uZWxlbWVudCAuYW5jaG9yLCAuZ3JvdXAgLmFuY2hvciB7IGN1cnNvcjogcG9pbnRlcjsgfS5lbGVtZW50LnNlbGVjdGVkIC5oYW5kbGUsIC5ncm91cC5zZWxlY3RlZCAuaGFuZGxlIHsgZmlsbDogcmdiYSgwLCAwLCAwLCAwLjAyMzUyOTQxMTc2NDcwNTg4Mik7IHN0cm9rZTogcmdiYSgwLCAwLCAwLCAwLjE0OTAxOTYwNzg0MzEzNzI1KTsgfS5lbGVtZW50LnNlbGVjdGVkIC5hbmNob3IsIC5ncm91cC5zZWxlY3RlZCAuYW5jaG9yIHsgZmlsbDogcmdiYSgyNTUsIDAsIDAsIDAuMDIzNTI5NDExNzY0NzA1ODgyKTsgc3Ryb2tlOiByZ2JhKDI1NSwgMCwgMCwgMC4yNDcwNTg4MjM1Mjk0MTE3OCk7IH0uc2VsZWN0aW9uIHsgZmlsbDogcmdiYSgwLCAwLCAyNTUsIDAuMDQ3MDU4ODIzNTI5NDExNzY0KTsgc3Ryb2tlOiByZ2JhKDAsIDAsIDI1NSwgMC4yOTgwMzkyMTU2ODYyNzQ1KTsgc3Ryb2tlLXdpZHRoOiAycHg7IH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iYmciPjxnIGNsYXNzPSJyb290IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtOTQsODEpc2NhbGUoMSkiPjxnIGNsYXNzPSJ1bmRlcmxheSI+PC9nPjxnIGNsYXNzPSJsaW5rcyI+PGcgY2xhc3M9ImxpbmsiPjxwYXRoIGNsYXNzPSJzaGFwZSBmdWxsIiBtYXJrZXItc3RhcnQ9InVybCgjTm9uZVN0YXJ0KSIgbWFya2VyLWVuZD0idXJsKCNOb3JtYWwpIiBkPSJNIDI4Ni41IDE3NSBDIDMyNi4yNSAxNzUgMzI2LjI1IDE3NSAzNjYgMTc1Ij48L3BhdGg+PC9nPjxnIGNsYXNzPSJsaW5rIj48cGF0aCBjbGFzcz0ic2hhcGUgZnVsbCIgbWFya2VyLXN0YXJ0PSJ1cmwoI05vbmVTdGFydCkiIG1hcmtlci1lbmQ9InVybCgjTm9ybWFsKSIgZD0iTSA2MjUgNTEzIEMgNjI1IDU5NS45MjQwMDUxMTkxNDUgNDc1IDUwMC44MjU5OTQ4ODA4NTQ5IDQ3NSA1ODMuNzUiPjwvcGF0aD48L2c+PGcgY2xhc3M9ImxpbmsiPjxwYXRoIGNsYXNzPSJzaGFwZSBmdWxsIiBtYXJrZXItc3RhcnQ9InVybCgjTm9uZVN0YXJ0KSIgbWFya2VyLWVuZD0idXJsKCNOb3JtYWwpIiBkPSJNIDYyNSA1MTMgQyA2MjUgNTQ4LjM3NSA2MjUgNTQ4LjM3NSA2MjUgNTgzLjc1Ij48L3BhdGg+PC9nPjxnIGNsYXNzPSJsaW5rIj48cGF0aCBjbGFzcz0ic2hhcGUgZnVsbCIgbWFya2VyLXN0YXJ0PSJ1cmwoI05vcm1hbFN0YXJ0KSIgbWFya2VyLWVuZD0idXJsKCNOb3JtYWwpIiBkPSJNIDYyNSAzODQgQyA2MjUgNDM1LjUgNjI1IDQzNS41IDYyNSA0ODciPjwvcGF0aD48L2c+PGcgY2xhc3M9ImxpbmsiPjxwYXRoIGNsYXNzPSJzaGFwZSBmdWxsIiBtYXJrZXItc3RhcnQ9InVybCgjTm9uZVN0YXJ0KSIgbWFya2VyLWVuZD0idXJsKCNOb3JtYWwpIiBkPSJNIDYyNSA1MTMgQyA2MjUgNTk1LjkyNDAwNTExOTE0NSA3NzUgNTAwLjgyNTk5NDg4MDg1NDkgNzc1IDU4My43NSI+PC9wYXRoPjwvZz48ZyBjbGFzcz0ibGluayI+PHBhdGggY2xhc3M9InNoYXBlIGZ1bGwiIG1hcmtlci1zdGFydD0idXJsKCNOb25lU3RhcnQpIiBtYXJrZXItZW5kPSJ1cmwoI05vcm1hbCkiIGQ9Ik0gNDg0IDE3NSBDIDUxMi43NSAxNzUgNTEyLjc1IDE3NSA1NDEuNSAxNzUiPjwvcGF0aD48L2c+PGcgY2xhc3M9ImxpbmsiPjxwYXRoIGNsYXNzPSJzaGFwZSBmdWxsIiBtYXJrZXItc3RhcnQ9InVybCgjTm9ybWFsU3RhcnQpIiBtYXJrZXItZW5kPSJ1cmwoI05vcm1hbCkiIGQ9Ik0gNjI1IDI2NiBDIDYyNSAyMjcgNjI1IDIyNyA2MjUgMTg4Ij48L3BhdGg+PC9nPjxnIGNsYXNzPSJsaW5rIj48cGF0aCBjbGFzcz0ic2hhcGUgZnVsbCIgbWFya2VyLXN0YXJ0PSJ1cmwoI05vbmVTdGFydCkiIG1hcmtlci1lbmQ9InVybCgjTm9ybWFsKSIgZD0iTSA2MjUgNjMgQyA2MjUgMTEyLjUgNjI1IDExMi41IDYyNSAxNjIiPjwvcGF0aD48L2c+PGcgY2xhc3M9ImxpbmsiPjxwYXRoIGNsYXNzPSJzaGFwZSBmdWxsIiBtYXJrZXItc3RhcnQ9InVybCgjTm9uZVN0YXJ0KSIgbWFya2VyLWVuZD0idXJsKCNOb3JtYWwpIiBkPSJNIDU4OSA1MCBDIDUzMC4yNSA1MCA1MzAuMjUgNTAgNDcxLjUgNTAiPjwvcGF0aD48L2c+PC9nPjxnIGNsYXNzPSJlbGVtZW50cyI+PGcgY2xhc3M9ImVsZW1lbnQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyNSwxMDApcm90YXRlKDApIj48cGF0aCBjbGFzcz0ic2hhcGUgZmlsbC1iZyBzdHJva2UtZmciIGQ9Ik0gLTEwMy41IC0xMDUgICAgICAgICBMIDEwMy41IC0xMDUgICAgICAgICBMIDEwMy41IC03NCAgICAgICAgIEwgLTEwMy41IC03NCAgICAgICAgIHogICAgICAgICBNIDEwMy41IC03NCAgICAgICAgIEwgMTAzLjUgMTA1ICAgICAgICAgTSAtMTAzLjUgLTc0ICAgICAgICAgTCAtMTAzLjUgMTA1ICAgICAgICAgTSAtMTAzLjUgMTA1ICAgICAgICAgTCAxMDMuNSAxMDUgICAgICAgICI+PC9wYXRoPjx0ZXh0IHg9IjAiIHk9Ii04NCI+PHRzcGFuIHg9IjAiPndzcmVsb2FkLnNlcnZlci5weTwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjI1LDUyNSlyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtMjI0LjUgLTExMCAgICAgICAgIEwgMjI0LjUgLTExMCAgICAgICAgIEwgMjI0LjUgLTc5ICAgICAgICAgTCAtMjI0LjUgLTc5ICAgICAgICAgeiAgICAgICAgIE0gMjI0LjUgLTc5ICAgICAgICAgTCAyMjQuNSAxMTAgICAgICAgICBNIC0yMjQuNSAtNzkgICAgICAgICBMIC0yMjQuNSAxMTAgICAgICAgICBNIC0yMjQuNSAxMTAgICAgICAgICBMIDIyNC41IDExMCAgICAgICAgIj48L3BhdGg+PHRleHQgeD0iMCIgeT0iLTg5Ij48dHNwYW4geD0iMCI+QnJvd3NlcjwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjI1LDE1MClyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtODUgLTUwICAgICAgICAgTCA4NSAtNTAgICAgICAgICBMIDg1IC0xOSAgICAgICAgIEwgLTg1IC0xOSAgICAgICAgIHogICAgICAgICBNIDg1IC0xOSAgICAgICAgIEwgODUgNTAgICAgICAgICBNIC04NSAtMTkgICAgICAgICBMIC04NSA1MCAgICAgICAgIE0gLTg1IDUwICAgICAgICAgTCA4NSA1MCAgICAgICAgIj48L3BhdGg+PHRleHQgeD0iMCIgeT0iLTI5Ij48dHNwYW4geD0iMCI+d3NyZWxvYWQucHk8L3RzcGFuPjwvdGV4dD48L2c+PGcgY2xhc3M9ImVsZW1lbnQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyNSw1MDApcm90YXRlKDApIj48cGF0aCBjbGFzcz0ic2hhcGUgZmlsbC1iZyBzdHJva2UtZmciIGQ9Ik0gLTg5LjM5OTk5OTk5OTk5OTk5IC0xMyAgICAgICAgIEwgODkuMzk5OTk5OTk5OTk5OTkgLTEzICAgICAgICAgTCA4OS4zOTk5OTk5OTk5OTk5OSAxMyAgICAgICAgIEwgLTg5LjM5OTk5OTk5OTk5OTk5IDEzICAgICAgICAgeiAgICAgICAgIE0gLTc0LjUgLTEzICAgICAgICAgTCAtNzQuNSAxMyAgICAgICAgIE0gNzQuNSAtMTMgICAgICAgICBMIDc0LjUgMTMgICAgICAgICI+PC9wYXRoPjx0ZXh0IHg9IjAiIHk9IjUiPjx0c3BhbiB4PSIwIj5Ccm93c2VyIGV4dGVuc2lvbjwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjI1LDYwMClyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtNTEuNSAtMTYuMjUgICAgICAgICBMIDUxLjUgLTE2LjI1ICAgICAgICAgTCA1MS41IDE2LjI1ICAgICAgICAgUSAyNS43NSA4LjEyNSAwIDE2LjI1ICAgICAgICAgVCAtNTEuNSAxNi4yNSAgICAgICAgIHoiPjwvcGF0aD48dGV4dCB4PSIwIiB5PSIyLjk2ODc1Ij48dHNwYW4geD0iMCI+QnJvd3NlciB0YWI8L3RzcGFuPjwvdGV4dD48L2c+PGcgY2xhc3M9ImVsZW1lbnQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyNSw1MClyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtMzYgLTEzICAgICAgICAgTCAzNiAtMTMgICAgICAgICBMIDM2IDEzICAgICAgICAgTCAtMzYgMTMgICAgICAgICB6ICAgICAgICAgTSAtMzAgLTEzICAgICAgICAgTCAtMzAgMTMgICAgICAgICBNIDMwIC0xMyAgICAgICAgIEwgMzAgMTMgICAgICAgICI+PC9wYXRoPjx0ZXh0IHg9IjAiIHk9IjUiPjx0c3BhbiB4PSIwIj5pbm90aWZ5PC90c3Bhbj48L3RleHQ+PC9nPjxnIGNsYXNzPSJlbGVtZW50IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUsMTc1KXJvdGF0ZSgwKSI+PHBhdGggY2xhc3M9InNoYXBlIGZpbGwtYmcgc3Ryb2tlLWZnIiBkPSJNIC02MS41IC0xMyAgICAgICAgIEwgNjEuNSAtMTMgICAgICAgICBMIDYxLjUgMTMgICAgICAgICBMIC02MS41IDEzICAgICAgICAgeiI+PC9wYXRoPjx0ZXh0IHg9IjAiIHk9IjUiPjx0c3BhbiB4PSIwIj53c3JlbG9hZCBjbGllbnQ8L3RzcGFuPjwvdGV4dD48L2c+PGcgY2xhc3M9ImVsZW1lbnQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyNSwzMjUpcm90YXRlKDkwKSI+PHBhdGggY2xhc3M9InNoYXBlIGZpbGwtYmcgc3Ryb2tlLWZnIiBkPSJNIDU0IDEzICAgICAgICAgQSA1IDEzIDAgMSAxIDU0IC0xMyAgICAgICAgIEEgNSAxMyAwIDEgMSA1NCAxMyAgICAgICAgIEwgLTU0IDEzICAgICAgICAgQSA1IDEzIDAgMSAxIC01NCAtMTMgICAgICAgICBMIDU0IC0xMyAgICAgICAgIj48L3BhdGg+PHRleHQgeD0iLTIuNSIgeT0iNSI+PHRzcGFuIHg9Ii0yLjUiPldlYnNvY2tldDwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjI1LDE3NSlyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtOTAgLTEzICAgICAgICAgTCA3NyAtMTMgICAgICAgICBMIDkwIDEzICAgICAgICAgTCAtNzcgMTMgICAgICAgICB6Ij48L3BhdGg+PHRleHQgeD0iMCIgeT0iNSI+PHRzcGFuIHg9IjAiPlRvcm5hZG8gd2Vic2VydmVyPC90c3Bhbj48L3RleHQ+PC9nPjxnIGNsYXNzPSJlbGVtZW50IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MjUsMTc1KXJvdGF0ZSgwKSI+PHBhdGggY2xhc3M9InNoYXBlIGZpbGwtYmcgc3Ryb2tlLWZnIiBkPSJNIDU0IDEzICAgICAgICAgQSA1IDEzIDAgMSAxIDU0IC0xMyAgICAgICAgIEEgNSAxMyAwIDEgMSA1NCAxMyAgICAgICAgIEwgLTU0IDEzICAgICAgICAgQSA1IDEzIDAgMSAxIC01NCAtMTMgICAgICAgICBMIDU0IC0xMyAgICAgICAgIj48L3BhdGg+PHRleHQgeD0iLTIuNSIgeT0iNSI+PHRzcGFuIHg9Ii0yLjUiPldlYnNvY2tldDwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDI1LDUwKXJvdGF0ZSgwKSI+PHBhdGggY2xhc3M9InNoYXBlIGZpbGwtYmcgc3Ryb2tlLWZnIiBkPSJNIC00Ni41IC0xOCAgICAgICAgIEEgNDYuNSA1IDAgMSAxIDQ2LjUgLTE4ICAgICAgICAgQSA0Ni41IDUgMCAxIDEgLTQ2LjUgLTE4ICAgICAgICAgTSA0Ni41IC0xOCAgICAgICAgIEwgNDYuNSAxOCAgICAgICAgIEEgNDYuNSA1IDAgMSAxIC00Ni41IDE4ICAgICAgICAgTCAtNDYuNSAtMTgiPjwvcGF0aD48dGV4dCB4PSIwIiB5PSI3LjUiPjx0c3BhbiB4PSIwIj5GaWxlc3lzdGVtPC90c3Bhbj48L3RleHQ+PC9nPjxnIGNsYXNzPSJlbGVtZW50IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NzUsNjAwKXJvdGF0ZSgwKSI+PHBhdGggY2xhc3M9InNoYXBlIGZpbGwtYmcgc3Ryb2tlLWZnIiBkPSJNIC01MS41IC0xNi4yNSAgICAgICAgIEwgNTEuNSAtMTYuMjUgICAgICAgICBMIDUxLjUgMTYuMjUgICAgICAgICBRIDI1Ljc1IDguMTI1IDAgMTYuMjUgICAgICAgICBUIC01MS41IDE2LjI1ICAgICAgICAgeiI+PC9wYXRoPjx0ZXh0IHg9IjAiIHk9IjIuOTY4NzUiPjx0c3BhbiB4PSIwIj5Ccm93c2VyIHRhYjwvdHNwYW4+PC90ZXh0PjwvZz48ZyBjbGFzcz0iZWxlbWVudCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzc1LDYwMClyb3RhdGUoMCkiPjxwYXRoIGNsYXNzPSJzaGFwZSBmaWxsLWJnIHN0cm9rZS1mZyIgZD0iTSAtNTEuNSAtMTYuMjUgICAgICAgICBMIDUxLjUgLTE2LjI1ICAgICAgICAgTCA1MS41IDE2LjI1ICAgICAgICAgUSAyNS43NSA4LjEyNSAwIDE2LjI1ICAgICAgICAgVCAtNTEuNSAxNi4yNSAgICAgICAgIHoiPjwvcGF0aD48dGV4dCB4PSIwIiB5PSIyLjk2ODc1Ij48dHNwYW4geD0iMCI+QnJvd3NlciB0YWI8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJvdmVybGF5Ij48L2c+PC9nPjwvZz48dGV4dCBpZD0idGl0bGUiIHg9IjQxNC43NSIgeT0iNTAiPndzcmVsb2FkIG92ZXJ2aWV3PC90ZXh0PjxpbWFnZSB4bGluazpocmVmPSJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUdRQUFBQW5DQVlBQUFENUx1MldBQUFBQkhOQ1NWUUlDQWdJZkFoa2lBQUFBQWx3U0ZsekFBQUVLUUFBQkNrQmZjWlJmZ0FBQUJsMFJWaDBVMjltZEhkaGNtVUFkM2QzTG1sdWEzTmpZWEJsTG05eVo1dnVQQm9BQUFmUFNVUkJWR2lCN1pwL2JGUFhGY2UvNXo3YitRVUpQeE1ZaFlTcURRdWlkS2xvSUFuYWFpQnBrcUtzV2NWN0w2VmpzSzFqN1RvNnBtMnEya2tvNjBRM2RXcFZ0QlZZVzdWRkJPSUhCUkZvNHBpaUZURkl3by9CWUlWTjNmaFJHSFNVRWFBaGpzSHZudjBSYkp6RXY1S1l4czM4a1N6NzNudk91ZWU5cjkrNzV6NmJtQmtKNGdjeDJBa2s2RTVDa0RnaklVaWNrUkFremtnSUVtZFlvakVxYW1vcWdFUVpFZlZiUUdZY3Vhdjk2blpqd1FLenZ6SCtINkJJWlc5eG84dkZoSktZVEFhY3ZTbTlCZnNyS2o2TlJUd2ZsWldWcWZYMTlSMnhqRGxZT1lUOXhzOXlmakM3cHhqRlk4Zmk2ZHg3b1daUFFvYlYyanNnRWVhTkg0Y2ZUY2xGMWNTSlNGWVUveGdERTYzQzh2MkJKaDJJM1c2M3BLYW1YTlEwN2V1eGpOdWZISFJkbnpYUVdHRnZXUXFiNVV6a2I3OXczelE4TXVFci92YTM3NTZNSDdUc3h3VzNHMENYR0M4L2tJL0NzV1A4Tm1yT0pEelowb3IybTE0QUFBUGxBSDQ5ME1SOTVPVGtXTnp1ampRQW8ySVZzNzg1Q0NGSEREUlcyQ3RFQ3VIL2VqOHdhbFEzTVFCZ2RGSVNuc3E5MTkrZU15NnJteGdBa0oyV2hrV1RKOS91SUNoSUVKS29GK2twNmNPRDkyZWtCOWlrQjdYSnpRamVIODhVTkRTTUMyd1RRTVV1VithZG5qZHFRYzUxQkYrdnpsM3Y2Sk9OajVxYW1tNXoyKzEyQzFIQS9iRUhTNWN1N2IxZzlaRkljd0FBMWRTSVF1Zk9Tb3V3WENoeTdsemc2eTkwdXA1amlVOW5PNTFUS0NCM1ZWVVZqOGVUQVFDbVNXbFZWVlVqQnBKclZHVXZBT3o5N0JLT3RsM0I5SkczYjVNM3BjUmIvL3lYdiswOGZ4NWFkalp5aHFYNSs5cTlYcXcvZGJwWHZCTW5qdGRxbXZheEVOektUQ3V5c2pLbmE1cDZROWZWL1ZMaVo0WmhIQ0VpMGpUdEtZQ2ZBWkNyNjlvMWdQY3FpbnkydG5ienlXanlWbFUxaFloV0VLRXNLeXN6VDlOVWo2NnJ4d0NzZHpnMnJlR0FNclBZNlhxNnFLRHdVVkt3V0hyNU5jVXFXdjJCV0RpSnpESHk4NHhQQ21jV3RSUTZYWDlvTGl0OVZ3aFJLNldwQVFBUk5pY2wyWEQxYWxzcmdINHQ4RkVMSXBteDdNQkJMTWllaE9ralIrQ1N4NFAzenB6RnlmWjJ2NDNIbEhpeXBSWFZPZG5JVFUvSGViY2JHMCtkeG44Nk8zdkZJOEo0QU9YTU5CekFHb0IrQldBWXdFdUVvUDI2cmkvVU5GVURlRDVBcndvaGQwc3BNZ0U4WTVyS1VWVlZaeHVHY1NSY3pxcXFUaFdDdGdESUFIZzFFUTVKU1dsRVZBamdWVlZWcTZxcXF0U3RXN2RldWVXU0tRbVp6U1VsNXdIOEpERFd2dko1aHdFY0JvQWk1ODVNQXNZRGdNMTJZNW5IWTMyZENMc0JXZzZnaFVqOE85cnoycE9vQlFHQUcxS2k5dFJwMUo0S2JYUGQ2OFdiQVZkTkJESUFVdXZxNmpZRjlOWHB1djRtd0E0QUxDWFBNUXpIYnQrZ3FxcTFSTFJEQ0hxSGlQSVhMMTRjTkxDcXFpbEMwR2FBejBpSmFzTXdMZ2NNRzZxcXZpRUV2WitVWkZzTm9EcmFoSHV5YnQyV2kwdVdMTG5tZG5kQUNQbjNEUnVNbHY3R0FnYjkwUW0zOWhBREFLQW95czhCTUlCNnd6QjJCNDRaaG1FUzBVOEIzUC80NDQvZEV5cXlFT0lGQUtPRXNDenNJWVl2em5FaXNSREFBbDNYNXcvNFVHTEVvQXBDUkI4RjY2K3RyVzBEY0FiZ3c4SEc4L0x5L2dIQUs2V1lGanE2bk1lTWR6WnMySEFwbE1YR2pSdjNBYndQd0x3K0pYNEhHVlJCbUhFenpQQ05XNjllckZpeFFnSXdtVVZTc1BHdVNvcW1FMUhZTmVhVzdVZEUvTFdvRXY0Q0dKSlBlMjlWVHBjQk9TYXlMWTFreG9oYmZsY0l5SWhpaHVDYnNoZ3dKQVhwZ2c4ejB6ZkNXZGp0ZGd1QUIvMGV4RWNBNU16Y3RXdDBLSjlaalkxM29jZGpHcHZOWmdKZ1pxUU1MT2NoTEFnenJTYkNZN3F1bDRheUdUY3U4NWNBMysxcmR3aHhBTUFGaTlkOE1aU1BJTXZLbm4xcjE2NjlDZUFDTTFVTU5POGhLNGpENFdnQWFBM0FocVpwM3cwY3E2aW9TTkkwN1dWbVBBL0FYNlAvdGJUME9qT1dNdU9IeFkxTnY3Vi8rR0d5YjJ6R2poMnB4VTdYS29DZkFPRHRQU1B0QWZBdFhkZkRGQnFSNmRNK0pKNGh3akpkMTJjNkhJN25mYnR2S2VXUGllZ3NFVmJydXZZaXdIOEJLQzA5ZlhnK2dPdFNjZ2tSbFJPaHpCZW51YngwZTdGejV5SW1yUEowM3ZoZWtiUHBJREVKbThVMmcwSFh3TENEOEc1WFZYNGJLZVV2aEtBOUFCL1RkZTBFUUwrcHE2dGIxOWZqQ0N0SXhGK3YrZ0d6NzBqNGo4eDBNWXpsNzRtVXZXSEdWeXFLdC9udHQrczZkVjEvQmNBRVp1NVdkUm1HWVFKNFNkZjE5NWg1RGhIZEIxQWJnRmZjYnZmdWJkdTJmVjVkWGQzSnpOMjJ1bnZMU3RZWE5EUjhvQ2pXK1lJeG5RbWRETGttT1RuWjlhZUhIbW92ZExwZVk4aGRQZWI2cExLeU1pOGxKV1VSZ0R3aHBIWEdvVU5XMjJlWDV6UEpyRkJIb1pqaTRKOHJTZzc2Mm1IUGVaRnpaeFhBVzBLZmxMN0R3S3Jtc3RKbll4a3pucGkyYVpOdCtMQ011YzNscFkxRlR0ZHpBRjZLNE1LS3FkeXo1NUc1SjRFSWEwaFNzblU3Z0hNeHloVUFKTE81Tm9ieDRvNk10QkZUaWZCK1VaTnJLNGltUnVGQ3BzV2I2MjlFdWl2TnJxOGZibHFUbjZDdW4zTHorNThxWHliUUNRYmFJOXQrcVJrTndqZUpJWm5RQ01hakVUMkl5L2M5L0xDejYyUGl2NzB4cGRqbG1zWVNSNWl4a0FqbEFMNFQwU2xBa0NGYjlnNFdlMHRMLzJaYWxhem04bEpIZi93VGd0d0JXdWZPL1c5L2ZST0NmQUhranhxSjVYbGZ4WVRVVkt6TXZ4L0RMQmE4WHZCZ1VOc2hzekdNWnc1ZmJzUHhxMWZoTVNWcWpoNkR4NVJZZnVoUVVOdkVGWElIWWNiSHZzOGVVd1o5QjhCU0NQL2ptOFFWY2djWkNmTjNWMkE1Q1E2OVUyZUlBeTBsSlg3aEVtVnZuSkc0WmNVWkNVSGlqSVFnY2NiL0FHVTk0RTBPVmdLUEFBQUFBRWxGVGtTdVFtQ0MiIHg9IjEwIiB3aWR0aD0iMTAwIiB5PSI3NDAiIGhlaWdodD0iMzkiPjwvaW1hZ2U+PC9zdmc+&quot; alt=&quot;wsreload overview&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the server is also used to watch over file modification using &lt;a href=&quot;https://github.com/seb-m/pyinotify&quot;&gt;pyinotify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For instance if you have told wsreload to watch over your &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp&lt;/code&gt; directory and to reload all the &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost:1234/*&lt;/code&gt; pages with the following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wsreload &lt;span class=&quot;nt&quot;&gt;--watch&lt;/span&gt; /tmp &lt;span class=&quot;nt&quot;&gt;--url&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://localhost:1234/*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;a inotify watcher will be added to the &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp&lt;/code&gt; directory with the url query attach to it.&lt;/p&gt;

&lt;p&gt;When a file change in &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp&lt;/code&gt;, inotify will tell the server and the server will send the corresponding query through all the connected websockets (opened by the browser extensions).&lt;/p&gt;

&lt;p&gt;All the extensions will receive the query and try to match any open tab with it, reloading the one matching.&lt;/p&gt;

&lt;p&gt;NB: The extension is also able to tell the server to watch for files when a url match the &lt;code class=&quot;highlighter-rouge&quot;&gt;file://&lt;/code&gt; prefix.&lt;/p&gt;

&lt;p&gt;That’s all for now.&lt;/p&gt;

&lt;p&gt;Ask me if you have any question :)&lt;/p&gt;

</description>
        <pubDate>Mon, 02 Dec 2013 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2013/12/02/wsreload-technical.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2013/12/02/wsreload-technical.html</guid>
      </item>
    
      <item>
        <title>wsreload 2.0</title>
        <description>&lt;p&gt;Today I released wsreload 2.0 which is IMHO a neat tool to increase productivity.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB: As it depends on inotify, it’s only available on linux (if you are interested in making it work on other OS feel free to make a &lt;a href=&quot;http://github.com/paradoxxxzero/wsreload&quot;&gt;pull request&lt;/a&gt; :D)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB: As of now it is only compatible with google chrome / chromium. Nothing prevents it to work under other browsers though, except from the fact that someone has to port the &lt;a href=&quot;http://github.com/paradoxxxzero/wsreload/tree/master/chrome-wsreload&quot;&gt;chrome extension code&lt;/a&gt; to his preferred browser again : &lt;a href=&quot;http://github.com/paradoxxxzero/wsreload&quot;&gt;pull request&lt;/a&gt; :)&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;reloading-your-tabs&quot;&gt;Reloading your tabs&lt;/h3&gt;

&lt;p&gt;wsreload has one aim: making you forget about the &lt;code class=&quot;highlighter-rouge&quot;&gt;[F5]&lt;/code&gt; key.&lt;/p&gt;

&lt;h4 id=&quot;file-reloading&quot;&gt;file:// reloading&lt;/h4&gt;

&lt;p&gt;Every local file opened in your browser with a &lt;code class=&quot;highlighter-rouge&quot;&gt;file://&lt;/code&gt; scheme will be automatically synchronized with the file.&lt;/p&gt;

&lt;h4 id=&quot;selective-tabs-reloading&quot;&gt;Selective tabs reloading&lt;/h4&gt;

&lt;p&gt;But that’s not all of it, wsreload comes with a handy executable: &lt;code class=&quot;highlighter-rouge&quot;&gt;wsreload&lt;/code&gt; which can reload any tab matching a criteria when a file is modified.&lt;/p&gt;

&lt;p&gt;For example, I’m currently using it while writing the draft of this blog post.&lt;/p&gt;

&lt;p&gt;The following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wsreload &lt;span class=&quot;nt&quot;&gt;--watch&lt;/span&gt; _site/ &lt;span class=&quot;nt&quot;&gt;--url&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://localhost:4000/*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;tells the browser to reload all tabs that match the following url pattern : &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost:4000/*&lt;/code&gt; whenever a file in the &lt;code class=&quot;highlighter-rouge&quot;&gt;_site/&lt;/code&gt; directory is modified.
(This is the directory in which jekyll generates this site.)
With it my draft preview is automatically reloaded every time I save the markdown file
(in conjunction with &lt;code class=&quot;highlighter-rouge&quot;&gt;jekill serve -w&lt;/code&gt; which regenerates the site when a file change).&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;wsreload&lt;/code&gt; command comes with several matching criteria:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt; wsreload &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;Reload all tabs matching query through websocket&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;optional arguments:&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;            show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--active&lt;/span&gt; ACTIVE       Whether the tabs are active &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;their windows.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--pinned&lt;/span&gt; PINNED       Whether the tabs are pinned.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--highlighted&lt;/span&gt; HIGHLIGHTED&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        Whether the tabs are highlighted.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;loading,complete&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        Whether the tabs have completed loading.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--title&lt;/span&gt; TITLE         Match page titles against a pattern.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--url&lt;/span&gt; URL             Match tabs against a URL pattern.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--windowId&lt;/span&gt; WINDOWID   The ID of the parent window, or&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        chrome.windows.WINDOW_ID_CURRENT &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the current&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        window.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--windowType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;normal,popup,panel,app&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        The &lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;of window the tabs are &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--index&lt;/span&gt; INDEX         The position of the tabs within their windows.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--delay&lt;/span&gt; DELAY         Delay to &lt;span class=&quot;nb&quot;&gt;wait &lt;/span&gt;before refreshing.&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; HOST, &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt; HOST&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; PORT, &lt;span class=&quot;nt&quot;&gt;--port&lt;/span&gt; PORT&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;-E&lt;/span&gt; ENDPOINT, &lt;span class=&quot;nt&quot;&gt;--endpoint&lt;/span&gt; ENDPOINT&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--watch&lt;/span&gt; WATCH &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;WATCH ...]&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        Tell the server to watch files and reload according to&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        the other options&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;  &lt;span class=&quot;nt&quot;&gt;--unwatch&lt;/span&gt; UNWATCH &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;UNWATCH ...]&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;                        Tell the server to unwatch the following files&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;These rules follow the &lt;a href=&quot;http://developer.chrome.com/extensions/tabs.html#method-query&quot;&gt;chrome extension api tabs query criteria&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;installing-it&quot;&gt;Installing it&lt;/h3&gt;

&lt;p&gt;To forget about the &lt;code class=&quot;highlighter-rouge&quot;&gt;F5&lt;/code&gt; key you have to install the wsreload library like any other python package:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip install wsreload&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then start the server using:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wsreload-server&amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;or if you are using systemd:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wget https://github.com/paradoxxxzero/wsreload/raw/master/wsreload.service&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mv wsreload.service /etc/systemd/system&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;wsreload&lt;br data-jekyll-commonmark-ghpages=&quot;&quot; /&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start wsreload&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And finally just install the &lt;a href=&quot;http://chrome.google.com/webstore/detail/wsreload/knefplbckfcppebehbomeankfgjalmak&quot;&gt;wsreload chrome extension&lt;/a&gt; like any other chrome extension.
That’s it !&lt;/p&gt;

&lt;p&gt;In a following post I will write about the technical details behind all of this.&lt;/p&gt;

</description>
        <pubDate>Fri, 29 Nov 2013 00:00:00 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2013/11/29/wsreload.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2013/11/29/wsreload.html</guid>
      </item>
    
      <item>
        <title>Prelude</title>
        <description>&lt;p&gt;Hello there and welcome to my brand new site &lt;a href=&quot;http://paradoxxxzero.github.io/&quot;&gt;paradoxxxzero.github.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ve decided to build up this site in order to write about my personal and professional projects and some less serious stuffs.&lt;/p&gt;

&lt;p&gt;I hope that you will enjoy reading it.&lt;/p&gt;

</description>
        <pubDate>Sun, 24 Nov 2013 15:24:42 +0000</pubDate>
        <link>http://paradoxxxzero.github.io/2013/11/24/prelude.html</link>
        <guid isPermaLink="true">http://paradoxxxzero.github.io/2013/11/24/prelude.html</guid>
      </item>
    
  </channel>
</rss>
