<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>GeekWare - Daniel Pecos Martínez</title>
    <link>https://danielpecos.com/</link>
    <description>Recent content on GeekWare - Daniel Pecos Martínez</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Tue, 23 Jan 2024 20:30:00 +0100</lastBuildDate>
    
	<atom:link href="https://danielpecos.com/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Attending a PGP / GnuPG signing party</title>
      <link>https://danielpecos.com/2024/01/23/attending-a-pgp-gnupg-signing-party/</link>
      <pubDate>Tue, 23 Jan 2024 20:30:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2024/01/23/attending-a-pgp-gnupg-signing-party/</guid>
      
      <description>










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2024/01/23/attending-a-pgp-gnupg-signing-party/assets/banner_hu5b147080dfad884c4117c2a816de1407_737293_700x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;700&#34; height=&#34;281&#34; alt=&#34;&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;In today&amp;rsquo;s digital world, ensuring the authenticity and security of our communications is more important than ever. PGP (Pretty Good Privacy) and GnuPG (GNU Privacy Guard) are tools designed to provide secure encryption and decryption of data, playing a crucial role in protecting privacy and information. A key component of this security model is the &amp;ldquo;web of trust,&amp;rdquo; an informal network of users who verify and sign each other&amp;rsquo;s public keys. By hosting a PGP/GnuPG signing party, individuals can expand their web of trust, increasing the reliability of key verification and enhancing overall communication security. This guide offers practical steps, complete with GnuPG command examples, to help you host a successful signing party.&lt;/p&gt;
&lt;p&gt;Before continuing, you should familiarize yourself with the concepts behind PGP/GnuPG, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Public/Private keys&lt;/li&gt;
&lt;li&gt;Encrypting content for someone else&lt;/li&gt;
&lt;li&gt;Signing your data and verifying signatures&lt;/li&gt;
&lt;li&gt;Key servers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This post does not cover those basics, but it&amp;rsquo;s really important that you feel comfortable with them in order to understand what you need to do.&lt;/p&gt;
&lt;p&gt;Also, a while back I blogged about how to rotate and create subkeys for different use cases, you can read more here:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/2019/03/30/how-to-rotate-your-openpgp-gnupg-keys/&#34;&gt;https://danielpecos.com/2019/03/30/how-to-rotate-your-openpgp-gnupg-keys/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;before-the-party&#34;&gt;Before the Party&lt;/h2&gt;
&lt;h3 id=&#34;publish-your-public-key&#34;&gt;Publish your public key&lt;/h3&gt;
&lt;p&gt;Check the instructions provided by the organizer of the key signing party. Sometimes you are requested to send your key to a specific email address a few days before the event, and sometimes you need to bring paper slips with your key details to hand over to other participants.&lt;/p&gt;
&lt;p&gt;Likewise, sometimes the organizer will send you a file with the list of key details of the participants, but others you&amp;rsquo;ll be collecting paper slips from everyone with those details.&lt;/p&gt;
&lt;p&gt;Double-check that you follow the correct steps detailed on the organization page.&lt;/p&gt;
&lt;p&gt;But in any way, making your public key available on key servers is something nice, as it will ease the process of getting it signed. These are some of the most typical servers (usually these servers sync between each other, but you can manually send your key to as many as you want):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keys.openpgp.org&lt;/li&gt;
&lt;li&gt;keyserver.ubuntu.org&lt;/li&gt;
&lt;li&gt;pgp.mit.edu&lt;/li&gt;
&lt;li&gt;keyserver.pgp.com&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In order to publish your public key, you can use the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg  --keyserver &amp;lt;server&amp;gt; --send-keys &amp;lt;your_key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All the &lt;code&gt;--send-keys&lt;/code&gt; and &lt;code&gt;--recv-keys&lt;/code&gt; accept &lt;code&gt;--keyserver&lt;/code&gt; to override your default key server (if any). I won&amp;rsquo;t be including this modifier in the following examples, but remember that&amp;rsquo;s an option if needed.&lt;/p&gt;
&lt;h3 id=&#34;prepare-key-information&#34;&gt;Prepare Key Information&lt;/h3&gt;
&lt;p&gt;Print out small slips of paper that contain your key&amp;rsquo;s fingerprint, your name, and email address. You should also include the key type (RSA, DSA, etc.), key size (2048-bit, 4096-bit, etc.), and the key&amp;rsquo;s full hexadecimal identifier. These slips can be handed out to others for key signing.&lt;/p&gt;
&lt;p&gt;You can obtain those details via the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --fingerprint &amp;lt;your_key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As an example, these are the details of my key:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --fingerprint 0xE881015C8A55678B
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pub   rsa4096 2019-03-27 &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;SC&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      31EF B482 E969 EB74 399D  BBC5 E881 015C 8A55 678B
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uid           &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;ultimate&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt; Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sub   rsa4096 2019-03-27 &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;E&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;expires: 2024-03-25&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sub   rsa4096 2019-03-27 &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;S&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;expires: 2024-03-25&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are some tools that generate nice paperslip prints ready to cut:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://openpgp.quelltextlich.at/slip.html&#34;&gt;https://openpgp.quelltextlich.at/slip.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://keysheet.net/&#34;&gt;https://keysheet.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://salsa.debian.org/signing-party-team/signing-party&#34;&gt;gpg-key2ps&lt;/a&gt;(&lt;a href=&#34;https://archlinux.org/packages/extra/x86_64/signing-party/&#34;&gt;arch pacakge&lt;/a&gt;): &lt;code&gt;gpg-key2ps &amp;lt;your_key_id&amp;gt; | ps2pdf - key_slips.pdf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;identity-verification&#34;&gt;Identity Verification&lt;/h3&gt;
&lt;p&gt;Bring a valid photo ID to the party for verifying identities. You should not sign any key whose ownership identity and fingerprint have not been verified face to face and with a valid identity document.&lt;/p&gt;
&lt;p&gt;People will rely on your signature when trusting third parties, so it&amp;rsquo;s really important to take this seriously. The web of trust is as strong as its weakest link, so let&amp;rsquo;s try not to introduce any.&lt;/p&gt;
&lt;h2 id=&#34;during-the-party&#34;&gt;During the Party&lt;/h2&gt;
&lt;p&gt;Usually, the way the signing party works is by forming two lines, connected on both ends (so it&amp;rsquo;s really a flattened circle), and you interact with the person you have in front of you. At that moment, you should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exchange key details, either by exchanging paper slips or by double-checking the provided key details with its owner&lt;/li&gt;
&lt;li&gt;Verify the owner&amp;rsquo;s identity with an official document ID.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the same time, you&amp;rsquo;re taking these steps, the person in front of you should be doing the same thing, so have your key details and ID ready to share as well.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;re done, you just rotate to the person next to the current one, so the whole circle of people moves in the same direction. The signing party will end once you&amp;rsquo;ve performed a whole rotation, gathering and validating all the other attendees&amp;rsquo; details.&lt;/p&gt;
&lt;h2 id=&#34;after-the-party&#34;&gt;After the Party&lt;/h2&gt;
&lt;p&gt;Once back at home, it&amp;rsquo;s time to sign the keys of the people whose details you&amp;rsquo;ve successfully verified.&lt;/p&gt;
&lt;p&gt;You can do it one by one, or you can use some of the many tools available to automate the process. For the sake of understanding, I&amp;rsquo;ll explain the manual steps to follow to sign each key one by one.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Retrieve the key from a public key server or from the list of provided keys. To fetch it from a key server, you have to use the following command:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --recv-keys &amp;lt;key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Verify that the key ID, fingerprint, name, and email match the ones you&amp;rsquo;ve validated during the party:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --fingerprint &amp;lt;key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Once verified, sign the key:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --sign-key --ask-cert-level &amp;lt;key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Finally, you can either email the signed key to its owner or publish it back to a public server. The public server will take care of merging signatures.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: as &lt;a href=&#34;https://digitalcourage.social/@duxsco&#34;&gt;David Sardari&lt;/a&gt; mentioned in the &lt;a href=&#34;https://digitalcourage.social/@duxsco/111807768746741424&#34;&gt;comments&lt;/a&gt;, sending an encrypted mail to the owner with his key and signed by you, is probably a better way of double checking the email address of the owner, as well as letting him/her decide where to publish it (if at all)&lt;/p&gt;
&lt;p&gt;Likewise, your key will hopefully be signed by multiple people, so keep an eye on your mailbox to see if someone is sending your key with their signature, or pull it from a keyserver to check if there are new signatures attached:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --recv-keys &amp;lt;your_key_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or to refresh all your keys in your keyring:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --refresh-keys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;A PGP/GnuPG signing party is not just a gathering; it&amp;rsquo;s a fundamental step in building a robust web of trust. This trust network is vital for verifying the authenticity of public keys, thereby enhancing the security of digital communications. By participating in such events and following these steps, you contribute significantly to a more secure digital environment. Spread the knowledge, expand the web of trust, and continue to uphold the principles of digital security. Happy signing!&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.linuxdays.cz/2018/en/key-signing-party/&#34;&gt;https://www.linuxdays.cz/2018/en/key-signing-party/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://security.stackexchange.com/questions/126533/why-shouldnt-i-bring-a-computer-to-a-key-signing-party&#34;&gt;https://security.stackexchange.com/questions/126533/why-shouldnt-i-bring-a-computer-to-a-key-signing-party&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ask.metafilter.com/92412/Help-a-PGPGPG-noob-hold-a-key-signing-party&#34;&gt;https://ask.metafilter.com/92412/Help-a-PGPGPG-noob-hold-a-key-signing-party&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>GnuPG / PGP key</title>
      <link>https://danielpecos.com/contact/gnupg/</link>
      <pubDate>Tue, 23 Jan 2024 14:15:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/contact/gnupg/</guid>
      
      <description>&lt;p&gt;My GnuPG key ID is:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-base64&#34; data-lang=&#34;base64&#34;&gt;0x8A55678B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-base64&#34; data-lang=&#34;base64&#34;&gt;0xE881015C8A55678B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-base64&#34; data-lang=&#34;base64&#34;&gt;31EFB482E969EB74399DBBC5E881015C8A55678B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and its fingerprint:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-base64&#34; data-lang=&#34;base64&#34;&gt;  31EF B482 E969 EB74 399D
  BBC5 E881 015C 8A55 678B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and you can download it &lt;a href=&#34;https://danielpecos.com/.well-known/key.pub&#34;&gt;here&lt;/a&gt;, copy it from down below, or fetch it from one of the public key servers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://keys.openpgp.org/search?q=31EFB482E969EB74399DBBC5E881015C8A55678B&#34;&gt;keys.openpp.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://keyserver.ubuntu.com/pks/lookup?search=31EFB482E969EB74399DBBC5E881015C8A55678B&amp;amp;fingerprint=on&amp;amp;op=index&#34;&gt;keyserver.ubuntu.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pgp.mit.edu/pks/lookup?search=31EFB482E969EB74399DBBC5E881015C8A55678B&amp;amp;op=index&#34;&gt;pgp.mit.edu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://keyserver.pgp.com/vkd/DownloadKey.event?keyid=0xE881015C8A55678B&#34;&gt;keyserver.pgp.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;key-0x8a55678b&#34;&gt;Key 0x8A55678B&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-base64&#34; data-lang=&#34;base64&#34;&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBFybiFwBEADUGomCJj1C71LOHmOD25N5o2pHVIWxpFdAd5kxBgB3NvQ5eRPu
jMoDIlGbqZcI4KRqaLe7r2QmFxB3hof8ngJO6DccTfjctMIYP4CEA/O4JM&amp;#43;27bwh
r5ZNcKmdnR&amp;#43;2j22RKu039NhHG0iQLo4tfMaRo5rSefy1NdmRIw&amp;#43;ZoM796oUo1yDI
ebVkyxmxj&amp;#43;7C&amp;#43;Z3V8j57uL3/AKYAHiT75VKi97Okhoo5bVp1fIM94WELXz3RXTvF
iwF7GiK2lPcm46W38JppHWYH5V36NtjlrqjzvZU5uzok84GSEs3ACUDsjyRPA&amp;#43;Lv
iHOHmAI24RT8GxlvEF7TNmQhEW6a8lGJsBrzOSJfBPgA8ygr5/1OVc41QqmKFA0l
bR30RKEsJlyPuaQ5eis1IQ&amp;#43;iWPfRotzWW144pL7U23CI&amp;#43;bX5xgCmztDR9JiS1Fr7
2bUJYvSOdufe7vEk3eu4wOpsdPMKtqcOBUpei1bprRP9xpC7y92vFYik7RJjxrSQ
HCz&amp;#43;gnRTOwibD7NSfJdrntU&amp;#43;se2&amp;#43;YpKA0evqaeGOEE1ieeeh7a7txrnAM2RPxGvk
qqN0BkTUyU&amp;#43;nfLqvdOs1VcBOng79UVL7/xGxGLUvgyUQ2FjbHOONMAkk9M7R1VxG
wm0RqH&amp;#43;WGHDNb0ISo2aGEr1JNr6YE//pP0/EJa6tnPhskhw6UFbiGsEHHwARAQAB
tCpEYW5pZWwgUGVjb3MgTWFydGluZXogPG1lQGRhbmllbHBlY29zLmNvbT6JAlEE
EwEIADsCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQQx77SC6WnrdDmdu8Xo
gQFcilVniwUCXJuLegIZAQAKCRDogQFcilVni9MKEACEqOsoW2elXSvkHu7Dqf4n
pGGOZUcNZsJfEgqY8HZKWEnJ1VqcybN3SOrGmlcGuRZPWfcmYrvjwFM/N&amp;#43;7QKvCY
lbZkM1IoUzDTJ3tIQf1WB2NqKJ6mVf&amp;#43;7ajchMOu02UgyH2egR49wXY26wTTkslvm
qJV8h5dG/N4eQlPhRZ6BnGv5DCBBKjZqSK603LeD4P2CMpRLLaOYwnxnZPqYVkot
QS14CERmSq2c2vvpetmkjlR3apWs4AdxjhzGgUO41T6yBVPZwhvHwbNbud6nqjal
/J8GVOgL&amp;#43;00RRRKeyyPAitpxO6kJaoW5CY1GTRsskT7onw7uoyAhOK50pAie6fFM
mPttuYfi00j1BD4cGFCMLm4p7ApI01TKS6tiwaVXUQ7mgBQt&amp;#43;vKDuFB5/aeMSCr3
jkYAnXnQ6VvuddsHClgQm8tA8sxXwq9Wqe7irYxmD2/lm6F2VmKfrUKMhlZsGt0n
WGJoOjsVxMTqhK9XqMypLU&amp;#43;efztk5WVJULcDNJI74BCslFUbYz4&amp;#43;wxOvQXtDl/9S
NmODjmu/AyZWZ3SPXQbc1zfb/YzW28M0tPwqjAUfDkSn2&amp;#43;PMhrnIDJ7bzA6GRfDN
2Q2xRyeyy8XYAbKF9jYKfbqLKSdjr3bFSduoeLWLz2UrDbMgJ7qukf6x78W/mPWE
5EmxaxkkXL7Ooh7O2gqt9ohdBBARAgAdFiEE9tExYvK&amp;#43;9lg49sjmvzta/NRIDmAF
AlybkIgACgkQvzta/NRIDmCWhgCfUiwPzNGHB6rHYQt8YTDE&amp;#43;tJgFLsAoJ/mR3Js
Y5fcaZGAQCyLA&amp;#43;mqIt4itCZEYW5pZWwgUGVjb3MgTWFydGluZXogPGRhbmlAZHBs
YWJzLmlvPokCTgQTAQgAOBYhBDHvtILpaet0OZ27xeiBAVyKVWeLBQJcm4sKAhsD
BQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEOiBAVyKVWeLdFEQAL3B9fqYnEtJ
HAUQbR5QcHxZ8yX6aNHZaXjLERAtIBjv3phTiPuUHAg1lUEXp3r175BBODbwKvJe
U/XBZ2knnuMT6Ac1j/LSv7Pj6jiaAFRcymhO0EnXSknrUf9xrTd2HEcElDxv3O95
Y5gdLH166E2mlDCOdSEC0V/h2bLrZ83A3Ne5sSxHYlGFhjdI45&amp;#43;m5wCYMl5106ex
5Ke2YN0sD5dtAtBQ6lO3Q5dZ1/4vMBtiyO1memSNcMvUgynfBHYyd15GkMWvTsiT
uCXR3PSfjrGIONOUPDusuJ09af3e0yIhzD1RkSwyqIyniKD4F8yX3qoPPDMO&amp;#43;/P1
hMaAW6pfpairlOS7x8tkRNDndPH/Rk3u1L6NySYBlFVnaZ5dQOCxAbRLMHfspGe5
0lar&amp;#43;R40j9stQk/omjEMHVb4vqeTXpQPDxnnA4oGFJKxHNZi/clfP&amp;#43;XTDsK5kkdm
qkketdb&amp;#43;BlDmaURsLv0/pMMAWmqwZa4/kMntk1JAdxlIATpUurPk&amp;#43;7H2NIrm47pu
1lbx/m/mwMPqch7SOpAaTnpJ1LibpCsuo8JkQXFWas&amp;#43;mJRbo7AB7/axOiBsfhu3x
6d6a7RDji9vbEQVXup5MyHW63IQ3XJMZ&amp;#43;OF98wry81&amp;#43;WXJqw&amp;#43;tzM3zsaXFVnflDL
f1Q9YZ&amp;#43;MDina8OgYr&amp;#43;hF0xIN58UPZY8ziF0EEBECAB0WIQT20TFi8r72WDj2yOa/
O1r81EgOYAUCXJuQkgAKCRC/O1r81EgOYM36AJwNInL0Q02lMFcGlQhC4S4lP6Mw
tACfSzgFsw&amp;#43;drv/NBYJPGG2uW9naDTWJAjYEMAEIACAWIQQx77SC6WnrdDmdu8Xo
gQFcilVniwUCXiQ2&amp;#43;AIdIAAKCRDogQFcilVni00oEACev5hFwJKVZXAcTVisJ8sd
UGV59QNa/iQV7YNVCGwcmHAZavxxQOn9AamrSK2UvMS9F5GpM9FatRIF9r1HsrQz
3gOQ7vK9xbiUK3RjQfSumWUzSIdV5Ql&amp;#43;wW0Pftdb1k8RfrRc30JQgz&amp;#43;OFNABHg6W
4hqvjNADI3R/CW72KkUHMIeviiDKEWz5JEAk5X3bbhwESEircxz12QYQmdQ7LV8H
BUg/gRMUd01reKwFL&amp;#43;oklYWFB7lBy8DidWXOk7PCsAA5srI7ND69ZjGk6kevQs9o
CGIhni6/4DZ9J9qSXjzQx66nt1c2L9TGifP0guD5uhEHASMBoIoZinw8Y/xzIYlk
PE5whHLV6Qa&amp;#43;kTh0c&amp;#43;3/DexnnqaXBtQV8oLQ5QAmiq7AbrNwrapmpoPdLmhprMy6
hi2CH/x94gffNCVgbdn/7Drp5l7sOnRA0gT7qQw7W5ywRCpKSjOu4V4fcfj4jKfW
odApz9IrpnsfiE0MwenAEtHZE/&amp;#43;avVnxSFayrWPax4pkm0DvXRC7AvPXzsvfcSrn
J8Jzp5lyqKfpKpiyrZUFh1FDY3ioAH359HTsKCnKk&amp;#43;fceze3a5gx8Ll/cj6vmPNh
KQQM6drRqIyi49ZrCR8FXTfFsqEoWFpE/gOudOCI0&amp;#43;6pDcQ1QGyku4WXbl1olBQP
BttosYv5heNblTnIxR2wULkCDQRcm4hcARAAnPPd8pTRwLOa3XCMe7aYhHZjd4i8
ezJukFR8D3muxhAUz16XTtG4mynOetoLzaJA6V3PEaYDnKffq9Da&amp;#43;pwiwlaIygsK
nhABrmFbz/Ufvz/9OJkQ2XZB6TsL6GQSULihx1IEePzGIT31a/b50s7RM6ySQipx
kD5eflRMHv9rmtZqLzJzVVkSVQT0Wr9qGmz6yxCAK&amp;#43;a/hHhTe&amp;#43;7Fq6E5RSdbqaSu
mYMHQRNwLO4/HrWK7mRpD4djDmJJ0jdrFqDrq&amp;#43;F7R4Jg/BftCmLlWlc/K/B/5qia
eIDgGWD5mNYBd9eDqqoVI/7s3jB&amp;#43;4QvqN4ZKrpja1NXlh3jGLLk8E8VcUdBGcX5X
&amp;#43;2Q/WOiY4LMvnc2FKV9hAodCCFeT1VI0Xvm3O2NVIyuqLfiDDyNQejIE1yC9PCsh
u3mdjFyGbsfypFYy9Blb5et&amp;#43;tJr2rCn4HYZxnDfW0o1ErHd2dUoPk/PXriNurcIT
0GMIKnP3gDcI3RnxchcNw35YPxCzQgI95fMHrp2&amp;#43;bUt/o8HXAD2yOzojUP4djCwi
joYn&amp;#43;GjnWZcieYG&amp;#43;pRYH4uK&amp;#43;jsAiQq/HIMUui&amp;#43;Nb7GSKTCclOgFywfVr746YrwEO
8n8CHSgxHiTEgHxIqcU4lwx5/wY2IRPUb02ixitqqc8nzXSMHpd8L9fc7T0HC8lM
NDm2Q1ua4aX4zFcAEQEAAYkCPAQYAQgAJgIbDBYhBDHvtILpaet0OZ27xeiBAVyK
VWeLBQJcm4xKBQkJZgVuAAoJEOiBAVyKVWeLjV8QAMG0R7bfaL/33EziyDowF4cv
ZhLgNrtHO8ycQrvv/qu3V4xGpiWY&amp;#43;O8uIcuagCw7BrRS/dEoyA03e4wgDWIIh&amp;#43;o8
7pX5GOSFlM6s4fn7&amp;#43;Ax5jngKvZimmtEGa14AA&amp;#43;YAWSqNkNB9lzMedRF/cUllZnTE
bZIRVjBLxEiF8IvMUR4tQ&amp;#43;V&amp;#43;cpQP3ppbsa4b/FfpCqmu29UXuMHOzTaZPdfRQaTP
vMEDhwd4nQFpM4&amp;#43;KrvkYtKm6c0bNfWl1WG5FO4DYMYvwoM368lVY36ObDPaA9u&amp;#43;y
x5OaFm&amp;#43;sDUXLEmIp4JdEyPfXTqg2OwPprKAZLOym4efhCOnkKJs&amp;#43;tgnFxx0uB/ys
UY&amp;#43;ifda9V9eSPTFQdEP1BoXrcQbXZTaQ7eORq8&amp;#43;&amp;#43;p6NelP/YNt1/UtX9yN4PywQl
d4mtrt800euPcEUcI020KzFXZFLrJZPovoMO5NP000wR/RgWigUpR1y8btU7tLdC
KsHj1TkuqQwzEoKwe9IroYfArUcJjiMABlUK9YuybxgKR0mWGyUU0q1UeVHZYdwn
NNLKKjoV3VYIybysZl6RvvUBWCLXrZxP&amp;#43;Ikoevb5&amp;#43;gV&amp;#43;&amp;#43;ZkRUgvCqK&amp;#43;K0OXBWBjm
Nm8mnve9ab62aexM2TnEpMxbGytiyZlgyEsVRbjjG6AFrtEGlwAnY0vPoCyedsrJ
Cdbf9CE2Wb5h4ViZz7KwuQINBFybi6wBEADKvOV0UXmwXbB8jGq7nIqfH&amp;#43;DclZ87
mnNdZ61GlV0ZTrAZG/CFo1QcW3yUuAdvuX6jWY3ZTRm6&amp;#43;8WSJcOIsjlU6/oddTsJ
WUEFf4&amp;#43;cCq09bGs0NCNl/ER9y95M0QNDrlEG8e8fX6ey&amp;#43;FASLT6A9/Mxlw9v5gOc
ykQC6FWLKxW&amp;#43;cyuPiWx4yhgiJFbhreBJI0vlL2jiACkPF9l&amp;#43;Jp8J2ZQerkqjzdJk
Y1jvV1yiV81EifU7xC09C2W&amp;#43;tLmZAHK1SW1Ryb9USaBpKNzjN9pKdxng9ITBj5sH
mut6xARlUBuO8jN7cu9ii1Xb6T&amp;#43;bdI21IcA51zBSnNdWKkk4z9T/c16hYxLmuz0z
YEa7TszbkbJMRnbd71hOrqQemXuIcUfftwFAboJMsropiEQgrf32YSVOKOJv/h3U
AMy5slv4tmUk16NOLqoi9gd0NJn4arOkBFNHoM6ssvBoaIrcSwRnOsjS0KvT4oC6
KKwcZTszLMj8R7Gg3pkXVsfRnqWcAx/HppsUrsKdoji8ly78AcRdfghTxe5u3x52
gx6DuOmFpavMyX1ZDDVyQfhHONFoRJmYI4uKgkELnNmVpDlwoFcHlu3r3Fk8A3&amp;#43;Q
qeF97lN&amp;#43;AA3p7DziORwzw3VTd2uAjVdId61&amp;#43;8nsYiPOPGvLaGZ3iPJ/ykAFYs5&amp;#43;P
&amp;#43;7eBowF5hiY1OQARAQABiQRyBBgBCAAmFiEEMe&amp;#43;0gulp63Q5nbvF6IEBXIpVZ4sF
Alybi6wCGwIFCQlmAYACQAkQ6IEBXIpVZ4vBdCAEGQEIAB0WIQQ&amp;#43;RdZap5dh9/QK
GtFmXiljP5fvEQUCXJuLrAAKCRBmXiljP5fvEdc&amp;#43;D/9Jb6&amp;#43;Pr1w5ZDnv86jx2uS1
3/4sT5x&amp;#43;EzVDf/yq2&amp;#43;cNU0zFzjjSXPE2d0gwY3RUKewa2dt&amp;#43;9vtRyBu33n7&amp;#43;1OEc
9/yiAZPxH2MW8qbJo1BptdnUuwR6/X5tLoi&amp;#43;p6jAoxHVubtbt6mFYocX&amp;#43;FnsMQJl
Ag/hMwKJdqiKnYFjYkRaX20I32n2V7flbNO5uY4cpaVg9OwJ1pw85jyHBhtosQpu
Ydb80TS1pfqbS6a3RKnR&amp;#43;aaO67VnzzNn/2weqsZ93NXwLwEX3GMg53R2gdvQmQzw
VqjfNOGXViwFyMskhS6jnD2ZxSWOGDpVxZK0miuPIvh0tWE61hhjPLldo/JtWiRk
zXZ6nW8fLk6FTInqPBuf/DdL&amp;#43;0yTa3m0zOcbVBZx2zSvxDFHpqmBjvwjQXpRilXn
a&amp;#43;0/4tpq8UJbKsYbBrtAtYXaWFTG/liLs5xFZqhOYfSuOi5W/wpaQ4B6grCSmAr1
wY/nbtA5AsgfpvPSIfidtpjY6TYtW72wUDaR1TyrtphYbSZaNQzwhvT91h1BKyKP
1eYWSWoTHxU/UlHQFSIcNORDTxAo&amp;#43;w2/B7RXPsbnG3cLGYuYMqSYjVsTbveYvg62
xIXCBJx8G6I19ZbHgOMQ5nyKWUEkCu7IQg88ebFuM0t8jm1yEZxP8/RmiLvH4Rxz
izkNRvgN5hVaSfs5GKY5pUP/EADUCfecWXrKjIW&amp;#43;kynf3Yg9GjENvAowPcOFfnwq
Y0K2MZP&amp;#43;G3bdFh1FTzE&amp;#43;pctwSI/YRkpBkDi2ztfBKc1nPL6U&amp;#43;8fMR3eUbNz3Qraa
IylttFXB05RV4BCN4GsETF5KhenomImZmO/xl1tzkw9sC9HYTxtJUHAJV14LxKN5
JI3rOdN&amp;#43;D1ugOyva1RgF0/DbLyh3dOmg3Y0GPXjpNnpuOioc12rZDkqTcVGB5sUF
b5J057LJ3ZhoBD2w9XwiAHU2nxuynTmVjTjKyVbO5lB&amp;#43;FfvOaVIZNqfBYPYqZ/3e
wQnc2OL2giKt/DKtnbVopEcy1os4BWzcBmPT5gXOGU5Y&amp;#43;TZzJcSgJL3Ltk6d46wx
5/MGtKx5oJCCzlYICf6w9EQUftf8zqnM5JDjeO9cLtC2qh&amp;#43;tA92bv5AkwiiPVhel
wsc3l7mckBfy9cNl5eTTYv5OJTuGuiz4qMzlFqruQDEQuAtfr2PiZzT30z8vdrAy
MAFKvs3J/GUDC19WYAY4cTf3U1unBDDHY/fmVSt6CfUCybfPBFMwhAofD6VniBts
kom33qvkzg&amp;#43;ar//T8A&amp;#43;ggIN8DDkivQZMQVr2Ym6Nn06Fi7q6n9&amp;#43;h9pHGtMNJjqlp
kaaWEy6sOaGjdIn0lhnIebvcMMttbQXpEUCMFKJlGzuevIsG6mZSSJGlJi5hNzmI
EivrkA==
=BypT
-----END PGP PUBLIC KEY BLOCK-----


&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>From Xorg to Wayland</title>
      <link>https://danielpecos.com/2023/06/08/from-xorg-to-wayland/</link>
      <pubDate>Thu, 08 Jun 2023 10:07:00 +0200</pubDate>
      
      <guid>https://danielpecos.com/2023/06/08/from-xorg-to-wayland/</guid>
      
      <description>










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/06/08/from-xorg-to-wayland/assets/wayland-xorg_hu6caa8af30302ace46ee4d468ffd979dd_90066_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;300&#34; alt=&#34;From Xorg to Wayland&#34; class=&#34;aligncenter&#34; /&gt;

&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The landscape of Linux desktop environments has been undergoing a major transformation, with the advent of Wayland as a promising successor to the long-standing Xorg display server. This shift has brought about significant changes in popular desktop environments such as Plasma and GNOME. In this post, we explore the state of the art in terms of Wayland&amp;rsquo;s impact on these environments and how they compare to Xorg, as well as explaining my path towards moving from Xorg to Wayland, steps I took, mistakes I made, and learnings I&amp;rsquo;ve got.&lt;/p&gt;
&lt;p&gt;But, first of all, why?&lt;/p&gt;
&lt;p&gt;Basically, and I&amp;rsquo;m personal case, to follow the hype. As simple as that, no shame. There was no real need to leave my perfectly working Xorg environment just yet. But it was a great oportunity to get out of my confort zone and do some experimentation on my linux box, and maybe learn a couple of things.&lt;/p&gt;
&lt;p&gt;So now that that&amp;rsquo;s out of the picture, let&amp;rsquo;s deep down on my path through this transition.&lt;/p&gt;
&lt;h2 id=&#34;state-of-the-art&#34;&gt;State of the art&lt;/h2&gt;
&lt;h3 id=&#34;wayland-the-future-unfolding&#34;&gt;Wayland: The Future Unfolding&lt;/h3&gt;
&lt;p&gt;Wayland represents a modern display protocol designed to overcome the limitations and shortcomings of Xorg, which had been the de facto standard for decades. Its main objective is to provide a secure, efficient, and flexible foundation for graphical environments. By taking advantage of the latest technologies and design principles, Wayland aims to offer smoother rendering, better performance, and improved security.&lt;/p&gt;
&lt;h3 id=&#34;plasma-navigating-the-wayland-path&#34;&gt;Plasma: Navigating the Wayland Path&lt;/h3&gt;
&lt;p&gt;The KDE Plasma desktop environment has been actively working towards embracing Wayland as the default display server. While Plasma has been historically associated with Xorg, recent iterations have made significant strides in Wayland compatibility. Users can now experience a native Wayland session with Plasma, benefiting from reduced input latency, improved multi-monitor support, and an overall more fluid experience. However, due to the inherent complexity of the transition, some legacy Xorg applications may still encounter compatibility issues.&lt;/p&gt;
&lt;h3 id=&#34;gnome-pioneering-the-wayland-experience&#34;&gt;GNOME: Pioneering the Wayland Experience&lt;/h3&gt;
&lt;p&gt;GNOME, one of the most popular Linux desktop environments, has been a front-runner in adopting Wayland as its primary display server. The GNOME Shell provides a seamless Wayland experience with full support for features such as fractional scaling, touchscreen gestures, and high-DPI displays. Thanks to GNOME&amp;rsquo;s early commitment to Wayland, many of its core applications have been optimized to work flawlessly under this new protocol. While Wayland support in GNOME is mature, occasional compatibility challenges with Xorg-dependent applications may still arise.&lt;/p&gt;
&lt;h2 id=&#34;btw-i-use-arch&#34;&gt;BTW, I use Arch&lt;/h2&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/06/08/from-xorg-to-wayland/assets/arch-linux_hu7406549a6c1fd560b36cf91fda2b4867_96495_250x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;250&#34; height=&#34;187&#34; alt=&#34;Arch Linux&#34; class=&#34;alignleft&#34; /&gt;

&lt;p&gt;In order to install Wayland, I just installed the following packages (assuming you have a Xorg Plasma working installation):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wayland&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;egl-wayland&lt;/code&gt;: because I have an NVidia Optimus card in my laptop&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plasma-wayland-session&lt;/code&gt;: so &lt;code&gt;sddm&lt;/code&gt; gives you the option to log into Plasma on Wayland&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the dependencies you&amp;rsquo;ll get as a result of installing the packages above is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xorg-xwayland&lt;/code&gt;: a fallback solution to run X11 applications within a Wayland environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which will be vital, at the current moment, to be able to run applications that are not 100% supported yet, or that you&amp;rsquo;re experiencinig issues with.&lt;/p&gt;
&lt;p&gt;Once these packages are installed, just restart the graphical environment (&lt;code&gt;sddm&lt;/code&gt;) or reboot the computer and log in back into Plasma, without forgetting to switch to the &lt;strong&gt;Plasma (Wayland)&lt;/strong&gt; session in SDDM. And if everything went all right, you are now using Wayland. One way to quickly confirm that is to open a terminal and run the following command:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ echo $XDG_SESSION_TYPE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you get &amp;lsquo;wayland&amp;rsquo; back, you&amp;rsquo;ve got your confirmation. Congratulations!&lt;/p&gt;
&lt;p&gt;There is one caveat though: at this moment not all the applications you may be using have support for Wayland yet, that&amp;rsquo;s where &lt;code&gt;xwayland&lt;/code&gt; comes into the picture. One really nice debug tool I&amp;rsquo;ve found that lets you inspect which applications are running natively on Wayland is the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ qdbus org.kde.KWin /KWin org.kde.KWin.showDebugConsole
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which obviously is only available on Plasma.&lt;/p&gt;
&lt;h2 id=&#34;issue-1---longer-application-loading-time&#34;&gt;Issue 1 - Longer application loading time&lt;/h2&gt;
&lt;p&gt;Usually my first action upon logging in is to open a terminal. &lt;code&gt;alacritty&lt;/code&gt; is my terminal of choice, because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it&amp;rsquo;s quite fast&lt;/li&gt;
&lt;li&gt;cross-platform&lt;/li&gt;
&lt;li&gt;configurable via YAML&lt;/li&gt;
&lt;li&gt;it&amp;rsquo;s written in Rust&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As usual, I pressed &lt;code&gt;Ctrl + Alt + t&lt;/code&gt; to open a new terminal and&amp;hellip; anda.. and&amp;hellip; there it goes, it works! But it took a while&amp;hellip; let&amp;rsquo;s try again&amp;hellip; &amp;hellip; &amp;hellip; same :-(&lt;/p&gt;
&lt;p&gt;Maybe it&amp;rsquo;s an issue with Alacritty, let&amp;rsquo;s check other apps like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;konsole&lt;/code&gt;: fast&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dolphin&lt;/code&gt;: slower than usual&lt;/li&gt;
&lt;li&gt;maybe &lt;code&gt;okular&lt;/code&gt;: too long for such a small app&lt;/li&gt;
&lt;li&gt;&lt;code&gt;firefox&lt;/code&gt;: couldn&amp;rsquo;t tell if there was an actual difference (there wasn&amp;rsquo;t) - don&amp;rsquo;t forget to set up &lt;code&gt;MOZ_ENABLE_WAYLAND=1&lt;/code&gt; in your environment, otherwise it will be running under XWayland&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And I&amp;rsquo;m talking a huge difference in loading times: from almost instantaneous loads under Xorg, to having to wait 2–3 seconds for the app just to appear. That can&amp;rsquo;t be right, people are for sure not going by with this huge performance difference, but&amp;hellip; I can&amp;rsquo;t find any comment / post talking about this issue&amp;hellip; :-(&lt;/p&gt;
&lt;p&gt;Time to deep dive into the issue.&lt;/p&gt;
&lt;h3 id=&#34;xwayland&#34;&gt;XWayland&lt;/h3&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/06/08/from-xorg-to-wayland/assets/wayland_hud07c71a4220b0665f0a8efd0c8a0c5ae_154840_250x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;250&#34; height=&#34;241&#34; alt=&#34;Wayland&#34; class=&#34;alignright&#34; /&gt;

&lt;p&gt;Starting with &lt;code&gt;alacritty&lt;/code&gt;, I searched for people reporting the same issue, and luckily, I found some. Their solution was to use something call &lt;strong&gt;XWayland&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;XWayland is a tool that allows you to run non-Wayland apps on a Wayland environment. And you can use this tool on an app-by-app basis, which is really convenient. And that&amp;rsquo;s exactly what I did, as simple as setting up an empty value to &lt;code&gt;WAYLAND_DISPLAY&lt;/code&gt; variable for &lt;code&gt;alacritty&lt;/code&gt; and voilà, back to a blazingly-fast terminal, as it used to be.&lt;/p&gt;
&lt;p&gt;Not really happy with the approach, but at this point I just wanted to focus on getting the rest of the apps ready, so I can use Wayland as I used to use Xorg. Something was not right, but at this point didn&amp;rsquo;t know what yet.&lt;/p&gt;
&lt;p&gt;Digging on the dependencies that &lt;code&gt;paru&lt;/code&gt; (or &lt;code&gt;pacman&lt;/code&gt;) installed, I found one that was a little bit off: &lt;code&gt;egl-wayland&lt;/code&gt;. Based on Arch&amp;rsquo;s wiki, this package provides EGLStreams API for NVidia GPUs. I have an internal NVidia GPU, but I wasn&amp;rsquo;t planning on using it, so I uninstalled this package (which also uninstalled &lt;code&gt;nouveau&lt;/code&gt;, NVidia GPU&amp;rsquo;s opensource driver).&lt;/p&gt;
&lt;p&gt;And after restarting the desktop environment, guess what? Everything was snappy and zero delays during start up. Even &lt;code&gt;alacritty&lt;/code&gt; was fast running under Wayland without having to rely on XWayland.&lt;/p&gt;
&lt;p&gt;Nice :-)&lt;/p&gt;
&lt;h2 id=&#34;issue-2-steam-requires-vulkan-and-egl&#34;&gt;Issue #2: Steam requires Vulkan and EGL&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t game much, but I like to have Steam and a couple of games ready for whenever I want to disconnect a little bit, so, given that this kind of applications are quite graphic intensive, I decided to try it out under Wayland.&lt;/p&gt;
&lt;p&gt;But it wasn&amp;rsquo;t there! It got uninstalled (and I didn&amp;rsquo;t notice it, shame on me) when I removed &lt;code&gt;egl-wayland&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;How could I resolve this conflict? Do I install back &lt;code&gt;egl-wayland&lt;/code&gt; back, so I get back Steam and everything gets slower again, or should I ditch out gaming alltogether? That can&amp;rsquo;t be the current state of Wayland!?! I know the major distros are fully moving into Wayland, so this cannot be a general issue.&lt;/p&gt;
&lt;p&gt;This needed more digging out across forums.&lt;/p&gt;
&lt;h3 id=&#34;wayland-and-nvidia-opensource-or-not&#34;&gt;Wayland and NVidia: opensource or not?&lt;/h3&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/06/08/from-xorg-to-wayland/assets/nvidia_hu2fe6632db44d28c9b9d53edd3914c1d6_112452_300x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;300&#34; height=&#34;239&#34; alt=&#34;NVidia&#34; class=&#34;alignleft&#34; /&gt;

&lt;p&gt;I decided to install Steam again, and with it, &lt;code&gt;egl-wayland&lt;/code&gt;, but this time something caught my attention during the installation: &lt;code&gt;paru&lt;/code&gt; was asking me which NVidia drivers I wanted to install, the closed-source officials, or the opensource alternative &lt;code&gt;nouveau&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I got this question during the first install attempt, and I decided to go for the opensource alternative wihout thinking it twice. But this time, after some reading about people complaining on some performance issues with &lt;code&gt;nouveau&lt;/code&gt;, I decided to try the official drivers instead. So after the installation was done, I rebooted the computer, just to be sure that all the kernel modules are loaded properly, and logged back into Plasma.&lt;/p&gt;
&lt;p&gt;And, oh wow, everything was running as smoothly as it was running before on Xorg. And no XWayland required at all!&lt;/p&gt;
&lt;p&gt;Turns out my issue was on &amp;rsquo;nouveau&amp;rsquo; and not &amp;rsquo;egl-wayland&amp;rsquo;.&lt;/p&gt;
&lt;h2 id=&#34;issue-3-clipboard-and-neovim&#34;&gt;Issue #3: Clipboard and Neovim&lt;/h2&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/06/08/from-xorg-to-wayland/assets/neovim_huef64c387a9c366ee9e4548215b103af9_74192_350x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;350&#34; height=&#34;101&#34; alt=&#34;Neovim&#34; class=&#34;alignright&#34; /&gt;

&lt;p&gt;So that was it, I had a nice, fully Wayland native, Plasma desktop for me to use :-D&lt;/p&gt;
&lt;p&gt;And so I did for a couple of days, and then I noticed a small nuance: I wasn&amp;rsquo;t able to copy from or to the system&amp;rsquo;s clipboard from &lt;code&gt;neovim&lt;/code&gt;. Ok, this must be a minor one, for sure someone in the amazing Neovim community has solved thi issues.&lt;/p&gt;
&lt;p&gt;Yep, easy one: just installed &lt;code&gt;wl-clipboard&lt;/code&gt; and the issue was gone.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Not everything was smooth, but that&amp;rsquo;s how usually works on linux, and the beauty of it, because thanks to these issues, I learned a lot about Wayland and how the different desktop environments and window managers are transitioning to it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m planning on gathering some metrics regarding the usage (or not) of the integrated Nvidia card, now that I&amp;rsquo;m using the official drivers. So keep an eye for my next post, coming soon!&lt;/p&gt;
&lt;p&gt;(Psst! You can follow me on &lt;a href=&#34;https://fosstodon.org/@dpecos&#34;&gt;Mastodon&lt;/a&gt; or subscribe to my &lt;a href=&#34;https://danielpecos.com/index.xml&#34;&gt;RSS feed&lt;/a&gt; not to miss it)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>FOSDEM 2023</title>
      <link>https://danielpecos.com/2023/02/05/fosdem-2023/</link>
      <pubDate>Sun, 05 Feb 2023 20:51:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2023/02/05/fosdem-2023/</guid>
      
      <description>&lt;h1 id=&#34;fosdem-2023---a-recap&#34;&gt;FOSDEM 2023 - A recap&lt;/h1&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/fosdem_2023_hu4dab01845815c87e2341126774338eef_75891_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;308&#34; alt=&#34;FOSDEM 2023&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;This weekend I traveled to Brussels to attend &lt;a href=&#34;https://fosdem.org/2023/&#34;&gt;FOSDEM 2023&lt;/a&gt;, although only for the first day (Saturday 4th, 2023). It hasn&amp;rsquo;t been my first one, but it has been the first massive event I have attended after the COVID-19 pandemic.&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8228_hu4992f9b272fc94d16ec8e20db5504684_104378_500x0_resize_q75_h2_lanczos.webp&#34; width=&#34;500&#34; height=&#34;375&#34; alt=&#34;FOSDEM 2023 - Daniel Pecos&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;After the morning keynote, I had a quick look around the buildings where the event was hosted to visit the different stands of the many sponsors of the conference. Among the most interesting ones (for me personally, all the stands where really interesting in one way or another) where:&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8240_hube3e0ab196810ec71ab4e4913ef1ae06_119468_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;225&#34; alt=&#34;FOSDEM 2023 - Goodies!&#34; class=&#34;alignright&#34; /&gt;

&lt;ul&gt;
&lt;li&gt;Mozilla&lt;/li&gt;
&lt;li&gt;Gnome&lt;/li&gt;
&lt;li&gt;PosgreSQL&lt;/li&gt;
&lt;li&gt;VLC&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;li&gt;Ham Radio&lt;/li&gt;
&lt;li&gt;Esprino (I&amp;rsquo;m still amazed about the Bangle.js 2 watch that I bought there)&lt;/li&gt;
&lt;li&gt;And many, many others&amp;hellip;&lt;/li&gt;
&lt;li&gt;&amp;hellip; oh, and the food trucks! :-P&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s unbelievable the amount of people that usually come to FOSDEM. On one side it&amp;rsquo;s probably one of the nicest things about this conference: the amount of poeple you can find talking about really interesting stuff, from personal projects or showing some electronics that they hack together, to &lt;a href=&#34;https://fosdem.org/2023/schedule/event/rust_glidesort/&#34;&gt;someone announcing a new sorting algorithm - Glidesort&lt;/a&gt; (btw, it hit &lt;a href=&#34;https://news.ycombinator.com/item?id=34646199&#34;&gt;Hacker News&lt;/a&gt; top 10! - repo here: &lt;a href=&#34;https://github.com/orlp/glidesort&#34;&gt;https://github.com/orlp/glidesort&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;On the other side, it&amp;rsquo;s always a big struggle trying to get into the room you are interested in, as chances are many other people are interested as well, and most probably there is not going to be enough room for everyone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FOSDEM tip&lt;/strong&gt;: if you are interested in a session and fear that it&amp;rsquo;s one of the popular ones, go to the session before (or 2 before) the one you&amp;rsquo;re interested and don&amp;rsquo;t get out!&lt;/p&gt;
&lt;p&gt;The only thing I really missed (and chances are that it happened on Sunday, the day I could not attend) was the classic PGP / GPG signing party :-(&lt;/p&gt;
&lt;p&gt;Nevertheless, once again FOSDEM has been an amazing event that I will most probably repeat next year!&lt;/p&gt;
&lt;p&gt;Some pictures from the event:&lt;/p&gt;
&lt;p&gt;










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8233_hu16ac85061970fa82fac94c4cc6ffdc0a_102195_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;225&#34; alt=&#34;FOSDEM 2023 - Keynote&#34; class=&#34;alignleft&#34; /&gt;












&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8238_hu413633dd4d2eb57ef4088014c9e49c53_116345_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;400&#34; alt=&#34;FOSDEM 2023 - Electronics stand&#34; class=&#34;alignleft&#34; /&gt;












&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8236_hu54817756b3b58f33309bddd85dc70021_114679_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;400&#34; alt=&#34;FOSDEM 2023 - Ham Radio stand 1&#34; class=&#34;alignleft&#34; /&gt;












&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2023/02/05/fosdem-2023/assets/IMG_8235_hu16ac85061970fa82fac94c4cc6ffdc0a_162580_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;225&#34; alt=&#34;FOSDEM 2023 - Ham Radio stand 2&#34; class=&#34;alignleft&#34; /&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mastodon as comment system for your static blog</title>
      <link>https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/</link>
      <pubDate>Sun, 25 Dec 2022 12:27:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/</guid>
      
      <description>&lt;p&gt;Comment systems are an essential part of modern websites, providing a platform for users to engage with the content and share their thoughts and opinions. While there are many options available for adding commenting functionality to a website, one alternative worth considering is integrating a Mastodon thread, also known as a &amp;ldquo;toot.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Mastodon is an open-source, decentralized social media platform that allows users to share text, images, and other types of media in a manner similar to Twitter.&lt;/p&gt;
&lt;p&gt;In this blog post, we will explore how to integrate a Mastodon thread into your static website as a way to replace traditional comment systems, using simple HTML and JavaScript. By the end of this tutorial, you will have a fully functional Mastodon thread on your website that allows users to participate in discussions and share their thoughts and ideas.&lt;/p&gt;
&lt;h2 id=&#34;the-fediverse--mastodon&#34;&gt;The Fediverse — Mastodon&lt;/h2&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/mastodon_hu9b28bf3677d9944ae9bc93ecdcaf7e42_18521_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;123&#34; alt=&#34;Mastodon&#34; class=&#34;alignleft&#34; /&gt;

&lt;p&gt;Twitter is a centralized social media platform that allows users to share short messages, called &amp;ldquo;tweets,&amp;rdquo; along with images, videos, and other types of media. Twitter is owned by a private company and has a centralized structure, which means that all user data and content is stored on servers owned and operated by the company.&lt;/p&gt;
&lt;p&gt;In contrast, Mastodon is a decentralized social media platform that is part of the Fediverse. The Fediverse is a network of interconnected, decentralized social media platforms that use the same open-source software and protocols, allowing users on different platforms to communicate with each other. Mastodon operates on a decentralized model, meaning that it is not owned or controlled by a single entity and user data and content is stored on servers run by individual users or organizations. This decentralized model allows for greater privacy and control over user data, as well as more diverse and independent communities.&lt;/p&gt;
&lt;p&gt;In terms of functionality, Mastodon is similar to Twitter in that it allows users to share text, images, and other types of media in short messages called &amp;ldquo;toots.&amp;rdquo; However, Mastodon also has additional features, such as the ability to boost (similar to retweeting) and favorite toots, as well as the ability to customize your profile and the look and feel of your Mastodon instance (server).&lt;/p&gt;
&lt;h2 id=&#34;disqus&#34;&gt;Disqus&lt;/h2&gt;
&lt;p&gt;Using a third party commenting system like Disqus does involve some trade-offs, including the fact that you are giving up some control over your user data. When you use a third-party system like Disqus, the user data (such as comments, email addresses, and any personal information provided by users) is stored on servers owned and operated by Disqus. This means that you do not have direct control over this data, and you will have to rely on Disqus to properly secure and manage it.&lt;/p&gt;
&lt;p&gt;There are a few potential disadvantages to not owning your user data when using a third party commenting system. First, you may be subject to the privacy policies and data handling practices of the third-party system, which may not align with your own policies or values. This can be especially concerning if you are collecting sensitive or personal information from your users, as you may not have control over how this information is used or shared.&lt;/p&gt;
&lt;p&gt;Second, not owning your user data can also make it more difficult to migrate to a different commenting system or platform in the future. If you decide to switch to a different system, you may have to manually transfer all the user data from the third-party system to the new platform, which can be time-consuming and may not be possible in all cases.&lt;/p&gt;
&lt;p&gt;Finally, using a third party commenting system can also potentially result in lost traffic to your website, as users may be directed to the third-party system&amp;rsquo;s website when they leave comments or log in to their accounts. This can be especially problematic if you are relying on advertising or other monetization methods that rely on website traffic.&lt;/p&gt;
&lt;h2 id=&#34;integrating-a-mastodon-toot-thread-into-your-blog-post&#34;&gt;Integrating a Mastodon Toot thread into your blog post&lt;/h2&gt;
&lt;p&gt;There are several potential advantages to integrating a blog post with the Fediverse, specifically Mastodon:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Increased visibility: By integrating your blog with Mastodon, you can potentially increase the visibility of your content by reaching a wider audience. Mastodon has a large and active user base, and by publishing your content on the platform, you can expose it to a new audience that may not have seen it otherwise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Greater control over user data: Mastodon operates on a decentralized model, which means that user data is stored on servers run by individual users or organizations. This can give you greater control over your user data and how it is used, compared to using a third party commenting system like Disqus.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Improved user experience: Mastodon allows users to easily share and engage with your content, as they can simply &amp;ldquo;boost&amp;rdquo; (similar to retweeting) your toots to share them with their followers. This can create a more interactive and engaging experience for your readers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enhanced privacy: Mastodon has a strong focus on privacy and user control, which can be appealing to users who are concerned about the data handling practices of centralized platforms. By integrating with Mastodon, you can offer a more private and secure commenting system for your readers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stronger sense of community: Mastodon is known for fostering strong and independent communities, and by integrating your blog with the platform, you can potentially create a more cohesive and engaged community around your content.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The technical proposal is to have a specific toot thread per blog post, so that a Mastodon user would be able to post replies to your post in the thread itself, as any other toot you may publish in the Fediverse itself. The &amp;ldquo;only&amp;rdquo; thing left is to integrate that thread into your blog, as if those were comments from a classic system.&lt;/p&gt;
&lt;p&gt;How? Thanks to &lt;a href=&#34;https://floss.social/@carlschwan&#34;&gt;Carl Schwan (@carlschwan@floss.social)&lt;/a&gt; who shared in a blogpost the Javscript code necessary to achieve this: &lt;a href=&#34;https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/&#34;&gt;https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the code that I finally ended using, heavily based on Carl&amp;rsquo;s. The main differences are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m importing the necessary libs from CloudFare&amp;rsquo;s CDN, not hosting those files directly&lt;/li&gt;
&lt;li&gt;Toot is automatically loaded as soon as the user scrolls to that section of the page&lt;/li&gt;
&lt;li&gt;and of course, the parameter names (which are based on Hugo and my &lt;strong&gt;modified&lt;/strong&gt; &lt;a href=&#34;https://github.com/kakawait/hugo-tranquilpeak-theme&#34;&gt;hugo-tranquilpeak-theme&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/hugo_hu0a3eac7007b0456c6c71c305c7266df4_77110_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;137&#34; alt=&#34;Hugo&#34; class=&#34;aligncenter&#34; /&gt;

&lt;div class=&#34;alert info &#34;&gt;
  &lt;p&gt;I&amp;rsquo;ve refactored the code in this article into a standalone webcomponent, easy to use and integrate. Find the code in the following GitHub repository: &lt;a href=&#34;https://github.com/dpecos/mastodon-comments&#34;&gt;&lt;i class=&#34;fab fa-github&#34;&gt;&lt;/i&gt; mastodon-comments&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;h2&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;Comments&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/h2&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;noscript&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;div id&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Please enable JavaScript to view the comments powered by the Fediverse&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/noscript&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;p&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;You can use your Fediverse &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;i&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;e&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt; Mastodon&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; among many others&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; account to reply to &lt;span style=&#34;color:#2838b0&#34;&gt;this&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;a &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;link&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    href&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;https://{{ .Site.Params.comment.fediverse.host }}/@{{ .Site.Params.comment.fediverse.user }}/{{ .Params.fediverse }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;post&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/a&amp;gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/p&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;p id&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;mastodon-comments-list&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/p&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;script src&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.1/purify.min.js&amp;#34;&lt;/span&gt; integrity&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;sha512-uHOKtSfJWScGmyyFr2O2+efpDx2nhwHU2v7MVeptzZoiC7bdF6Ny/CmZhN2AwIK1oCFiVQQ5DA/L9FSzyPNu6Q==&amp;#34;&lt;/span&gt; crossorigin&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt; referrerpolicy&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;no-referrer&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;script type&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;text/javascript&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; host &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;{{ .Site.Params.comment.fediverse.host }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; user &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;{{ .Site.Params.comment.fediverse.user }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; id &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;{{ .Params.fediverse }}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; escapeHtml&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;unsafe&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; unsafe
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a848a8&#34;&gt;/&amp;amp;/g&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;amp;amp;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a848a8&#34;&gt;/&amp;lt;/g&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;amp;lt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a848a8&#34;&gt;/&amp;gt;/g&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;amp;gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a848a8&#34;&gt;/&amp;#34;/g&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;amp;quot;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a848a8&#34;&gt;/&amp;#39;/g&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;amp;#039;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; commentsLoaded &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; toot_active&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; what&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; count &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;what&lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;_count&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; count &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;active&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; toot_count&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; what&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; count &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;what&lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;_count&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; count &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;?&lt;/span&gt; count &lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; user_account&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; result &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;`@&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;acct&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;acct&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;indexOf&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;@&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; domain &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;new&lt;/span&gt; URL&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      result &lt;span style=&#34;color:#666&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`@&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;domain&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;hostname&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; result&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; render_toots&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toots&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; in_reply_to&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; depth&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; tootsToRender &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; toots
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;filter&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;in_reply_to_id &lt;span style=&#34;color:#666&#34;&gt;===&lt;/span&gt; in_reply_to&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;sort&lt;span style=&#34;color:#888&#34;&gt;((&lt;/span&gt;a&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; b&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; a&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;created_at&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;localeCompare&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;b&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;created_at&lt;span style=&#34;color:#888&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tootsToRender&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;forEach&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; render_toot&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toots&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; depth&lt;span style=&#34;color:#888&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; render_toot&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toots&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; depth&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;display_name &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; escapeHtml&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;display_name&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;emojis&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;forEach&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;emoji &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;display_name &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;display_name&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;replace&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;`:&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;emoji&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;shortcode&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;:`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;img src=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;escapeHtml&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;emoji&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;static_url&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; alt=&amp;#34;Emoji &lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;emoji&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;shortcode&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; height=&amp;#34;20&amp;#34; width=&amp;#34;20&amp;#34; /&amp;gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mastodonComment &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;div class=&amp;#34;mastodon-comment&amp;#34; style=&amp;#34;margin-left: calc(var(--mastodon-comment-indent) * &lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;depth&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;)&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;        &amp;lt;div class=&amp;#34;author&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &amp;lt;div class=&amp;#34;avatar&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;            &amp;lt;img src=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;escapeHtml&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;avatar_static&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; height=60 width=60 alt=&amp;#34;&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &amp;lt;div class=&amp;#34;details&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;            &amp;lt;a class=&amp;#34;name&amp;#34; href=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; rel=&amp;#34;nofollow&amp;#34;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;display_name&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;            &amp;lt;a class=&amp;#34;user&amp;#34; href=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; rel=&amp;#34;nofollow&amp;#34;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;user_account&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;account&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &amp;lt;a class=&amp;#34;date&amp;#34; href=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; rel=&amp;#34;nofollow&amp;#34;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;created_at&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;substr&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;created_at&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;substr&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;11&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;        &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;        &amp;lt;div class=&amp;#34;content&amp;#34;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;content&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;        &amp;lt;div class=&amp;#34;attachments&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;media_attachments&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;map&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;attachment &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#666&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;image&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;a href=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; rel=&amp;#34;nofollow&amp;#34;&amp;gt;&amp;lt;img src=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;preview_url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; alt=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;description&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; /&amp;gt;&amp;lt;/a&amp;gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt; else if (attachment.type === &amp;#39;video&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;              return `&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;video controls&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;source src&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;${attachment.url}&amp;#34;&lt;/span&gt; type&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;${attachment.mime_type}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/video&amp;gt;`;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#666&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;gifv&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;video autoplay loop muted playsinline&amp;gt;&amp;lt;source src=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; type=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;mime_type&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;gt;&amp;lt;/video&amp;gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#666&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;audio&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;audio controls&amp;gt;&amp;lt;source src=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; type=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;mime_type&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;gt;&amp;lt;/audio&amp;gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;`&amp;lt;a href=&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;url&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34; rel=&amp;#34;nofollow&amp;#34;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;${&lt;/span&gt;attachment&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;type&lt;span style=&#34;color:#b83838;text-decoration:underline&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;lt;/a&amp;gt;`&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#888&#34;&gt;}).&lt;/span&gt;join&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;div &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;div &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;replies ${toot_active(toot, &amp;#39;replies&amp;#39;)}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;a href&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;${toot.url}&amp;#34;&lt;/span&gt; rel&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;nofollow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;i &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;fa fa-reply fa-fw&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/i&amp;gt;${toot_count(toot, &amp;#39;replies&amp;#39;)}&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;div &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;reblogs ${toot_active(toot, &amp;#39;reblogs&amp;#39;)}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;a href&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;${toot.url}&amp;#34;&lt;/span&gt; rel&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;nofollow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;i &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;fa fa-retweet fa-fw&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/i&amp;gt;${toot_count(toot, &amp;#39;reblogs&amp;#39;)}&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;div &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;favourites ${toot_active(toot, &amp;#39;favourites&amp;#39;)}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;a href&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;${toot.url}&amp;#34;&lt;/span&gt; rel&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;nofollow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;i &lt;span style=&#34;color:#2838b0&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;fa fa-star fa-fw&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/i&amp;gt;${toot_count(toot, &amp;#39;favourites&amp;#39;)}&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/div&amp;gt;`;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#388038&#34;&gt;document&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;getElementById&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;mastodon-comments-list&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;).&lt;/span&gt;appendChild&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;DOMPurify&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;sanitize&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;mastodonComment&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;RETURN_DOM_FRAGMENT&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    render_toots&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;toots&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; toot&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;id&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; depth &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; loadComments&lt;span style=&#34;color:#888&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;commentsLoaded&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#388038&#34;&gt;document&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;getElementById&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;mastodon-comments-list&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;).&lt;/span&gt;innerHTML &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Loading comments from the Fediverse...&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fetch&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;https://&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; host &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;/api/v1/statuses/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; id &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;/context&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;then&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;response&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; response&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;json&lt;span style=&#34;color:#888&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;then&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;data&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;data&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;descendants&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;isArray&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;data&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;descendants&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;])&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; data&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;descendants&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;].&lt;/span&gt;length &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#388038&#34;&gt;document&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;getElementById&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;mastodon-comments-list&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;).&lt;/span&gt;innerHTML &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            render_toots&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;data&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;descendants&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;],&lt;/span&gt; id&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#388038&#34;&gt;document&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;getElementById&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;mastodon-comments-list&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;).&lt;/span&gt;innerHTML &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;lt;p&amp;gt;Not comments found&amp;lt;/p&amp;gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        commentsLoaded &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;function&lt;/span&gt; respondToVisibility&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;element&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; callback&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; options &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      root&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;null&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; observer &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;new&lt;/span&gt; IntersectionObserver&lt;span style=&#34;color:#888&#34;&gt;((&lt;/span&gt;entries&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; observer&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      entries&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;forEach&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;entry &lt;span style=&#34;color:#888&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#2838b0&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;entry&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;intersectionRatio &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          callback&lt;span style=&#34;color:#888&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;},&lt;/span&gt; options&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    observer&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;observe&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;element&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;var&lt;/span&gt; comments &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;document&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;getElementById&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;mastodon-comments-list&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  respondToVisibility&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;comments&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; loadComments&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;background-color:#a848a8&#34;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and the CSS supporting the generated HTML markup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;background-color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;--&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;block&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;background&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;border-radius&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;--&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;block&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;border&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;radius&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;border&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;--&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;block&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;border&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;solid&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;padding&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;20&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-bottom&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;1.5&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;rem&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;display&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;flex&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;flex-direction&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;column&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;--&lt;/span&gt;font&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;var&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;--&lt;/span&gt;font&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;size&lt;span style=&#34;color:#888&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-bottom&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;padding-top&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;display&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444;font-style:italic&#34;&gt;flex&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;text-decoration&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;none&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;avatar&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;img&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-right&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;rem&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;min-width&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;60&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;border-radius&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;details&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;display&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;flex&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;flex-direction&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;column&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;details&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;font-weight&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;bold&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;details&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;user&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;#5d686f&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;medium&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;author&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-left&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;auto&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;small&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;content&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;20&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;attachments&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;attachments&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;content&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;first-child&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-top&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-bottom&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;display&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;inline-block&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;margin-right&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;px&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;#5d686f&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;text-decoration&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;none&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;replies&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;active&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;#003eaa&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;reblogs&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;active&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;#8c8dff&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;mastodon-comment&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;favourites&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#287088&#34;&gt;active&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;#ca8f04&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You&amp;rsquo;ll need also to add some config to your &lt;code&gt;config.toml&lt;/code&gt;:&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/hugo_config_hu5b7bfea515c31de5f8597f6fceb07d2d_11460_300x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;300&#34; height=&#34;203&#34; alt=&#34;Hugo config&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;as well as to the meta section of your post (the toot ID to use as a thread, last attribute of the following screenshot):&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/post_meta_huc694190398353b51c7d036238dea7b36_29796_300x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;300&#34; height=&#34;396&#34; alt=&#34;Post meta&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;The code snippet above code, based on a toot ID that the post must define in its metadata, fetches via JSON the whole discussion thread. Once that&amp;rsquo;s done, it&amp;rsquo;s just a matter of sanitizing the HTML (to be sure nobody can inject JS into your blog but just replying to the toot) and rendering it into the HTML.&lt;/p&gt;
&lt;p&gt;There is a small chicken and egg issue though: you need to know the ID of the toot to use as discussion thread to specify it as part of the post metadata, but probably (although not mandatory) you&amp;rsquo;d like to include the URL of the post itself, as part of the content of the toot (and ideally the link should work as soon as the toot is published).&lt;/p&gt;
&lt;p&gt;Yes, you can edit toots, so you would be able to publish the toot, grab its ID, change the post and publish. The problem is that you&amp;rsquo;ll be losing the momentum that publishing a new toot gives you, as the toot would initially not contain the link to the blog post itself.&lt;/p&gt;
&lt;p&gt;So my workflow, although not ideal, is going to be as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Publish the post without Fediverse discussion enabled (no toot ID)&lt;/li&gt;
&lt;li&gt;Publish the toot containing the URL to the post and grab its ID&lt;/li&gt;
&lt;li&gt;Change the post to include the toot ID&lt;/li&gt;
&lt;li&gt;Republish the website&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&amp;rsquo;s not ideal, as you are potentially loosing comments from early visitor to your post, but given that publishing a static website is quite fast, it should not be that many people.&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/fediverse_huead76b699e6aa68e1adb1f65b5b106e5_49092_300x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;300&#34; height=&#34;300&#34; alt=&#34;Fediverse&#34; class=&#34;alignleft&#34; /&gt;

&lt;p&gt;And with that, you have a fresh new comment system based on the Fediverse for your blog!&lt;/p&gt;
&lt;p&gt;Note: I&amp;rsquo;ve kept as a fallback for existing posts (with existing comments) Disqus, so if a post does not define a toot ID, then the comments system fall backs to Disqus. Ideally I&amp;rsquo;d love to move all those posts to Mastodon threads, but I don&amp;rsquo;t think that&amp;rsquo;s possible, as you&amp;rsquo;ll need to post toots on behalf of the users that created those comments (or you can use your own account and mimick the message as if they would have post it). Maybe something to explore in the future.&lt;/p&gt;
&lt;p&gt;Thanks again to &lt;a href=&#34;https://floss.social/@carlschwan&#34;&gt;Carl Schwan (@carlschwan@floss.social)&lt;/a&gt; for its contribution to the community!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/01/01 Update&lt;/strong&gt; — I&amp;rsquo;ve recently changed the markup (and some functionality) to include some extra features, as the botton links to boost / reply, as well as including the count. This is the latest code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/01/02 Update&lt;/strong&gt; — Quick hack to group / nest replies properly&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/06/20 Update&lt;/strong&gt; — Screenshots for blog config and post meta added&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/06/23 Update&lt;/strong&gt; — Media attachments rendered as part of the toot:&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/assets/post_attachments_huf23cdee7ec3f53943e0d8620327f3e1c_103584_300x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;300&#34; height=&#34;540&#34; alt=&#34;Toot attachments&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;&lt;strong&gt;2023/06/24 Update&lt;/strong&gt; — Sort comments by date&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/07/19 Update&lt;/strong&gt; - Added CSS snippet&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2023/07/23 Update&lt;/strong&gt; - Code refactored into a standalone webcomponent: &lt;a href=&#34;https://github.com/dpecos/mastodon-comments&#34;&gt;&lt;i class=&#34;fab fa-github&#34;&gt;&lt;/i&gt; mastodon-comments&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Parchis: the reason why I am a developer</title>
      <link>https://danielpecos.com/2021/11/06/parchis-the-reason-why-i-am-a-developer/</link>
      <pubDate>Sat, 06 Nov 2021 21:58:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2021/11/06/parchis-the-reason-why-i-am-a-developer/</guid>
      
      <description>&lt;p&gt;A while back, digging into an old &lt;code&gt;DO NOT DELETE&lt;/code&gt; backup folder in one of my old hard drives, I stumped upon a folder called &lt;code&gt;parchis&lt;/code&gt;, and for a moment I held my breath until I found some &lt;code&gt;*.bas&lt;/code&gt; files there!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;So what?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Well, I just found the lost source code of my very first project, the one I coded while learning about variables, procedures and loops, the one that made me realize that this is the kind of stuff I wanted to do as my professional career and hobby.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The one that made me love coding.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But before explaining further, let me explain what the Parchís game is about, and for that I&amp;rsquo;m going to borrow the &lt;a href=&#34;https://en.wikipedia.org/wiki/Parch%C3%ADs&#34;&gt;definition from the Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Parchís is a Spanish board game of the Cross and Circle family. It is an adaptation of the Indian game Pachisi. Parchís was a very popular game in Spain at one point as well as in Europe and north Morocco - specifically Tangiers and Tetouan, and it is still popular specially among adults and seniors. Since it uses dice, Parchís is not usually regarded as an abstract strategy game like checkers or chess. It does not depend entirely on luck either, since the four pawns under a player&amp;rsquo;s command demand some sort of strategy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So here I am, 17 years old me, learning how to code from a book I borrowed from the library about QuickBasic. Yep, back then Internet was not a thing yet (at least not much yet in Spain), so that was how we used to browse and learn new topics, by going to a library. And, oh did I enjoy it.&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/11/06/parchis-the-reason-why-i-am-a-developer/assets/code_hu2a2fd31f230d92380bd427b7bb280600_24451_850x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;850&#34; height=&#34;572&#34; alt=&#34;Parchis in QuickBasic&#34; class=&#34;&#34; /&gt;

&lt;p&gt;I still don&amp;rsquo;t know what exactly hooked me up, but there I was writing this weird mixed of English &amp;amp; Spanish that the computer was able to understand, using this archaic environment in MS-DOS. Maybe it was being able to finally understand how games were made, or the beauty of taking a problem and plan and design a solution, and not only that, taking care of the solution being elegant and simple. Pure beauty.&lt;/p&gt;
&lt;p&gt;But anyway, after a few weeks (if I remember correctly), I managed to put something together that resembled the game I was aiming for and that kind of worked. To be honest, trying to read the code today is quite painful, and hard to keep all the logic and structure in your head, which makes me even prouder of being able of making it work being so poorly written.&lt;/p&gt;
&lt;p&gt;This is how the program looks like:&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/11/06/parchis-the-reason-why-i-am-a-developer/assets/parchis_hu2a0905b088cd91f4e03749ae5151d25c_17057_850x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;850&#34; height=&#34;643&#34; alt=&#34;Parchis - Daniel Pecos - 1998&#34; class=&#34;&#34; /&gt;

&lt;p&gt;And no, the screenshot is not from back then, but from a couple of days ago, when I found the source code. I wanted to check if it was possible to still run that code, so I started digging about modern quick basic interpreters, and found some, but at the end the best solution was to use &lt;code&gt;dosbox&lt;/code&gt;, a MS-DOS emulator and installing QuickBasic 4.5 to open the software.&lt;/p&gt;
&lt;p&gt;And lo and behold, it worked!&lt;/p&gt;
&lt;p&gt;(BTW, I use Arch, and this is running on Arch Linux)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve put all the &lt;a href=&#34;https://github.com/dpecos/parchis&#34;&gt;code together in a Github repository&lt;/a&gt;, where I&amp;rsquo;ve fixed some MS-DOS &lt;strong&gt;encoding&lt;/strong&gt; issues and cleaned a little bit the code, but I&amp;rsquo;ve kept all the original comments, bugs and code smells that I wrote back then. There are some instructions on how to get it running, just in case you are interested on running old QuickBasic programs.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t want to change a single bit of it, but I want to be able to look at it from time to time and remember how all of this started.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to have a look, feel free, although I doubt you&amp;rsquo;ll find any value on the code itself, it&amp;rsquo;s ugly, poorly written, anb barely works, but to me :-)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/dpecos/parchis&#34;&gt;https://github.com/dpecos/parchis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And if you&amp;rsquo;d like to actually see how I got it up and running, here you have a small screencast of the process and gameplay:&lt;/p&gt;

&lt;video width=&#34;800&#34; height=&#34;600&#34; controls&gt;
  &lt;source src=&#34;https://danielpecos.com/2021/11/06/parchis-the-reason-why-i-am-a-developer/assets/demo.webm&#34; type=&#34;video/webm&#34;&gt;
&lt;/video&gt;


&lt;p&gt;Last but not least, I have to say that it was my friend &lt;a href=&#34;https://www.youtube.com/user/t3rr1k&#34;&gt;Alfredo&lt;/a&gt; who actually introduced me to software development, showing me a couple of small programs he was developing to learn QuickBasic, and triggering my curiosity about it, leading towards this project.&lt;/p&gt;
&lt;p&gt;So basically all of this is his fault. Thx for that &lt;a href=&#34;https://www.youtube.com/user/t3rr1k&#34;&gt;Alfredo&lt;/a&gt; ;-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Cryptocurrencies and Climate Change</title>
      <link>https://danielpecos.com/2021/03/03/cryptocurrencies-and-climate-change/</link>
      <pubDate>Wed, 03 Mar 2021 10:50:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2021/03/03/cryptocurrencies-and-climate-change/</guid>
      
      <description>










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/03/03/cryptocurrencies-and-climate-change/assets/bitcoin-co2_huf121a72efeb1b70d3951bd7714f64faf_105879_300x0_resize_q75_h2_lanczos.webp&#34; width=&#34;300&#34; height=&#34;300&#34; alt=&#34;Cryptocurrencies and Climage Change&#34; class=&#34;alignleft&#34; /&gt;

&lt;p&gt;Bitcoin (and many more) cryptocurrency prices have been sky rocketing for the lasts weeks/months, and thus their usage and mining. But have we stop thinking how this impacts the Climate Change?&lt;/p&gt;
&lt;p&gt;Before jumping into graphs, a quick recap on how cryptocurrencies work: when you buy or sell Bitcoins (for example), your transaction is being recorded into a distributed ledger. This distributed ledger is cryptographically secured against tampering, meaning that once anything is written into it, there is no way of changing nor removing it. But that ledger needs to reside and be supported by a platform. This platform is what the miners provide, and the computation power they contribute with is what enables the distributed ledger.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve covered more in detail &lt;a href=&#34;https://danielpecos.com/2018/11/10/demistifying-blockchain-part-1/&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;https://danielpecos.com/2018/11/15/demistifying-blockchain-part-2/&#34;&gt;here&lt;/a&gt; how blockchain works and how you could have a basic implementation with a few lines of code.&lt;/p&gt;
&lt;p&gt;The issue here is that in order to seal the ledger&amp;rsquo;s records, a really hard computation is performed in parallel across all the miners in the world, as a race to be the first to figure out the challenge and earn some coins (the transaction fees) in exchange.&lt;/p&gt;
&lt;p&gt;This process is extremely inefficient and power demanding, and this is why it should concern us. A lot.&lt;/p&gt;
&lt;p&gt;Based on &lt;a href=&#34;https://www.bbc.com/news/science-environment-56215787&#34;&gt;different&lt;/a&gt; &lt;a href=&#34;https://www.theguardian.com/technology/2021/feb/27/bitcoin-mining-electricity-use-environmental-impact&#34;&gt;articles&lt;/a&gt;, power consumption for bitcoin (alone) is higher than some countries (and not exactly third world countries):&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/03/03/cryptocurrencies-and-climate-change/assets/bitcoin-netherlands-power-consumption_hud9fc26edd937c122592721a8de023027_100982_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;430&#34; alt=&#34;Bitcoin power consumption&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;This is worrisome, to say the least: we&amp;rsquo;re generating an incredible amount of CO2 that is not yielding anything useful in return. I&amp;rsquo;m not saying cryptocurrencies are not useful, but that cryptocurrencies (based on &lt;a href=&#34;https://en.wikipedia.org/wiki/Proof_of_work&#34;&gt;proof-of-work&lt;/a&gt;) are not worth it if to make them work we increase our chances of having a climate disaster in the close future.&lt;/p&gt;
&lt;p&gt;Please, I know it&amp;rsquo;s tempting to buy Bitcoins, I&amp;rsquo;ve did it in the past and &lt;a href=&#34;https://danielpecos.com/2017/10/25/web-mining-is-that-bad/&#34;&gt;vouched for these kind of coins to be a way of monetizing the web&lt;/a&gt;, but this is out of control and, IMHO, not worth it at all.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How I write AWS SES email templates using MJML</title>
      <link>https://danielpecos.com/2021/01/27/how-i-write-aws-ses-email-templates-using-mjml/</link>
      <pubDate>Wed, 27 Jan 2021 09:05:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2021/01/27/how-i-write-aws-ses-email-templates-using-mjml/</guid>
      
      <description>










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/01/27/how-i-write-aws-ses-email-templates-using-mjml/assets/SES-MJML_huf8d61e8a086ae2a284c68d776b08faa8_26004_750x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;750&#34; height=&#34;261&#34; alt=&#34;SES templates with MJML&#34; class=&#34;&#34; /&gt;

&lt;p&gt;If you are a &lt;a href=&#34;https://aws.amazon.com/ses&#34;&gt;AWS SES&lt;/a&gt; user (AWS&amp;rsquo; email system) you probably know that working with its JSON based templates is not a user-friendly task:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Text and HTML content are defined as properties of a JSON object&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s a JSON file, meaning that you have to escape some characters, like &lt;code&gt;&amp;quot;&lt;/code&gt; in the HTML&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s quite hard to find the content to change in the HTML being stored in a single line&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But still, is a quite convenient system, as hosting your own email server is quite an effort, and you want it to be reliable.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I decided to use it, despite the not so friendly interface. Together with a Lambda function triggered by SNS messages, I have managed to build a quite robust mail gateway solution for &lt;a href=&#34;https://app.papyro.dplabs.tech&#34;&gt;Papyro&lt;/a&gt; (let me know if you are interested in knowing how theses pieces fit together and I&amp;rsquo;ll write a future post about it).&lt;/p&gt;
&lt;p&gt;But the pain of creating some nice looking emails using this system is way too much from the moment that you have to manage more than 3 or 4 email templates.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s when I started looking into &lt;a href=&#34;https://mjml.io/&#34;&gt;MJML&lt;/a&gt;. MJML is a responsive email library that allows you to create rich emails using a syntax similar to HTML. It also offers a CLI to convert the MJML files into (minimized, and this is important) HTML.&lt;/p&gt;
&lt;p&gt;So in order to use MJML for SES templates, two issues needed to be adressed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate plain text from MJML - not supported directly by MJML&lt;/li&gt;
&lt;li&gt;All generated output must be valid when expressed in a single line - because still, the output must be part of a JSON property in the SES template&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For 1, and given an already minimized HTML, it&amp;rsquo;s just a matter of removing all the &lt;code&gt;\n&lt;/code&gt; and making sure that the generated CSS does not contain any problematic comment (which by default, is the case, phew).&lt;/p&gt;
&lt;p&gt;For 2, I decided to use &lt;code&gt;html-to-text&lt;/code&gt; (&lt;a href=&#34;https://www.npmjs.com/package/html-to-text&#34;&gt;https://www.npmjs.com/package/html-to-text&lt;/a&gt;) node package (specifically its CLI) and some &lt;code&gt;bash&lt;/code&gt; magic to properly format the contents in the format that AWS expects (using &lt;code&gt;\r\n&lt;/code&gt; for line breaks).&lt;/p&gt;
&lt;p&gt;So this is what my solution looks like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;├── bin
│   └── upload-ses-template.sh
├── build
│   └── welcome.json
└── templates
    ├── welcome.json
    └── welcome.mjml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This bash script is driving all the process (&lt;code&gt;upload-ses-template.sh&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#289870&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#289870&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;TEMPLATE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;RAW_HTML&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;$(&lt;/span&gt;mjml ./templates/&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;.mjml --config.minify &lt;span style=&#34;color:#388038&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;HTML&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#388038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b04040&#34;&gt;$RAW_HTML&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;|&lt;/span&gt; sed -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;s/&amp;#34;/\\\\&amp;#34;/g&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;TEXT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#388038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b04040&#34;&gt;$RAW_HTML&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;|&lt;/span&gt; html-to-text --ignore-image --noLinkBrackets &lt;span style=&#34;color:#888&#34;&gt;|&lt;/span&gt; sed -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;s/&amp;#34;/\\\\&amp;#34;/g&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;TEXT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;$(while&lt;/span&gt; &lt;span style=&#34;color:#b04040&#34;&gt;IFS&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;read&lt;/span&gt; -r line&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;$line&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;\\\\r\\\\n&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt; &lt;span style=&#34;color:#2838b0&#34;&gt;done&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;$TEXT&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;|&lt;/span&gt; tr -d &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p ./build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat ./templates/&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;.json &lt;span style=&#34;color:#888&#34;&gt;|&lt;/span&gt; sed -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;s~%html%~&lt;/span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;$HTML&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;~&amp;#34;&lt;/span&gt; -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;s/%html%/\&amp;amp;/g&amp;#39;&lt;/span&gt; -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;s~%text%~&lt;/span&gt;&lt;span style=&#34;color:#b04040&#34;&gt;$TEXT&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;~&amp;#34;&lt;/span&gt; -e &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#39;s/%text%/\&amp;amp;/g&amp;#39;&lt;/span&gt; &amp;gt; ./build/&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat ./build/&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#388038&#34;&gt;set&lt;/span&gt; -x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aws ses delete-template --template-name papyro-&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aws ses create-template --cli-input-json file://build/&lt;span style=&#34;color:#b04040&#34;&gt;$TEMPLATE&lt;/span&gt;.jso
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(BTW, if you know a better way of joining a multiline text using &lt;code&gt;\r\n&lt;/code&gt;, please let me know, I did struggle quite a bit and the solution is not that nice as you may have noticed)&lt;/p&gt;
&lt;p&gt;So given a wireframe (note the &lt;code&gt;%text%&lt;/code&gt; and &lt;code&gt;%html%&lt;/code&gt; placeholders) of SES template (&lt;code&gt;templates/welcome.json&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#2838b0&#34;&gt;&amp;#34;Template&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;&amp;#34;TemplateName&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;papyro-welcome&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;&amp;#34;SubjectPart&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Welcome to Papyro!&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;&amp;#34;TextPart&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;%text%&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#2838b0&#34;&gt;&amp;#34;HtmlPart&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;%html%&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and its MJML template (&lt;code&gt;templates/welcome.mjml&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mjml&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-head&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-title&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;Papyro&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-title&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-head&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-body&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-section&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-column&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-image&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;width&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;100px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;https://app.papyro.dplabs.tech/assets/app-logo/logo.png&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-image&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-divider&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;border-color&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;#fcba03&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-divider&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;20px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;#fcba03&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;helvetica&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;Hello {{name}}!&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;16px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;helvetica&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;Welcome to Papyro!&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;16px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;helvetica&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;Before starting, we need to validate your email. Click in this link to proceed:&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-button&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;20px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;helvetica&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;background-color&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;#fcba03&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;{{link}}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt; Validate email &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-button&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-size&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;20px&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;color&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;#fcba03&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#388038&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;helvetica&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;Papyro Team.&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-text&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-column&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-section&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mj-body&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#2838b0&#34;&gt;mjml&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the script generates a valid AWS SES template file (&lt;code&gt;build/welcome.json&lt;/code&gt;) and uploads to SES it using &lt;code&gt;aws&lt;/code&gt; cli:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./bin/upload-ses-template.sh welcome
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Template&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;TemplateName&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;papyro-welcome&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;SubjectPart&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Welcome to Papyro!&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;TextPart&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Hello {{name}}!\r\nWelcome to Papyro!\r\nBefore starting, we need to validate your email. Click in this link to proceed:\r\n\r\nValidate email {{link}}\r\n\r\nPapyro Team.\r\n&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;HtmlPart&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;lt;!-- FILE: ./templates/welcome.mjml --&amp;gt; &amp;lt;!doctype html&amp;gt;&amp;lt;html xmlns=\&amp;#34;http://www.w3.org/1999/xhtml\&amp;#34; xmlns:v=\&amp;#34;urn:schemas-microsoft-com:vml\&amp;#34; xmlns:o=\&amp;#34;urn:schemas-microsoft-com:office:office\&amp;#34;&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Papyro&amp;lt;/title&amp;gt;&amp;lt;!--[if !mso]&amp;gt;&amp;lt;!--&amp;gt;&amp;lt;meta http-equiv=\&amp;#34;X-UA-Compatible\&amp;#34; content=\&amp;#34;IE=edge\&amp;#34;&amp;gt;&amp;lt;!--&amp;lt;![endif]--&amp;gt;&amp;lt;meta http-equiv=\&amp;#34;Content-Type\&amp;#34; content=\&amp;#34;text/html; charset=UTF-8\&amp;#34;&amp;gt;&amp;lt;meta name=\&amp;#34;viewport\&amp;#34; content=\&amp;#34;width=device-width,initial-scale=1\&amp;#34;&amp;gt;&amp;lt;style type=\&amp;#34;text/css\&amp;#34;&amp;gt;#outlook a { padding: 0; } body { margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } table, td { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; } p { display: block; margin: 13px 0; }&amp;lt;/style&amp;gt;&amp;lt;!--[if mso]&amp;gt; &amp;lt;xml&amp;gt; &amp;lt;o:OfficeDocumentSettings&amp;gt; &amp;lt;o:AllowPNG/&amp;gt; &amp;lt;o:PixelsPerInch&amp;gt;96&amp;lt;/o:PixelsPerInch&amp;gt; &amp;lt;/o:OfficeDocumentSettings&amp;gt; &amp;lt;/xml&amp;gt; &amp;lt;![endif]--&amp;gt;&amp;lt;!--[if lte mso 11]&amp;gt; &amp;lt;style type=\&amp;#34;text/css\&amp;#34;&amp;gt; .mj-outlook-group-fix { width:100% !important; } &amp;lt;/style&amp;gt; &amp;lt;![endif]--&amp;gt;&amp;lt;style type=\&amp;#34;text/css\&amp;#34;&amp;gt;@media only screen and (min-width:480px) { .mj-column-per-100 { width: 100% !important; max-width: 100%; } }&amp;lt;/style&amp;gt;&amp;lt;style type=\&amp;#34;text/css\&amp;#34;&amp;gt;@media only screen and (max-width:481px) { table.mj-full-width-mobile { width: 100% !important; } td.mj-full-width-mobile { width: auto !important; } }&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body style=\&amp;#34;word-spacing:normal;\&amp;#34;&amp;gt;&amp;lt;div&amp;gt;&amp;lt;!--[if mso | IE]&amp;gt;&amp;lt;table align=\&amp;#34;center\&amp;#34; border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; class=\&amp;#34;\&amp;#34; style=\&amp;#34;width:600px;\&amp;#34; width=\&amp;#34;600\&amp;#34; &amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=\&amp;#34;line-height:0px;font-size:0px;mso-line-height-rule:exactly;\&amp;#34;&amp;gt;&amp;lt;![endif]--&amp;gt;&amp;lt;div style=\&amp;#34;margin:0px auto;max-width:600px;\&amp;#34;&amp;gt;&amp;lt;table align=\&amp;#34;center\&amp;#34; border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; role=\&amp;#34;presentation\&amp;#34; style=\&amp;#34;width:100%;\&amp;#34;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=\&amp;#34;direction:ltr;font-size:0px;padding:20px 0;text-align:center;\&amp;#34;&amp;gt;&amp;lt;!--[if mso | IE]&amp;gt;&amp;lt;table role=\&amp;#34;presentation\&amp;#34; border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=\&amp;#34;\&amp;#34; style=\&amp;#34;vertical-align:top;width:600px;\&amp;#34; &amp;gt;&amp;lt;![endif]--&amp;gt;&amp;lt;div class=\&amp;#34;mj-column-per-100 mj-outlook-group-fix\&amp;#34; style=\&amp;#34;font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;\&amp;#34;&amp;gt;&amp;lt;table border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; role=\&amp;#34;presentation\&amp;#34; style=\&amp;#34;vertical-align:top;\&amp;#34; width=\&amp;#34;100%\&amp;#34;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;center\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;table border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; role=\&amp;#34;presentation\&amp;#34; style=\&amp;#34;border-collapse:collapse;border-spacing:0px;\&amp;#34;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=\&amp;#34;width:100px;\&amp;#34;&amp;gt;&amp;lt;img height=\&amp;#34;auto\&amp;#34; src=\&amp;#34;https://app.papyro.dplabs.tech/assets/app-logo/logo.png\&amp;#34; style=\&amp;#34;border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;\&amp;#34; width=\&amp;#34;100\&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;center\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;p style=\&amp;#34;border-top:solid 4px #fcba03;font-size:1px;margin:0px auto;width:100%;\&amp;#34;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;!--[if mso | IE]&amp;gt;&amp;lt;table align=\&amp;#34;center\&amp;#34; border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; style=\&amp;#34;border-top:solid 4px #fcba03;font-size:1px;margin:0px auto;width:550px;\&amp;#34; role=\&amp;#34;presentation\&amp;#34; width=\&amp;#34;550px\&amp;#34; &amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=\&amp;#34;height:0;line-height:0;\&amp;#34;&amp;gt; &amp;amp;nbsp; &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;![endif]--&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;left\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;div style=\&amp;#34;font-family:helvetica;font-size:20px;line-height:1;text-align:left;color:#fcba03;\&amp;#34;&amp;gt;Hello {{name}}!&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;left\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;div style=\&amp;#34;font-family:helvetica;font-size:16px;line-height:1;text-align:left;color:#000000;\&amp;#34;&amp;gt;Welcome to Papyro!&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;left\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;div style=\&amp;#34;font-family:helvetica;font-size:16px;line-height:1;text-align:left;color:#000000;\&amp;#34;&amp;gt;Before starting, we need to validate your email. Click in this link to proceed:&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;center\&amp;#34; vertical-align=\&amp;#34;middle\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;table border=\&amp;#34;0\&amp;#34; cellpadding=\&amp;#34;0\&amp;#34; cellspacing=\&amp;#34;0\&amp;#34; role=\&amp;#34;presentation\&amp;#34; style=\&amp;#34;border-collapse:separate;line-height:100%;\&amp;#34;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;center\&amp;#34; bgcolor=\&amp;#34;#fcba03\&amp;#34; role=\&amp;#34;presentation\&amp;#34; style=\&amp;#34;border:none;border-radius:3px;cursor:auto;mso-padding-alt:10px 25px;background:#fcba03;\&amp;#34; valign=\&amp;#34;middle\&amp;#34;&amp;gt;&amp;lt;a href=\&amp;#34;{{link}}\&amp;#34; style=\&amp;#34;display:inline-block;background:#fcba03;color:#ffffff;font-family:helvetica;font-size:20px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:10px 25px;mso-padding-alt:0px;border-radius:3px;\&amp;#34; target=\&amp;#34;_blank\&amp;#34;&amp;gt;Validate email&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=\&amp;#34;left\&amp;#34; style=\&amp;#34;font-size:0px;padding:10px 25px;word-break:break-word;\&amp;#34;&amp;gt;&amp;lt;div style=\&amp;#34;font-family:helvetica;font-size:20px;line-height:1;text-align:left;color:#fcba03;\&amp;#34;&amp;gt;Papyro Team.&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;!--[if mso | IE]&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;![endif]--&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;!--[if mso | IE]&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;![endif]--&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+ aws ses delete-template --template-name papyro-welcome
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+ aws ses create-template --cli-input-json file://build/welcome.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;resulting in an email looking like this:&lt;/p&gt;











&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2021/01/27/how-i-write-aws-ses-email-templates-using-mjml/assets/welcome-email_hu40dc90b02d2fee14fb874db08ae31def_101157_750x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;750&#34; height=&#34;711&#34; alt=&#34;&#34; class=&#34;&#34; /&gt;

&lt;p&gt;Hope this could be useful to someone else. I used to hate having to create emails, but now I can easily do it and I get really nice results with little effort.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What is a Monorepo</title>
      <link>https://danielpecos.com/2020/02/26/what-is-a-monorepo/</link>
      <pubDate>Wed, 26 Feb 2020 20:35:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2020/02/26/what-is-a-monorepo/</guid>
      
      <description>&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2020/02/monorepos.png&#34; alt=&#34;What is a Monorepo&#34;&gt;&lt;/p&gt;
&lt;p&gt;Definition: A &lt;strong&gt;monorepo&lt;/strong&gt; is a standard &lt;em&gt;Version Control System&lt;/em&gt;, or VCS (such as &lt;em&gt;Git&lt;/em&gt;, &lt;em&gt;Subversion&lt;/em&gt; or &lt;em&gt;CVS&lt;/em&gt;) repository, which instead of containing just one application or unit of software (applications, libraries, micro services, modules&amp;hellip;), contains all the components that a project (or company) needs to operate.&lt;/p&gt;
&lt;p&gt;At first glance, it sounds counterintuitive to host more than one unit of software in a single repository, but there are few advantages on having all components stored in the same place:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All dependencies are easily within reach, just in a different path&lt;/li&gt;
&lt;li&gt;Multiple-project changes in a single changeset&lt;/li&gt;
&lt;li&gt;No more versioning issues between internal modules, all of them are always in sync&lt;/li&gt;
&lt;li&gt;Easier to share knowledge between teams, their code is just there for you to change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why then, would you ask, have we typically used single repositories until recently? Well, there are a few reasons also:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code isolation&lt;/li&gt;
&lt;li&gt;Smaller repository size&lt;/li&gt;
&lt;li&gt;Access control to the code&lt;/li&gt;
&lt;li&gt;Higher chance of merge conflicts&lt;/li&gt;
&lt;li&gt;Easier to deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So there are some tradeoffs to using one approach or the other, some of them are greater than others, but also probably harder to grasp.&lt;/p&gt;
&lt;p&gt;In this series of posts we will deep down into how to properly structure a monorepo, tools that can help us manage it and challenges that you and your team will face in the transition to a monorepo.&lt;/p&gt;
&lt;p&gt;Will the effort be worth it? Subscribe to &lt;a href=&#34;https://danielpecos.com/index.xml&#34;&gt;our feed&lt;/a&gt; to figure it out&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Image credit: Erzhan Torokulov (&lt;a href=&#34;https://medium.com/@erzhtor/javascript-monorepo-with-lerna-5729d6242302&#34;&gt;https://medium.com/@erzhtor/javascript-monorepo-with-lerna-5729d6242302&lt;/a&gt;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>JCrete 2019</title>
      <link>https://danielpecos.com/2019/07/20/jcrete-2019/</link>
      <pubDate>Sat, 20 Jul 2019 22:57:27 +0200</pubDate>
      
      <guid>https://danielpecos.com/2019/07/20/jcrete-2019/</guid>
      
      <description>&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2019/07/JCrete-logo.png&#34; alt=&#34;JCrete 2019&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Amazing&lt;/strong&gt;. That&amp;rsquo;s the one word summary for this unconference.&lt;/p&gt;
&lt;p&gt;It wasn&amp;rsquo;t my first time in an &lt;a href=&#34;https://en.wikipedia.org/wiki/Unconference&#34;&gt;unconference&lt;/a&gt;, although the previous ones were slightly smaller and my experience then wasn&amp;rsquo;t that satisfactory as the one I&amp;rsquo;ve had in JCrete. And I have just discovered the key ingredient for a successful unconference: &lt;strong&gt;the people&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2019/07/D_cA4AqXoAAc-2S.jpg&#34; alt=&#34;Assistants&#34;&gt;&lt;/p&gt;
&lt;p&gt;Because is not only about the technical content of the sessions (which was quite high, don&amp;rsquo;t get me wrong), but about those interactions during and after the sessions, happening without any planification, as natural as a conversation can be. Probably the most interesting ones are, in fact, those unexpected gatherings happening at random places, like at the beach, or during breakfast, or while trekking to Balos beach, or while snokerkeling in a beautiful location of the island.&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s because of the people willing to share, discuss and talk about almost any subject, while being open and friendly to opposite ideas.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2019/07/D_vZodYXkAEyOEW.jpg&#34; alt=&#34;Session proposals&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m really glad that I got the chance to participate in JCrete 2019 (even proposing, as you should do in any unconference, an small session about &lt;a href=&#34;https://en.wikipedia.org/wiki/FIRE_movement&#34;&gt;F.I.R.E&lt;/a&gt;, and I hope next year I&amp;rsquo;ll get the chance to hang out with all the awesome people I&amp;rsquo;ve met in the beautiful island of Crete.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2019/07/D_wdTPhXkAYgPp7.jpg&#34; alt=&#34;Assistants&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How to rotate your OpenPGP / GnuPG keys</title>
      <link>https://danielpecos.com/2019/03/30/how-to-rotate-your-openpgp-gnupg-keys/</link>
      <pubDate>Sat, 30 Mar 2019 18:05:18 +0100</pubDate>
      
      <guid>https://danielpecos.com/2019/03/30/how-to-rotate-your-openpgp-gnupg-keys/</guid>
      
      <description>










&lt;img style=&#34;max-width: 100%; width: auto; height: auto;&#34; src=&#34;https://danielpecos.com/2019/03/30/how-to-rotate-your-openpgp-gnupg-keys/assets/gnupg_logo.svg_hu0714f6eae76f09a9656d1d23cfb20209_32095_500x0_resize_q75_h2_lanczos_3.webp&#34; width=&#34;500&#34; height=&#34;205&#34; alt=&#34;GnuPG&#34; class=&#34;aligncenter&#34; /&gt;

&lt;p&gt;It&amp;rsquo;s been a while (well, years) since I rotated my GPG keys, and to be honest, now that I know better how to handle a GPG key pair in order to avoid master key rotation, I think it&amp;rsquo;s the time to get a new pair.&lt;/p&gt;
&lt;p&gt;This tutorial will show you the steps I followed with explanations on what we are achieving in every step.&lt;/p&gt;
&lt;h2 id=&#34;environment&#34;&gt;Environment&lt;/h2&gt;
&lt;p&gt;This is the GnuPG version used in this tutorial (if you are using a different version, probably not every command would work the same, but I wouldn&amp;rsquo;t expect for the concept to change that much):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --version
gpg (GnuPG) 2.2.14
libgcrypt 1.8.4
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;https://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /Users/dpecos/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;rsquo;re using MacOSX, you will need this application to handle password prompts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;brew install pinentry-mac
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;create-a-new-key-pair&#34;&gt;Create a new key pair&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start generating the new key pair, without expiration date (we will be able to set one if needed in the future):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --full-generate-key
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
  (1) RSA and RSA (default)
  (2) DSA and Elgamal
  (3) DSA (sign only)
  (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
        0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks
      &amp;lt;n&amp;gt;m = key expires in n months
      &amp;lt;n&amp;gt;y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Daniel Pecos Martinez
Email address: me@danielpecos.com
Comment:
You selected this USER-ID:
    &amp;quot;Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;&amp;quot;

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key E881015C8A55678B marked as ultimately trusted
gpg: revocation certificate stored as &#39;/Users/dpecos/.gnupg/openpgp-revocs.d/31EFB482E969EB74399DBBC5E881015C8A55678B.rev&#39;
public and secret key created and signed.

pub   rsa4096 2019-03-27 [SC]
      31EFB482E969EB74399DBBC5E881015C8A55678B
uid                      Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
sub   rsa4096 2019-03-27 [E]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We got the key ID &lt;code&gt;31EFB482E969EB74399DBBC5E881015C8A55678B&lt;/code&gt;, which we&amp;rsquo;ll be using to reference the key whenever needed (like editing the key, adding signatures, &amp;hellip;).&lt;/p&gt;
&lt;p&gt;Note that a revocation certificate has already been created, so we don&amp;rsquo;t need to create a new one if we don&amp;rsquo;t want:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gpg: revocation certificate stored as &#39;/Users/dpecos/.gnupg/openpgp-revocs.d/31EFB482E969EB74399DBBC5E881015C8A55678B.rev&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;add-uids&#34;&gt;Add UIDs&lt;/h3&gt;
&lt;p&gt;Now let&amp;rsquo;s add any extra ID that we would want to use to the key pair. This step is optional and should be repeated as many times as needed. In my case I&amp;rsquo;d like to add an extra UID:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

gpg&amp;gt; adduid
Real name: Daniel Pecos Martinez
Email address: dani@dplabs.io
Comment:
You selected this USER-ID:
    &amp;quot;Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;&amp;quot;

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2). Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; uid 2

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)* Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; trust
sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)* Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

Please decide how far you trust this user to correctly verify other users&#39; keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don&#39;t know or won&#39;t say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)* Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have multiple UIDs within the same key, it&amp;rsquo;s important to check that the primary UID is properly set. If not, we have to change it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1). Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

gpg&amp;gt; uid 2

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1). Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
[ultimate] (2)* Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

gpg&amp;gt; primary

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
[ultimate] (2)* Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

gpg&amp;gt; save
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;create-subkeys&#34;&gt;Create subkeys&lt;/h3&gt;
&lt;p&gt;At this moment, we have a key pair generated and containing the UIDs we want to use, and we could be good to go, but, what would happen if we lost the laptop where this key pair is stored? We would have to revoke them and generate a new key pair, loosing all its signatures and the trust gathered with time.&lt;/p&gt;
&lt;p&gt;In order to avoid this situation is a common (and good) practice to generate what is known as &lt;strong&gt;laptop keys&lt;/strong&gt;. These keys are &lt;em&gt;disposable&lt;/em&gt; keys that are linked to your master key and that you would copy to the device where you would use them as usual, keeping the master key safe offline.&lt;/p&gt;
&lt;p&gt;If by any eventuality you&amp;rsquo;d loose access to those &lt;strong&gt;laptop keys&lt;/strong&gt; you could easily revoke them with the master key and generate a new set to replace them, but the master key pair (and thus your PGP/GPG ID) would remain the same.&lt;/p&gt;
&lt;p&gt;Sounds good? Let&amp;rsquo;s generate a new subkey for signing. If you&amp;rsquo;ve paid attention to the process you&amp;rsquo;d have notice that a subkey for encrypting was already generated for your master key (&lt;code&gt;ssb rsa4096/89BF354A17A61CC5&lt;/code&gt; with &lt;code&gt;usage: E&lt;/code&gt;), so no need to generate an extra key for that, as we already got one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; addkey
Please select what kind of key you want:
  (3) DSA (sign only)
  (4) RSA (sign only)
  (5) Elgamal (encrypt only)
  (6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
        0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks
      &amp;lt;n&amp;gt;m = key expires in n months
      &amp;lt;n&amp;gt;y = key expires in n years
Key is valid for? (0) 5y
Key expires at Mon Mar 25 15:42:11 2024 CET
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that I&amp;rsquo;ve set up an expire date for this subkey, as I want to rotate them from time to time. We would probably also want to set an expire date for the previously created encryption subkey:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; key 1

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb* rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: never       usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
        0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks
      &amp;lt;n&amp;gt;m = key expires in n months
      &amp;lt;n&amp;gt;y = key expires in n years
Key is valid for? (0) 5y
Key expires at Mon Mar 25 15:44:22 2024 CET
Is this correct? (y/N) y

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb* rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; save
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;rotate-your-previous-key-pair&#34;&gt;Rotate your previous key pair&lt;/h2&gt;
&lt;p&gt;This is the tricky and painful part of the process, as you are effectively decomissioning your previous PGP/GPG ID, loosing the created web of trust around it.&lt;/p&gt;
&lt;p&gt;In order to let the world know that your new key pair actually belongs to you without having to meet in person again, the standard procedure is to sign the new key with the old one and the other way around, establishing a hard trust link between them (this action could not have been done without access to the old secret key, so as far as anyone can tell, this two-way signature could only have been done by you).&lt;/p&gt;
&lt;h3 id=&#34;signing-the-new-and-old-public-keys&#34;&gt;Signing the new and old public keys&lt;/h3&gt;
&lt;p&gt;First of all, let&amp;rsquo;s check that both secret keys are available in our keyring:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --list-secret-keys
/Users/dpecos/.gnupg/pubring.kbx
--------------------------------
sec   dsa1024 2002-11-11 [SC]
      F6D13162F2BEF65838F6C8E6BF3B5AFCD4480E60
uid           [  full  ] Daniel Pecos Martinez
uid           [  full  ] Daniel Pecos Martinez &amp;lt;dpecos@gmail.com&amp;gt;
uid           [  full  ] Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
ssb   elg4096 2009-11-19 [E]

sec   rsa4096 2019-03-27 [SC]
      31EFB482E969EB74399DBBC5E881015C8A55678B
uid           [ultimate] Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
uid           [ultimate] Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
ssb   rsa4096 2019-03-27 [E] [expires: 2024-03-25]
ssb   rsa4096 2019-03-27 [S] [expires: 2024-03-25]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now in order to establish trust between the new and the old keys, we have to sign each other. First let&amp;rsquo;s sign the new key with old one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --default-key F6D13162F2BEF65838F6C8E6BF3B5AFCD4480E60 --sign-key 31EFB482E969EB74399DBBC5E881015C8A55678B

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

Really sign all user IDs? (y/N) y
gpg: using &amp;quot;F6D13162F2BEF65838F6C8E6BF3B5AFCD4480E60&amp;quot; as default secret key for signing

sec  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
Primary key fingerprint: 31EF B482 E969 EB74 399D  BBC5 E881 015C 8A55 678B

    Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
    Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

Are you sure that you want to sign this key with your
key &amp;quot;Daniel Pecos Martinez&amp;quot; (BF3B5AFCD4480E60)

Really sign? (y/N) y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then the other way around:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --default-key 31EFB482E969EB74399DBBC5E881015C8A55678B --sign-key F6D13162F2BEF65838F6C8E6BF3B5AFCD4480E60

gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: depth: 1  valid:   1  signed:   0  trust: 1-, 0q, 0n, 0m, 0f, 0u
sec  dsa1024/BF3B5AFCD4480E60
    created: 2002-11-11  expires: never       usage: SC
    trust: unknown       validity: full
The following key was revoked on 2009-11-19 by DSA key BF3B5AFCD4480E60 Daniel Pecos Martinez
ssb  elg2048/3FBD37D1977AB8A4
    created: 2002-11-11  revoked: 2009-11-19  usage: E
ssb  elg4096/0DE841998B4ADD00
    created: 2009-11-19  expires: never       usage: E
[  full  ] (1). Daniel Pecos Martinez
[  full  ] (2)  Daniel Pecos Martinez &amp;lt;dpecos@gmail.com&amp;gt;
[ revoked] (3)  Daniel Pecos Martinez &amp;lt;dani@netpecos.org&amp;gt;
[  full  ] (4)  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

Really sign all user IDs? (y/N) y
gpg: using &amp;quot;31EFB482E969EB74399DBBC5E881015C8A55678B&amp;quot; as default secret key for signing
User ID &amp;quot;Daniel Pecos Martinez &amp;lt;dani@netpecos.org&amp;gt;&amp;quot; is revoked.  Unable to sign.

sec  dsa1024/BF3B5AFCD4480E60
    created: 2002-11-11  expires: never       usage: SC
    trust: unknown       validity: full
Primary key fingerprint: F6D1 3162 F2BE F658 38F6  C8E6 BF3B 5AFC D448 0E60

    Daniel Pecos Martinez
    Daniel Pecos Martinez &amp;lt;dpecos@gmail.com&amp;gt;
    Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

Are you sure that you want to sign this key with your
key &amp;quot;Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;&amp;quot; (E881015C8A55678B)

Really sign? (y/N) y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s check that the new key has been properly signed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --list-sigs E881015C8A55678B
pub   rsa4096 2019-03-27 [SC]
      31EFB482E969EB74399DBBC5E881015C8A55678B
uid           [ultimate] Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
sig 3        E881015C8A55678B 2019-03-27  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
sig          BF3B5AFCD4480E60 2019-03-27  Daniel Pecos Martinez
uid           [ultimate] Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
sig 3        E881015C8A55678B 2019-03-27  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
sig          BF3B5AFCD4480E60 2019-03-27  Daniel Pecos Martinez
sub   rsa4096 2019-03-27 [E] [expires: 2024-03-25]
sig          E881015C8A55678B 2019-03-27  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
sub   rsa4096 2019-03-27 [S] [expires: 2024-03-25]
sig          E881015C8A55678B 2019-03-27  Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The lines containing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sig          BF3B5AFCD4480E60 2019-03-27  Daniel Pecos Martinez
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;reflect a signature on a UID. &lt;code&gt;BF3B5AFCD4480E60&lt;/code&gt; is the sort ID of my old key.&lt;/p&gt;
&lt;h3 id=&#34;revoke-old-key-pair&#34;&gt;Revoke old key pair&lt;/h3&gt;
&lt;p&gt;Now we have to effectively decomission the old key pair. For that, we have to generate a revocation certificate for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg -a --gen-revoke BF3B5AFCD4480E60 &amp;gt; BF3B5AFCD4480E60.rev

sec  dsa1024/BF3B5AFCD4480E60 2002-11-11 Daniel Pecos Martinez

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 2
Enter an optional description; end it with an empty line:
&amp;gt; Superseeded by E881015C8A55678B
&amp;gt;
Reason for revocation: Key is superseded
Superseeded by E881015C8A55678B
Is this okay? (y/N) y
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then import it to our keyring to actually revoke the key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --import BF3B5AFCD4480E60.rev
gpg: key BF3B5AFCD4480E60: &amp;quot;Daniel Pecos Martinez&amp;quot; revocation certificate imported
gpg: Total number processed: 1
gpg:    new key revocations: 1
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u

$ gpg --list-secret-keys
/Users/dpecos/.gnupg/pubring.kbx
--------------------------------
sec   dsa1024 2002-11-11 [SC] [revoked: 2019-03-27]
      F6D13162F2BEF65838F6C8E6BF3B5AFCD4480E60
uid           [ revoked] Daniel Pecos Martinez
uid           [ revoked] Daniel Pecos Martinez &amp;lt;dpecos@gmail.com&amp;gt;
uid           [ revoked] Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

sec   rsa4096 2019-03-27 [SC]
      31EFB482E969EB74399DBBC5E881015C8A55678B
uid           [ultimate] Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
uid           [ultimate] Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
ssb   rsa4096 2019-03-27 [E] [expires: 2024-03-25]
ssb   rsa4096 2019-03-27 [S] [expires: 2024-03-25]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we&amp;rsquo;re done! Next step is to publish our changes to the world.&lt;/p&gt;
&lt;h3 id=&#34;publish-to-pgp-servers&#34;&gt;Publish to PGP servers&lt;/h3&gt;
&lt;p&gt;We have to publish our new key pair and also the revoked old key pair. I&amp;rsquo;ve published them to two separate PGP servers in order to speed up the spreading of the changes, but that&amp;rsquo;s not strictly necessary as the key servers sync between them from time to time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --keyserver hkp://pgp.mit.edu --send-keys BF3B5AFCD4480E60 E881015C8A55678B
gpg: sending key BF3B5AFCD4480E60 to hkp://pgp.mit.edu
gpg: sending key E881015C8A55678B to hkp://pgp.mit.edu

$ gpg --keyserver hkp://pgp.surfnet.nl --send-keys BF3B5AFCD4480E60 E881015C8A55678B
gpg: sending key BF3B5AFCD4480E60 to hkp://pgp.surfnet.nl
gpg: sending key E881015C8A55678B to hkp://pgp.surfnet.nl
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;publish-to-keybase&#34;&gt;Publish to Keybase&lt;/h3&gt;
&lt;p&gt;If you are a Keybase user, you should also publish your new key there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ keybase pgp select
You are selecting a PGP key from your local GnuPG keychain, and
will publish a statement signed with this key to make it part of
your Keybase.io identity.

Note that GnuPG will prompt you to perform this signature.

You can also import the secret key to *local*, *encrypted* Keybase
keyring, enabling decryption and signing with the Keybase client.
To do that, use &amp;quot;--import&amp;quot; flag.

Learn more: keybase pgp help select

#    Algo    Key Id             Created   UserId
=    ====    ======             =======   ======
1    4096R   E881015C8A55678B             Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;, Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
Choose a key: 1
▶ INFO Generated new PGP key:
▶ INFO   user: Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
▶ INFO   4096-bit RSA key, ID E881015C8A55678B, created 2019-03-27
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;backup-everything&#34;&gt;Backup everything&lt;/h2&gt;
&lt;p&gt;Last step is to make a backup of our new key pair (and the old one if we didn&amp;rsquo;t already). We will encrypt the private key files before storing them, adding an extra layer of security in case these files are uploaded to a cloud storage or somewhere else not 100% under our control.&lt;/p&gt;
&lt;p&gt;First the old key pair (public &amp;amp; secret):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --export --armor BF3B5AFCD4480E60&amp;gt; BF3B5AFCD4480E60.pub
$ gpg --export-secret-keys --armor BF3B5AFCD4480E60 | gpg --symmetric --armor &amp;gt; BF3B5AFCD4480E60.sec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Latest command will ask you for a password 3 times: the first two correspond to the symmetric encryption and the password has to be exactly the same the first two times; third time corresponds to the key pair&amp;rsquo;s password (the one you set up while creating the new pair).&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s backup the new key pair (also public &amp;amp; secret):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --export --armor E881015C8A55678B &amp;gt; E881015C8A55678B.pub
$ gpg --export-secret-keys --armor E881015C8A55678B | gpg --symmetric --armor &amp;gt; E881015C8A55678B.sec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And also the revocation certificate that was generate during key creation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat ~/.gnupg/openpgp-revocs.d/31EFB482E969EB74399DBBC5E881015C8A55678B.rev |  gpg --symmetric --armor &amp;gt; E881015C8A55678B.rev
$ rm cat ~/.gnupg/openpgp-revocs.d/31EFB482E969EB74399DBBC5E881015C8A55678B.rev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When exporting and encrypting the secret keys, we must use a different password for the backup encryption than the key&amp;rsquo;s password, otherwise this extra layer won&amp;rsquo;t provide any security in case of a 3rd party trying to break the password.&lt;/p&gt;
&lt;h2 id=&#34;store-your-master-key-pair-offline-and-remove-it-from-your-keyring---laptop-keys&#34;&gt;Store your master key pair offline and remove it from your keyring - Laptop keys&lt;/h2&gt;
&lt;p&gt;Now that we have everything backed up, we should remove our master key from the day-to-day device and use only the previously generated subkeys. The process is a little bit tricky, but not really hard. First of all, let&amp;rsquo;s export the subkeys to a (encrypted) file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --export-secret-subkeys --armor E881015C8A55678B | gpg --symmetric --armor &amp;gt; E881015C8A55678B-subkeys.sec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we delete the master key from our keyring (public &amp;amp; private keys):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --delete-secret-key E881015C8A55678B

gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


sec  rsa4096/E881015C8A55678B 2019-03-27 Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y

$ gpg --delete-key E881015C8A55678B

gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


pub  rsa4096/E881015C8A55678B 2019-03-27 Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;

Delete this key from the keyring? (y/N) y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally we import back just the subkeys. First the secret part:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat E881015C8A55678B-subkeys.sec | gpg --decrypt | gpg --import
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
gpg: key E881015C8A55678B: public key &amp;quot;Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;&amp;quot; imported
gpg: To migrate &#39;secring.gpg&#39;, with each smartcard, run: gpg --card-status
gpg: key E881015C8A55678B: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
gpg: no ultimately trusted keys found
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then the public:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat E881015C8A55678B.pub| gpg --import
gpg: key E881015C8A55678B: &amp;quot;Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;&amp;quot; not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly we have to reset trust to &lt;code&gt;ultimate&lt;/code&gt; for the imported subkeys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret subkeys are available.

pub  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: unknown       validity: unknown
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ unknown] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

gpg&amp;gt; trust
pub  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: unknown       validity: unknown
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ unknown] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;

Please decide how far you trust this user to correctly verify other users&#39; keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don&#39;t know or won&#39;t say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: unknown
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ unknown] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ unknown] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg&amp;gt; save
Key not changed so no update needed.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s double check that we don&amp;rsquo;t have the master key available in our keyring, just the subkeys. If we try to edit the master key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret subkeys are available.

pub  rsa4096/E881015C8A55678B
    created: 2019-03-27  expires: never       usage: SC
    trust: ultimate      validity: ultimate
ssb  rsa4096/89BF354A17A61CC5
    created: 2019-03-27  expires: 2024-03-25  usage: E
ssb  rsa4096/665E29633F97EF11
    created: 2019-03-27  expires: 2024-03-25  usage: S
[ultimate] (1). Daniel Pecos Martinez &amp;lt;me@danielpecos.com&amp;gt;
[ultimate] (2)  Daniel Pecos Martinez &amp;lt;dani@dplabs.io&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ll see the message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Secret subkeys are available.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Meaning that we won&amp;rsquo;t be able to create new subkeys, revoke, &amp;hellip;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gpg&amp;gt; addkey
Need the secret key to do this.

$ gpg --gen-revoke 31EFB482E969EB74399DBBC5E881015C8A55678B
gpg: secret key &amp;quot;31EFB482E969EB74399DBBC5E881015C8A55678B&amp;quot; not found: No secret key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For those critical operations we will have to import the backed up master key. For business as usual operations, subkeys are good enough, and if we loose them, we can restore the master key, revoke the subkeys and generate a new set, without our changing PGP/GPG ID and thus loosing the established trust.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;p&gt;This tutorial is based on information gathered from the following links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sungo.wtf/2016/11/23/gpg-strong-keys-rotation-and-keybase.html&#34;&gt;https://sungo.wtf/2016/11/23/gpg-strong-keys-rotation-and-keybase.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://riseup.net/en/security/message-security/openpgp/best-practices&#34;&gt;https://riseup.net/en/security/message-security/openpgp/best-practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://alexcabal.com/creating-the-perfect-gpg-keypair&#34;&gt;https://alexcabal.com/creating-the-perfect-gpg-keypair&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.debian.org/Subkeys?action=show&amp;amp;redirect=subkeys&#34;&gt;https://wiki.debian.org/Subkeys?action=show&amp;amp;redirect=subkeys&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Demistifying blockchain - Part 2</title>
      <link>https://danielpecos.com/2018/11/15/demistifying-blockchain-part-2/</link>
      <pubDate>Thu, 15 Nov 2018 23:10:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2018/11/15/demistifying-blockchain-part-2/</guid>
      
      <description>&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2018/11/15/blockchain-part2.jpg&#34; alt=&#34;Demistifying blockchain - Part 2&#34;&gt;&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;../demistifying-blockchain-part-1&#34;&gt;the previous post&lt;/a&gt; we explained from a theoretical point of view how a block chain works. In this post we will get down to work and will implement a working blockchain in Go.&lt;/p&gt;
&lt;p&gt;If you &lt;a href=&#34;../demistifying-blockchain-part-1&#34;&gt;haven&amp;rsquo;t read it yet&lt;/a&gt;, we recommend you to do it now before continuing. It&amp;rsquo;ll provide you the basic concepts needed to understand the examples below.&lt;/p&gt;
&lt;p&gt;(You can find the complete example in this Github repository: &lt;a href=&#34;https://github.com/dplabs/demistifying-blockchain&#34;&gt;https://github.com/dplabs/demistifying-blockchain&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;First of all, let&amp;rsquo;s define what a block looks like for us:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;type&lt;/span&gt; Block &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Number &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Timestamp time&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Data &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Nonce &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Hash &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Previous &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;center&gt;
https://github.com/dplabs/demistifying-blockchain/blob/master/block.go#L14
&lt;/center&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Number&lt;/code&gt;: is used to identify a block in the chain. In our case it will be the &lt;strong&gt;position this block has in the chain&lt;/strong&gt;. Note that the attribute is just used to have a user friendly reference to the block, not to actually link blocks between them.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Timestamp&lt;/code&gt;: when this block was created.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Data&lt;/code&gt;: the actual information this block contains.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Nonce&lt;/code&gt;: field used to for the hash of the block &lt;em&gt;to meet certain rules&lt;/em&gt;. More on this later.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Hash&lt;/code&gt;: the result of applying a &lt;a href=&#34;https://en.wikipedia.org/wiki/Cryptographic_hash_function&#34;&gt;cryptographic hash function&lt;/a&gt; to this block. It has to take into account all the fields in the block (but &lt;code&gt;Hash&lt;/code&gt; itself) in order to be able to detect tampering attempts to its content.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Previous&lt;/code&gt;: hash of the previous block in the chain. &lt;strong&gt;This is the actual field linking blocks in the chain&lt;/strong&gt; (and in our example, also the position in the array of blocks).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now let&amp;rsquo;s define an structure that will help us handle the block chain:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;type&lt;/span&gt; BlockChain &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	Blocks    &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;Block
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	Challenge &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	LastBlock &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;Block
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;center&gt;
https://github.com/dplabs/demistifying-blockchain/blob/master/blockchain.go#L8
&lt;/center&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Blocks&lt;/code&gt;: is the actual collection of blocks. Contiguous blocks are stored in contiguous positions in the array, although this is just an implementation detail, because the actual linkage should be done referencing their hashes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Challenge&lt;/code&gt;: represents the level of difficulty the resulting hash has to meet in order to be considered valid. In our case we will say a block has is valid if it starts with the &lt;code&gt;Challenge&lt;/code&gt; substring. The longer this challenge is, the hardest and more time consuming &lt;strong&gt;mining&lt;/strong&gt; a block would be.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LastBlock&lt;/code&gt;: is a pointer to the latest block added to the chain, used to make computation easier.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So far we have presented two quite interesting fields: &lt;code&gt;Nonce&lt;/code&gt; for a &lt;code&gt;Block&lt;/code&gt;, and &lt;code&gt;Challenge&lt;/code&gt; for a &lt;code&gt;BlockChain&lt;/code&gt;, and the deserve a more in depth explanation. But first let&amp;rsquo;s talk about what a valid hash or signature for a block is, and for that we have to talk a little bit about &lt;em&gt;Bitcoin&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When Bitcoin was designed, in order to achieve value as a coin, the concept of &lt;strong&gt;scarcity&lt;/strong&gt; had to be taken into consideration: if a resource is easy to get, probably it won&amp;rsquo;t be valuable at all. The more difficult or unique the resource is, the more value people will give it. But being a &lt;em&gt;digital currency&lt;/em&gt;, this was a not easy to solve challenge.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s how the concept of &lt;strong&gt;mining a block&lt;/strong&gt; came into the picture: same way as gold is extracted from the ground (with lots of effort), a &lt;em&gt;block&lt;/em&gt; has to require a lot of (artificial) effort to be added to the chain. Whomever manages to first mine a block, gets rewarded with &lt;strong&gt;coins&lt;/strong&gt; in exchange for his effort.&lt;/p&gt;
&lt;p&gt;In Blockchain, mining a block consist on calculating its hash, as we have explained. But usually hash functions are quite fast, so in order to make it harder (and thus create scarcity), a &lt;em&gt;valid hash&lt;/em&gt; has to comply with a set of rules. In our implementation, the rule we&amp;rsquo;ve chosen is that the resulting hash has to begin with the &lt;code&gt;Challenge&lt;/code&gt; substring defined while initializing the chain.&lt;/p&gt;
&lt;p&gt;So in order to mine a block in our chain, the resulting signature of a block has to start with a certain string (in our example we&amp;rsquo;ve chosen it to be &lt;code&gt;&#39;0000&#39;&lt;/code&gt;). So the algorithm for mining a block would first calculate current hash of the block and if the results fits the criteria of a valid hash, then we could add a successfully mined block to the chain. Otherwise we would have to change something in the block and repeat the process, and this is important, because if we don&amp;rsquo;t change anything in the block, the resulting hash will be the same. And thats what &lt;code&gt;Nonce&lt;/code&gt; field is for. We will increment this number on every attempt to get a valid hash, until when eventually, we will get a hash matching the criteria. That&amp;rsquo;s why the longer the &lt;code&gt;Challenge&lt;/code&gt; string is, the harder to mine a block will be.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;block &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;Block&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;Mine&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;challenge &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#2838b0;font-style:italic&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	fmt&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;Printf&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Mining block %d... &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Number&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	tsStart &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; time&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;Now&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Hash &lt;span style=&#34;color:#888&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Nonce &lt;span style=&#34;color:#888&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#2838b0&#34;&gt;for&lt;/span&gt; done &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#444;font-style:italic&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;!&lt;/span&gt;done&lt;span style=&#34;color:#888&#34;&gt;;&lt;/span&gt; done &lt;span style=&#34;color:#888&#34;&gt;=&lt;/span&gt; strings&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;HasPrefix&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Hash&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; challenge&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Nonce &lt;span style=&#34;color:#888&#34;&gt;=&lt;/span&gt; block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Nonce &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#444&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Hash &lt;span style=&#34;color:#888&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#785840&#34;&gt;calculateHash&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;block&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	tsEnd &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; time&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;Now&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	elapsedTime &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; tsEnd&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;Sub&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;tsStart&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	p &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; message&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;NewPrinter&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;language&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;English&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	p&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;Printf&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#b83838&#34;&gt;&amp;#34;Valid hash found in %s! (hash: %s, nonce: %d)\n&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; elapsedTime&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#785840&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;(),&lt;/span&gt; block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Hash&lt;span style=&#34;color:#888&#34;&gt;,&lt;/span&gt; block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Nonce&lt;span style=&#34;color:#888&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#2838b0&#34;&gt;return&lt;/span&gt; block&lt;span style=&#34;color:#888&#34;&gt;.&lt;/span&gt;Hash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;center&gt;
https://github.com/dplabs/demistifying-blockchain/blob/master/block.go#L27
&lt;/center&gt;
&lt;p&gt;As you can see in the following execution of our demo, it takes between 10 and 30 seconds to find a valid hash (starting with &amp;lsquo;0000&amp;rsquo;) for every block. If you try this yourself, you will get different results as the timestamp of a block is taken into consideration for mining it (&lt;a href=&#34;https://github.com/dplabs/demistifying-blockchain/blob/master/block.go#L51)&#34;&gt;https://github.com/dplabs/demistifying-blockchain/blob/master/block.go#L51)&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ go run .
Blockchain initialized with challenge &amp;#39;0000&amp;#39;

Mining block 0... Valid hash found in 10.943824518s! (hash: 0000ociyEZOQk8ekRZ5VXcNJPLY=, nonce: 18,158,423)
Mining block 1... Valid hash found in 11.316462656s! (hash: 0000Dk0duKeCCHvDKuyFepXgUNc=, nonce: 15,208,609)
Mining block 2... Valid hash found in 28.805735271s! (hash: 0000O104QmKwfp2tVJ2JowVd9DI=, nonce: 37,840,116)

Resulting blockchain (in reversed order):

Block 2: {
   ts:          2018-11-10 15:17:40.602154 +0100 CET m=+22.260933223
   nonce:       37840116
   hash:        0000O104QmKwfp2tVJ2JowVd9DI=
   previous:    0000Dk0duKeCCHvDKuyFepXgUNc=
}

Block 1: {
   ts:          2018-11-10 15:17:29.285761 +0100 CET m=+10.944444407
   nonce:       15208609
   hash:        0000Dk0duKeCCHvDKuyFepXgUNc=
   previous:    0000ociyEZOQk8ekRZ5VXcNJPLY=
}

Block 0: {
   ts:          2018-11-10 15:17:18.341964 +0100 CET m=+0.000555870
   nonce:       18158423
   hash:        0000ociyEZOQk8ekRZ5VXcNJPLY=
   previous:
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We encourage you to play with this code. You can download from the repository and compile and execute it yourself: &lt;a href=&#34;https://github.com/dplabs/demistifying-blockchain&#34;&gt;https://github.com/dplabs/demistifying-blockchain&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the following and last post of this series, we will implement some benchmarks to analyze how much time it requires to mine a block based on the difficult we set.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Demistifying blockchain - Part 1</title>
      <link>https://danielpecos.com/2018/11/10/demistifying-blockchain-part-1/</link>
      <pubDate>Sat, 10 Nov 2018 16:30:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2018/11/10/demistifying-blockchain-part-1/</guid>
      
      <description>&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2018/11/10/blockchain-part1.jpg&#34; alt=&#34;Demistifying blockchain - Part 1&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Blockchain&#34;&gt;Blockchain&lt;/a&gt;&lt;/strong&gt; is one of those buzzwords everyone is listening nowadays, but what it really is?&lt;/p&gt;
&lt;p&gt;In this series of posts we will dig one general concepts about BlockChain and a little bit of its relation with BitCoin, as well as we will develop a simple blockchain in Go.&lt;/p&gt;
&lt;p&gt;To put it simple, and as its name states, it&amp;rsquo;s just a chain of blocks. The interesting detail is that is a &lt;em&gt;cryptographic chain&lt;/em&gt; providing some characteristics that make them really useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tamper-proof&lt;/li&gt;
&lt;li&gt;Distributed&lt;/li&gt;
&lt;li&gt;Decentralized&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We say a blockchain is tamper-proof because once a block has been added to the chain, nobody can modify it without also modifying its &lt;strong&gt;signature&lt;/strong&gt; or &lt;strong&gt;cryptographic hash&lt;/strong&gt;. But what if the attacker would also modify the signature to make it match its new content? A block stores as part of its data, the signature of the previous block in the chain (and that&amp;rsquo;s why it&amp;rsquo;s a chain), so if an attacker would try to replace a block in the chain (even using the correct cryptographic signature), would have to cascade the changes across all blocks from that one on until the end of the chain.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2018/11/10/blockchain-diagram.png&#34; alt=&#34;Blockchain diagram&#34; title=&#34;Blockchain diagram&#34;&gt;&lt;/p&gt;
&lt;p&gt;Even though, that&amp;rsquo;s a plausible attack scenario. How can BlockChain avoid it? Making the chain distributed and decentralized, so an attacker trying to modify the chain, would have to modify all instances ot the chain distributed across the world. And it has to be done at once to more than 50% of the nodes in the network, because being a decentralized network means that there is no &lt;strong&gt;golden copy&lt;/strong&gt; of the chain. All instances in the network are equal.&lt;/p&gt;
&lt;p&gt;This also means that whenever someone tries to attach a new node to the end of the chain, the network has to agree to that action. Once the network has &lt;strong&gt;acknowledged or achieved consensus&lt;/strong&gt;, the new block is considered permanently and successfully added to the chain.&lt;/p&gt;
&lt;p&gt;These characteristics are what make the Blockchain a &lt;strong&gt;secure, read-only and distributed database&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;BlockChain is in the bare-bones of &lt;strong&gt;Bitcoin&lt;/strong&gt;, as the cryptocurrency uses a blockchain implementation as the &lt;strong&gt;public ledger system&lt;/strong&gt;, and thus since the boom of cryptocurrencies, this type of databases have caught the interest of more and more researchers and developers.&lt;/p&gt;
&lt;p&gt;In the following video you will find a more detailed explanation of what we want to implement in this series of posts. If the concept of what a block chain is is still not clear, please have a look to the video before going further in the series:&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/_160oMzblY8&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;In the following post we will start implementing our own blockchain in &lt;strong&gt;Go&lt;/strong&gt;, as well as going more in detail into the characteristics of &lt;strong&gt;block mining&lt;/strong&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Web Mining: is that bad?</title>
      <link>https://danielpecos.com/2017/10/25/web-mining-is-that-bad/</link>
      <pubDate>Wed, 25 Oct 2017 09:20:46 +0100</pubDate>
      
      <guid>https://danielpecos.com/2017/10/25/web-mining-is-that-bad/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;size-medium alignleft&#34; src=&#34;https://danielpecos.com/assets/2017/10/cryptocurrency-mining.jpeg&#34; alt=&#34;Cryptocurrency Mining&#34; width=&#34;300&#34; height=&#34;218&#34; /&gt;There has been a lot of noise around &lt;a href=&#34;https://en.wikipedia.org/wiki/Monero_(cryptocurrency)&#34;&gt;Monero&lt;/a&gt; and &lt;a href=&#34;https://coinhive.com/&#34;&gt;Coinhive&lt;/a&gt; lately, or web mining in general, and don’t quite agree with most of what I’m hearing.&lt;/p&gt;
&lt;p&gt;It all started with &lt;a href=&#34;https://thepiratebay.org/&#34;&gt;The Pirate Bay&lt;/a&gt; adding a web mining script to their site, so whenever you’d visit them, your CPU would be used to mine some Monero for them. That was made without any notice to the user, just “stealing” their power. That was probably the best ad Coinhive (which is the service hosting the mining script and providing the required infrastructure to mine Monero) could get, as it appeared all over the news (even some local newspaper got noticed). And, as it was to expect, plenty of sites added the same piece of script so they could also benefit from their users base.&lt;/p&gt;
&lt;p&gt;But something really interesting followed to this: most ad-block extensions started to block Coinhive, frustrating all the efforts of these people getting reach.&lt;/p&gt;
&lt;p&gt;Let’s stop for a second and analyze what happened:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Website owners use their users’ computers to mine (earn)  some (crypto-) money.&lt;/li&gt;
&lt;li&gt;Ad-blockers think that’s an abuse and not legitimate and start blocking that mining.&lt;/li&gt;
&lt;li&gt;Lots of news about how evil these people are written all over the internet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Really? So I, as a content creator, &lt;strong&gt;willingly giving that content to the community&lt;/strong&gt;, am an evil person for &lt;strong&gt;trying to monetize that content / time&lt;/strong&gt; with the cost of the electricity the user spends while being on my site. Because everything on Internet must be free of cost, and those evil people trying, not to live from it, but just to get a little money for their time, should be ashamed of even trying.&lt;/p&gt;
&lt;img class=&#34;size-medium alignright&#34; src=&#34;https://danielpecos.com/assets/2017/10/miner-blockers.png&#34; alt=&#34;Mining Blockers&#34; width=&#34;300&#34; height=&#34;188&#34; /&gt;
&lt;p&gt;Well, a similar thing happened with ads, and when sites started abusing of them, making the user experience a pain, is when ad blockers started flourishing, and well-behaved content creators getting their incomes cut. And the same should happen to those who mine under the hood, without the user approval, or those who mine using too much CPU time, making user’s computer unusable.&lt;/p&gt;
&lt;p&gt;But we have not given yet the chance to make of web mining a legitimate way to monetize content. And why? Probably not because you’re abusing your users CPU or because users are not aware, &lt;strong&gt;but because you’re making money without taking into account Adsense or other gigantic ad platforms that could run into serious problems if this becomes a trend.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Why otherwise would &lt;a href=&#34;https://www.bleepingcomputer.com/news/google/google-chrome-may-add-a-permission-to-stop-in-browser-cryptocurrency-miners/&#34;&gt;Chrome’s team have worried so much and so fast&lt;/a&gt; about this, proposing even the &lt;a href=&#34;https://bugs.chromium.org/p/chromium/issues/detail?id=766068#c13&#34;&gt;creation of a throttle down inside the browser itself&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I don’t think this recent noise is all about mining itself but about those ad platforms losing their control over Internet content monetization&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: as you would probably have noticed when loaded this post, a popup appeared asking for your permission to mine using your CPU. It’s totally up to you to decide if should get some of your time or not.&lt;/em&gt;&lt;/p&gt;
&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2017/10/Screenshot_20171025_111416.png&#34; alt=&#34;Coinhive&#34; width=&#34;274&#34; height=&#34;300&#34; /&gt;
</description>
    </item>
    
    <item>
      <title>REST API with Node.js and Swagger</title>
      <link>https://danielpecos.com/2017/09/06/rest-api-with-node-js-and-swagger/</link>
      <pubDate>Tue, 05 Sep 2017 22:07:29 +0100</pubDate>
      
      <guid>https://danielpecos.com/2017/09/06/rest-api-with-node-js-and-swagger/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;size-fp-small aligncenter&#34; src=&#34;https://danielpecos.com/assets/2017/09/swaggerfornodejs.jpg&#34; alt=&#34;Swagger for Node.js&#34; width=&#34;640&#34; height=&#34;296&#34; /&gt;In this tutorial I&amp;rsquo;ll show how to piece together the required NPM modules to build a REST API in Node.js with proper Swagger documentation. We&amp;rsquo;re going to use Express as the HTTP framework, and the Swagger documentation will be written as inline comments within the code, as close as possible to the handling endpoint or models that will implement the contract, so it will be harder for them to eventually diverge.&lt;/p&gt;
&lt;p&gt;First of all, these are the main modules we are going to use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;swagger-jsdoc&lt;/strong&gt; to extract the documentation from the comments in the source code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;swagger-ui-express&lt;/strong&gt; to build on-the-fly an HTML version of the documentation (which will allow us also to live test it)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;swagger-model-validator&lt;/strong&gt; to check that the input &amp;amp; outputs of the request match the models defined for the endpoints&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s start with the handlers for the REST endpoints:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// api/controllers/stocks.js

router.get(&amp;#39;/&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.retrieveAll()
  res.send(response)
})

router.get(&amp;#39;/:id&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.retrieve(parseInt(req.params.id, 10))
  res.send(response)
})

router.put(&amp;#39;/:id&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.update(parseInt(req.params.id, 10), req.body.lastUpdate)
  res.send(response)
})

router.post(&amp;#39;/&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.create(req.body)
  res.send(response)
})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nothing especial hear, just plain Express handlers, using GET, PUT and POST HTTP verbs.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s write the Swagger documentation as JSON documents within JS multiline comments:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// api/models/stock-model.js

/**
 * @swagger
 * definitions:
 *   Stock:
 *     type: object
 *     required:
 *       - id
 *       - name
 *       - currentPrice
 *       - lastUpdate
 *     properties:
 *       id:
 *         type: number
 *       name:
 *         type: string
 *       currentPrice:
 *         type: number
 *       lastUpdate:
 *         type: number
 *   Stocks:
 *     type: array
 *     items:
 *       $ref &amp;#39;#definitions/Stock&amp;#39;
 */
export default class Stock {
  constructor (id, name, currentPrice, lastUpdate) {
    this.id = id
    this.name = name
    this.currentPrice = currentPrice
    this.lastUpdate = lastUpdate
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// api/controllers/stocks.js

/**
 * @swagger
 * /stocks:
 *   get:
 *     description: Retrieve the full list of stocks
 *     tags:
 *       - stocks
 *     produces:
 *       - application/json
 *     responses:
 *       200:
 *         description: stocks
 *         schema:
 *           $ref: &amp;#39;#/definitions/Stocks&amp;#39;
 */
router.get(&amp;#39;/&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.retrieveAll()
  res.send(response)
})

/**
 * @swagger
 * /stocks/{id}:
 *   get:
 *     description: Retrieve an specific stock
 *     tags:
 *       - stocks
 *     produces:
 *       - application/json
 *     parameters:
 *       - name: id
 *         description: id of the stock to retrieve
 *         in: path
 *         required: true
 *         type: number
 *     responses:
 *       200:
 *         description: stock
 *         schema:
 *           $ref: &amp;#39;#/definitions/Stock&amp;#39;
 */
router.get(&amp;#39;/:id&amp;#39;, (req, res, next) =&amp;gt; {
  const response = dao.retrieve(parseInt(req.params.id, 10))
  res.send(response)
})

...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have all the documentation in place, let&amp;rsquo;s define a new endpoint to serve the live documentation:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// api/controllers/swagger.js

const options = {
  swaggerDefinition: {
    info: {
      title: &amp;#39;REST - Swagger&amp;#39;,
      version: &amp;#39;1.0.0&amp;#39;,
      description: &amp;#39;REST API with Swagger doc&amp;#39;,
      contact: {
        email: &amp;#39;contact@danielpecos.com&amp;#39;
      }
    },
    tags: [
      {
        name: &amp;#39;stocks&amp;#39;,
        description: &amp;#39;Stocks API&amp;#39;
      }
    ],
    schemes: [&amp;#39;http&amp;#39;],
    host: &amp;#39;localhost:3000&amp;#39;,
    basePath: &amp;#39;/api&amp;#39;
  },
  apis: [&amp;#39;./api/controllers/stocks.js&amp;#39;, &amp;#39;./api/models/stock-model.js&amp;#39;]
}

const swaggerJSDoc = require(&amp;#39;swagger-jsdoc&amp;#39;)
const swaggerUi = require(&amp;#39;swagger-ui-express&amp;#39;)
const swaggerSpec = swaggerJSDoc(options)

router.get(&amp;#39;/json&amp;#39;, function (req, res) {
  res.setHeader(&amp;#39;Content-Type&amp;#39;, &amp;#39;application/json&amp;#39;)
  res.send(swaggerSpec)
})

router.use(&amp;#39;/&amp;#39;, swaggerUi.serve, swaggerUi.setup(swaggerSpec))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see in the next screenshot, the docs are live and working against the endpoints served by the same application:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2017/09/Screenshot_20170905_233237.png?ssl=1&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2017/09/Screenshot_20170905_233237.png&#34; alt=&#34;Swagger UI&#34; width=&#34;291&#34; height=&#34;300&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And you can even test them in realtime!&lt;/p&gt;
&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2017/09/Screenshot_20170905_233349.png&#34; alt=&#34;Swagger UI - Endpoint test&#34; width=&#34;291&#34; height=&#34;300&#34; /&gt;
&lt;p&gt;Finally let&amp;rsquo;s put some code that will allow us to check that the inputs &amp;amp; outputs of the different endpoints match the models defined in Swagger:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// api/controllers/stocks.js
...
router.put(&amp;#39;/:id&amp;#39;, (req, res, next) =&amp;gt; {
  Swagger.validateModel(&amp;#39;TimeStamp&amp;#39;, req.body)
  const response = dao.update(parseInt(req.params.id, 10), req.body.lastUpdate)
  Swagger.validateModel(&amp;#39;Stock&amp;#39;, response)
  res.send(response)
})
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we have a proper (and documented) REST API that we can hand over to any developer, making her life easier and more productive.&lt;/p&gt;
&lt;p&gt;You can find this example in this GitHub repository:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/dpecos/rest-swagger-example&#34;&gt;https://github.com/dpecos/rest-swagger-example&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>From Ubuntu to Arch Linux</title>
      <link>https://danielpecos.com/2017/05/24/ubuntu-arch-linux/</link>
      <pubDate>Wed, 24 May 2017 20:57:44 +0100</pubDate>
      
      <guid>https://danielpecos.com/2017/05/24/ubuntu-arch-linux/</guid>
      
      <description>&lt;img class=&#34;size-full aligncenter&#34; src=&#34;https://danielpecos.com/assets/2017/04/ubuntu_vs_arch.png&#34; alt=&#34;Ubuntu vs Arch&#34; width=&#34;773&#34; height=&#34;303&#34; /&gt;
&lt;p&gt;Recently I took the decision of leaving my &lt;a href=&#34;https://danielpecos.com/2008/06/10/debian-vs-ubuntu/&#34;&gt;long beloved distro – Ubuntu (sorry, link in spanish)&lt;/a&gt; and moving forward into Arch Linux.&lt;/p&gt;
&lt;p&gt;And why? As &lt;a href=&#34;https://en.wikipedia.org/wiki/We_choose_to_go_to_the_Moon&#34;&gt;JFK said&lt;/a&gt; when the USA was aiming to land on the moon, “not because it’s easy, but because it’s hard”, maybe not that much compared to getting to the moon, but definitely more tedious than Ubuntu. One thing you can take for sure if you take the chance to install Arch: no matter if you success or give up with it, &lt;strong&gt;you will learn something new about how a Linux distro works&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But really, why? Well, the announcement of retiring Unity 8 from Ubuntu from version 18.04 was the trigger to explore other desktop options. I started testing &lt;strong&gt;Gnome 3&lt;/strong&gt; (which is going to be the official replacement for Unity) but it didn’t make me fall in love with it. Then I tried &lt;strong&gt;XFCE&lt;/strong&gt; but it was too simple, way to much. Finally I tried &lt;strong&gt;Plasma (former KDE Desktop)&lt;/strong&gt; and I got impressed. Since I switched to Ubuntu back in 2008, I’ve been using Gnome 2 or Unity based desktops and never got too curious about trying anything else. Plus, installing KDE always required tons of extra libraries that would be probable be left out in the system after an eventual removal of the desktop environment (and the screenshots and feedback I read for KDE 4 were really discouraging).&lt;/p&gt;
&lt;p&gt;But Plasma look &amp;amp; feel was really slick. And, after digging a little bit about latest events in the KDE / Qt community, finally decided to completely move to Plasma, specifically to latest version available in Ubuntu 17.04, Plasma 5.8.&lt;/p&gt;
&lt;p&gt;And then I saw a review of Plasma 5.9, introducing some improvements over previous version and decided to test it, so I looked for a PPA to install it in Ubuntu, but there was none available 🙁&lt;/p&gt;
&lt;p&gt;What could I do to get the latest version working in my desktop? I could have waited for a while until it would eventually made it into a PPA. Or I could try a rolling distro 😉 And this is when Arch ringed a bell. Maybe this was the opportunity to give it a chance and try the (tedious) installation process. And of course move to a totally different package system (&lt;strong&gt;pacman&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;The first installation took me around a couple hours, going from a blank VM to a fully working Plasma desktop. Don’t get me wrong, I’m not saying it’s an easy process or meant to someone with little or none Linux experience: it requires some basic knowledge and experience in Linux systems to know what you’re doing (and not just blindly copying &amp;amp; pasting from the wiki) .&lt;/p&gt;
&lt;p&gt;I have to confess: I’ve been hooked by Arch since then on, and decided to move all my desktop environments to Arch + Plasma. Although it has a quite steep learning curve, once you get familiar with pacman and any of the &lt;strong&gt;AUR&lt;/strong&gt; package managers, it’s quite straight forward to get the packages you need installed and set up. And when you eventually face any problem then you discover the strong point of this distro: its documentation. It’s really amazing to see how many pages that wiki contains and how complete it is. It even has a page to setup &lt;a href=&#34;https://wiki.archlinux.org/index.php/starcraft&#34;&gt;Starcraft&lt;/a&gt; (which now is free!)&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nacidos de la Bruma III – El Héroe de las Eras – Mistborn</title>
      <link>https://danielpecos.com/2016/11/30/nacidos-de-la-bruma-iii-el-heroe-de-las-eras-mistborn/</link>
      <pubDate>Wed, 30 Nov 2016 07:02:06 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/30/nacidos-de-la-bruma-iii-el-heroe-de-las-eras-mistborn/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/Mistborn-III-H%C3%A9roe-Las-Eras/dp/8466658912%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8466658912&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-héroe-de-las-eras.jpg&#34; alt=&#34;Mistborn - El Héroe de las Eras&#34; width=&#34;350&#34; height=&#34;545&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En &lt;strong&gt;El Héroe de las Eras&lt;/strong&gt;, tercera y última entrega de la saga &lt;strong&gt;Nacidos de la Bruma – Mistborn&lt;/strong&gt;, Brandon Sanderson nos presenta el colofón a esta épica historia de aventuras y magia – &lt;em&gt;alomancia&lt;/em&gt;, en la que los protagonistas viajan a través del mundo en busca de las pistas que &lt;em&gt;Lord Legislador&lt;/em&gt; les dejó para combatir el mal que les avecina: &lt;em&gt;Ruina&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;La Banda de Kelsier, encabezada por &lt;em&gt;Vin&lt;/em&gt; y &lt;em&gt;Lord Elend&lt;/em&gt;, tratarán de aunar las distintas ciudades del mundo en una lucha común contra las brumas, aunque no será una tarea fácil. Los restos de la iglesia de Lord Legislador y sus criaturas, se han diseminado por el mundo y, aunque sin ser lo fuertes que fueron cuando éste estaba gobernando, serán causa de gran multitud de problemas para nuestros protagonistas.&lt;/p&gt;
&lt;p&gt;En esta entrega podemos ver cómo Brandon Sanderson, genio de la narrativa de ciencia ficción y épica fantástica, engrana gran cantidad detalles, en un principio nimios, para dar un cierre colosal a la historia, hacia el que todas las pequeñas tramas que se han ido mostrando durante la trilogía convergen, consiguiendo un final digno de la obra.&lt;/p&gt;
&lt;p&gt;Como viene siendo habitual con este autor, el ritmo, la forma de describir el mundo y unos personajes que nos harán sentir partícipes de sus aventuras, son el común denominador de la historia, haciendo que la devoremos desde el primer momento, prácticamente sin darnos cuenta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El Héroe de las Eras&lt;/strong&gt; es el cierre de una obra de arte de la literatura de ficción contemporánea, considerada como uno de los imprescindibles del género por muchos. Política y Religión, temas subyacentes de la saga, hacen que su lectura sea apasionante e inmersiva, haciendo de esta entrega, y sobre todo de la saga &lt;strong&gt;Nacidos de la Bruma – Mistborn&lt;/strong&gt;, una lectura obligatoria para los amantes de la temática.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Nacidos de la Bruma II – El Pozo de la Ascensión – Mistborn</title>
      <link>https://danielpecos.com/2016/11/25/nacidos-de-la-bruma-ii-el-pozo-de-la-ascension-mistborn/</link>
      <pubDate>Fri, 25 Nov 2016 06:30:06 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/25/nacidos-de-la-bruma-ii-el-pozo-de-la-ascension-mistborn/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/pozo-ascensi%C3%B3n-Nacidos-Bruma-Mistborn-ebook/dp/B00AR07H9A%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00AR07H9A&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-pozo-de-la-ascensión.jpg&#34; alt=&#34;Mistborn - El Pozo de la Ascensión&#34; width=&#34;350&#34; height=&#34;544&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El Pozo de la Ascensión&lt;/strong&gt; es la segunda parte de la saga de &lt;strong&gt;Nacidos de la Bruma (Mistborn)&lt;/strong&gt; de Brandon Sanderson, en la que ha demostrado que posee la creatividad suficiente para dar vida a una historia de gran envergadura, y lo mejor, conservando la esencia de la entrega anterior, añadiendo unos toques que proporcionan un aire de frescura y misterio a la franquicia.&lt;/p&gt;
&lt;p&gt;Esta entrega se inicia con los problemas que nuestros protagonistas enfrentan tras conseguir su objetivo: la muerte de su enemigo, &lt;em&gt;Lord Legislador&lt;/em&gt;, pero a un alto precio, el sacrificio de su líder &lt;em&gt;Kelsier&lt;/em&gt;. Inestabilidad política encaminada a una guerra económica es el ambiente que se respira en el imperio, un destino nada previsto por los liberadores y que tratarán de evitar por todo lo posible.&lt;/p&gt;
&lt;p&gt;Para ello entablarán alianzas con la nobleza donde encontrarán un inesperado aliado, &lt;em&gt;Elend Venture&lt;/em&gt;, hijo de la casa más poderosa de &lt;em&gt;Luthadel&lt;/em&gt;, pero difícil heredero de ésta. El interés principal de su padre no será precisamente el de una transición de poder pacífica.&lt;/p&gt;
&lt;p&gt;Brandon Sanderson de nuevo nos presenta un mundo fantástico, con héroes con poderes alomáticos y, también, debilidades humanas. Como viene siendo habitual con este autor, es una obra dinámica, de fácil lectura y que engancha desde el primer minuto.&lt;/p&gt;
&lt;p&gt;En resumen, &lt;strong&gt;El Pozo de la Ascensión&lt;/strong&gt;, segunda parte de esta magnífica saga, &lt;strong&gt;Nacidos de la Bruma (Mistborn)&lt;/strong&gt;, es una obra trepidante y que sin duda nos sorprenderá y mantendrá en vilo en muchas ocasiones.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Nacidos de la Bruma I – El Imperio Final – Mistborn</title>
      <link>https://danielpecos.com/2016/11/21/nacidos-en-la-bruma-i-el-imperio-final-mistborn/</link>
      <pubDate>Mon, 21 Nov 2016 07:00:30 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/21/nacidos-en-la-bruma-i-el-imperio-final-mistborn/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/Mistborn-Imperio-Final-Nueva-Edici%C3%B3n/dp/8466658890%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8466658890&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-imperio-final.jpg&#34; alt=&#34;Mistborn - El Imperio Final&#34; width=&#34;350&#34; height=&#34;544&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si lo que deseas es una trama absorbente, con una gran cantidad de misterio, situaciones fantásticas y personajes entrañables, &lt;strong&gt;El Imperio Final&lt;/strong&gt;, primer libro de la saga &lt;strong&gt;Nacidos de la Bruma – Mistborn&lt;/strong&gt; de Brandon Sanderson es estás buscando. Sin duda alguna es una historia que demuestra que aún es posible encontrar libros con un buen contenido literario y un tono oscuro, tan difícil de encontrar en la literatura fantástica desde hace mucho tiempo. Puede considerarse un digno sucesor de grandes libros épicos del estilo del Señor de los Anillos o Juego de Tronos, sin duda alguna, una joya que te recomiendo no perder.&lt;/p&gt;
&lt;p&gt;Dentro de &lt;strong&gt;Nacidos de la Bruma – El Imperio Final&lt;/strong&gt;, Brandon Sanderson nos introduce en un mundo muy diferente al habitual y especialmente sombrío en el cual nada florece y las cenizas son constantes, los ciudadanos se encuentran oprimidos por un tirano conocido como el Lord Legislador, que junto sus asociados, la iglesia y la clase alta, controlan el metal más preciado de la &lt;em&gt;alomancia&lt;/em&gt;: el &lt;em&gt;Atium&lt;/em&gt;, extraído lenta y dolorosamente de los &lt;em&gt;Pozos de Hathsin&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Los &lt;em&gt;skaa&lt;/em&gt;, la clase obrera controlada y explotada por los nobles, son el motivo por el cual los protagonistas, Kelsier y Vin, pelearán contra los tiranos para conseguir que se les libere de su tormento. Ambos &lt;em&gt;nacidos de la sombra&lt;/em&gt;, reunirán un grupo de &lt;em&gt;alómanticos&lt;/em&gt; que les ayudarán a conseguir sus objetivos.&lt;/p&gt;
&lt;p&gt;En &lt;strong&gt;Nacidos de la Bruma – El Imperio Final&lt;/strong&gt; nos encontramos con una historia llena de acción repleta de personajes que van evolucionando a lo largo de la misma, donde es posible observar traición, amor, duda, proezas épicas, y supervivencia todo con tal de lograr liberarse del yugo por el cual se encuentran oprimidos los &lt;em&gt;skaa&lt;/em&gt;, con un desenlace trepidante y que hará que saltes a por la segunda parte de esta magnífica saga.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Elantris</title>
      <link>https://danielpecos.com/2016/11/17/elantris/</link>
      <pubDate>Thu, 17 Nov 2016 07:05:58 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/17/elantris/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/Elantris-NB-NOVA-Brandon-Sanderson/dp/846665884X%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D846665884X&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/Elantris.jpg&#34; alt=&#34;Elantris&#34; width=&#34;350&#34; height=&#34;538&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;La ciudad de los dioses ya no es un lugar con seres de grandes poderes y magia, es ahora un lugar en ruinas llena de &lt;em&gt;no muertos&lt;/em&gt; que sufren incansablemente por un hambre sobrehumana, dolores que nunca sanan y un corazón que no late. &lt;strong&gt;Elantris&lt;/strong&gt; de Brandon Sanderson es la ciudad donde una misteriosa desgracia cambió todo, sus habitantes se transformaron y después de ser unas maravillas, son ahora seres malditos. Esta novela llena de fantasía y acción presenta la historia de tres personajes, el príncipe Raoden (quién sufrió la transformación), la princesa Sarene y el sacerdote Hrathenun.&lt;/p&gt;
&lt;h3 id=&#34;elantris-el-lugar-de-los-dioses-ahora-es-la-tierra-de-los-no-vivos&#34;&gt;Elantris el lugar de los dioses ahora es la tierra de los “no vivos”&lt;/h3&gt;
&lt;p&gt;Existe una magia en Elantris de Brandon Sanderson, quizás los &lt;em&gt;Aones&lt;/em&gt; están relacionados con la catástrofe que cambió el curso del reino de &lt;em&gt;Arelon&lt;/em&gt;. La población aún no asume el cambio tan grande que ocurrió en su tierra, cuál fue la causa de tanta desesperanza y sufrimiento.&lt;/p&gt;
&lt;p&gt;Mucho sufrimiento para los &lt;em&gt;No vivos&lt;/em&gt;, la aristocracia tiene un poder que sobrepasa los derechos de los ciudadanos, la anarquía y el hambre inacabable predominan en la lucha de los habitantes. &lt;strong&gt;Elantris&lt;/strong&gt; de Brandon Sanderson muestra la intención de la religión para conquistar el poder absoluto, el sacerdote Hrathenun utiliza artimañas para hacer que la corrupción, los vicios e intereses personales perturben el amor de los príncipes para dominar el reino a través de su secta.&lt;/p&gt;
&lt;p&gt;En Elantris el príncipe Raoden luego de ser el heredero del reino, sufre el mal de &lt;em&gt;Shaod&lt;/em&gt; provocando su exilio en la tierra de los &lt;em&gt;no muertos&lt;/em&gt;, al parecer la transformación no es por completo, poco a poco va sintiendo que se apodera de sus sentidos, inicia una guerra interna con sus recuerdos y el presente.&lt;/p&gt;
&lt;h3 id=&#34;el-amor-de-sarene-y-raoden-los-príncipes-de-elantris&#34;&gt;El amor de Sarene y Raoden los príncipes de “Elantris”&lt;/h3&gt;
&lt;p&gt;La energía que mantiene viva a la ciudad representa un factor importante en la vida de Raoden, quien a lo largo de la historia analiza y trata de comprender la finalidad de los &lt;em&gt;Aones&lt;/em&gt; en la vida de los Elantrinos. El pretexto recibir a los &lt;em&gt;no muertos&lt;/em&gt; como maravillas logró que los trasladaran, al llegar a la ciudadela la realidad es otra, son encarcelados, obligados a una vida sin final y tomados como no vivos por los que no han sido afectados por el &lt;em&gt;Shaod&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Sarene, la novia política de Roaden, tiene el dilema de amar y respetar a su príncipe muerto o seguir las recomendaciones del sacerdote Hrath, casarse con otro hombre. Esta elección altera rápidamente el curso del amor y amenaza con el destino de los habitantes de Arelon. El reino se ve amenazado por la decisión que tome la princesa, casarse nuevamente o no.&lt;/p&gt;
&lt;p&gt;Una trama que mantiene el misterio de principio a fin, situaciones llenas de controversia en un régimen político amenazado por una desgracia, el interés religioso, el amor inalcanzable entre los príncipes, la búsqueda del significado de los &lt;em&gt;Aones&lt;/em&gt; y la trasformación de Raoden hacen de &lt;strong&gt;Elantris&lt;/strong&gt; de Brandon Sanderson una revolucionaria novela de ficción, fantasía y amor.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Gracias Mamá</title>
      <link>https://danielpecos.com/2016/11/15/gracias-mama/</link>
      <pubDate>Tue, 15 Nov 2016 07:01:12 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/15/gracias-mama/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2016/11/RosaMartinez.png&#34; alt=&#34;Rosa Martínez&#34; width=&#34;171&#34; height=&#34;228&#34; /&gt;Por todo lo que has sido y hecho, no puedo hacer otra cosa que estarte agradecido.&lt;/p&gt;
&lt;p&gt;Llevo meses tratando de escribir este post, y realmente puede que sea el más difícil escrito nunca. Varias veces he tenido que parar y dejarlo para otro momento. No pretendo que sea un post público sino algo que te escribo a ti. Para mi.&lt;/p&gt;
&lt;p&gt;Ni que decir que te echaré de menos. Nunca te olvidaré y haré todo lo posible para que Izan tampoco lo haga. Todas las noches mira las estrellas para mandarte besos.&lt;/p&gt;
&lt;p&gt;Gracias por todo mamá!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>El Temor de un Hombre Sabio</title>
      <link>https://danielpecos.com/2016/11/14/el-temor-de-un-hombre-sabio/</link>
      <pubDate>Mon, 14 Nov 2016 07:00:46 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/14/el-temor-de-un-hombre-sabio/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/Temor-Hombre-Sabio-BEST-SELLER/dp/8499899617%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8499899617&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-Temor-de-un-Hombre-Sabio.jpg&#34; alt=&#34;El Temor de un Hombre Sabio&#34; width=&#34;350&#34; height=&#34;532&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;El ex profesor de lengua y literatura inglesa Patrick Rothfuss presenta &lt;strong&gt;El Temor de un Hombre Sabio&lt;/strong&gt; la continuación del libro &lt;strong&gt;&lt;a href=&#34;https://biblo.es/el-nombre-del-viento/&#34;&gt;El Nombre del Viento&lt;/a&gt;&lt;/strong&gt;, incluido en la &lt;strong&gt;Crónica el Asesino de Reyes&lt;/strong&gt;. Narra la historia de un joven prodigio que todos dan por muerto, ahora con nuevo nombre en una aldea extraviada, trata de rehacer y continuar con su vida. Los recuerdos sobre interesantes batallas, alegrías y penurias explican porque la arrogancia y seguridad en la actitud de Kvothe, “Quizás hayas oído hablar de mí”.&lt;/p&gt;
&lt;h3 id=&#34;kvothe-vuelve-con-heroísmo-y-penurias-en-el-temor-de-un-hombre-sabio&#34;&gt;Kvothe vuelve con heroísmo y penurias en “El Temor de un Hombre Sabio”&lt;/h3&gt;
&lt;p&gt;Kvothe sigue siendo el héroe, trotamundos y ladrón acostumbrado, su pasado lo persigue a través de sus recuerdos. No puede culminar sus estudios, recorre los paisajes de &lt;em&gt;Severen&lt;/em&gt;, allí se vincula a la política de la sociedad cortesana. Una interesante, pero peligrosa mujer aparece, &lt;em&gt;Felurian&lt;/em&gt;, quien logra seducirlo con mucha sensualidad a través de sus encantos. Tanto así que la acompaña sin pensarlo al &lt;em&gt;mundo de los Fatas&lt;/em&gt; ese del cual nadie regresa, creando muchas circunstancias amorosas en la vida del joven.&lt;/p&gt;
&lt;p&gt;Poco a poco se vuelve buen asesino, cualidad incondicional para lograr su venganza contra los &lt;em&gt;Chandrian&lt;/em&gt;. En &lt;strong&gt;&lt;em&gt;El Temor de un Hombre Sabio&lt;/em&gt;&lt;/strong&gt; Kvothe cuenta con la compañía de Tempi, un mercenario Adem. Aprende el legendario &lt;em&gt;ketan&lt;/em&gt;, en esta oportunidad se suman enseñanzas y misiones que fortalecen sus conocimientos en combate.&lt;/p&gt;
&lt;h3 id=&#34;el-hombre-había-desaparecido-el-mito-había-quedado&#34;&gt;“El hombre había desaparecido, el mito había quedado”&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;El Temor de un Hombre Sabio&lt;/em&gt;&lt;/strong&gt; empieza donde termina** &lt;a href=&#34;https://biblo.es/el-nombre-del-viento/&#34;&gt;El Nombre del Viento&lt;/a&gt;**. Mundos de tinieblas y oscuridad, donde Kvothe se ve maduro, argumenta sus decisiones, posee dinero, empieza a asumir responsabilidades en la espontánea vida que ha llevado. Aparecen nuevamente sus amigos, se reencuentra con todos ellos y nacen nuevas tertulias y anécdotas que comprueban porque hay rebeldía, irreverencia a los lujos y fuerte lucha contra la pobreza en la vida del trotamundos.&lt;/p&gt;
&lt;p&gt;Es un nuevo joven, rebelde, pero comienza a comprender la responsabilidad de su poder, está más enfocado en la venganza, se mantiene bajo perfil ahora planea sus acciones. Sin embargo aparecen nuevas cadenas que romper y decisiones que tomar para este casi adulto.&lt;/p&gt;
&lt;p&gt;“He recorrido de noche caminos de los que otros no se atreven a hablar ni siquiera de día”. En **El Temor de un Hombre Sabio **la arrogancia es fiel compañera de Kvothe, el enemigo interno resulta en ocasiones más poderoso que la voluntad, la cualidad de héroe se resalta y comprueba con las habilidades adquiridas desde niño hasta el presente.&lt;/p&gt;
&lt;p&gt;**El Temor de un Hombre Sabio **es la obra de ficción fantasía que trasmite realidad en un mundo lleno de magia, dioses, clasismo y la ideología Teccam, creíble y cierta para Kvothe. El destino depara mundos nuevos, costumbres sociales diferentes y distintos sistemas monetarios al cual debe adaptarse para poder pasar inadvertido ante los problemas. La premisa de venganza se mantiene y el miedo no es la mejor opción. “Todo hombre sabio teme tres cosas: la tormenta en el mar, la noche sin luna y la ira de un hombre amable”.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>El Nombre del Viento</title>
      <link>https://danielpecos.com/2016/11/07/el-nombre-del-viento/</link>
      <pubDate>Mon, 07 Nov 2016 07:00:50 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/07/el-nombre-del-viento/</guid>
      
      <description>&lt;p align=&#34;justify&#34;&gt;
  &lt;a href=&#34;https://www.amazon.es/nombre-del-viento-BEST-SELLER/dp/8499082475%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8499082475&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-Nombre-del-Viento.jpg&#34; alt=&#34;El Nombre del Viento&#34; width=&#34;350&#34; height=&#34;532&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;Asesino, músico, mendigo, estudiante, ladrón, mago y héroe: ésta es la verdadera historia de Kvothe. Tras soportar los cotilleos, rumores y conjeturas que las personas hicieron sobre su vida, en &lt;strong&gt;El Nombre del Viento&lt;/strong&gt; se narra las verdaderas vivencias de su auténtica y dificultosa existencia en el mundo.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Se trata de una novela llena de fantasía escrita por el estadounidense Patrick Rothfuss, su primera edición fue en 2011 y hoy en día cuenta con muy buenos comentarios de críticos en todo el mundo. Este libro ganó el Premio Pluma al mejor libro en el género de literatura fantástica, lo cual representó un impulso para que su autor se dedicara con más pasión a la escritura.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  “&lt;em&gt;He recorrido de noche caminos de los que otros no se atreven a hablar ni siquiera de día. He hablado con dioses, he amado a mujeres y he escrito canciones que hacen llorar a los bardos. Me llamo Kvothe. Quizá hayas oído hablar de mí.&lt;/em&gt;”
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Después de tanto, en esta historia Kvothe narra la verdad sobre sí mismo. Ante todo lo que ha pasado, siempre debe haber un comienzo: su infancia con sus padres en una troupe. Durante sus años de crecimiento y gracias a su familia, se encuentra constantemente relacionado con la actuación, la música, los juglares y la acrobacia.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Debido a este ambiente artístico donde pasó la mayor parte de su vida, Kvothe se convirtió en un niño con mucho talento para la música y los cuentos, además todos lo conocían como una persona diplomática, alegre y muy servicial.
&lt;/p&gt;
&lt;h3 align=&#34;justify&#34;&gt;
  Viajé, amé, perdí, confié y me traicionaron
&lt;/h3&gt;
&lt;p align=&#34;justify&#34;&gt;
  El nombre del viento cuenta de manera detallada los años de Kvothe malviviendo como ladrón en la gran ciudad, cometiendo pequeños y grandes crímenes que le dan rumbos inesperados a la historia. Mediante pasan los años, el protagonista conoce a distintas personas que se vuelven parte importante de la historia.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Después de distintos retos y acontecimientos, el protagonista de esta historia viaja a la universidad, un reconocido centro de educación mágica donde lograr encontrar muchas de las respuestas que había estado buscando hacía tanto tiempo; este centro de formación es para personas con dinero y poder adquisitivo, lo que le dificulta su aprendizaje y su estadía en el lugar.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  “&lt;em&gt;He robado princesas a reyes agónicos. Incendié la ciudad de Trebon. He pasado la noche con Felurian y he despertado vivo y cuerdo. Me expulsaron de la Universidad a una edad a la que a la mayoría todavía no los dejan entrar&lt;/em&gt;”
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  El libro tiene dos líneas temporales diferentes: el pasado narrado por Kvothe, basados en sus recuerdos y vivencias memorables; y el presente, narrado en tercera persona. La novela pese a tantos acontecimientos inesperados, se desarrolla en un solo día.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Desde su lanzamiento, esta historia ha causado un impacto positivo en los críticos literarios y los amantes del género fantástico; finalmente, después de tantas especulaciones y rumores, en el nombre del viento se narra los sucesos reales y la verdadera historia de Kvothe.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  &lt;noscript&gt;
  &lt;/noscript&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Plan de ahorro personal</title>
      <link>https://danielpecos.com/2016/11/07/plan-de-ahorro-personal/</link>
      <pubDate>Mon, 07 Nov 2016 06:45:47 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/07/plan-de-ahorro-personal/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2016/11/business-man-in-a-presentation_1133-197.jpg&#34; alt=&#34;Plan de ahorro&#34; width=&#34;300&#34; height=&#34;300&#34; /&gt;Tras unos días de análisis e introspectiva financiera, he conseguido detallar cuáles son mis gastos previsibles mes a mes, por lo que creo que me encuentro en situación de pasar a la siguiente fase: &lt;strong&gt;definir un plan de ahorro personal&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Voy a optar por un plan bastante agresivo, puesto que mi colchón actual está completamente deshinchado y esto es algo que me hace sentir poco seguro. Tras hablarlo con mi mujer, hemos decidido apretarnos un poco el cinturón con el fin de poder corregir esta situación. Así que nos hemos fijado como objetivo ahorrar el 25% de nuestro salario cada mes. Una vez alcancemos la cantidad de 2000€ en líquido, el resto de los futuros ahorros los invertiremos en bolsa a largo plazo y plazos fijos. No tengo todavía claro en qué porcentaje, pero todavía tengo tiempo disponible para pensarlo.&lt;/p&gt;
&lt;p&gt;Comprobando el balance financiero personal que desarrollé, durante 5 de los 12 meses nuestro disponible mensual se queda por debajo de este 25% del salario, a veces por mucho y otras veces por menos. Para los otros 7 meses, por lo normal el disponible es bastante mayor al porcentaje de ahorro, por lo que espero poder compensar unos meses con otros. ¿Cómo? &lt;strong&gt;Teniendo unos 2000€ líquidos siempre en cuenta&lt;/strong&gt;, de forma que en los meses que el ahorro del 25% se cubra íntegramente con el salario del mes, hincharé el colchón con el resto disponible en en líquido para poder complementar el salario de los meses más duros y así conseguir la meta del 25% todos los meses.&lt;/p&gt;
&lt;p&gt;Siguiendo el objetivo inicial de esta página, voy a tratar de publicar de forma periódica (seguramente trimestral) un pequeño análisis de cómo van estos objetivos, y ver cómo de cerca o lejos me encuentro de esta meta de ahorro.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lo primero: reducir gastos superfluos&lt;/strong&gt;, que gracias al balance financiero es muchísimo más fácil identificarlos ahora que cuando no disponía de esta herramienta. Además me permite focalizar esfuerzos en aquello que me va a generar un mayor retorno.&lt;/p&gt;
&lt;p&gt;¡Manos a la obra!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Canción de Hielo y Fuego: Juego de Tronos: 1</title>
      <link>https://danielpecos.com/2016/11/02/cancion-de-hielo-y-fuego-juego-de-tronos-1/</link>
      <pubDate>Wed, 02 Nov 2016 07:00:06 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/11/02/cancion-de-hielo-y-fuego-juego-de-tronos-1/</guid>
      
      <description>&lt;p align=&#34;justify&#34;&gt;
  &lt;a href=&#34;https://www.amazon.es/Canci%C3%B3n-hielo-fuego-tronos-Gigamesh/dp/8496208923%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8496208923&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/Canción-de-hielo-y-fuego-Juego-de-tronos-1.jpg&#34; alt=&#34;Canción de hielo y fuego: Juego de tronos: 1&#34; width=&#34;350&#34; height=&#34;525&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;&lt;strong&gt;Juego de Tronos (Game of Thrones)&lt;/strong&gt; es una de las franquicias más exitosas de los últimos tiempos que combina batallas épicas, dinastías poderosas y todo un mundo místico que se cierne sobre sus personajes, llenos de emociones netamente humanas. La historia se desarrolla en un mundo ficticio medieval, en un continente llamado Poniente, donde se desenvuelve una historia llena de sucesos impresionantes, increíbles personajes y desenlaces totalmente inesperados. Se trata de &lt;strong&gt;Canción de Hielo y Fuego&lt;/strong&gt;, escrita por George R. R. Martin, una novela que ha sido traducida a más de 30 idiomas desde su lanzamiento. El escritor comenzó a crear esta obra en 1993 y tiempo después, en 1996 fue publicado su primer tomo.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Después de un largo verano, los Siete Reinos se ven amenazados por un invierno devastador. El señor de Invernalia, Lord Eddard Stark debe emprender un viaje hacia Poniente con su viejo amigo el rey Robert Baratheon, abandonando sus dominios en Invernalia para ocupar el cargo de Mano de Rey en la capital.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Lord Stark en búsqueda de respuestas a una serie de intrigas sobre el reinado de Poniente, pone en riesgo su vida y la vida de sus familiares más cercanos. Sin embargo, detrás de distintos sucesos la historia se basa en tres líneas argumentales: la creciente amenaza de los Otros y los salvajes, la temida guerra civil dinástica por el control de la capital y el viaje de Daenerys Targaryen, la hija de un exiliado rey.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Estas tres historias son relacionadas de manera constante durante toda la narración de canción de hielo y fuego, transcurriendo de acuerdo a una serie de sucesos inesperados que cautivan a cualquier lector.
&lt;/p&gt;
&lt;h3 align=&#34;justify&#34;&gt;
  “La noche es oscura y alberga cosas aterradoras”
&lt;/h3&gt;
&lt;p align=&#34;justify&#34;&gt;
  Los otros o conocidos en el Pueblo Libre como &lt;em&gt;caminantes blancos&lt;/em&gt;, son criaturas que protagonizan de manera indirecta esta historia, forman parte importante de la historia y representan la mayor y más temida amenaza de los Siete Reinos.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  La historia es narrada en tercera persona, permitiéndonos ver mediante los ojos y la posición de distintos personajes. En muchas escenas existen muestras claras de cómo la guerra por el poder y la conquista puede destruir familias y acabar con la vida de personas inocentes.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  En la historia de canción de fuego y hielo, existen múltiples casas representadas con diferentes emblemas, sin embargo las 4 casas más importantes de toda la historia son: la casa Stark, la casa Baratheon, la casa Targaryen y la prestigiosa casa Lannister.
&lt;/p&gt;
&lt;h3 align=&#34;justify&#34;&gt;
  “Cuando se juega al juego de tronos sólo se puede ganar o morir. No hay puntos intermedios”
&lt;/h3&gt;
&lt;p align=&#34;justify&#34;&gt;
  Al transcurrir la narración, se puede apreciar tanto la unión como el enfrentamiento entre estas y las demás casas nobles de Poniente; &lt;strong&gt;Canción de Hielo y Fuego&lt;/strong&gt; no sólo se basa en extensos e increíbles personajes sino también en cambios de trama repentinos y violentos, argumentos políticos bien desarrollados y un manejo constante de géneros como la ciencia ficción, la fantasía erótica y el drama.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  Esta novela es considerada como una de las obras más innovadoras de su género y ha logrado captar la atención de millones de personas en todo el mundo, incluso para el 2013, esta serie de novelas había alcanzado a más de 25 millones de personas.
&lt;/p&gt;
&lt;p align=&#34;justify&#34;&gt;
  &lt;noscript&gt;
  &lt;/noscript&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostGreSQL vs. MySQL</title>
      <link>https://danielpecos.com/documents/postgresql-vs-mysql/</link>
      <pubDate>Sun, 30 Oct 2016 22:29:43 +0100</pubDate>
      
      <guid>https://danielpecos.com/documents/postgresql-vs-mysql/</guid>
      
      <description>&lt;h1 id=&#34;postgresql-vs-mysql&#34;&gt;PostgreSQL vs. MySQL&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Tabla de contenidos&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN1&#34;&gt;Introducción&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN12&#34;&gt;PostGreSQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.1. &lt;a href=&#34;#AEN17&#34;&gt;¿Qué es postgresql?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.2. &lt;a href=&#34;#AEN22&#34;&gt;Historia de PostGreSQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.3. &lt;a href=&#34;#AEN30&#34;&gt;Características de PostGreSQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.4. &lt;a href=&#34;#AEN50&#34;&gt;¿Qué es lo que le falta?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.5. &lt;a href=&#34;#AEN53&#34;&gt;Opinión Personal&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN13&#34;&gt;MySQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.1. &lt;a href=&#34;#AEN59&#34;&gt;¿Qué es MySQL?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.2. &lt;a href=&#34;#AEN64&#34;&gt;Historia de MySQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.3. &lt;a href=&#34;#AEN71&#34;&gt;Características de MySQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.4. &lt;a href=&#34;#AEN87&#34;&gt;¿Qué es lo que le falta?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.5. &lt;a href=&#34;#AEN102&#34;&gt;Opinión Personal&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN14&#34;&gt;Comparativa&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.1. &lt;a href=&#34;#AEN110&#34;&gt;Introducción&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.2. &lt;a href=&#34;#AEN115&#34;&gt;Lo mejor de PostGreSQL …&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.3. &lt;a href=&#34;#AEN125&#34;&gt;… y lo peor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.4. &lt;a href=&#34;#AEN135&#34;&gt;Lo mejor de MySQL …&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.5. &lt;a href=&#34;#AEN149&#34;&gt;… y lo peor&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN15&#34;&gt;Conclusión&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;#AEN16&#34;&gt;Bibliografía&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hoy en día existen muchas empresas y sitios web que necesitan mantener de forma eficiente un gran volumen de datos. Muchos de ellos optan por soluciones comerciales, aunque muchas otras confían en el software libre optando por una solución como PostGreSQL o MySQL.&lt;/p&gt;
&lt;p&gt;En este documento se tratará de hacer una comparativa entre los sistemas de gestión de bases de datos libres más importantes y más usados en la red, los cuales proporcionan soluciones a miles de personas, de forma totalmente gratuita, sin pérdida de eficiencia alguna.&lt;/p&gt;
&lt;h1 id=&#34;a-nameaen1a1-introducción&#34;&gt;&lt;a name=&#34;AEN1&#34;&gt;&lt;/a&gt;1. Introducción&lt;/h1&gt;
&lt;p&gt;Común es la pregunta entre las personas que se adentran por primera vez en el mundo de las bases de datos libres: ¿MySQL o PostGreSQL? En realidad no es una pregunta asociada específicamente a los “novatos”, ya que incluso los profesionales dedicados a este campo se realizan muchas veces esta misma pregunta. La verdad es que no es una pregunta fácil de responder, y no carente de grandes controversias.&lt;/p&gt;
&lt;p&gt;El objetivo de este documento será introducir las características de estos dos magníficos sistemas de gestión de bases de datos, haciendo una pequeña comparativa entre ellas, con el fin de conducir a la elección más adecuada para cada situación.&lt;/p&gt;
&lt;h1 id=&#34;a-nameaen12a2-postgresql&#34;&gt;&lt;a name=&#34;AEN12&#34;&gt;&lt;/a&gt;2. PostGreSQL&lt;/h1&gt;
&lt;h2 id=&#34;a-nameaen17a21-qué-es-postgresql&#34;&gt;&lt;a name=&#34;AEN17&#34;&gt;&lt;/a&gt;2.1. ¿Qué es PostGreSQL?&lt;/h2&gt;
&lt;p&gt;PostGreSQL es un sistema de gestión de bases de datos objeto-relacional (ORDBMS) basado en el proyecto POSTGRES, de la universidad de Berkeley. El director de este proyecto es el profesor Michael Stonebraker, y fue patrocinado por Defense Advanced Research Projects Agency (DARPA), el Army Research Office (ARO), el National Science Foundation (NSF), y ESL, Inc.&lt;/p&gt;
&lt;p&gt;PostGreSQL es una derivación libre (OpenSource) de este proyecto, y utiliza el lenguaje SQL92/SQL99, así como otras características que comentaremos más adelante.&lt;/p&gt;
&lt;p&gt;Fue el pionero en muchos de los conceptos existentes en el sistema objeto-relacional actual, incluido, más tarde en otros sistemas de gestión comerciales. PostGreSQL es un sistema objeto-relacional, ya que incluye características de la orientación a objetos, como puede ser la herencia, tipos de datos, funciones, restricciones, disparadores, reglas e integridad transaccional. A pesar de esto, PostGreSQL no es un sistema de gestión de bases de datos puramente orientado a objetos.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen22a22-historia-de-postgresql&#34;&gt;&lt;a name=&#34;AEN22&#34;&gt;&lt;/a&gt;2.2. Historia de PostGreSQL&lt;/h2&gt;
&lt;p&gt;PostGreSQL (llamado también Postgres95) fue derivado del proyecto Postgres, como ya se ha comentado. A sus espaldas, este proyecto lleva más de una década de desarrollo, siendo hoy en día, el sistema libre más avanzado con diferencia, soportando la gran mayoría de las transacciones SQL, control concurrente, teniendo a su disposición varios “language bindings” como por ejemplo C, C++, Java, Python, PHP y muchos más.&lt;/p&gt;
&lt;p&gt;La implementación de Postgres DBMS comenzó en 1986, y no hubo una versión operativa hasta 1987. La versión 1.0 fue liberada en Junio de 1989 a unos pocos usuarios, tras la cual se liberó la versión 2.0 en Junio de 1990 debido a unas críticas sobre el sistema de reglas, que obligó a su reimplementación. La versión 3.0 apareció en el año 1991, e incluyó una serie de mejoras como una mayor eficiencia en el ejecutor de peticiones. El resto de versiones liberadas a partir de entonces, se centraron en la portabilidad del sistema. El proyecto se dio por finalizado en con la versión 4.2, debido al gran auge que estaba teniendo, lo cual causó la imposibilidad de mantenimiento por parte de los desarrolladores.&lt;/p&gt;
&lt;p&gt;En 1994, Andrew Yu y Jolly Chen añadieron un intérprete de SQL a este gestor. Postgres95, como así se llamó fue liberado a Internet como un proyecto libre (OpenSource). Estaba escrito totalmente en C, y la primera versión fue un 25% más pequeña que Postgres, y entre un 30 y un 50% más rápida. A parte de la corrección de algunos bugs, se mejoró el motor interno, se añadió un nuevo programa monitor, y se compiló usando la utilidad GNU Make y el compilador gcc sin necesidad de parchearlo (como había hecho falta en versiones anteriores).&lt;/p&gt;
&lt;p&gt;En 1996, los desarrolladores decidieron cambiar el nombre a al DBMS, y lo llamaron PostGreSQL (versión 6.0) para reflejar la relación entre Postgres y las versiones recientes de SQL. Se crearon nuevas mejoras y modificaciones, que repercutieron en un 20-40% más de eficiencia, así como la incorporación del estándar SQL92.&lt;/p&gt;
&lt;p&gt;La versión que se ofrece a fechas de este escrito, es la versión 7.2.1. Se puede encontrar más información acerca de las características e historia en &lt;a href=&#34;#POSTGRES&#34;&gt;[PostGreSQL_Manual]&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen30a23-características-de-postgresql&#34;&gt;&lt;a name=&#34;AEN30&#34;&gt;&lt;/a&gt;2.3. Características de PostGreSQL&lt;/h2&gt;
&lt;p&gt;A continuación se enumeran las principales características de este gestor de bases de datos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Implementación del estándar SQL92/SQL99.&lt;/li&gt;
&lt;li&gt;Soporta distintos tipos de datos: además del soporte para los tipos base, también soporta datos de tipo fecha, monetarios, elementos gráficos, datos sobre redes (MAC, IP …), cadenas de bits, etc. También permite la creación de tipos propios.&lt;/li&gt;
&lt;li&gt;Incorpora una estructura de datos array.&lt;/li&gt;
&lt;li&gt;Incorpora funciones de diversa índole: manejo de fechas, geométricas, orientadas a operaciones con redes, etc.&lt;/li&gt;
&lt;li&gt;Permite la declaración de funciones propias, así como la definición de disparadores.&lt;/li&gt;
&lt;li&gt;Soporta el uso de índices, reglas y vistas.&lt;/li&gt;
&lt;li&gt;Incluye herencia entre tablas (aunque no entre objetos, ya que no existen), por lo que a este gestor de bases de datos se le incluye entre los gestores objeto-relacionales.&lt;/li&gt;
&lt;li&gt;Permite la gestión de diferentes usuarios, como también los permisos asignados a cada uno de ellos.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-nameaen50a24-qué-es-lo-que-le-falta&#34;&gt;&lt;a name=&#34;AEN50&#34;&gt;&lt;/a&gt;2.4. ¿Qué es lo que le falta?&lt;/h2&gt;
&lt;p&gt;PostGreSQL es un magnífico gestor de bases de datos, capaz de competir con muchos gestores comerciales, aunque carezca de alguna característica casi imprescindible. Ésta es, bajo mi punto de vista, un conjunto de herramientas que permitan una fácil gestión de los usuarios y de las bases de datos que contenga el sistema. Por otro lado, la velocidad de respuesta que ofrece este gestor con bases de datos relativamente pequeñas puede parecer un poco deficiente, aunque esta misma velocidad la mantiene al gestionar bases de datos realmente grandes, cosa que resulta loable.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen53a25-opinión-personal&#34;&gt;&lt;a name=&#34;AEN53&#34;&gt;&lt;/a&gt;2.5. Opinión Personal&lt;/h2&gt;
&lt;p&gt;PostGreSQL es un magnífico gestor de bases de datos. Tiene prácticamente todo lo que tienen los gestores comerciales, haciéndo de él una muy buena alternativa GPL. A pesar de ello, el primer encuentro con este gestor es un poco “duro”, ya que la sintaxis de algunos de sus comandos no es nada intuitiva. También resulta engorroso las pequeñas variaciones que presenta este gestor en algunos de los tipos de datos que maneja, siendo el problema más comentado el referente al tipo “serial”.&lt;/p&gt;
&lt;p&gt;Una vez nos hayamos hecho con su sintaxis y fijándonos en estos pequeños detalles (que por otro lado están totalmente documentados), PostGreSQL es un gestor magnífico, que posee una gran escalabilidad, haciéndolo idóneo para su uso en sitios web que posean alrededor de 500.000 peticiones por día.&lt;/p&gt;
&lt;h1 id=&#34;a-nameaen13a3-mysql&#34;&gt;&lt;a name=&#34;AEN13&#34;&gt;&lt;/a&gt;3. MySQL&lt;/h1&gt;
&lt;h2 id=&#34;a-nameaen59a31-qué-es-mysql&#34;&gt;&lt;a name=&#34;AEN59&#34;&gt;&lt;/a&gt;3.1. ¿Qué es MySQL?&lt;/h2&gt;
&lt;p&gt;MySQL es un sistema de gestión de bases de datos relacional, licenciado bajo la GPL de la GNU. Su diseño multihilo le permite soportar una gran carga de forma muy eficiente. MySQL fue creada por la empresa sueca MySQL AB, que mantiene el copyright del código fuente del servidor SQL, así como también de la marca.&lt;/p&gt;
&lt;p&gt;Aunque MySQL es software libre, MySQL AB distribuye una versión comercial de MySQL, que no se diferencia de la versión libre más que en el soporte técnico que se ofrece, y la posibilidad de integrar este gestor en un software propietario, ya que de no ser así, se vulneraría la licencia GPL.&lt;/p&gt;
&lt;p&gt;Este gestor de bases de datos es, probablemente, el gestor más usado en el mundo del software libre, debido a su gran rapidez y facilidad de uso. Esta gran aceptación es debida, en parte, a que existen infinidad de librerías y otras herramientas que permiten su uso a través de gran cantidad de lenguajes de programación, además de su fácil instalación y configuración.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen64a32-historia-de-mysql&#34;&gt;&lt;a name=&#34;AEN64&#34;&gt;&lt;/a&gt;3.2. Historia de MySQL&lt;/h2&gt;
&lt;p&gt;MySQL surgió como un intento de conectar el gestor mSQL a las tablas propias de MySQL AB, usando sus propias rutinas a bajo nivel. Tras unas primeras pruebas, vieron que mSQL no era lo bastante flexible para lo que necesitaban, por lo que tuvieron que desarrollar nuevas funciones. Esto resultó en una interfaz SQL a su base de datos, con una interfaz totalmente compatible a mSQL.&lt;/p&gt;
&lt;p&gt;Se comenta en el manual &lt;a href=&#34;#MYSQL&#34;&gt;[MySQL_Manual]&lt;/a&gt; que no se sabe con certeza de donde proviene su nombre. Por un lado dicen que sus librerías han llevado el prefijo ‘my’ durante los diez últimos años. Por otro lado, la hija de uno de los desarrolladores se llama My. No saben cuál de estas dos causas (aunque bien podrían tratarse de la misma), han dado lugar al nombre de este conocido gestor de bases de datos.&lt;/p&gt;
&lt;p&gt;La versión estable de este gestor a días de hoy es la 3.23.49. Se puede encontrar más información sobre este gestor en el manual &lt;a href=&#34;#MYSQL&#34;&gt;[MySQL_Manual]&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen71a33-características-de-mysql&#34;&gt;&lt;a name=&#34;AEN71&#34;&gt;&lt;/a&gt;3.3. Características de MySQL&lt;/h2&gt;
&lt;p&gt;Las principales características de este gestor de bases de datos son las siguientes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Aprovecha la potencia de sistemas multiprocesador, gracias a su implementación multihilo.&lt;/li&gt;
&lt;li&gt;Soporta gran cantidad de tipos de datos para las columnas.&lt;/li&gt;
&lt;li&gt;Dispone de API’s en gran cantidad de lenguajes (C, C++, Java, PHP, etc).&lt;/li&gt;
&lt;li&gt;Gran portabilidad entre sistemas.&lt;/li&gt;
&lt;li&gt;Soporta hasta 32 índices por tabla.&lt;/li&gt;
&lt;li&gt;Gestión de usuarios y passwords, manteniendo un muy buen nivel de seguridad en los datos.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-nameaen87a34-qué-es-lo-que-le-falta&#34;&gt;&lt;a name=&#34;AEN87&#34;&gt;&lt;/a&gt;3.4. ¿Qué es lo que le falta?&lt;/h2&gt;
&lt;p&gt;MySQL surgió cómo una necesidad de un grupo de personas sobre un gestor de bases de datos rápido, por lo que sus desarrolladores fueron implementando únicamente lo que precisaban, intentando hacerlo funcionar de forma óptima. Es por ello que, aunque MySQL se incluye en el grupo de sistemas de bases de datos relacionales, carece de algunas de sus principales características:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Subconsultas: tal vez ésta sea una de las características que más se echan en falta, aunque gran parte de las veces que se necesitan, es posible reescribirlas de manera que no sean necesarias.&lt;/li&gt;
&lt;li&gt;SELECT INTO TABLE: Esta característica propia de Oracle, todavía no está implementada.&lt;/li&gt;
&lt;li&gt;Triggers y Procedures: Se tiene pensado incluir el uso de procedures almacenados en la base de datos, pero no el de triggers, ya que los triggers reducen de forma significativa el rendimiento de la base de datos, incluso en aquellas consultas que no los activan.&lt;/li&gt;
&lt;li&gt;Transacciones: a partir de las últimas versiones ya hay soporte para transacciones, aunque no por defecto (se ha de activar un modo especial).&lt;/li&gt;
&lt;li&gt;Integridad referencial: aunque sí que admite la declaración de claves ajenas en la creación tablas, internamente no las trata de forma diferente al resto de campos.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Los desarrolladores comentan en la documentación que todas estas carencias no les resultaban un problema, ya que era lo que ellos necesitaban. De hecho, MySQL fue diseñada con estas características, debido a que lo que buscaban era un gestor de bases de datos con una gran rapidez de respuesta. Pero ha sido con la distribución de MySQL por Internet, cuando más y más gente les están pidiendo estas funcionalidades, por lo que serán incluidas en futuras versiones del gestor.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen102a35-opinión-personal&#34;&gt;&lt;a name=&#34;AEN102&#34;&gt;&lt;/a&gt;3.5. Opinión Personal&lt;/h2&gt;
&lt;p&gt;Tras haber probado la PostGreSQL, y viendo las carencias que poseía MySQL, pensé que no merecería la pena ni tan siquiera probarlo, aunque por otro lado, creía que algo debía tener para que hubiera tanta gente que lo use, cuando está a merced de cada uno elegir la base de datos que quiere usar. La verdad es tras haber hecho unas pocas pruebas, mi impresión sobre este gestor mejoró considerablemente.&lt;/p&gt;
&lt;p&gt;Para comenzar, el shell de comandos muestra una interfaz más amena y los comandos para gestionar la base de datos son más intuitivos, siendo muchos de ellos sentencias SQL (hay que decir que no dispone de ayuda en línea sobre las palabras clave de SQL). Por otro lado, la API de PHP para acceder a MySQL era muchísimo más sencilla de usar, teniendo un estilo mucho más natural.&lt;/p&gt;
&lt;p&gt;Impresiones en contra, la imposibilidad de usar subconsultas, así como también la definición de vistas, aunque según la documentación oficial, éstas dos características serán incluidas en la versión 4.1 aproximadamente (en las versiones actuales, se incluyen dos comandos, LEFT JOIN y RIGTH JOIN, que son capaces de suplir las subconsultas en gran parte de los casos, obteniendo, por otra parte, una mayor eficiencia).&lt;/p&gt;
&lt;p&gt;La verdad es que aunque estas diferencias son agradables, no llegan a tener una importancia suficiente como para cambiar el gestor que habitualmente solemos usar. Este tipo de cambios deberían estar basados en diferencias en el rendimiento que se nos ofrece, que es lo que se tratará en el siguiente apartado.&lt;/p&gt;
&lt;h1 id=&#34;a-nameaen14a4-comparativa&#34;&gt;&lt;a name=&#34;AEN14&#34;&gt;&lt;/a&gt;4. Comparativa&lt;/h1&gt;
&lt;h2 id=&#34;a-nameaen110a41-introducción&#34;&gt;&lt;a name=&#34;AEN110&#34;&gt;&lt;/a&gt;4.1. Introducción&lt;/h2&gt;
&lt;p&gt;Son muchos los benchmarks que se han publicado sobre estos gestores de bases de datos, aunque muchos de ellos tienen una clara tendencia hacia uno de los dos bandos. Es por esto que hay que saber extraer bien las conclusiones a partir de un benchmark. Por ejemplo, es importante que las comparaciones entre los dos gestores se realicen en igualdad de condiciones, cosa que por otra parte, muchas veces resulta complicado debido a las distintas implementaciones que poseen estos gestores.&lt;/p&gt;
&lt;p&gt;Además, resulta muy complicado diseñar un buen benchmark, que tenga en cuenta todas las posibles mejoras de rendimiento que pueda aplicar cada uno de estos gestores. Es lógico pues, que haya algunas pruebas que se le apliquen a un gestor, y que no tenga ningún sentido realizarselas al otro.&lt;/p&gt;
&lt;p&gt;A continuación se resumen las conclusiones obtenidas a partir de diversos benchmark’s, intentando hacer un descarte de los que tenían una clara tendencia hacia uno de los bandos.&lt;/p&gt;
&lt;h2 id=&#34;a-nameaen115a42-lo-mejor-de-postgresql-&#34;&gt;&lt;a name=&#34;AEN115&#34;&gt;&lt;/a&gt;4.2. Lo mejor de PostGreSQL …&lt;/h2&gt;
&lt;p&gt;Las características positivas que posee este gestor según las opiniones más comunes en Internet, son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Posee una gran escalabilidad. Es capaz de ajustarse al número de CPUs y a la cantidad de memoria que posee el sistema de forma óptima, haciéndole capaz de soportar una mayor cantidad de peticiones simultáneas de manera correcta (en algunos benchmarks se dice que ha llegado a soportar el triple de carga de lo que soporta MySQL).&lt;/li&gt;
&lt;li&gt;Implementa el uso de rollback’s, subconsultas y transacciones, haciendo su funcionamiento mucho más eficaz, y ofreciendo soluciones en campos en las que MySQL no podría.&lt;/li&gt;
&lt;li&gt;Tiene la capacidad de comprobar la integridad referencial, así como también la de almacenar procedimientos en la propia base de datos, equiparándolo con los gestores de bases de datos de alto nivel, como puede ser Oracle.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-nameaen125a43--y-lo-peor&#34;&gt;&lt;a name=&#34;AEN125&#34;&gt;&lt;/a&gt;4.3. … y lo peor&lt;/h2&gt;
&lt;p&gt;Por contra, los mayores inconvenientes que se pueden encontrar a este gestor son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Consume gran cantidad de recursos.&lt;/li&gt;
&lt;li&gt;Tiene un límite de 8K por fila, aunque se puede aumentar a 32K, con una disminución considerable del rendimiento.&lt;/li&gt;
&lt;li&gt;Es de 2 a 3 veces más lento que MySQL.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-nameaen135a44-lo-mejor-de-mysql-&#34;&gt;&lt;a name=&#34;AEN135&#34;&gt;&lt;/a&gt;4.4. Lo mejor de MySQL …&lt;/h2&gt;
&lt;p&gt;Es evidente que la gran mayoría de gente usa este gestor en Internet, por lo que encontrar opiniones favorables no ha resultado en absoluto complicado:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sin lugar a duda, lo mejor de MySQL es su velocidad a la hora de realizar las operaciones, lo que le hace uno de los gestores que ofrecen mayor rendimiento.&lt;/li&gt;
&lt;li&gt;Su bajo consumo lo hacen apto para ser ejecutado en una máquina con escasos recursos sin ningún problema.&lt;/li&gt;
&lt;li&gt;Las utilidades de administración de este gestor son envidiables para muchos de los gestores comerciales existentes, debido a su gran facilidad de configuración e instalación.&lt;/li&gt;
&lt;li&gt;Tiene una probabilidad muy reducida de corromper los datos, incluso en los casos en los que los errores no se produzcan en el propio gestor, sino en el sistema en el que está.&lt;/li&gt;
&lt;li&gt;El conjunto de aplicaciones Apache-PHP-MySQL es uno de los más utilizados en Internet en servicios de foro (Barrapunto.com) y de buscadores de aplicaciones (Freshmeat.net).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-nameaen149a45--y-lo-peor&#34;&gt;&lt;a name=&#34;AEN149&#34;&gt;&lt;/a&gt;4.5. … y lo peor&lt;/h2&gt;
&lt;p&gt;Debido a esta mayor aceptación en Internet, gran parte de los inconvenientes se exponen a continuación, han sido extraídos de comparativas con otras bases de datos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Carece de soporte para transacciones, rollback’s y subconsultas.&lt;/li&gt;
&lt;li&gt;El hecho de que no maneje la integridad referencial, hace de este gestor una solución pobre para muchos campos de aplicación, sobre todo para aquellos programadores que provienen de otros gestores que sí que poseen esta característica.&lt;/li&gt;
&lt;li&gt;No es viable para su uso con grandes bases de datos, a las que se acceda continuamente, ya que no implementa una buena escalabilidad.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;a-nameaen15a5-conclusión&#34;&gt;&lt;a name=&#34;AEN15&#34;&gt;&lt;/a&gt;5. Conclusión&lt;/h1&gt;
&lt;p&gt;Después de haber leído diversos artículos sobre estos gestores de bases de datos, FAQ’s y benchmarks (algunos con un curioso “modus operandi”), la conclusión que se puede sacar es que en realidad no hay que sacar ninguna conclusión sobre el tema. Cada uno de estos gestores es idóneo para ciertos campos, e intentar utilizar el otro acarrearía una pérdida de productividad del programa, como también grandes quebraderos de cabeza.&lt;/p&gt;
&lt;p&gt;Ninguno de estos dos gestores son totalmente perfectos, por lo que no hay que obcecarse en la elección única y fanática, como se suele hacer en muchos casos de alguno de ellos. Simplemente se trata de escoger el más conveniente en cada caso. Éstos son los grandes inconvenientes y a la vez las grandes maravillas que conlleva el mundo OpenSource.&lt;/p&gt;
&lt;p&gt;Como reflexión final, creo que la pregunta con la que se introducía el escritp podría transformarse en: ¿velocidad o potencia?, siendo su carácter mucho más acertado.&lt;/p&gt;
&lt;h1 id=&#34;a-nameaen16a-bibliografía&#34;&gt;&lt;a name=&#34;AEN16&#34;&gt;&lt;/a&gt; Bibliografía&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&#34;MYSQL&#34;&gt;&lt;/a&gt;[MySQL_Manual] &lt;i&gt;Manual de MySQL&lt;/i&gt;, &lt;a href=&#34;https://dev.mysql.com/doc/&#34; target=&#34;_top&#34;&gt;&lt;a href=&#34;https://dev.mysql.com/doc/&#34;&gt;https://dev.mysql.com/doc/&lt;/a&gt;&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;a name=&#34;POSTGRES&#34;&gt;&lt;/a&gt;[PostGreSQL_Manual] &lt;i&gt;Manual de PostGreSQL&lt;/i&gt;, &lt;a href=&#34;https://www.postgresql.org/docs/&#34; target=&#34;_top&#34;&gt;&lt;a href=&#34;https://www.postgresql.org/docs/&#34;&gt;https://www.postgresql.org/docs/&lt;/a&gt;&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;a name=&#34;ART1&#34;&gt;&lt;/a&gt;[Article_MySQL-PostGreSQL] &lt;i&gt;Artículo comparativo&lt;/i&gt;, &lt;a href=&#34;http://www.phpbuilder.com/columns/tim20000705.php3?page=1&#34; target=&#34;_top&#34;&gt;&lt;a href=&#34;http://www.phpbuilder.com/columns/tim20000705.php3?page=1&#34;&gt;http://www.phpbuilder.com/columns/tim20000705.php3?page=1&lt;/a&gt;&lt;/a&gt; .&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>About me</title>
      <link>https://danielpecos.com/about-me/</link>
      <pubDate>Sun, 30 Oct 2016 22:17:20 +0100</pubDate>
      
      <guid>https://danielpecos.com/about-me/</guid>
      
      <description>&lt;p&gt;Software developer, expert in technologies like &lt;strong&gt;JVM languages, Node.js, Golang &amp;amp; frontend&lt;/strong&gt;, among others, with a wide range expertise in several technology stacks like &lt;strong&gt;MEAN&lt;/strong&gt; (MongoDB, ExpressJS, Angular, Node.JS) or &lt;strong&gt;Java/JEE&lt;/strong&gt; (SCJP5 Certified).&lt;/p&gt;
&lt;img class=&#34;alignright&#34; src=&#34;https://danielpecos.com/assets/2016/10/nodejs_big.png&#34; alt=&#34;Node.Js&#34; data-recalc-dims=&#34;1&#34; /&gt;
&lt;p&gt;Passionate about his job, loves non-stop learning, blogging and facing new challenges to improve in what he enjoys most: creating software. And if it can improve someone else&amp;rsquo;s life, even better.&lt;/p&gt;
&lt;p&gt;TDD and agile practitioner, has developed several OpenSource projects pet projects as well as for final clients, always trying to apply latest technologies to improve final user experience. Take a look in one of these sites.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Github: &lt;a href=&#34;https://github.com/dpecos&#34;&gt;https://github.com/dpecos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BitBucket: &lt;a href=&#34;https://bitbucket.org/dpecos&#34;&gt;https://bitbucket.org/dpecos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2016/10/freelance-300x199.jpg&#34; alt=&#34;Freelance&#34; width=&#34;225&#34; height=&#34;150&#34; data-recalc-dims=&#34;1&#34; /&gt;
&lt;p&gt;&lt;strong&gt;Freelance consultant&lt;/strong&gt;. More than 10 years developing web based (enterprise and public) solutions.&lt;/p&gt;
&lt;p&gt;Currently based in Amsterdam area, Netherlands, but accepting relocations or remote positions.&lt;/p&gt;
&lt;p&gt;Active member of several local user groups (Javascript, Golang, Frontenders, Makers). Speaker and trainer in different subjects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functional Programming&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;JEE&lt;/li&gt;
&lt;li&gt;Web Security&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can contact him commenting in this page or via one of the following social network profiles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LinkedIn: &lt;a href=&#34;https://www.linkedin.com/in/danielpecos&#34;&gt;https://www.linkedin.com/in/danielpecos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Github: &lt;a href=&#34;https://github.com/dpecos&#34;&gt;https://github.com/dpecos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&#34;https://twitter.com/danielpecos&#34;&gt;https://twitter.com/danielpecos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google+: &lt;a href=&#34;https://plus.google.com/u/0/+DanielPecosMart%C3%ADnez&#34;&gt;https://plus.google.com/u/0/+DanielPecosMartínez&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Facebook: &lt;a href=&#34;https://www.facebook.com/daniel.pecos&#34;&gt;https://www.facebook.com/daniel.pecos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Un monstruo viene a verme</title>
      <link>https://danielpecos.com/2016/10/28/un-monstruo-viene-a-verme/</link>
      <pubDate>Fri, 28 Oct 2016 05:43:14 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/28/un-monstruo-viene-a-verme/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/monstruo-viene-verme-NUBE-TINTA/dp/8416588112%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D8416588112&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/Un-monstruo-viene-a-verme.jpg&#34; alt=&#34;Un monstruo viene a verme&#34; width=&#34;350&#34; height=&#34;518&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;Es media noche, Conor apenas se despierta luego de tener la misma pesadilla que lo agobia todos los días. Pero, en esta instancia los hechos han sido diferentes, ya que esta vez un monstruo lo espera en el jardín de su hogar, pues el árbol antiguo y robusto que antes solía observar desde la ventana de la cocina, ahora dispone de brazos, piernas y un rostro completamente aterrador.&lt;/p&gt;
&lt;p&gt;Sin embargo, el monstruo no pretende asustarlo, tan solo está buscando una cosa: la verdad, algo que Conor no desea contar bajo ninguna circunstancia. Este personaje tiene trece años de edad, y está atravesando una pésima situación, dado a que su madre se encuentra enferma de cáncer, además sufre de acoso escolar y su padre no vive con él, pues vive en América tras conocer a otra mujer.&lt;/p&gt;
&lt;p&gt;Pero lo único que el adolescente quiere es que la visita del monstruo suponga el fin de las pesadillas que lo asedian durante todas las noches. Así se produce el desenlace de &lt;strong&gt;Un monstruo viene a verme&lt;/strong&gt;, un libro que hace referencia a las dificultades por la que atravesamos los seres humanos para aceptar una valiosa pérdida y lidiar con los lazos vulnerables que nos mantienen sujetos a la vida.&lt;/p&gt;
&lt;h3 id=&#34;la-aleación-perfecta-entra-la-realidad-y-la-ficción&#34;&gt;La aleación perfecta entra la realidad y la ficción&lt;/h3&gt;
&lt;p&gt;Al comienzo de la historia, da la impresión de que nos estamos adentrando a un cuento de terror, pero al sumergirte más en la lectura de &lt;strong&gt;Un monstruo viene a verme&lt;/strong&gt;, notarás que realmente se trata de una trama muy profunda, que conjuga a la perfección lo irreal con la más severa realidad.&lt;/p&gt;
&lt;p&gt;Empleando un vocabulario fácil de comprender, que está al alcance de todo público, el escritor Patrick Ness nos invita tácitamente a reflexionar y a pensar acerca de la realidad antes de pasar cada página. El estilo en que se relata la historia es sumamente impecable y logra que la lectura sea diferible y fácil, por lo que no se torna pesada en ningún momento.&lt;/p&gt;
&lt;p&gt;En síntesis, Un monstruo viene a verme despertará en ti un cúmulo de emociones, ya que te hará reír, reflexionar y hasta llorar, pero lo más importante es que podrás disfrutar de los escenarios que se crean en esta historia fantástica.&lt;/p&gt;
&lt;h3 id=&#34;merecedor-de-números-premios&#34;&gt;Merecedor de números premios&lt;/h3&gt;
&lt;p&gt;Este libro ha sido publicado en diecisiete países y ha sido galardonado con el Premio Nacional Galaxy, gracias a la votación de un grupo de libreros especialistas en el área, también ostenta el Premio The Red House, donde el laurel depende de la decisión de un grupo de niños.&lt;/p&gt;
&lt;p&gt;Además, &lt;strong&gt;Un monstruo viene a verme&lt;/strong&gt; es el primer libro en ganar al unísono, dos de los más famosos premios del Reino Unido, que son: la Medalla Kate Greenaway, en virtud de las asombrosas ilustraciones de Jim Kay, y la Medalla Carnegie al mérito literario del escritor, Patrick Ness, aunque la idea de la historia se le atribuye a Siobhán Dowd, la autora de varios libros juveniles, que no pudo culminar el material bibliográfico tras fallecer en 2007.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Inferno</title>
      <link>https://danielpecos.com/2016/10/25/inferno/</link>
      <pubDate>Tue, 25 Oct 2016 05:38:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/25/inferno/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.es/Inferno-versi%C3%B3n-espa%C3%B1ola-Dan-Brown-ebook/dp/B00CHSPHWY%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00CHSPHWY&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/libro-inferno-dan-brown.jpg&#34; alt=&#34;Inferno&#34; width=&#34;367&#34; height=&#34;519&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;El profesor Robert Langdon se despierta a mitad de la noche en un hospital, con una herida en la cabeza ocasionada por una bala, sin embargo, el docente de simbología no tenía idea de cómo sucedieron los hechos, ya que no recuerda nada de los últimos dos días, tampoco cómo había llegado al centro médico, ni de la procedencia de una objeto macabro que hallaron en el bolsillo de su chaqueta.&lt;/p&gt;
&lt;h3 id=&#34;una-historia-llena-de-acertijos&#34;&gt;&lt;strong&gt;Una historia llena de acertijos&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Tras lo ocurrido, el mundo de Langdon pronto se transforma en un caos, por lo que se ve obligado a huir por las calles de Florencia, ya que en el hospital donde se encontraba internado una joven buscó asesinarlo. Sin embargo, una inteligente doctora llamada Sienna Brooks, le salva la vida ayudándolo a salir del centro hospitalario. En su huida y con la compañía de la doctora, el profesor irá a reunir información que lo conducirán a nuevos desafíos y retos, que le permitirán descifrar códigos y jeroglíficos, que a medida en que se topa con estos acertijos la trama se va tornando más siniestra e inquietante.&lt;/p&gt;
&lt;p&gt;Al tiempo descubre, que no solamente la joven del hospital quería quitarle la vida, sino también unos “hombres de negro”, que estaban equipados con tecnología de punta. Langdon y Sienna recorren escenarios conocidos en Florencia como el Palacio Vecchio y los jardines Boboli, entre otros lugares.&lt;/p&gt;
&lt;p&gt;En su camino por las calles, el profesor se encuentra con símbolos, llamativos cuadros, estatuas y sitios con pasadizos secretos por toda Florencia, una parte de Venecia y en Estambul, por lo que no tardará en percatarse de que está ante una conjunto de códigos diseñados por un científico obsesionado con el fin del mundo, que solo es comparable a su atracción que tiene por una de las obras maestras de más reconocimiento en el mundo: Inferno de Dante Aligheri.&lt;/p&gt;
&lt;h3 id=&#34;un-libro-complicado-pero-logra-enganchar&#34;&gt;Un libro complicado pero logra enganchar&lt;/h3&gt;
&lt;p&gt;El Infierno de Dan Brown es una lectura complicadamente divertida, que es capaz de cautivar al lector a través de la belleza del arte, la literatura italiana y la historia, mientras que a su vez plantea conjeturas acerca del rol que tendrá la ciencia en los tiempos venideros. Por otro lado, la trama mantiene una coherencia y lógica muy interesante.&lt;/p&gt;
&lt;p&gt;Además, nos ofrece una percepción muy llamativa, a medio camino, entre los hechos y las suposiciones sobre la vida y obra de Dante. En la historia se van desnudando paulatinamente la influencia que tuvo el escritor en el concepto cristiano del infierno y cómo su obra influyó en la visión religiosa de otros artistas.&lt;/p&gt;
&lt;h3 id=&#34;el-infierno-de-dan-brown-y-su-gran-lanzamiento&#34;&gt;El infierno de Dan Brown y su gran lanzamiento&lt;/h3&gt;
&lt;p&gt;El Infierno de Dan Brown fue traducido en alemán. Turco, francés, catalán, español, neerlandés, italiano, portugués, entre otras lenguas, todo esto con el propósito de ser lanzado mundialmente de manera simultánea en estos países.&lt;/p&gt;
&lt;p&gt;Pero, aunque este libro, tiene sus puntos cuestionables desde la perspectiva de la calidad narrativa, aun así, logra enganchar al lector e introducirlo en un universo de maquinaciones y conspiraciones del que difícilmente se puede huir una vez que se entra en él.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Me cuesta llegar a fin de mes, ¿cómo ahorro?</title>
      <link>https://danielpecos.com/2016/10/20/me-cuesta-llegar-fin-mes-ahorro/</link>
      <pubDate>Thu, 20 Oct 2016 06:09:27 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/20/me-cuesta-llegar-fin-mes-ahorro/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2016/10/ahorrar-en-septiembre.jpg&#34; alt=&#34;Llegar a fin de mes&#34; width=&#34;300&#34; height=&#34;199&#34; /&gt;Ya hemos comentado que &lt;a href=&#34;http://inversornovato.es/la-base-de-la-inversion-el-ahorro/&#34;&gt;el ahorro es la base de la inversión&lt;/a&gt;, pero &lt;strong&gt;¿cómo conseguir ahorrar si a duras penas llego a fin de mes?&lt;/strong&gt; Aunque sin fácil solución, te voy a comentar algunos trucos o consejos que he utilizado en alguna ocasión.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Primero y posiblemente el más importante: &lt;strong&gt;reduce gastos fijos&lt;/strong&gt;. ¿Necesitas todo lo que tienes contratado? Puedes empezar por reducir la cobertura del seguro del coche, la velocidad del internet contratado, la tarifa del móvil, incluso servicios absurdos, como por ejemplo el servicio de identificación de llamadas de la línea fija (sí, no es broma, 1€/mes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Renegociar condiciones hipotecarias&lt;/strong&gt;: puede que no sea fácil o incluso una opción en ese determinado momento, pero estad siempre pendientes de las condiciones hipotecarias que ofrece el mercado. Es posible que un cambio de banco o una renegociación de condiciones con el actual, nos ayude a aumentar nuestro líquido disponible. Consejo: tratad de no alargar los plazos de amortización, eso se termina traduciendo en mayor pago de intereses al final del préstamo o hipoteca.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Austeridad&lt;/strong&gt;: si tenemos problemas para llegar a fin de mes, reduce gastos puntuales que no sean directamente esenciales: eventos sociales (cines, cenas, cubatas, …), llévate comida de casa en vez de comer de restaurante o trata de reducir el uso del coche (haz un uso compartido o incluso utiliza la bicicleta si es posible)&lt;/li&gt;
&lt;li&gt;Busca &lt;strong&gt;liquidez a coste 0&lt;/strong&gt;: por ejemplo, un truco que he usado en alguna ocasión para no tirar de crédito de tarjeta para obtener liquidez consiste en hacer compras de valor importante de familiares que vayan a comprar por voluntad propia (no es cuestión de obligarles a gastarse el dinero), pagarlas con mi tarjeta en modo aplazado a final de mes (que en mi caso, y seguro que en el de muchos más, no tiene coste alguno) y que éstos nos den el dinero en metálico. Con esto conseguimos algo de liquidez extra. Aunque no hay que pasarse con ésto, ¡a final de mes llegará puntualmente el acumulado total de la tarjeta!&lt;/li&gt;
&lt;li&gt;Buscar &lt;strong&gt;ingresos extras&lt;/strong&gt;: buscar tareas en webs de freelance que nos permitan obtener un dinero extra. Por lo normal, requerirán que les dediquemos un determinado esfuerzo / tiempo (&lt;strong&gt;estamos vendiendo nuestro tiempo, que es el único bien del que disponemos y que siempre va en decremento&lt;/strong&gt;), por lo que no es el ideal, pero siempre será mejor que aumentar nuestro endeudamiento. Lo ideal sería conseguir una &lt;strong&gt;fuente de ingresos pasivos&lt;/strong&gt;, pero eso es algo que requiere algún tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para terminar, mi última recomendación es que trates por todo lo posible de pedir préstamos o aplazar pagos de tarjetas. Todo esto tiene un coste asociado, por lo que terminarás pagando más de lo que inicialmente precisabas, por lo que si no es del todo imprescindible (y en tal caso, meditar largo y tendido si realmente nos va a hacer algún bien) evita el contratar este tipo de servicios.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>El Juego de Ender</title>
      <link>https://danielpecos.com/2016/10/20/el-juego-de-ender/</link>
      <pubDate>Thu, 20 Oct 2016 06:00:02 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/20/el-juego-de-ender/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.es/El-juego-Ender-B-Books-ebook/dp/B00DSNF5OM%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00DSNF5OM&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-Juego-de-Ender.jpg&#34; alt=&#34;El Juego de Ender&#34; width=&#34;359&#34; height=&#34;550&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;Una especie extraterrestre con apariencia de insectos ataca la Tierra. Estos seres son capaces de comunicarse telepáticamente y se catalogan como una especie superior a los humanos, por lo que se proponen destruir a cada persona que habite en el mundo.&lt;/p&gt;
&lt;p&gt;Sin embargo, la humanidad tratará de evitar su exterminio, así que para vencer a los insectores (nombre de los extraterrestres) necesitan de un genio militar capaz de contrarrestar esta amenaza, por lo que permiten el nacimiento de Ender, el tercer primogénito de una pareja en un planeta donde se ha reducido el número de descendientes a dos personas.&lt;/p&gt;
&lt;p&gt;Ender nació para recibir entrenamiento especial en una estación, luego de que su hermana mayor y Peter (su hermano) hayan sido considerados como no aptos para la misión. Y bajo la estricta supervisión de la Flota Internacional, el respetado Coronel Hyrum Graff se hace cargo de comandar el entrenamiento, donde estos jóvenes, quienes se distribuyen en grupos, combaten entre sí, utilizando armas que paralizan sus armaduras.&lt;/p&gt;
&lt;h3 id=&#34;los-simuladores-en-el-juego-de-ender&#34;&gt;&lt;strong&gt;Los simuladores en El Juego de Ender&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;En consecuencia, Ender deberá aprender cada uno de las técnicas alusivas a la guerra a través de videojuegos y en los difíciles ensayos de batallas que realiza junto a sus compañeros de entrenamiento. Por consiguiente, a la habilidad de cómo se narran las emociones en esta novela, también se le añade un elemento muy llamativo, que es el empleo de las simulaciones y juegos de fantasía en la preparación militar, psicológica y estratégica del protagonista.&lt;/p&gt;
&lt;p&gt;Ahora bien, Ender logra desarrollar habilidades únicas y su potencial para luchar es más avanzada que la de los demás, así que rápidamente sube de rango en la estación y termina convirtiéndose en un líder indiscutible, es decir, en el guerrero más apto para dar órdenes a las flotas terrestres contras los insectores. Sin embargo, al llegar a la Escuela de Alto Mando, el prodigioso guerrero se percata que la guerra contra la especie extraterrestre es mucho más difícil de lo que se había imaginado.&lt;/p&gt;
&lt;h3 id=&#34;el-futuro-del-mundo-depende-de-ender&#34;&gt;&lt;strong&gt;El futuro del mundo depende de Ender&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;De esta forma, comienza la acción en &lt;strong&gt;El Juego de Ender&lt;/strong&gt;, donde se pretende salvar a la humanidad de un Apocalipsis y un futuro devastador. Así que el destino de la humanidad está en mano del nuevo y legendario Mazer, que es nada menos que Ender Wiggin, cuya personalidad es bastante tímida pero posee un talento innato y peligroso para los enfrentamientos bélicos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Una lectura épica&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El Juego de Ender&lt;/strong&gt; está perfectamente relatado, gracias a que logra recrearte imágenes en tu mente acerca de las batallas, de manera que te las imaginas totalmente, lo que resulta muy divertido a la hora de leer un libro.&lt;/p&gt;
&lt;p&gt;Por otra parte, el autor Orson Scott Card, describe de manera excepcional los diferentes estados de ánimo del protagonista, que frecuentemente tiende a reflexionar acerca del sentido del juego, incluyendo a sus jóvenes compañeros, colegas, superiores y sus subordinados, así como también a su familia.&lt;/p&gt;
&lt;p&gt;Si obtienes &lt;strong&gt;El Juego de Ender&lt;/strong&gt; te darás un gran banquete y tendrás la oportunidad de disfrutar de un bestseller, que fue galardonado en los premios más afamados de la ciencia ficción: el Premio Nébula como la mejor novela en 1985 y un año después el Premio Hugo.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>El Marciano</title>
      <link>https://danielpecos.com/2016/10/17/el-marciano/</link>
      <pubDate>Mon, 17 Oct 2016 06:00:05 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/17/el-marciano/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.es/El-marciano-Andy-Weir-ebook/dp/B00OXYQR38%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00OXYQR38&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/El-marciano-1.jpg&#34; alt=&#34;El Marciano&#34; width=&#34;350&#34; height=&#34;534&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;El astronauta de la NASA, ingeniero mecánico y botánico, Mark Watney, es integrante de una tripulación de seis personas de la misión Ares 3, que está destinada en ser la primera en aterrizar y realizar estudios en Marte. Pero una tormenta de arena con vientos que supera a gran escala los pronósticos de la NASA, obligó al equipo espacial a abandonar el Hab (habitáculo donde iban a residir) y a despegar hacia la Hermes (la nave espacial en la que llegaron en órbita).&lt;/p&gt;
&lt;p&gt;Durante el proceso de evacuación, el potente viento marciano desprendió la antena parabólica de radio del Hab, impactando en la integridad física de Mark, ocasionándole una herida en la zona del abdomen y al mismo tiempo fue arrastrado por el viento, lo que generó que se extraviara en Marte.&lt;/p&gt;
&lt;p&gt;Ante este incidente, Lewis, quien es la capitana de la misión, luego de varios intentos de rescatar a Mark toma la decisión de abandonar Marte, pensando que el astronauta había fallecido. Pero para fortuna de Mark, el hierro de la antena y la sangre de la herida, cubren la lesión y sellan el traje, haciendo que el astronauta se mantenga con vida.&lt;/p&gt;
&lt;h3 id=&#34;sólo-en-marte&#34;&gt;&lt;strong&gt;Sólo, en Marte&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Así es cómo empieza la aventura de Mark y se genera el desenlace en El Marciano, ya que el astronauta se encuentra solo en este planeta, con alimento para un año -debido a que se queda con el suministro para seis personas- y sin probabilidad de hacer contacto con el planeta Tierra sin la antena de radio.&lt;/p&gt;
&lt;p&gt;Analizando su situación, se percata que su única oportunidad de mantenerse con vida por más tiempo es sobrevivir durante cuatro años, el tiempo que tardará en regresar la misión Ares 4.&lt;/p&gt;
&lt;p&gt;En la Tierra los científicos de la NASA se dan cuenta que Mark continúa vivo, gracias a los satélites que orbitan el planeta Marte, por lo que empiezan a trabajar para intentar auxiliarlo con las pocas opciones que tienen.&lt;/p&gt;
&lt;h3 id=&#34;su-lucha-por-sobrevivir&#34;&gt;&lt;strong&gt;Su lucha por sobrevivir&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Mark sigue luchando para seguir con vida, así que contando con su ingenio, sus habilidades y sus conocimientos de botánica, logra encarar obstáculos que parecen insuperables. Además, su sentido del humor se convierte en el motor que le provee fuerza para continuar luchando y aferrándose a la idea de seguir viviendo, por lo que ejecutará un plan maestro para ponerse en contacto con la NASA.&lt;/p&gt;
&lt;h3 id=&#34;una-gran-experiencia-literaria&#34;&gt;&lt;strong&gt;Una gran experiencia literaria&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Con un final espectacular, &lt;strong&gt;El Marciano&lt;/strong&gt; es una novela de ciencia ficción escrita por Andy Weir que se ha convertido en un bestseller online, obteniendo una gran cantidad de ventas en plataformas como Amazon.&lt;/p&gt;
&lt;p&gt;La historia forjada en este libro posee un delirio fantástico y una mecánica de suspenso que sorprende al lector, haciendo que éste se adentre en el cosmos y el instinto humano de luchar por la supervivencia. En síntesis, El Marciano hará que tengas una experiencia literaria irrepetible.&lt;/p&gt;
&lt;p&gt;Esta novela ha cautivado a insignes personajes como al astronauta y comandante de la Estación Espacial Internacional, Chris Hadfield, al autor de Ready Player One, Ernest Cline, al famoso escritor estadounidense, Steve Berry, entre otros intelectuales, fanáticos y reconocidos artífices de obras literarias.&lt;/p&gt;
&lt;p&gt;El portal de noticias The Wall Street Journal, ha catalogado a &lt;strong&gt;El Marciano&lt;/strong&gt; como: “La mejor novela de ciencia ficción en años”. ¿Qué esperas? ¡Anímate! Una vez que empieces no pararás de leerla.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Ready Player One</title>
      <link>https://danielpecos.com/2016/10/13/ready-player-one/</link>
      <pubDate>Thu, 13 Oct 2016 20:49:22 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/13/ready-player-one/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.es/Ready-Player-One-B-Books-ebook/dp/B00UVAREXK%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00UVAREXK&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/Ready-Player-One.jpg&#34; alt=&#34;Ready Player One&#34; width=&#34;300&#34; height=&#34;459&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;En el año 2044, el mundo es cada vez más un lugar sombrío, con terribles carencias para la población, razón por la cual, muchas personas escapan de esta realidad participando en el videojuego “Oasis”, entre ellas nuestro protagonista Wade Watts, un adolescente solitario, común y un tanto deprimido que sabe lo afortunado que es por tener un techo, comida suficiente y unas condiciones de vida mucho mejores que la mayoría.&lt;/p&gt;
&lt;p&gt;En “Oasis” los jugadores forman comunidades virtuales, y pueden jugar en diversos universos de ciencia ficción (Star trek, Dune, Star Wars, Firefly); sin embargo, Wade está atascado en los niveles más básicos del juego pues no tiene suficiente puntos de experiencia ni dinero virtual para viajar a esos mundos.&lt;/p&gt;
&lt;p&gt;El creador del juego, James Hallyday murió muy recientemente, y no tuvo hijos, por lo que decidió dejar su fortuna y el control del juego a quien logre encontrar un easter egg (un mensaje oculto) dentro del juego; ya van 5 años de jugadores buscando el mensaje sin éxito alguno, y la única pista que tienen es que se relaciona a los años 80s, (pues Hallyday estaba obsesionado con esa época).&lt;/p&gt;
&lt;p&gt;Es aquí cuando la vida Wade da un vuelco rotundo, al lograr descubrir una pista y avanzar en la búsqueda, ubicándose (con su pseudónimo en el juego llamado Parzival) en solitario en el ranking; esto le da prestigio en el importante mundo de Oasis, pero a la vez cambiará su vida y causará que se vea involucrado en retos y búsquedas que no pertenecen solo al mundo virtual.&lt;/p&gt;
&lt;h3 id=&#34;un-libro-amado-por-los-gamers&#34;&gt;&lt;strong&gt;Un libro amado por los gamers&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Ready Player One&lt;/strong&gt; se ha convertido en un libro de culto, es muy apreciado por retratar con autenticidad el espíritu de los gamers y su sentido de comunidad; y a la vez por incorporar elementos atrayentes para los amantes de la ciencia ficción y de lo relacionado a la cultura de los años 80s (música, videojuegos, películas, tv, juegos, cultura pop).&lt;/p&gt;
&lt;p&gt;En la historia los jugadores de Oasis usan un visor y guantes hápticos (para realidad virtual) para adentrarse en un mundo de gran realismo, donde, a su vez, es posible visitar otros mundos donde pueden o no, usar magia o tecnología; incluso es posible asistir a la Escuela en este mundo virtual.&lt;/p&gt;
&lt;h3 id=&#34;próxima-adaptación-al-cine&#34;&gt;&lt;strong&gt;Próxima adaptación al cine&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Además de su atrayente trama, otra razón para leer este libro muy pronto, es que actualmente se está filmando su adaptación cinematográfica, dirigida por el reconocido directo Steven Spielberg. El estreno está planificado para Marzo del 2018 y en el guion está participando el autor.&lt;/p&gt;
&lt;h3 id=&#34;entretenimiento-para-todos&#34;&gt;&lt;strong&gt;Entretenimiento para todos&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;En definitiva, &lt;strong&gt;Ready Player One&lt;/strong&gt; es un libro que logra atrapar a todo tipo de lectores, pues la suma de sus componentes: una buena historia con argumentos sólidos, personajes con los cuales el lector se puede sentir identificado por ser comunes y corrientes, y una búsqueda constante para alcanzar un objetivo tangible; garantizan una lectura divertida y emocionante, que ha atrapado y cautivado a millones de personas alrededor del mundo.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Harry Potter y el Legado Maldito</title>
      <link>https://danielpecos.com/2016/10/13/harry-potter-legado-maldito/</link>
      <pubDate>Thu, 13 Oct 2016 20:22:29 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/13/harry-potter-legado-maldito/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.es/Harry-Potter-legado-maldito-Rowling/dp/849838754X%3FSubscriptionId%3DAKIAJHGGVVP5D22LY7JQ%26tag%3Dbiblo-es-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D849838754X&#34;&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2017/10/Harry-Potter-y-el-Legado-Maldito.jpg&#34; alt=&#34;Harry Potter y el Legado Maldito&#34; width=&#34;350&#34; height=&#34;570&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/a&gt;La historia del niño que vivió es conocida mundialmente, es referencia cultural y conserva vigencia entre las generaciones que crecieron viviendo el fenómeno de los libros y películas de Harry Potter, y aún logra atraer a muchos nuevos lectores y espectadores, curiosos y ávidos de sumarse a este universo.&lt;/p&gt;
&lt;p&gt;Es por eso, que el mundo no puedo recibir el libro “&lt;strong&gt;Harry Potter y el Legado Maldito&lt;/strong&gt;”, con más que inmensas expectativas, luego de casi diez años del final de la saga.&lt;/p&gt;
&lt;p&gt;En esta historia, J.K.Rowling nos narra, en forma de obra (el libro corresponde al texto de la obra de teatro que actualmente se presenta en Londres, con el mismo nombre) una historia situada 19 años después de que el trío dorado (Harry Potter, Hermione Granger y Ron Weasley) resulte vencedor contra Voldemort en la Batalla de Hogwarts.&lt;/p&gt;
&lt;p&gt;Es el presente y Harry, casado con Ginny Weasley tiene tres hijos, James, Albus y Lily. El hijo del medio, Albus Severus, está por empezar su primer año en Hogwarts junto a Rose Weasley (hija de Hermione y Ron), y no está muy seguro de cómo vivir bajo la sombra de todos los logros, fama y errores de su padre. Lo más peculiar es que Albus, entabla una amistad desde el principio con alguien inesperado, Scorpius Malfoy, el único hijo del conocido Draco Malfoy (enemigo de Harry y su grupo en el tiempo de Hogwarts).&lt;/p&gt;
&lt;p&gt;Por su parte, Harry Potter, héroe del mundo mágico, es Jefe del Departamento de Seguridad Mágica, y sumado a los retos que presenta este trabajo, debe lidiar con las diferencias que tiene con su hijo Albus Severus; y con hechos del pasado que insisten en seguirlo y generar conflictos que pueden tener graves consecuencias para todo el mundo mágico, incluyendo viajes en el tiempo, que como sabemos, pueden alterar gravemente lo ocurrido en pasado, presente y futuro, permitiendo la reaparición de enemigos derrotados, como Lord Voldemort.&lt;/p&gt;
&lt;h3 id=&#34;una-historia-que-nunca-muere&#34;&gt;&lt;strong&gt;Una historia que nunca muere&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;En palabras de su autora “Ninguna historia vive al menos que alguien quiera escucharla” y en definitiva, todo el universo de Harry Potter, sus incontables aventuras, sus personajes, aún tienen vigencia y causan interés, es por eso que el libro &lt;strong&gt;Harry Potter y el Legado Maldito&lt;/strong&gt; ha sido esperado con tantas ansias, no solo por los seguidores y fanáticos; sino también por el mundo literario, curioso por saber que le ha deparado el futuro a la historia del mundo mágico y que novedades ha incorporado su escritora.&lt;/p&gt;
&lt;p&gt;Algunos fanáticos de la serie se han mostrado un poco preocupados, pues no están seguros de que &lt;strong&gt;Harry Potter y el Legado Maldito&lt;/strong&gt; esté a la altura de la saga original, y sabemos que difícilmente logre complacer a todos los lectores, pues parte de la magia es lo que cada quien imagino que ocurría con los personajes luego de Harry Potter y las Reliquias de la Muerte; sin embargo, esa sensación cálida de volver a un viejo amigo, al empezar las páginas del que sería el octavo libro en la serie, de seguro estará presente para todos.&lt;/p&gt;
&lt;noscript&gt;
&lt;/noscript&gt;
</description>
    </item>
    
    <item>
      <title>Diversificar inversiones para aumentar nuestra tranquilidad</title>
      <link>https://danielpecos.com/2016/10/11/diversificar-inversiones-aumentar-nuestra-tranquilidad/</link>
      <pubDate>Tue, 11 Oct 2016 05:59:58 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/11/diversificar-inversiones-aumentar-nuestra-tranquilidad/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2016/10/business-icons-design_1133-223-e1476165867752.jpg&#34; alt=&#34;Diversificar inversiones&#34; width=&#34;300&#34; height=&#34;300&#34; /&gt;Antes de asumir el &lt;strong&gt;riesgo que supone la inversión en Bolsa&lt;/strong&gt;, quise asegurarme de que era el modo que quería utilizar para sacar rendimientos a mis ahorros. Todo el mundo sabe que invertir en bolsa es algo arriesgado y en aquel momento prefería optar a un rendimiento menor a cambio de una &lt;strong&gt;mayor seguridad de retorno de mi dinero&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;¡Manos a la obra! Acto seguido empecé a bucear por las páginas de inversión de las entidades bancarias con las que trabajo e ir extrayendo una lista de productos tipos a fin de poder investigar sobre cada uno de ellos y las condiciones que les aplican. Tras unas horas de investigación conseguí la siguiente lista de productos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Depósitos&lt;/li&gt;
&lt;li&gt;Fondos de inversión&lt;/li&gt;
&lt;li&gt;Seguros de ahorro&lt;/li&gt;
&lt;li&gt;Planes de pensiones&lt;/li&gt;
&lt;li&gt;Bolsa&lt;/li&gt;
&lt;li&gt;Y alguno más… (Tranquilos, en posteriores artículos entraré en detalle con cada uno de ellos)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;¿Por cuál decidirme? &lt;strong&gt;Cada uno tenía sus ventajas e inconvenientes&lt;/strong&gt;. Tras mucho leer en foros, llegué a una línea argumental bastante común: &lt;strong&gt;diversificar las inversiones&lt;/strong&gt;, no sólo decidiendo en qué empresas invertir, sino en qué productos utilizar. De esta forma, repartiendo tus ahorros en distintos productos, consigues una &lt;strong&gt;mayor seguridad financiera&lt;/strong&gt;. En general, no resulta conveniente poner todos los huevos en la misma cesta.&lt;/p&gt;
&lt;p&gt;El problema que le vi a este enfoque, es que, a parte de conservador, &lt;strong&gt;requería un capital considerable&lt;/strong&gt;, puesto que la diversificación lo repartiría en montoncitos de menor tamaño. En mi caso era poco viable debido a los ahorros de partida, por lo que a pesar del consejo, decidí centrarme en la inversión en bolsa.&lt;/p&gt;
&lt;p&gt;Por último y antes de terminar, quería comentaros un par de opciones que me resultaron de especial interés (por su novedad) y que recuperé a través de contactos, foros y blogs especializados en inversión:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Inversión inmobiliaria&lt;/strong&gt;: y no hablo de comprar un piso asumiendo una hipoteca (y sus intereses) con el fin de venderlo en un futuro, sino de compras en comunidad (crowdfunding), por decirlo de algún modo, que permiten destinar parte de nuestro dinero a la compra de una vivienda real, rehabilitarla, alquilarla durante un determinado tiempo, repartiéndose el importe del alquiler entre los propietarios (a modo de dividendo) para finalmente vender la vivienda y repartir beneficios. Personalmente, conocía el crowdfunding, pero no lo había visto todavía aplicado a la compra / venta inmobiliaria. Realmente me pareció muy interesante, y puesto que no hay un mínimo para participar, resulta una opción a considerar. Para más detalles, consultad la web de &lt;a href=&#34;https://www.housers.es/es&#34;&gt;Housers&lt;/a&gt; (gracias a mi amigo Fidel Añó por comentarme este tipo de inversiones!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&#34;embed-youtube&#34; style=&#34;text-align:center; display: block;&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Inversión en negocios en fases iniciales (a.k.a startups)&lt;/strong&gt;: sin duda es la opción que más retorno puede producir, pero también la más arriesgada. Por Silicon Valley se dice que más del 90% de las startups resultan fallidas. Lo suyo es, una vez más, diversificar en distintas startups y buscar ese 10% que cubra al resto de inversiones fallidas y retorne un beneficio. Y sobre todo, tratar de encontrar aquella que se convierta en &lt;strong&gt;unicornio&lt;/strong&gt; (se valore en más de 1.000 millones de $), lo cual no es tarea fácil. Aún así, si dispones de una cantidad importante de ahorros, y dado el &lt;strong&gt;efecto social que genera este tipo de inversión&lt;/strong&gt; (creación de autoempleo, fomento del emprendedurismo, buena publicidad al inversor, etc) resulta una opción a tener en cuenta.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin duda el momento actual de crisis por el que estamos pasando, aumenta la &lt;strong&gt;creatividad de las personas&lt;/strong&gt;, y no sería nada raro ver nacer nuevos tipos de productos o proyectos inversión como el de Housers.&lt;/p&gt;
&lt;p&gt;Permanezcamos atentos, lo bueno puede estar por venir.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Padre Rico, Padre Pobre</title>
      <link>https://danielpecos.com/2016/10/06/padre-rico-padre-pobre/</link>
      <pubDate>Thu, 06 Oct 2016 06:00:09 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/06/padre-rico-padre-pobre/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2016/10/Padre-Rico-Padre-Pobre-e1475605213828.jpg&#34; alt=&#34;Padre Rico, Padre Pobre&#34; width=&#34;197&#34; height=&#34;300&#34; /&gt;Intentar abordar desde el &lt;strong&gt;desconocimiento&lt;/strong&gt; una técnica de inversión para conseguir revalorizar tus ahorros, está desde mi humilde punto de vista, &lt;strong&gt;destinado al fracaso&lt;/strong&gt;. ¿Por qué tropezar con piedras con los que otros ya lo han hecho y además han explicado el camino que llevaban y sus consecuencias? (Una de las referencias que personalmente suelo utilizar para conseguir consejo es precisamente mi padre, al igual que el autor de este libro, y supongo que muchos otros más).&lt;/p&gt;
&lt;p&gt;Es por ello que ya desde un primer momento decidí que parte de los ahorros tenía que &lt;strong&gt;destinarlos al aprendizaje sobre inversión&lt;/strong&gt;, empezando por libros introductorios a este mundo. Pero no creas que resulta fácil. Existe mucha literatura que trata el tema de la inversión, y mucha de ella, de &lt;strong&gt;baja calidad o refritos de otros libros&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Por lo que tras leer algunos comentarios, decidí comenzar con éste:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.es/Padre-rico-pobre-edici%C3%B3n-actualizada-ebook/dp/B007HPS120/ref=dp_kinw_strp_1&#34;&gt;Padre Rico, Padre Pobre&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En este libro el autor narra cómo desde muy joven se introdujo en el mundo de la inversión, y las disyuntivas que se le planteaban entre su padre biológico (Padre Pobre) y el padre de su mejor amigo (Padre Rico). Padre Rico era un empresario de su pueblo natal que le enseñaría a comprender los flujos del dinero y la forma de pensar de las personas acerca del dinero y el trabajo.&lt;/p&gt;
&lt;p&gt;Es un libro realmente ameno y fácil de leer, y aunque está escrito para un entorno legal americano (hay algunos puntos legales que en España no son trasladables), me resultó &lt;strong&gt;clarificador&lt;/strong&gt; y sobre todo &lt;strong&gt;motivante&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Mi valoración personal (escala de 0 – Nada recomendable a 5 – ¿Cómo es posible que no lo tengas?): &lt;strong&gt;4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>La base de la inversión: el Ahorro</title>
      <link>https://danielpecos.com/2016/10/03/la-base-de-la-inversion-el-ahorro/</link>
      <pubDate>Mon, 03 Oct 2016 08:09:37 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/10/03/la-base-de-la-inversion-el-ahorro/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2016/10/saving-money-in-the-piggy-bank_1133-86-e1475095442900.jpg&#34; alt=&#34;Ahorro&#34; width=&#34;300&#34; height=&#34;300&#34; /&gt;Posiblemente si algo tuviera que ser la piedra angular de la inversión, apostaría a que lo es el ahorro.&lt;/p&gt;
&lt;p&gt;Y es que parece lógico que para poder invertir en cualquier tipo de producto financiero, es necesario disponer de un &lt;strong&gt;mínimo de líquido disponible&lt;/strong&gt;. Parece una obviedad, pero la &lt;strong&gt;constancia en el ahorro&lt;/strong&gt;, determinará nuestra disponibilidad de capital para la inversión.&lt;/p&gt;
&lt;p&gt;Pienso que ahorro e inversión son dos caras de una misma moneda: &lt;strong&gt;el ahorro es la herramienta que permite a la inversión hacer que éstos crezcan&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Por ello es importante preparar un &lt;a href=&#34;https://es.wikipedia.org/wiki/Estado_de_flujo_de_efectivo&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;análisis del flujo de efectivo&lt;/a&gt; mensual. Un simple &lt;strong&gt;ejercicio de introspectiva financiera&lt;/strong&gt;. No es más que una hoja de cálculo donde se indiquen todos los ingresos y gastos previstos mes a mes. No es necesario ser super detallado, pero sí no olvidar ninguno de los gastos que de forma normal ocurren en cada periodo del año (primas de seguros, gastos de comunidad, vacaciones, etc). Es muy importante ser honesto con uno mismo, así como también incluir una partida para gastos imprevistos.&lt;/p&gt;
&lt;p&gt;Con este análisis veremos cuál es nuestro disponible estimado mes a mes, y así poder determinar qué montante destinamos a ahorro. Personalmente he decidido ahorrar 500€ todos los meses. Es una cantidad que está &lt;strong&gt;ligeramente por encima de lo que me resulta cómodo&lt;/strong&gt;, pero creo que de esta forma podré acercarme más rápidamente a la libertad financiera.&lt;/p&gt;
&lt;p&gt;Todavía es pronto, pero voy intuyendo que poner todos los huevos en la misma cesta no es una opción demasiado acertada, por lo que tendré que ir planteándome cómo repartir estos ahorros mensuales en distintos tipos de inversión, no sólo bolsa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Diversificar&lt;/strong&gt; al fin y al cabo, posiblemente otras de las herramientas base para conseguir &lt;strong&gt;mayor seguridad&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;No quiero perder el foco: no quiero dejar totalmente al azar el futuro de mis ahorros, si no que quiero &lt;strong&gt;minimizar riesgos aunque ello implique un rendimiento menor&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Aunque tampoco quiero engañarme: &lt;strong&gt;algún riesgo hay que asumir&lt;/strong&gt;, aunque éste sea menor.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¿Es la bolsa la inversión que quiero para mis ahorros?</title>
      <link>https://danielpecos.com/2016/09/29/es-la-bolsa-una-buena-inversion/</link>
      <pubDate>Thu, 29 Sep 2016 05:51:17 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/09/29/es-la-bolsa-una-buena-inversion/</guid>
      
      <description>&lt;figure id=&#34;attachment_454&#34; class=&#34;wp-caption alignleft&#34;&gt;&lt;img class=&#34;size-medium&#34; src=&#34;https://danielpecos.com/assets/2016/09/ibex351-680x365-e1475095925648-300x161.jpg&#34; alt=&#34;IBEX 35&#34; width=&#34;300&#34; height=&#34;161&#34; /&gt;&lt;figcaption class=&#34;wp-caption-text&#34;&gt;Sede de la bolsa de mercados y valores de madrid&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Permíteme que te explique cómo decidí que la inversión en bolsa era el camino que quería seguir para rentabilizar mis modestas inversiones.&lt;/p&gt;
&lt;p&gt;Todo empezó por una (creo que sensata) &lt;strong&gt;preocupación por cómo llegaría al momento de mi jubilación&lt;/strong&gt;. La primera preocupación, y aunque parece remota, era siquiera si iba a disponer de una jubilación y la segunda, si la cantidad a percibir cubriría lo que a mi me gustaría. Al fin y al cabo son los últimos años de tu vida disponibles para disfrutar, tras más de 40 años de trabajo.&lt;/p&gt;
&lt;p&gt;Esto me llevó por el camino más lógico: buscar &lt;strong&gt;planes de jubilación privados&lt;/strong&gt;. Todo suena bien en un primer momento: ahorras la cantidad que te parezca oportuna (incluso algunos de ellos no te imponen una periodicidad) y además reduces tu base imponible, ahorrándote impuestos cada año. ¡Y encima el dinero genera intereses!&lt;/p&gt;
&lt;p&gt;Pero (tenía que haberlo) pierdes la disponibilidad de esos ahorros hasta el momento de la jubilación. Es verdad, hay condiciones de rescate bajo las cuales es posible recuperar tus ahorros de forma anticipada, pero en cualquier caso, si estás en esas condiciones, estás realmente jodido y el disponer o no de tus ahorros de toda la vida no es el mayor de tus problemas llegados a esa situación.&lt;/p&gt;
&lt;p&gt;Continué investigando y lo siguiente en que me fijé fueron los &lt;strong&gt;depósitos a renta fija&lt;/strong&gt; y los &lt;strong&gt;fondos de inversión&lt;/strong&gt; (en renta fija), cualquier cosa que sonara a renta variable me daba realmente pánico ¿quién en su sano juicio quiere jugarse su esfuerzo por un posible beneficio? Estos tipos de productos en general dan un buen nivel de seguridad aunque a unos intereses modestos. Aún así, frente a las ventajas fiscales que ofrecen los planes de jubilación, se me quedaban algo cortos.&lt;/p&gt;
&lt;p&gt;Así pues, parece que la renta variable es la única opción restante y no demasiado descabellada como puede ser la inversión en &lt;strong&gt;futuros, derivados o CFDs&lt;/strong&gt;. Pero mi conocimiento de este tipo de productos es muy superficial, necesitaría tiempo para conocer el mercado y las características de éstos, antes de ponerme a invertir en serio en cualquiera de estas opciones.&lt;/p&gt;
&lt;p&gt;Llegados a este punto decidí meter la cabeza en la operativa de bolsa con un capital mínimo, así que contraté el broker de ING, invertí 1.000€ en una &lt;strong&gt;ETF que replica el IBEX&lt;/strong&gt; (ahora mismo, se encuentra en valores bajos teniendo en cuenta su histórico y es de esperar que a medio / largo recupere el valor de 10.000 o más) y que además reparte &lt;strong&gt;dividendos&lt;/strong&gt; y me daría unos meses a mi mismo para formarme y poder tomar decisiones con una mejor base.&lt;/p&gt;
&lt;p&gt;Y en este punto me encuentro. En futuros posts explicaré más en detalle los distintos productos de los que he estado hablando e iré revisando los distintos libros que vaya leyendo y compartiendo mi opinión sobre ellos con todos vosotros.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¿Interesado en invertir y no sabes por dónde empezar?</title>
      <link>https://danielpecos.com/2016/09/28/interesado-invertir-no-sabes-donde-empezar/</link>
      <pubDate>Wed, 28 Sep 2016 03:55:09 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/09/28/interesado-invertir-no-sabes-donde-empezar/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2016/09/worker-with-doubts_1012-193-e1475041218469.jpg&#34; alt=&#34;Dudas inversión&#34; width=&#34;300&#34; height=&#34;300&#34; /&gt;No te sientas solo, es lo más normal.&lt;/p&gt;
&lt;p&gt;Y lo digo porque a mi me pasa exactamente lo mismo: es un mundo lleno de _jargon _y donde cometer un error sale caro, pero por contra, el potencial beneficio es muy interesante.&lt;/p&gt;
&lt;p&gt;¿Y por qué si no tengo ni idea de en lo que me estoy metiendo, sigo adelante?&lt;/p&gt;
&lt;p&gt;Primero: quiero &lt;strong&gt;ahorrar&lt;/strong&gt; y que mis ahorros crezcan lo máximo posible, como le gustaría a cualquier hijo de vecino.&lt;/p&gt;
&lt;p&gt;Segundo: aunque en este punto 0, optar por la &lt;strong&gt;libertad financiera&lt;/strong&gt; queda lejos, el objetivo está claro y el camino todo un reto.&lt;/p&gt;
&lt;p&gt;Y por último: porque es &lt;strong&gt;emocionante&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En este blog trataré de ser lo más trasparente posible sobre los pasos y decisiones que voy tomando, así como sus resultados y conclusiones. Además compartiré todos lo utilizaré como libreta de apuntes, con el fin de allanar el camino al resto de novatos que se quieran internar en este mundo de la inversión.&lt;/p&gt;
&lt;p&gt;Bienvenido!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PAPIs.io Connect 2016 – Valencia</title>
      <link>https://danielpecos.com/2016/03/15/papis-io-connect-2016-valencia/</link>
      <pubDate>Tue, 15 Mar 2016 20:35:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2016/03/15/papis-io-connect-2016-valencia/</guid>
      
      <description>&lt;img src=&#34;https://danielpecos.com/assets/2016/03/papis-lanyard.png&#34; alt=&#34;PAPIs.io Connect&#34; class=&#34;alignleft&#34; /&gt;
&lt;p&gt;I just got home after enjoying a couple of days in the &lt;a href=&#34;http://www.papis.io/connect&#34;&gt;PAPIs.io Connect&lt;/a&gt; conferences in Valencia. And they’ve been great!&lt;/p&gt;
&lt;p&gt;There have been sessions about Machine Learning, Deep Learning, APIs, AI, BigData and many more. Oh, and there have been drones too.&lt;/p&gt;
&lt;p&gt;To summarize, the ecosystem surrounding BigData and AI technologies is amazing and currently is really on fire. In my humble opinion, I think this quote from &lt;a href=&#34;https://www.linkedin.com/in/ramonlopezdemantaras&#34;&gt;Ramón López de Mántaras&lt;/a&gt;’s keynote “Past, Present and Future of AI: A fascinating journey” describes the energy and enthusiasm that people working in AI and BigData transmit when they talk about the matter:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The goal of human-level intelligence remains elusive but has inspired and still inspires our work on AI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Speakers from many different companies, like Amazon, ING, BigML, Telefonica R&amp;amp;D, So1, Ŷhat, just to name a few, have been talking about their experience in solving many different types of problems using Machine Learning technologies and what the main benefits and caveats have they found during the process.&lt;/p&gt;
&lt;img src=&#34;https://danielpecos.com/assets/2016/03/papis-topics.png&#34; alt=&#34;PAPIs.io Topics&#34; class=&#34;aligncenter&#34; /&gt;
&lt;p&gt;Just to provide an idea of the huge amount of effort and solutions around BigData and what the ecosystem looks like nowadays, nothing better than this image:&lt;/p&gt;
&lt;img src=&#34;https://danielpecos.com/assets/2016/03/bigdata-ecosystem.jpg&#34; alt=&#34;BigData ecosystem&#34; class=&#34;aligncenter&#34; /&gt;
&lt;p&gt;Great speakers, really cool topics for the talks and really nice venue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What else could you ask for?&lt;/strong&gt; Oh yeah, Valencia’s Fallas and great food!&lt;/p&gt;
&lt;p&gt;In the following link you can have a look into the activity that has happened in Twitter #papisconnect hashtag during the event:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/hashtag/papisconnect&#34;&gt;https://twitter.com/hashtag/papisconnect&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT (2016/03/16):&lt;/strong&gt; Completely forgot to mention the Startups Battle. It was really cool to see how a AI (&lt;a href=&#34;http://preseries.com/&#34;&gt;&lt;strong&gt;preseries&lt;/strong&gt;&lt;/a&gt;) drives an &lt;em&gt;interview&lt;/em&gt; in order to rank an startup, using BigML technology and Amazon Echo. My only &lt;em&gt;concern&lt;/em&gt; was that it never asked a single question about any project at all, just questions about the team experience and seed rounds. Is that the only thing that matters to get your project fund? Don’t think so.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Surprises with Java packages</title>
      <link>https://danielpecos.com/2015/12/23/surprises-with-java-packages/</link>
      <pubDate>Wed, 23 Dec 2015 16:30:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/12/23/surprises-with-java-packages/</guid>
      
      <description>&lt;p&gt;Packages in Java is a quite simple and straightforward concept of the language. It’s there from the beginning and it’s commonly used by every Java programmer. In a few words, these are the rules you have to follow to create a class inside a package (spoiler: which are not completely true, as we’ll see later):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Package statement must be the first one specified in a java class file&lt;/li&gt;
&lt;li&gt;A package namespace must match the physical path of the file, i.e a class defined with a package &lt;code class=&#34;highlighter-rouge&#34;&gt;a.b.c&lt;/code&gt; must be placed in a path &lt;code class=&#34;highlighter-rouge&#34;&gt;a/b/c/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Easy right? Let’s check…&lt;/p&gt;
&lt;p&gt;Turns out that the second rule is not mandatory but a recommendation (a good one, BTW), but Eclipse IDE enforces it to the point that if you don’t follow it, it throws a compilation error. Let’s open the following class in Eclipse:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package a.b.c;

public class HelloWorld {
 public static void main(String[] args) {
   System.out.println(&amp;#34;Hello world!&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And you’ll get the following error:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://danielpecos.com/assets/2015/12/eclipse_error.png&#34; alt=&#34;Eclipse error with package statement&#34;&gt;&lt;/p&gt;
&lt;p&gt;But as I said, it’s not a restriction of the language but from the IDE itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://bugs.eclipse.org/bugs/show_bug.cgi?id=16209&#34;&gt;https://bugs.eclipse.org/bugs/show_bug.cgi?id=16209&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://stackoverflow.com/questions/8395916/package-name-is-different-than-the-folder-structure-but-still-java-code-compiles&#34;&gt;http://stackoverflow.com/questions/8395916/package-name-is-different-than-the-folder-structure-but-still-java-code-compiles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In fact, turns out that manually compiling this class works perfectly fine (also tried maven and worked flawesly):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ javac src/HelloWorld.java -d bin

$ java -cp bin a.b.c.HelloWorld
Hello world!

$ tree bin/
bin/
└── a
    └── b
        └── c
            └── HelloWorld.class
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Corollary: if you’re a programmer, don’t trust even the most basic and accepted statement you could think of. Even if you’re absolutely right at this very moment, it will eventually be modified and surprise you.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Codemotion 2015</title>
      <link>https://danielpecos.com/2015/11/29/codemotion-2015/</link>
      <pubDate>Sun, 29 Nov 2015 22:00:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/11/29/codemotion-2015/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://2015.codemotion.es&#34;&gt;&lt;img src=&#34;https://danielpecos.com/assets/2015/11/codemotion.png&#34; alt=&#34;Codemotion 2015&#34; class=&#34;alignleft&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day after Codemotion 2015, this is my overall opinion of the event: meh. Don’t get me wrong, technical sessions have been quite interesting, full of really nice people and organization must have worked really to get the event running. But, in my opinion, this event is dying of success. Way too many assistants, making really hard to walk from one session to another (even having 15 min between them), or having to arrive 30 min before start if you’re intention was to have a nice place to plug your laptop and be able to see the presentation.&lt;/p&gt;
&lt;p&gt;Now, speaking about content, it’s really nice to have so much diversity to choose from in every time slot (although sometimes you were force to discard really nice sessions). Personally, I chose to assist to an JVM / Scala track that covered approximately the whole time slots of the first day (and part of the second) without significant overlaps. BTW, really interesting stuff is happening around the JVM, nothing to envy to the Node.js community.&lt;/p&gt;
&lt;p&gt;But I also wanted to have a look into different technologies which were newer to me, such as Docker or Big Data. And it’s impressive how much has the technology evolved and what amazing things are people achieving in these fields. Currently, recorded sessions are &lt;del&gt;not yet published&lt;/del&gt; &lt;a href=&#34;https://www.youtube.com/channel/UCd_1KHg4t2VKGsSDF8OD5Cw/videos&#34;&gt;already published!&lt;/a&gt;, but I’m pretty sure it will be worth taking a look into what I missed.&lt;/p&gt;
&lt;img src=&#34;https://danielpecos.com/assets/2015/11/ray_dani_small.jpg&#34; alt=&#34;StreetFighter&#34; class=&#34;aligncenter&#34; /&gt;
&lt;p&gt;But as always, the best thing of these events is the people you meet, old and new acquaintances. And, of course, nothing as a good as an old arcade machine and a StreetFighter match in the chill out area to relax and have some fun 😉&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Coursera: Principles of Reactive Programming</title>
      <link>https://danielpecos.com/2015/04/07/coursera-principles-of-reactive-programming/</link>
      <pubDate>Tue, 07 Apr 2015 03:32:33 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/04/07/coursera-principles-of-reactive-programming/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2015/04/principles-reactive-v1.0-300x169.jpg&#34; alt=&#34;Principles of Reactive Programming&#34; width=&#34;300&#34; height=&#34;169&#34; /&gt;In little less than a week, a new edition of Coursera&amp;rsquo;s course, &lt;a href=&#34;https://www.coursera.org/course/reactive&#34;&gt;Principles of Reactive Programming&lt;/a&gt; from Martin Odersky, Erik Meijer and Roland Kuhn, is launching.&lt;/p&gt;
&lt;p&gt;This course is a follow-up of &lt;a href=&#34;https://www.coursera.org/course/progfun&#34;&gt;Principles of Functional Programming in Scala&lt;/a&gt;, which I took in its first edition and which I enjoyed a lot. I&amp;rsquo;ve regretted missing out first edition of this second course for a long time (more than a year, in fact), so if you want to learn about this magnificent frameworks of the Scala world, don&amp;rsquo;t miss this chance!&lt;/p&gt;
&lt;p&gt;And best of all, it&amp;rsquo;s free!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Java 8 and Functional Programming</title>
      <link>https://danielpecos.com/2015/04/02/java-8-functional-programming/</link>
      <pubDate>Thu, 02 Apr 2015 10:54:58 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/04/02/java-8-functional-programming/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2015/04/duke_lambda.jpg&#34; alt=&#34;Duke Lambda&#34; width=&#34;230&#34; height=&#34;229&#34; /&gt;Purpose of this post is to provide a glimpse of the new features included in Java 8 that shift this language towards a more Functional Programming paradigm. But before, let’s define what we understand for Functional Programming (FP). Functional programming key characteristics include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Higher Order Functions&lt;/li&gt;
&lt;li&gt;Pure Functions and Immutability&lt;/li&gt;
&lt;li&gt;Tail Call Recursion&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Higher Order Functions&lt;/strong&gt; for a FP language means that functions are considered first class citizens, allowing the programmer to use them as any other value the language defines, for example, a Function value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can be assigned to a variable defined with a proper type&lt;/li&gt;
&lt;li&gt;can be passed or returned to/from another functions, allowing functions to be composed or _curried_ (partially applied).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Pure Functions&lt;/strong&gt; are those functions that don’t produce &lt;em&gt;side effects&lt;/em&gt;. Instead of directly modifying data structures within the function body, those data structures are returned as result of the invocation. This behaviour results in &lt;strong&gt;Immutable data structures&lt;/strong&gt;, which are far less error prone than classical mutable data structures.&lt;/p&gt;
&lt;img class=&#34; size-medium alignright&#34; src=&#34;https://danielpecos.com/assets/2015/04/xkcd-functional-252x300.png&#34; alt=&#34;Tail recursion&#34; width=&#34;252&#34; height=&#34;300&#34; /&gt;
&lt;p&gt;&lt;strong&gt;Tail Call Recursion&lt;/strong&gt; allows a compiler to reuse a call stack frame in a recursive algorithm, making the execution behave (in terms of memory allocation) as if it were an iterative algorithm. Instead of allocating new stack frames for every recursive call, if the structure of the call follows an specific pattern, the compiler then can reuse same frame, making possible the use recursion without any increase in program’s memory footprint.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2015/04/tail_call.jpg&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2015/04/tail_call-300x216.jpg&#34; alt=&#34;Tail Call Optimization&#34; width=&#34;300&#34; height=&#34;216&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, what does Java 8 include in order to make FP paradigm closer to the programmer? The key feature included in this release is are &lt;strong&gt;Lambda Expressions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But what’s a Lambda Expression? Well, it just a syntactic sugar included in the language,  reducing the amount of code needed to work with anonymous classes. Lambdas’ its syntax kind of reminds of a closure or monad, but let’s better see an example of a lambda:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; System.out.println(&amp;#34;Hello Lambdas!&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But, as previously said, this could also be defined as anonymous class, as this is &lt;em&gt;just&lt;/em&gt; syntactic sugar (let’s assume that &lt;em&gt;LambadInterface&lt;/em&gt; is an already defined interface with one method &lt;em&gt;apply&lt;/em&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;new LambdaInterface {
   @Override
   public void apply() {
      System.out.println(&amp;#34;Hello... Lambdas?&amp;#34;);
   }
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Not quite the same? Let’s evolve these pieces of code a little bit further:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; System.out.println(&amp;#34;Hello Lambdas!&amp;#34;);
lamdba.apply(); // Hello Lambdas!

LambdaInterface lambda = new LambdaInterface {
   public void apply() {
      System.out.println(&amp;#34;Hello... Lambdas?&amp;#34;);
   }
};
lamdba.apply(); // Hello... Lambdas?
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;How do Lambdas differ from FP &lt;em&gt;Closures?&lt;/em&gt; Well, a closure is an anonymous function packed with the context where it was defined, being able to modify it’s context (context defined variables are, in fact, &lt;em&gt;closed&lt;/em&gt;) . Java 8 Lambdas can access external context variables but only if they’re defined as &lt;em&gt;final&lt;/em&gt; or if the programmer assures that they are not going to change their value (are actually &lt;em&gt;final&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;We said that &lt;strong&gt;Function Composition&lt;/strong&gt; is also another key characteristic of FP, so, are Lambdas composable? Let’s see an actual example of Lambdas composition in action:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; n * 2;
Function&amp;amp;lt;Integer, Integer&amp;amp;gt; increment = (n) -&amp;gt; n + 1;

Function&amp;amp;lt;Integer, Integer&amp;amp;gt; doublePlusOne = duplicate.andThen(increment);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately, &lt;strong&gt;Tail recursion&lt;/strong&gt; is not included in Java 8, so we’ll still have to be cautious with memory consumption in recursive algorithms.&lt;/p&gt;
&lt;p&gt;In future posts, we’ll deep into Lambdas and Functional Interfaces, and how they allow us to create a cleaner and more expressive code.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Groovy to be part of the Apache Software Foundation</title>
      <link>https://danielpecos.com/2015/03/25/groovy-part-of-apache-software-foundation/</link>
      <pubDate>Wed, 25 Mar 2015 19:06:15 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/03/25/groovy-part-of-apache-software-foundation/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2015/03/groovy-logo-300x150.png&#34; alt=&#34;Groovy&#34; width=&#34;300&#34; height=&#34;150&#34; /&gt;As March 11th, &lt;a href=&#34;http://blog.pivotal.io/pivotal/news-2/groovy-2-4-and-grails-3-0-to-be-last-major-releases-under-pivotal-sponsorship&#34;&gt;Pivotal dropped its financial sponsorship for Groovy&lt;/a&gt;, and despite of not really endangering it, as Groovy is an already well established language with a great community backing it, it raised many concerns, as the required boost a platform like this deserves was missing until now. Furthermore, its creator and project leader until lately, &lt;a href=&#34;http://restlet.com/blog/2015/03/02/head-of-groovy-project-joins-restlet-to-lead-api-development-tools/&#34;&gt;Guillaume Laforge, also recently stepped back&lt;/a&gt; in order to focus in Restlet.&lt;/p&gt;
&lt;p&gt;Also the recent release of Java 8, with the introduction of lambdas into the Java language has increased the interest and traction of Java, making a lot of people question if there were still room for other JVM languages, even more being so closed to Java.&lt;/p&gt;
&lt;p&gt;So being worried about Groovy’s future is a normal consequence of this recent events. But don’t forget that this language has been community driven for a long time now, making this changes have a lower impact than initially expected.&lt;/p&gt;
&lt;p&gt;So in order to clarify them, &lt;a href=&#34;https://blogs.apache.org/foundation/entry/groovy_submitted_to_become_a&#34;&gt;moving to the Apache Software Foundation&lt;/a&gt; has been a really smart move by the community, and as &lt;a href=&#34;http://melix.github.io/blog/2015/02/who-is-groovy.html&#34;&gt;Cédric Champeu explains&lt;/a&gt;, a natural next step in Groovy&amp;rsquo;s lifetime that will help it weathering those changes.&lt;/p&gt;
&lt;p&gt;This backup guarantees the position Groovy has as a trending alternative inside the JVM, making it still the most successful productivity booster and most enjoyable language, compared to the Old Java Language, within the JVM.&lt;/p&gt;
&lt;p&gt;Further references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://groovy.dzone.com/articles/groovy-submitted-apache&#34;&gt;http://groovy.dzone.com/articles/groovy-submitted-apache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Java 8 one year later</title>
      <link>https://danielpecos.com/2015/03/23/java-8-one-year-later/</link>
      <pubDate>Mon, 23 Mar 2015 19:48:20 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/03/23/java-8-one-year-later/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2015/03/duke-java-8-e1427183087802-300x285.png&#34; alt=&#34;Duke - Java 8&#34; width=&#34;300&#34; height=&#34;285&#34; /&gt;It’s been a little more than a year since &lt;a href=&#34;https://www.java.com/en/download/faq/release_dates.xml&#34;&gt;Java 8 was released (2014/03/18)&lt;/a&gt; and you might think that it’s a little too late for a &lt;em&gt;What’s new in&lt;/em&gt; post. In fact latest public update available is 8u40, so let’s review not only what was initially included in Java 8, but what else has changed during this first year, up to release 8u40.&lt;/p&gt;
&lt;p&gt;Lots of changes were included in the initial Java 8 release, being probably the most notable of them, in my opinion (feel free to disagree, looking forward to discussions):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java Language
&lt;ul&gt;
&lt;li&gt;Lambda Expressions&lt;/li&gt;
&lt;li&gt;Method references&lt;/li&gt;
&lt;li&gt;Default methods&lt;/li&gt;
&lt;li&gt;Functional interfaces&lt;/li&gt;
&lt;li&gt;Method parameter reflection&lt;/li&gt;
&lt;li&gt;Optional references&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API
&lt;ul&gt;
&lt;li&gt;Collections Streams API&lt;/li&gt;
&lt;li&gt;Date-Time API (based on the popular Joda time library)&lt;/li&gt;
&lt;li&gt;Parallel Array Sorting&lt;/li&gt;
&lt;li&gt;Base64 encoding and decoding&lt;/li&gt;
&lt;li&gt;Unsigned Arithmetic Support&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tools
&lt;ul&gt;
&lt;li&gt;Nashorn Script Engine – Javascript in the JVM&lt;/li&gt;
&lt;li&gt;Java Mission Control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;… among many other optimizations, fixes and new capabilities. You can get a fully detailed changelog detail &lt;a href=&#34;http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We’re not going to go into further detail for these new characteristics, as you’ll find plenty of articles about them. Furthermore some of those would require entire books to proper explain and deal with them, and that’s not the purpose of this article.&lt;/p&gt;
&lt;p&gt;But let’s review &lt;a href=&#34;http://www.oracle.com/technetwork/java/javase/8u-relnotes-2225394.html&#34;&gt;what has changed during this first year of Java 8’s life&lt;/a&gt; (up to 8u40 release). Again, these are the most important in my opinion:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New jdeps analysis tool&lt;/li&gt;
&lt;li&gt;Advanced Management Console (AMC)&lt;/li&gt;
&lt;li&gt;New Garbage Collection Tuning Guide added to JDK 8 documentation&lt;/li&gt;
&lt;li&gt;SSLv3 disabled by default&lt;/li&gt;
&lt;li&gt;Java Flight Recorder can be enabled in runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;… and many other improvements and bugfixes.&lt;/p&gt;
&lt;p&gt;And last but no least, we should talk about Java 8 adoption rate, which &lt;a href=&#34;http://jaxenter.com/java-2-111936.html&#34;&gt;has been surprisingly higher than initially expected&lt;/a&gt; based on a &lt;a href=&#34;http://info.typesafe.com/COLL-2014-10-20-Java-8-II-Survey-Report-LP.html?lsd=COLL-2014-10-20-Java-8-II-Survey-Report&#34;&gt;Typesafe’s survey&lt;/a&gt;:&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; src=&#34;https://danielpecos.com/assets/2015/03/typesafejava8.jpg&#34; alt=&#34;Java 8 Upgrade Plans&#34; width=&#34;448&#34; height=&#34;387&#34; /&gt;
&lt;p&gt;Interestingly, one of the conclusions extracted from that survey is that the inclusion of Lambdas in the Java language has not hurt Scala at all, but validated its approach to Functional Programming:&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; src=&#34;https://danielpecos.com/assets/2015/03/typefacejavascala.jpg&#34; alt=&#34;Java 8 vs Scala&#34; width=&#34;638&#34; height=&#34;352&#34; /&gt;
&lt;p&gt;Other references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.javacodegeeks.com/2014/03/8-new-features-for-java-8.html&#34;&gt;http://www.javacodegeeks.com/2014/03/8-new-features-for-java-8.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.infoq.com/articles/Java-8-Quiet-Features&#34;&gt;http://www.infoq.com/articles/Java-8-Quiet-Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.javaworld.com/article/2078836/java-se/love-and-hate-for-java-8.html&#34;&gt;http://www.javaworld.com/article/2078836/java-se/love-and-hate-for-java-8.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Welcome to jvmGeek!</title>
      <link>https://danielpecos.com/2015/03/20/welcome-to-jvmgeek/</link>
      <pubDate>Fri, 20 Mar 2015 14:09:42 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/03/20/welcome-to-jvmgeek/</guid>
      
      <description>&lt;p&gt;Welcome to &lt;strong&gt;jvmGeek&lt;/strong&gt;! &lt;img class=&#34;alignright size-medium&#34; src=&#34;https://danielpecos.com/assets/2015/03/duke_hi-167x300.png&#34; alt=&#34;Greetings from Duke!&#34; width=&#34;167&#34; height=&#34;300&#34; /&gt;&lt;/p&gt;
&lt;p&gt;This new blog aims to talk and discuss about the JVM ecosystem, with news and articles discussing about Java – &lt;em&gt;the language&lt;/em&gt; -, and also about other JVM languages such as Scala, Kotlin or Clojure.&lt;/p&gt;
&lt;p&gt;But it won&amp;rsquo;t deal only about programming languages, but also about tools and libraries. You&amp;rsquo;ll find news, tutorials, code examples and more general articles, among other.&lt;/p&gt;
&lt;p&gt;From time to time I will also try to gather events and news related to one particular matter and post them as a flash post that will help you keep up to date with this effervescent platform.&lt;/p&gt;
&lt;p&gt;I hope you&amp;rsquo;ll enjoy reading this blog as least as much as I did writing it!&lt;/p&gt;
&lt;p&gt;Thank you very much!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/&#34;&gt;Daniel Pecos&lt;/a&gt; (&lt;a href=&#34;http://twitter.com/danielpecos&#34;&gt;@danielpecos&lt;/a&gt;).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Using Chromebook for node.js development</title>
      <link>https://danielpecos.com/2015/03/05/using-chromebook-for-node-js-development/</link>
      <pubDate>Thu, 05 Mar 2015 15:54:50 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/03/05/using-chromebook-for-node-js-development/</guid>
      
      <description>&lt;p&gt;Every single working day I spend between 2 and 2.5 hours in a train. And I feel pretty lucky about this, mostly because is one single train, no need to pay attention for switch overs or other kind of public transports, and that allows me to invest that time in whatever task I want: podcasts, videos, blogging or even programming. And that&amp;rsquo;s what I want this post to focus in, because there are plenty of posts that explain how to use a Chromebook for day-to-day tasks (even being offline) but not that many that talk about programming in node.js using a Chromebook.&lt;/p&gt;
&lt;p&gt;There are two main challenges we have to figure out when using a Chromebook (CB) for usual programming tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connectivity&lt;/li&gt;
&lt;li&gt;A proper development environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Connectivity&lt;/em&gt; is a big issue because, despite of there are quite a few web IDEs or even environments that expose a whole virtual machine, they often require a connection in order to work.&lt;/p&gt;
&lt;p&gt;On the other hand, as a developer I want to use the best tools possible in order to achieve my goals, &lt;em&gt;a proper development environment&lt;/em&gt;, and that for me means having:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A linux shell&lt;/li&gt;
&lt;li&gt;tmux (not a must, but really nice to have)&lt;/li&gt;
&lt;li&gt;vim&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;node.js virtual machine (managed with nvm if possible)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It turns out that CB really suck in this point, so my idea when I bought this platform was to create a tiny partition and install a Linux OS there with all this requirements. But I was surprised when I heard about &lt;strong&gt;crouton&lt;/strong&gt;: this amazing tool creates chroot environments within the very ChromeOS (which is a Linux underneath), where you can do whatever (well, almost) you want. All you need is root access (&lt;em&gt;Developer mode&lt;/em&gt; in ChromeOS jargon) and some free space (but really not that much).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to explain how to get this chroot environment up and running. There are plenty of posts and tutorials that explain this process. Just a quick spoiler: it&amp;rsquo;s super easy and takes no more than 15 minutes.&lt;/p&gt;
&lt;p&gt;Once you have a chroot with at least crouton cli-extra, getting the rest of the tools up and ready is easy peasy. Use apt-get install to get tmux, vim and git, download nvm and fetch latest node.js binary. Integrate all of this into your bash scripts, so you don&amp;rsquo;t need to setup nvm with every login and you&amp;rsquo;re good to go.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt; self-promotion &amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last but not least, setup your config files for vim, git, ssh, bash… or use one handy opensource tool (developed in node.js using a ChromeBook) call &lt;strong&gt;dotback&lt;/strong&gt;. Just install it using npm:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install -g dotback
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And setup your configuration definition file.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dotback --action install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or if you already have done that and it&amp;rsquo;s available through a git repository, fetch it using:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dotback --action init REPO_URL
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Takes a little bit to tune, but once it&amp;rsquo;s done, you&amp;rsquo;ll see the effort was worth of it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt; / self-promotion &amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s how I got a really portable box, with enough power for node.js development, and really really light, which is good if you have to carry it with you almost all the time 🙂&lt;/p&gt;
&lt;p&gt;I hope you liked my Chromebook &amp;amp; Node.js feedback and that it helped you to decide if you&amp;rsquo;re thinking about getting a Chromebook or not, and as I was, were worried about being able to use it as a developer environment.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>HTPC automatic workflow for Movies and TV Shows</title>
      <link>https://danielpecos.com/2015/02/27/htpc-automatic-workflow-for-movies-and-tv-shows/</link>
      <pubDate>Fri, 27 Feb 2015 06:40:51 +0100</pubDate>
      
      <guid>https://danielpecos.com/2015/02/27/htpc-automatic-workflow-for-movies-and-tv-shows/</guid>
      
      <description>&lt;p&gt;Watching Movies and TV Shows from online streaming sources is a pain, as you depend on the availability of the your ISP network and current status of the stream provider. Furthermore, you don’t always have an internet connection available when you want to spend some time in front of the TV. So downloading it it’s a much better way to go in order to avoid this issues (giving that you have to anticipate a little bit to get downloads finished).&lt;/p&gt;
&lt;p&gt;BTW, PopCorn Time is a recent solution that works pretty neat: it streams video directly fetched from torrent sources. I recommend giving it a try.&lt;/p&gt;
&lt;p&gt;But looking for latest TV shows episodes or movies using torrent search providers is also a pain, because it requires a certain time and dedication you could spend in some other task.&lt;/p&gt;
&lt;p&gt;But we’re computer engineers and we love automating things, and this specific problem we’re describing has to be more common than unusual, so I started googling about this matter and I found these pretty cool tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://couchpota.to/&#34;&gt;CouchPotato&lt;/a&gt;: tool that looks for movies in different torrent providers, fetching the appropriate torrent based on your quality requirements as soon is ready. It integrates with IMDB via a browser plugin, so you can queue upcoming movies without even opening its interface.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://flexget.com/&#34;&gt;flexget&lt;/a&gt;: really powerful tool that keeps track of your latest downloaded TV show episodes and fetches new ones (well, their torrents) as soon they’re available and meeting your quality requirements&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.filebot.net&#34;&gt;filebot&lt;/a&gt;: renames, organizes and downloads subtitles for video archives based on their metadata and search results on internet video databases.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.pushbullet.com&#34;&gt;PushBullet&lt;/a&gt;: get notifications from other applications directly into your mobile device.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kodi.tv&#34;&gt;Kodi / XBMC&lt;/a&gt;: one of the best HTPC platforms, with lots of plugins and features.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.tvshowtime.com&#34;&gt;TV Show Time&lt;/a&gt;: really nice social network and episode tracking site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s wire it all together! This is how they interact with each other in my current workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Movies&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;I look for movies in IMDB and when I find any of interest, I queue that one into CouchPotato using its browser plugin (available for Chrome and Firefox).&lt;/li&gt;
&lt;li&gt;CouchPotato keeps looking for torrent sources for queued movies and whenever one is available, it queues it to the download list and I get a notification in my cell phone.&lt;/li&gt;
&lt;li&gt;Once the file is ready, filebot attaches proper metadata &amp;amp; subtitles and moves / renames that file to its final destination and tells Kodi to refresh its library.&lt;/li&gt;
&lt;li&gt;Kodi (previously known as XBMC) reloads a set of preconfigured directories (where filebot places files) from time to time and gets new videos stored into its database, fetching art work and IMDB / TV Shows DB info if required.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;TV Shows&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Flexget keeps looking for existing / returning TV shows I’m interested in (and previously configured in its config file), getting notified as when they’re in the torrent download queue&lt;/li&gt;
&lt;li&gt;Rest of the steps for this workflow are exactly the same as for movies.&lt;/li&gt;
&lt;li&gt;One difference but, is that once I finish watching that episode, Kodi automatically marks it as watched in my TV Show Time account.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So after expending some time setting this workflow up and integrating these tools into my HTPC, I got a totally automated TV Show / Movies box. I totally recommend that you expend some time with these tools. Once running you can almost forget about looking for torrents ever more.&lt;/p&gt;
&lt;p&gt;Awesome!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: Here you can find a nice tutorial on &lt;a href=&#34;https://www.cloudwards.net/how-to-use-kodi/&#34;&gt;How to Use Kodi: What You Need to Know&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>From Node.js back to Java</title>
      <link>https://danielpecos.com/2014/10/22/node-js-back-java/</link>
      <pubDate>Wed, 22 Oct 2014 12:33:19 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/10/22/node-js-back-java/</guid>
      
      <description>&lt;p&gt;During last year, I had the chance to work as CTO of a startup, working mainly within MEAN stack. I was happy, the technology I was working with was in a great hype and its community grew bigger and bigger with lots of projects popping up everywhere.&lt;/p&gt;
&lt;img class=&#34;alignleft size-full&#34; src=&#34;https://danielpecos.com/assets/2014/10/jjs.png&#34; alt=&#34;Java vs Node.js&#34; width=&#34;81&#34; height=&#34;81&#34; /&gt;
&lt;p&gt;But life is continuously changing, and I started to work in a new company within Java/JEE technologies. I was back to my first days as a professional computer engineer. Java ecosystem is huge, and there are some well established tools that you must control if you want to progress as Java developer. But Java -the language- is getting older, and newer languages are more expressive and require less boiler plate code (don&amp;rsquo;t get me wrong, JVM is a great platform, and probably the best one for enterprise applications). Even with the recent release of Java 8, which introduced Lambdas and some functional style capabilities, I still feel like writing too much, or at least much more than with other languages.&lt;/p&gt;
&lt;p&gt;You could ask yourself then why did I change?&lt;/p&gt;
&lt;p&gt;Not long ago JVM included some bytecode instructions that allowed scripting languages to be run within it. That turn the JVM into a polyglot ecosystem, with languages like Groovy, Scala or Clojure gaining traction, attracting more users into it and making its community more vibrant than ever.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re living a Functional Renaissance, where OOP is not the only solution one would dare to apply any more. And probably its flagships are Scala and Clojure, both JVM based (whereas there are implementations of Scala for .NET platform, its origin and biggest user base is using JVM version).&lt;/p&gt;
&lt;p&gt;And this transformation happening within the JVM was the main reason I wanted to come back. It&amp;rsquo;s a perfect moment to be there and worth of losing daily touch with Node.js (at least in my job, because I still love this technology and its community). JVM is a great platform, has great tools, and now finally, has some great languages.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Functional programming in javascript: Function composition</title>
      <link>https://danielpecos.com/2014/06/24/function-composition/</link>
      <pubDate>Tue, 24 Jun 2014 06:30:07 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/06/24/function-composition/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Function_composition_%28computer_science%29&#34;&gt;&lt;strong&gt;Function composition&lt;/strong&gt;&lt;/a&gt; is one the key features (among others) of functional programming. Programming languages that offer &lt;a href=&#34;http://en.wikipedia.org/wiki/Higher-order_function&#34;&gt;&lt;em&gt;higher order functions&lt;/em&gt;&lt;/a&gt; as a feature can potentially use function composition. But, still, programmers need to be aware of some key concepts to successfully apply this pattern in our code.&lt;/p&gt;
&lt;img class=&#34;alignleft size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/06/composition-of-functions-300x162.jpg&#34; alt=&#34;Composition of Functions&#34; width=&#34;300&#34; height=&#34;162&#34; /&gt;
&lt;p&gt;Function composition, as defined on Wikipedia, is  &lt;em&gt;an act or mechanism to combine simple &lt;a href=&#34;http://en.wikipedia.org/wiki/Subroutine&#34; title=&#34;Subroutine&#34;&gt;functions&lt;/a&gt; to build more complicated ones.&lt;/em&gt; In other words, we can define new functions, equivalent to the result of &lt;a href=&#34;http://en.wikipedia.org/wiki/Method_chaining&#34;&gt;&lt;em&gt;chaining&lt;/em&gt;&lt;/a&gt; a set of given functions, so the input of function &lt;strong&gt;i&lt;/strong&gt; is the output (or result) of function &lt;strong&gt;i-1&lt;/strong&gt;. Let&amp;rsquo;s see an example in javascript.&lt;/p&gt;
&lt;p&gt;Having these two functions:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function double(x) {
   return x*2;
}

function triple(x) {
   return x*3;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We define &lt;em&gt;sixtimes&lt;/em&gt; as the &lt;strong&gt;composition&lt;/strong&gt; of the two previous:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function sixtimes(x) {
   return double(triple(x));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Obviously in this case it would have been easier just to multiply &lt;em&gt;x&lt;/em&gt; by 6 inside &lt;em&gt;sixtimes&lt;/em&gt;, but let me continue with this dumb example just to get to the concept.&lt;/p&gt;
&lt;p&gt;This pattern is going to be used widespread in functional programming, so one could define a compose function that would return a new function resulting of the composition of two given:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function compose(f, g) {
   return function(x) {
      return g(f(x));
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, using &lt;em&gt;compose&lt;/em&gt; to define our previous function &lt;em&gt;sixtimes&lt;/em&gt;, would be as easy as:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;var sixtimes = compose(triple, double);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Isn&amp;rsquo;t it beautiful?&lt;/p&gt;
&lt;p&gt;In following posts I will show you some gems extracted from &lt;a href=&#34;https://leanpub.com/javascript-allonge?a=3ErUYtQxnDzhImL2jSakU-&#34;&gt;Javascript Allongé&lt;/a&gt; by &lt;a href=&#34;https://twitter.com/raganwald&#34;&gt;Reginald Braithwaite&lt;/a&gt;, where the author explains some useful composition tips and a really nice concept he calls &lt;em&gt;Function decorators.&lt;/em&gt; (&lt;strong&gt;Update&lt;/strong&gt;: after digging a little bit, I found this concept comes from Python world, where the very syntax allows you to list decorators for functions in its definition)&lt;/p&gt;
&lt;p&gt;Until then you&amp;rsquo;re welcome to take a look at my presentation slides and code I used during a talk in a Ruby local users group (valencia.rb) comparing OOP and FP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.slideshare.net/dpecos/20140401-oopfp-presentacion-33034962&#34;&gt;Slides&lt;/a&gt; (mix of Spanish and English, sorry!)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/valenciarb/functional-programming&#34;&gt;Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Who is who in computer science</title>
      <link>https://danielpecos.com/2014/05/28/who-is-who-computer-science/</link>
      <pubDate>Wed, 28 May 2014 03:32:21 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/05/28/who-is-who-computer-science/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignright&#34; src=&#34;https://danielpecos.com/assets/2014/05/einstein_who-300x191.jpg&#34; alt=&#34;Who is who?&#34; width=&#34;200&#34; height=&#34;127&#34; /&gt;I have problems remembering people&amp;rsquo;s names. Really, I&amp;rsquo;m not good at it. And that&amp;rsquo;s no exception with computer technology. That&amp;rsquo;s why I&amp;rsquo;ve written this post, to try to improve and persist those names in my head. Let&amp;rsquo;s see who is who in nowadays computer science.&lt;/p&gt;
&lt;h2 id=&#34;methodologies&#34;&gt;Methodologies&lt;/h2&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/KentBeck.jpg&#34; alt=&#34;KentBeck&#34; width=&#34;75&#34; height=&#34;100&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Kent Beck&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Kent_Beck&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;https://twitter.com/KentBeck&amp;quot;&amp;gt;twitter&amp;lt;/a&amp;gt;) &amp;amp;#8211; XP, Agile, TDD
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;http://martinfowler.com/&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/martin_fowler.png&amp;quot; alt=&amp;quot;martin_fowler&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;85&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;http://martinfowler.com/&amp;quot;&amp;gt;Martin Fowler&amp;lt;/a&amp;gt; &amp;lt;/strong&amp;gt;(&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Martin_Fowler&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;https://twitter.com/martinfowler&amp;quot;&amp;gt;twitter&amp;lt;/a&amp;gt;) &amp;amp;#8211; OOP, Agile, TDD
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/photo_martin_r.jpg&#34; alt=&#34;photo_martin_r&#34; width=&#34;75&#34; height=&#34;100&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Robert Cecil Martin &amp;amp;#8211; &amp;lt;em&amp;gt;Uncle Bob&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Robert_Cecil_Martin&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;https://twitter.com/unclebobmartin&amp;quot;&amp;gt;twitter&amp;lt;/a&amp;gt;) &amp;amp;#8211; Software Craftmanship, Agile Manifesto
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;http://martinfowler.com/&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/j-b-rainsberger.jpg&amp;quot; alt=&amp;quot;j-b-rainsberger&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;http://www.jbrains.ca/&amp;quot;&amp;gt;J. B. Rainsberger&amp;lt;/a&amp;gt; &amp;lt;/strong&amp;gt;(&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/J._B._Rainsberger&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;https://twitter.com/jbrains&amp;quot;&amp;gt;twitter&amp;lt;/a&amp;gt;) &amp;amp;#8211; Agile
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/mike-cohn.jpg&#34; alt=&#34;Mike Cohn&#34; width=&#34;90&#34; height=&#34;100&#34; /&gt;&lt;strong&gt;&lt;a href=&#34;http://www.mountaingoatsoftware.com/company/about-mike-cohn&#34;&gt;Mike Cohn &lt;/a&gt;&lt;/strong&gt;(&lt;a href=&#34;http://en.wikipedia.org/wiki/Mike_Cohn&#34;&gt;wikipedia&lt;/a&gt;) &amp;#8211; Scrum
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;h2 id=&#34;technology-and-languages&#34;&gt;Technology and Languages&lt;/h2&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;a href=&#34;http://www.w3.org/People/Berners-Lee/&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/bernerslee-300x226.jpeg&#34; alt=&#34;bernerslee&#34; width=&#34;100&#34; height=&#34;75&#34; /&gt;&lt;strong&gt;Tim Berners-Lee&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;http://en.wikipedia.org/wiki/Tim_Berners-Lee&#34;&gt;wikipedia&lt;/a&gt;) &amp;#8211; HTTP
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/dijkstra-300x233.jpg&amp;quot; alt=&amp;quot;dijkstra&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;78&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;
      &amp;lt;strong&amp;gt;Edsger W. Dijkstra&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Edsger_W._Dijkstra&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;) &amp;amp;#8211; Sortest Path Algorithm
    &amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/linus-torvalds-197x300.jpg&#34; alt=&#34;linus-torvalds&#34; width=&#34;66&#34; height=&#34;100&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Linus Torvalds&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Linus_Torvalds&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;) &amp;amp;#8211; Linux
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;http://www.stroustrup.com/&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/Bjarne-Stroustrup.jpg&amp;quot; alt=&amp;quot;Bjarne-Stroustrup&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;75&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;http://www.stroustrup.com/&amp;quot;&amp;gt;Bjarne Stroustrup&amp;lt;/a&amp;gt; &amp;lt;/strong&amp;gt;(&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Bjarne_Stroustrup&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;) &amp;amp;#8211; C++
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;a href=&#34;http://lerdorf.com&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/lerdorf-200x300.jpg&#34; alt=&#34;Rasmus Lerdorf&#34; width=&#34;67&#34; height=&#34;100&#34; /&gt;&lt;/a&gt;&lt;strong&gt;&lt;a href=&#34;http://lerdorf.com&#34;&gt;Rasmus Lerdorf&lt;/a&gt; &lt;/strong&gt;(&lt;a href=&#34;http://en.wikipedia.org/wiki/Rasmus_Lerdorf&#34;&gt;wikipedia&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/rasmus&#34;&gt;twitter&lt;/a&gt;) &amp;#8211; PHP
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/james-gosling-300x200.jpg&amp;quot; alt=&amp;quot;james-gosling&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;67&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;James Gosling&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/James_Gosling&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;) &amp;amp;#8211; Java
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;a href=&#34;https://www.python.org/~guido/&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/van-rossum-290x300.png&#34; alt=&#34;van-rossum&#34; width=&#34;97&#34; height=&#34;100&#34; /&gt;&lt;/a&gt;&lt;a href=&#34;https://www.python.org/~guido/&#34;&gt;&lt;strong&gt;Guido van Rosum&lt;/strong&gt; &lt;/a&gt;(&lt;a href=&#34;http://en.wikipedia.org/wiki/Guido_van_Rossum&#34;&gt;wikipedia&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/gvanrossum&#34;&gt;twitter&lt;/a&gt;) &amp;#8211; Python
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/matz-199x300.jpg&amp;quot; alt=&amp;quot;matz&amp;quot; width=&amp;quot;67&amp;quot; height=&amp;quot;100&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Yukihiro &amp;amp;#8220;&amp;lt;em&amp;gt;matz&amp;lt;/em&amp;gt;&amp;amp;#8221; Matsumoto&amp;lt;/strong&amp;gt; (&amp;lt;a href=&amp;quot;http://en.wikipedia.org/wiki/Yukihiro_Matsumoto&amp;quot;&amp;gt;wikipedia&amp;lt;/a&amp;gt;, &amp;lt;a href=&amp;quot;https://twitter.com/yukihiro_matz&amp;quot;&amp;gt;twitter&amp;lt;/a&amp;gt;) &amp;amp;#8211; Ruby
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;a href=&#34;https://brendaneich.com/&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/brendan-eich-300x300.jpg&#34; alt=&#34;brendan-eich&#34; width=&#34;100&#34; height=&#34;100&#34; /&gt;&lt;/a&gt;&lt;strong&gt;&lt;a href=&#34;https://brendaneich.com/&#34;&gt;Brendan Eich&lt;/a&gt; &lt;/strong&gt;(&lt;a href=&#34;http://en.wikipedia.org/wiki/Brendan_Eich&#34;&gt;wikipedia&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/BrendanEich&#34;&gt;twitter&lt;/a&gt;) &amp;#8211; Javascript
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/ryan.jpg&amp;quot; alt=&amp;quot;ryan&amp;quot; width=&amp;quot;98&amp;quot; height=&amp;quot;100&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Ryan Lienhart&amp;lt;/strong&amp;gt; Dahl &amp;amp;#8211; Node.js
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;h2 id=&#34;books&#34;&gt;Books&lt;/h2&gt;
&lt;p&gt;Well, those here are not strictly &lt;em&gt;people&lt;/em&gt;, but books and their writers.&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/design-patterns-228x300.jpg&#34; alt=&#34;design-patterns&#34; width=&#34;76&#34; height=&#34;100&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Design Patterns: Elements of Reusable Object-Oriented Software&amp;lt;/strong&amp;gt;  &amp;amp;#8211; &amp;lt;em&amp;gt;&amp;lt;strong&amp;gt;Gang of Four&amp;lt;/strong&amp;gt;&amp;lt;/em&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/The_pragmatic_programmer-238x300.jpg&amp;quot; alt=&amp;quot;The_pragmatic_programmer&amp;quot; width=&amp;quot;80&amp;quot; height=&amp;quot;100&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;The Pragmatic Programmer: From Journeyman to Master&amp;lt;/strong&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/clean-code-225x300.jpg&#34; alt=&#34;Martin_MECH.qxd&#34; width=&#34;75&#34; height=&#34;100&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Clean Code: A Handbook of Agile Software Craftsmanship&amp;lt;br /&amp;gt; &amp;lt;/strong&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/the-clean-coder-231x300.jpg&amp;quot; alt=&amp;quot;the-clean-coder&amp;quot; width=&amp;quot;77&amp;quot; height=&amp;quot;100&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;The Clean Coder: A Code of Conduct for Professional Programmers (Robert C. Martin Series)&amp;lt;br /&amp;gt; &amp;lt;/strong&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/code-complete-2-246x300.jpg&#34; alt=&#34;code-complete-2&#34; width=&#34;82&#34; height=&#34;100&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Code Complete: A Practical Handbook of Software Construction, Second Edition&amp;lt;br /&amp;gt; &amp;lt;/strong&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/javascript_patterns-227x300.jpg&amp;quot; alt=&amp;quot;javascript_patterns&amp;quot; width=&amp;quot;76&amp;quot; height=&amp;quot;100&amp;quot; data-recalc-dims=&amp;quot;1&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;JavaScript Patterns&amp;lt;br /&amp;gt; &amp;lt;/strong&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td width=&#34;50%&#34;&gt;
      &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/JavaScript-The-Good-Parts-Cover-228x300.jpg&#34; alt=&#34;JavaScript The Good Parts Cover&#34; width=&#34;76&#34; height=&#34;100&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;br /&gt; &lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/douglas-crockford-300x217.jpg&#34; alt=&#34;douglas-crockford&#34; width=&#34;100&#34; height=&#34;72&#34; data-recalc-dims=&#34;1&#34; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;JavaScript: The Good Parts&amp;lt;/strong&amp;gt; &amp;amp;#8211; &amp;lt;a href=&amp;quot;http://www.crockford.com&amp;quot;&amp;gt;Douglas Crockford&amp;lt;/a&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;

&amp;lt;td width=&amp;quot;50%&amp;quot;&amp;gt;
  &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/javascript_allonge-232x300.jpg&amp;quot; alt=&amp;quot;javascript_allonge&amp;quot; width=&amp;quot;77&amp;quot; height=&amp;quot;100&amp;quot; data-recalc-dims=&amp;quot;1&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;img class=&amp;quot;alignleft&amp;quot; src=&amp;quot;/assets/2014/05/Reg-Braithwaite-300x300.png&amp;quot; alt=&amp;quot;Reg-Braithwaite&amp;quot; width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; data-recalc-dims=&amp;quot;1&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;strong&amp;gt;Javascript Allongé&amp;lt;/strong&amp;gt; &amp;amp;#8211; &amp;lt;a href=&amp;quot;http://braythwayt.com/&amp;quot;&amp;gt;Reg Braithwaite&amp;lt;/a&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;&lt;strong&gt;Do you miss some one? No problem, leave a comment and I&amp;rsquo;ll update this post.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Organizing your Code: Javascript Modules</title>
      <link>https://danielpecos.com/2014/05/08/organizing-code-javascript-modules/</link>
      <pubDate>Thu, 08 May 2014 12:35:09 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/05/08/organizing-code-javascript-modules/</guid>
      
      <description>&lt;p&gt;The way you structure your code is a key factor when you define your source code organization. It will make your life easier or miserable, and once this structure is established it will become a really tedious task to redefine it. That&amp;rsquo;s why you know about the different patterns available and choose the one fits your project best.&lt;/p&gt;
&lt;p&gt;But, why should I care about modules? Well, is the way Javascript offers to organize and encapsulate your code, and if you don&amp;rsquo;t think you need to do it, because maybe it&amp;rsquo;s a small project or you don&amp;rsquo;t care at all, trust me, you are making a huge mistake!&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start talking about what a module really is, and talking about Javascript modules is talking about Javascript scope: the only way to achieve privacy in Javascript code is enclosing the private code in a closure (an &lt;a href=&#34;http://benalman.com/news/2010/11/immediately-invoked-function-expression/&#34;&gt;IIFE – Immediately Invoked Function Expression&lt;/a&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(function() {

  // your code goes here

})();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And this is exactly all we are going to need to create blocks of encapsulated code, hidden one from another. But modules as we know them today are a little bit more: modules are ways of defining chunks of code that are dynamically loaded.&lt;/p&gt;
&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/05/Asynchronous_Module_Definition_overview-300x257.png&#34; alt=&#34;Asynchronous Module Definition&#34; width=&#34;300&#34; height=&#34;257&#34; /&gt;
&lt;p&gt;Currently there are three main different ways of defining a module:&lt;/p&gt;
&lt;h2 id=&#34;amd&#34;&gt;AMD&lt;/h2&gt;
&lt;p&gt;Format proposed by Dojo. Uses XHR and eval to dynamically load code, allows defining module dependencies and has a great support for browser loaders (&lt;a href=&#34;http://requirejs.org/&#34;&gt;require.js&lt;/a&gt;, &lt;a href=&#34;http://github.com/unscriptable/curl&#34;&gt;curl.js&lt;/a&gt;). It also can be used in server-side with require.js:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;AMD module definition&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// foo.js

define(&amp;#34;foo&amp;#34;, [&amp;#34;bar&amp;#34;], function(bar) {

return function() { ... };

});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;AMD module requirement&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// app.js

require([&amp;#34;foo&amp;#34;], function(foo) {

...

});
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;commonjs&#34;&gt;Common.JS&lt;/h2&gt;
&lt;p&gt;Born from a group of volunteer aiming to standardize modules and packages in Javascript. This is the pattern used by Node.js, but it&amp;rsquo;s also supported in browsers using &lt;a href=&#34;http://github.com/unscriptable/curl&#34;&gt;curl.js&lt;/a&gt; or &lt;a href=&#34;http://sproutcore.com&#34;&gt;SproutCore&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;CJS module definition&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// foo.js

exports.foo = function() { ... }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;CJS module requirement&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// app.js

foo = require(&amp;#34;./foo&amp;#34;).foo
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;es6--es-harmony&#34;&gt;ES6 / ES Harmony&lt;/h2&gt;
&lt;p&gt;Next version of the language incorporates some new features, including, &lt;a href=&#34;https://wiki.mozilla.org/ES6_plans&#34;&gt;among others&lt;/a&gt;, a standard way to define and consume modules:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;ES6 module definition&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// foo.js

module foo {

  export var foo = function() { ... };

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;ES6 module requirement&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// app.js

module foo from &amp;#34;./foo&amp;#34; // remote URLs also allowed here

import * from foo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;AMD &amp;amp; CommonJS have a wide support, but in my opinion, each of them have a slightly different approach: AMD seems to fit better in browser-side (it&amp;rsquo;s inherently asynchronous) and CommonJS seems to fit better in server-side, where synchronously loading code is a choice. Of course, you can use third libraries to use them in whatever environment, but it doesn&amp;rsquo;t seem the natural way.&lt;/p&gt;
&lt;p&gt;There are some hybrid approaches, so you don&amp;rsquo;t have to pick any them, but both, but this only makes things harder and difficult to follow.&lt;/p&gt;
&lt;p&gt;Luckily, ES6 modules are (or will be) part of our day-to-day, so I strongly suggest this should be the way to go. Currently,  browser support for ES6 modules is only achieved via &lt;em&gt;transpilers&lt;/em&gt; or libraries, so we&amp;rsquo;ll have to wait a little bit longer to use this feature. V8 implementation is still incomplete, so no luck neither in server-side.&lt;/p&gt;
&lt;p&gt;Until then, you&amp;rsquo;ll still have to choose a pattern to go with. I recommend you not to enter this holy war, but just to pick one of them and keep coding great stuff.&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; src=&#34;https://danielpecos.com/assets/2014/05/download.png&#34; alt=&#34;Keep Coding&#34; width=&#34;120&#34; height=&#34;140&#34; /&gt;
&lt;p&gt;Bibliography:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://addyosmani.com/writing-modular-js/&#34;&gt;http://addyosmani.com/writing-modular-js/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://tagneto.blogspot.com.es/2011/04/on-inventing-js-module-formats-and.html&#34;&gt;http://tagneto.blogspot.com.es/2011/04/on-inventing-js-module-formats-and.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://requirejs.org/docs/whyamd.html&#34;&gt;http://requirejs.org/docs/whyamd.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Node.js blog: NodeGeek</title>
      <link>https://danielpecos.com/2014/05/06/node-js-blog-nodegeek/</link>
      <pubDate>Tue, 06 May 2014 17:54:48 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/05/06/node-js-blog-nodegeek/</guid>
      
      <description>&lt;p&gt;Javascript is an old well-known friend that is &lt;a href=&#34;https://blog.nodejitsu.com/npm-innovation-through-modularity&#34;&gt;growing rapidly&lt;/a&gt; and gaining traction since Node.js, a command line Javascript interpreter based on Chrome V8 Javascript Virtual Machine, was published. Its community is &lt;a href=&#34;http://npmjs.org&#34;&gt;building great stuff&lt;/a&gt;, and &lt;a href=&#34;http://blog.appfog.com/node-js-is-taking-over-the-enterprise-whether-you-like-it-or-not/&#34;&gt;more&lt;/a&gt; and &lt;a href=&#34;http://www.ebaytechblog.com/2013/05/17/how-we-built-ebays-first-node-js-application/&#34;&gt;more&lt;/a&gt; companies are moving into this stack, with a high success ratio.&lt;/p&gt;
&lt;h2 style=&#34;text-align: center;&#34;&gt;
  &lt;a href=&#34;http://nodegeek.net&#34;&gt;http://nodegeek.net&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://nodegeek.net&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2014/05/nodejs-150x150.png&#34; alt=&#34;NodeGeek&#34; width=&#34;150&#34; height=&#34;136&#34; /&gt;&lt;/a&gt;Luckily for me, for my last two professional years I have been involved in one way or another with it, been able to relearn the language and discover its framework. And since not long ago, I&amp;rsquo;ve been writing articles for a new site where I could focus about this amazing programming stack:&lt;/p&gt;
&lt;p class=&#34;size-thumbnail&#34;&gt;
  Until this very moment I have post some quite successful posts related to its &lt;a href=&#34;http://nodegeek.net/2013/12/nodejs-v8-history/&#34;&gt;history&lt;/a&gt; or its &lt;a href=&#34;http://nodegeek.net/2014/03/create-publish-npm-module/&#34;&gt;package system&lt;/a&gt;, and many more are almost ready to be published.
&lt;/p&gt;
&lt;p&gt;So if you are interested in this technology I would suggest you to subscribe to its &lt;a href=&#34;http://nodegeek.net&#34;&gt;mailing list&lt;/a&gt; in order to be noticed for latest published posts. Or follow its &lt;a href=&#34;http://twitter.com/nodegeek&#34;&gt;twitter account&lt;/a&gt;! And if you think you could collaborate with this project, don&amp;rsquo;t hesitate to &lt;a href=&#34;https://danielpecos.com/about-me/&#34; title=&#34;About me&#34;&gt;contact me&lt;/a&gt;!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Create and publish an NPM module</title>
      <link>https://danielpecos.com/2014/03/13/create-publish-npm-module/</link>
      <pubDate>Thu, 13 Mar 2014 18:07:28 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/03/13/create-publish-npm-module/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft &#34; src=&#34;https://danielpecos.com/assets/2014/03/npm-300x116.png&#34; alt=&#34;npm&#34; width=&#34;180&#34; height=&#34;70&#34; /&gt;Code modularization, achieved in one way or another, is a technique a good developer must aim for because it helps keeping things small, well-tested and organized. And of course, it follows the DRY directive. So as a Node.js developer (and &lt;em&gt;maybe&lt;/em&gt; contributor to the Open Source), creating and publishing an NPM module is one of those steps you will eventually face.&lt;/p&gt;
&lt;p&gt;Probably if any Node.js developer would have to pick an indispensable tool of the ecosystem, &lt;em&gt;&lt;a href=&#34;https://www.npmjs.org&#34;&gt;npm&lt;/a&gt;&lt;/em&gt; would win by far. Its greatness resides in how much easy is to build applications using on of several modules, each of them providing one certain functionality, as if they were building bricks, picking the right tool for each task.&lt;/p&gt;
&lt;p&gt;But, how difficult is the process of creating an NPM module? Well, here is a cheat sheet to get this done:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a directory with the name of the module and place your code in it. How you structure your content is up to you. The index file will define your external API (module’s exports), the functionality other developers can reach of your module.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you never logged in into &lt;em&gt;npm&lt;/em&gt; (usually you don’t need to do it unless you want to push some content into NPM repository), this would be your next step:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm adduser

$ npm login
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-192924.png&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-192924-300x173.png&#34; alt=&#34;NPM - login&#34; width=&#34;300&#34; height=&#34;173&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialize your module and fill in the required information:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm init
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-193445.png&#34; rel=&#34;attachment wp-att-272&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-193445-300x221.png&#34; alt=&#34;NPM - init&#34; width=&#34;300&#34; height=&#34;221&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t forget to install all your dependencies so they appear in the package.json manifest:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm install whaterver-module --save
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you have set up your package.json file, you’re ready to make it public. &lt;strong&gt;Increase the version number&lt;/strong&gt; of you module and publish it:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm publish
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-193605.png&#34; rel=&#34;attachment wp-att-273&#34;&gt;&lt;img class=&#34;aligncenter&#34; src=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-193605-300x102.png&#34; alt=&#34;NPM - publish&#34; width=&#34;300&#34; height=&#34;102&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you’ll be able to find it in the NPM repository:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm search test-module-dpecos
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-194020.png&#34; rel=&#34;attachment wp-att-274&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-194020-300x118.png&#34; alt=&#34;NPM - search&#34; width=&#34;300&#34; height=&#34;118&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optionally, tag your GIT repository with current version number. It makes easier to guess what was included with each release of your module.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And that’s it!, your package will soon appear in NPM registry search results (it it hasn’t already), allowing other developers to find and use it.&lt;/p&gt;
&lt;p&gt;Whenever you want to publish and update of one of your already published modules, these are the steps you should follow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Increase your module’s version number&lt;/li&gt;
&lt;li&gt;Publish it again&lt;/li&gt;
&lt;li&gt;Optionally, tag your GIT repository with current version number&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You have to take care about version numbers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can’t repeat them&lt;/li&gt;
&lt;li&gt;You can’t publish a lower version number than the previously published version&lt;/li&gt;
&lt;li&gt;You can follow any scheme to designate your version number, but &lt;a href=&#34;http://en.wikipedia.org/wiki/Software_versioning&#34;&gt;there are some of them&lt;/a&gt; considered standard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But sometimes, software gets old, deprecated or replaced by a better one. If, sadly, this is the case for your module, you can remove it from NPM registry with these command:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ npm unpublish
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-194233.png&#34; rel=&#34;attachment wp-att-275&#34;&gt;&lt;img class=&#34;aligncenter size-medium&#34; src=&#34;https://danielpecos.com/assets/2014/03/Screenshot-from-2014-03-13-194233-300x118.png&#34; alt=&#34;NPM - unpublish&#34; width=&#34;300&#34; height=&#34;118&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And it will be gone forever 🙁&lt;/p&gt;
&lt;p&gt;If you want to get an deeper knowledge of npm commands, I recommend you to visit the official &lt;a href=&#34;https://www.npmjs.org/doc/&#34;&gt;CLI docs.&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Node.js ecosystem</title>
      <link>https://danielpecos.com/2014/01/08/node-js-ecosystem/</link>
      <pubDate>Wed, 08 Jan 2014 20:38:59 +0100</pubDate>
      
      <guid>https://danielpecos.com/2014/01/08/node-js-ecosystem/</guid>
      
      <description>&lt;p&gt;&lt;img class=&#34;alignleft &#34; src=&#34;https://danielpecos.com/assets/2014/01/nodejs-dark.png&#34; alt=&#34;Node.js - Theme title&#34; width=&#34;191&#34; height=&#34;103&#34; /&gt;The Node.js &lt;a href=&#34;https://npmjs.org/&#34;&gt;ecosystem&lt;/a&gt; is quite young and prolific: new tools appear almost every day or week, changing and turning upside down your current workflow, always trying to squeeze a little more productivity to your time and effort or simply making your work easier.&lt;/p&gt;
&lt;p&gt;As an example, take a look on the &lt;a href=&#34;http://nodeframework.com/&#34;&gt;NodeFramework page&lt;/a&gt;, where &lt;a href=&#34;http://azat.co/&#34;&gt;Azat Mardanov&lt;/a&gt; (&lt;a href=&#34;https://twitter.com/azat_co&#34;&gt;@azat_co&lt;/a&gt;) collects lot&amp;rsquo;s of frameworks and utilities related to Node.js. Or &lt;a href=&#34;http://nodewebmodules.com/&#34;&gt;NodeWebModules&lt;/a&gt;, more web oriented than the previous one, from &lt;a class=&#34;url&#34; href=&#34;http://crpwebdev.com&#34; rel=&#34;external nofollow&#34;&gt;Caio Ribeiro Pereira &lt;/a&gt;(&lt;a href=&#34;http://twitter.com/crp_underground&#34;&gt;@crp_underground&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the basics:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;node&lt;/strong&gt; and &lt;strong&gt;npm&lt;/strong&gt;. &lt;em&gt;node&lt;/em&gt; is the command line Javascript interpreter and it&amp;rsquo;s the core for the whole ecosystem. &lt;em&gt;npm&lt;/em&gt; on the other hand, is a tool to manage that ecosystem, allowing you to install new modules and tools, and keeping them up to date. Although &lt;em&gt;npm&lt;/em&gt; is not tightened to node, it&amp;rsquo;s provided with the default Node.js installation package, making it the defacto Node.js module manager.&lt;/p&gt;
&lt;p&gt;But &lt;em&gt;npm&lt;/em&gt; is not only a module manager: it&amp;rsquo;s also a great tool to manage a node project dependencies, taking care of recursive dependencies and resolving collisions between modules. You can take a look to all its capabilities in this &lt;a href=&#34;http://howtonode.org/introduction-to-npm&#34;&gt;great tutorial&lt;/a&gt; from &lt;a href=&#34;http://github.com/isaacs&#34;&gt;Isaac Z. Schlueter&lt;/a&gt; (&lt;a href=&#34;http://twitter.com/izs&#34;&gt;@izs&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Anyone can create and share npm modules, making the ecosystem bigger and bigger. At this moment &lt;a href=&#34;https://npmjs.org/&#34;&gt;npm repository&lt;/a&gt; has around 54K packages ready to download, and its growth rate is &lt;a href=&#34;https://blog.nodejitsu.com/npm-innovation-through-modularity&#34;&gt;faster than other&amp;rsquo;s ecosystems&lt;/a&gt; (see also &lt;a href=&#34;http://www.futurealoof.com/posts/open-source-ecosystem-growth.html&#34;&gt;this link&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.nodejitsu.com/npm-innovation-through-modularity&#34;&gt;&lt;img class=&#34; &#34; src=&#34;https://danielpecos.com/assets/2014/01/package_growth_comparison.png&#34; alt=&#34;Packages per day across popular platforms (Source: www.modulecounts.com)&#34; width=&#34;680&#34; height=&#34;337&#34; /&gt;&lt;/a&gt; Packages per day across popular platforms (Source: &lt;a href=&#34;http://www.modulecounts.com&#34;&gt;www.modulecounts.com&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The current state of art of the Node.js ecosystem include, among others, these tools as the most popular ones,  in my opinion:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CoffeeScript&lt;/li&gt;
&lt;li&gt;Grunt&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;Mocha&lt;/li&gt;
&lt;li&gt;PM2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But I’m sure that many other tools and modules deserve to appear in this top 5 list. It’s so nice and funny to keep discovering new jewels every single day, isn’t it? &lt;img src=&#34;https://danielpecos.com/assets/2014/01/icon_smile.gif&#34; alt=&#34;:-)&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Node.js and V8 history</title>
      <link>https://danielpecos.com/2013/12/19/nodejs-v8-history/</link>
      <pubDate>Thu, 19 Dec 2013 06:15:38 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/12/19/nodejs-v8-history/</guid>
      
      <description>&lt;p&gt;Talking about Node.js history, it&amp;rsquo;s talking a little bit about V8 history. But let&amp;rsquo;s start with a one line definition of what  it is: Node.js is a platform built around Google Chrome V8 Javascript engine, to create lightweight, fast, scalable, event-driven and non-blocking I/O applications. So lets begin talking about Node.js origins, the V8 javascript engine.&lt;/p&gt;
&lt;p&gt;V8 is an opensource project by Google and it is in the very core of Google Chrome browser. Its first public release was on September 2, 2008, same date Chrome&amp;rsquo;s first release was announced. It was a big step forward in browsers&amp;rsquo; performance, and it pushed browsers&amp;rsquo; technology to a new whole level. It&amp;rsquo;s written in C++ and its biggest revolution was that it precompiled the Javascript source code to machine code instead of just interpret it and then applied a JIT process again in runtime to improve dynamic code execution.&lt;/p&gt;
&lt;p&gt;&lt;img class=&#34;size-medium&#34; src=&#34;https://danielpecos.com/assets/2013/12/ryan_dahl-300x172.jpg&#34; alt=&#34;Ryan Dahl - Creator of Node.js&#34; width=&#34;300&#34; height=&#34;172&#34; /&gt;Ryan Dahl – Creator of Node.js&lt;/p&gt;
&lt;p&gt;Then, around 2009, Ryan Dahl was trying to solve a tough problem in that days: making the browser know how much time of an upload process was left. Inspired by Ruby&amp;rsquo;s Mongrel webserver and by the recent release of Chrome and V8, he decided to give Javascript a chance, creating the seeds that would transform in short time into Node.js.&lt;/p&gt;
&lt;p&gt;The project has been develop and sponsored by Joyent, company where Ryan was working. Nowadays he is still working there, but has stepped back, delegating the gatekeeper position to Isaac Schlueter on January 30, 2012.&lt;/p&gt;
&lt;p&gt;If you are interested in further details about Ryan Dahl and how and why he decided to create Node.js, here you have a video of himself talking about that:&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;embed-youtube&#34; style=&#34;text-align:center; display: block;&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;line-height: 1.5em&#34;&gt;Historically, Javascript browser environments are limited to just one execution process / thread, making impossible to update DOM and execute some business logic simultaneously, and this also applied to V8, so, why someone would be interested in such limited and poor performance platform to run in a server environment?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Well, truth is that maybe Javascript is not the most calculation efficient language available, but its event-driven non blocking design, makes Node.js one of the lightweight platforms (runs really well in a RaspberryPI) and more performant web platforms, competing directly with the old JEE Java Platform, PHP and Ruby.&lt;/p&gt;
&lt;p&gt;From a developer perspective, the amount of innovation the Node.js community is creating is simply astonishing, and that&amp;rsquo;s also because one of the three other key tools a Node.js developer must known: NPM.&lt;/p&gt;
&lt;p&gt;But this is a story we will address another day.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Nodejs&#34;&gt;http://en.wikipedia.org/wiki/Nodejs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/V8&#34;&gt;http://en.wikipedia.org/wiki/V8&lt;/a&gt;_(JavaScript_engine)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://code.google.com/p/v8/&#34;&gt;https://code.google.com/p/v8/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Hello world! Node.js &amp; Javascript blog</title>
      <link>https://danielpecos.com/2013/12/16/hello-world-node-js-javascript-blog/</link>
      <pubDate>Mon, 16 Dec 2013 13:35:57 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/12/16/hello-world-node-js-javascript-blog/</guid>
      
      <description>&lt;h3 id=&#34;wellcome-to-this-new-site-where-youll-find-lots-of-information-about-nodejs-javascript-and-html-5-technologies&#34;&gt;Wellcome to this new site where you&amp;rsquo;ll find lots of information about Node.js, Javascript and HTML 5 technologies!&lt;/h3&gt;
&lt;img class=&#34;size-thumbnail alignnone&#34; src=&#34;https://danielpecos.com/assets/2013/12/javascript_2-150x150.png&#34; alt=&#34;Javascript&#34; width=&#34;150&#34; height=&#34;150&#34; /&gt;
&lt;img class=&#34;alignnone&#34; src=&#34;https://danielpecos.com/assets/2013/12/nodejs1-150x150.png&#34; alt=&#34;Node.js&#34; width=&#34;150&#34; height=&#34;150&#34; /&gt;
&lt;img class=&#34;size-thumbnail alignnone&#34; src=&#34;https://danielpecos.com/assets/2013/12/html5-150x150.png&#34; alt=&#34;HTML5&#34; width=&#34;150&#34; height=&#34;150&#34; /&gt;
&lt;br style=&#34;clear:both&#34;/&gt;
&lt;p&gt;This project is a chance for me to share my passion about these new and amazing technologies, trying to make you easier to step into it and to discuss and enjoy technology talks to whomever who wants to.&lt;/p&gt;
&lt;p&gt;It will be mainly focused on &lt;strong&gt;Node.js&lt;/strong&gt;, but sometimes we will talk about generic Javascript or even frontend Javascript related to HTML5 capabilities.&lt;/p&gt;
&lt;p&gt;And if you consider yourself kind of a Node.js guru or simply would like to participate, please just contact me and you will be very welcome to collaborate.&lt;/p&gt;
&lt;p&gt;Hope you enjoy this content as much as I enjoyed creating it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pssst!!&lt;/strong&gt; Don&amp;rsquo;t forget to follow us in &lt;a href=&#34;http://twitter.com/nodegeek&#34;&gt;twitter&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href=&#34;https://danielpecos.com/&#34;&gt;Daniel Pecos Martínez&lt;/a&gt; (&lt;a href=&#34;http://twitter.com/danielpecos&#34;&gt;@danielpecos&lt;/a&gt;)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;dl id=&#34;attachment_44&#34; class=&#34;wp-caption aligncenter&#34; style=&#34;width: 528px&#34;&gt;
  &lt;dt class=&#34;wp-caption-dt&#34;&gt;
  &lt;/dt&gt;
&lt;/dl&gt;
</description>
    </item>
    
    <item>
      <title>Javascript Allongé: a review</title>
      <link>https://danielpecos.com/2013/11/04/javascript-allonge-review/</link>
      <pubDate>Mon, 04 Nov 2013 16:02:50 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/11/04/javascript-allonge-review/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/B00FLKRCVO/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B00FLKRCVO&amp;amp;linkCode=as2&amp;amp;tag=geekware-20&amp;amp;linkId=ZPIPTVEH3LP5UJCO&#34;&gt;&lt;img class=&#34; alignleft&#34; src=&#34;https://danielpecos.com/assets/2013/11/javascript_allonge.jpg&#34; alt=&#34;javascript_allonge&#34; width=&#34;181&#34; height=&#34;233&#34; /&gt;&lt;/a&gt;&lt;a href=&#34;https://leanpub.com/javascript-allonge?a=3ErUYtQxnDzhImL2jSakU-&#34;&gt;&lt;strong&gt;Javascript Allongé&lt;/strong&gt;&lt;/a&gt;&lt;a href=&#34;https://twitter.com/raganwald&#34;&gt;@raganwald&lt;/a&gt; is one of the more refreshing coding books I have read in a big while. Usually when I face a programming language book, I skip the beginner chapters (if I already know the language, of course) and go directly for the juicy ones, but with this one I tried to follow it from end to end because I read some comments on twitter telling that the way basics are explained, become a really solid base for the language, so I gave it a chance.&lt;/p&gt;
&lt;p&gt;And they were right! This book is not the usual &lt;em&gt;Learn the language in 24 hours&lt;/em&gt; or something like that. It&amp;rsquo;s actually a very sharp and deep reading about Javascript and function composition.&lt;/p&gt;
&lt;p&gt;The way the author explains how to create really simple functions and use them to build more complex ones just blowed my mind. The resulting code is so clear and easy follow that is almost impossible to imagine a better way to express that functionality.&lt;/p&gt;
&lt;p&gt;This book is a total recommendation if you deal with Javascript in your day-to-day. I bought a digital copy in &lt;a href=&#34;https://leanpub.com/javascript-allonge&#34;&gt;Leanpub&lt;/a&gt;, but recently the author &lt;a href=&#34;http://braythwayt.com/2013/10/01/javascript-allonge-is-free.html&#34;&gt;made it opensource&lt;/a&gt;, so you&amp;rsquo;re free to get a copy of it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buy it: &lt;a href=&#34;https://leanpub.com/javascript-allonge?a=3ErUYtQxnDzhImL2jSakU-&#34;&gt;https://leanpub.com/javascript-allonge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Buy it (Kindle): &lt;a href=&#34;http://www.amazon.com/gp/product/B00FLKRCVO/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B00FLKRCVO&amp;amp;linkCode=as2&amp;amp;tag=geekware-20&amp;amp;linkId=ZPIPTVEH3LP5UJCO&#34;&gt;Amazon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read it online: &lt;a href=&#34;https://leanpub.com/javascript-allonge/read&#34;&gt;https://leanpub.com/javascript-allonge/read&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Get the sources: &lt;a href=&#34;https://github.com/raganwald/javascript-allonge&#34;&gt;https://github.com/raganwald/javascript-allonge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>RaspberryPi shutdown button</title>
      <link>https://danielpecos.com/2013/09/30/raspberrypi-custom-command-button/</link>
      <pubDate>Mon, 30 Sep 2013 15:57:55 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/09/30/raspberrypi-custom-command-button/</guid>
      
      <description>&lt;p&gt;Last Friday I got some spare time (finally!) and, with the help and tools of my friend &lt;a href=&#34;https://twitter.com/aprades&#34;&gt;Alfredo&lt;/a&gt;, we placed a button in the RaspberryPi case so, when I push it, a custom command its executed on the RaspberryPi, like for example, a clean system shutdown.&lt;/p&gt;
&lt;p&gt;First lets start with some pictures of the final result:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.42.31.jpg&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.42.31-150x150.jpg&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.43.02.jpg&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.43.02-150x150.jpg&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.47.33.jpg&#34;&gt;&lt;img class=&#34;alignleft&#34; src=&#34;https://danielpecos.com/assets/2013/09/2013-09-30-19.47.33-150x150.jpg&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br style=&#34;clear:both&#34;/&gt;
&lt;p&gt;And now the schematics (pins used in the schematics are 3.3v, GND and GPIO):&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2013/09/raspberry_gpio_button-809x1024.png&#34;&gt;&lt;img class=&#34;aligncenter&#34; src=&#34;https://danielpecos.com/assets/2013/09/raspberry_gpio_button-809x1024.png&#34; alt=&#34;raspberry_gpio_button&#34; width=&#34;210&#34; height=&#34;266&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We mainly followed this &lt;a href=&#34;http://www.cl.cam.ac.uk/~db434/raspi/buttons_and_switches/&#34;&gt;post&lt;/a&gt;, but used a different GPIO port, we soldered the components (once we tested the schematics on a protyping board) and modified the code to launch a custom command. This is the resulting code we used to do a &lt;strong&gt;system&lt;/strong&gt; &lt;strong&gt;shutdown&lt;/strong&gt; (I removed some comments from the original code of the post):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import os
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4,GPIO.IN)

prev_input = 0
while True:
  input = GPIO.input(4)
  if ((not prev_input) and input):
    os.system(&amp;#34;sudo halt&amp;#34;)
  prev_input = input
  #slight pause to debounce
  time.sleep(0.05)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The line highlighted is the one you should modify to set your custom command. To test it, you have to execute it as &lt;em&gt;root&lt;/em&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo python gpio_button.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and press the button. Finally, to launch this code in the startup process, just add it to &lt;em&gt;/etc/rc.local&lt;/em&gt; (just before the &lt;em&gt;exit 0&lt;/em&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo vi /etc/rc.local
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Easy peasy!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Next steps&lt;/em&gt;&lt;/strong&gt;: modify the program to detect single click, double-click and long click.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Madrid – OpenSpace Persistencia</title>
      <link>https://danielpecos.com/2013/01/19/madrid-openspace-persistencia/</link>
      <pubDate>Sat, 19 Jan 2013 20:31:50 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/01/19/madrid-openspace-persistencia/</guid>
      
      <description>&lt;p&gt;&lt;em&gt;Persistencia&lt;/em&gt; ha sido el tema tratado en el OpenSpace que se ha realizado en las oficinas de tuenti. Hemos podido hablar sobre temas como NoSQL, ActiveRecord, BD basados en grafos, geoespaciales, … entre otros muchos. Ha habido mucho debate, con muchas opiniones, pero sobre todo muy buen ambiente.&lt;/p&gt;
&lt;p&gt;Muy interesante la charla que ha dado la gente de tuenti sobre como gestionan la persistencia. Es de agradecer la claridad y transparencia con la que han participado.&lt;/p&gt;
&lt;p&gt;Dar las gracias a @borillo por el esfuerzo en la organización del evento y a tuenti por ofrecer sus oficinas para el evento.&lt;/p&gt;
&lt;p&gt;Os recomiendo que en cuanto tengáis la oportunidad, acudáis a un OpenSpace siempre resulta una actividad muy gratificante y en la que seguro aprenderás algo nuevo.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Javascript Promises Pattern in plain Javascript</title>
      <link>https://danielpecos.com/2013/01/16/javascript-promises-101-part2/</link>
      <pubDate>Wed, 16 Jan 2013 13:05:01 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/01/16/javascript-promises-101-part2/</guid>
      
      <description>&lt;p&gt;In the &lt;a href=&#34;https://danielpecos.com/2013/01/08/javascript-promises-pattern-101/&#34; title=&#34;Javascript Promises – 101&#34;&gt;previous post&lt;/a&gt; I gave a glimpse of the Javascript Promises Pattern (JPP). Now we are going to take a more in deep look into it and implement our (simplified) version of this pattern.&lt;/p&gt;
&lt;p&gt;First of all, let’s sow the code I we defined works: we had three operations (to make the example simpler, they all share the same code, but this is not a requisite), each of them expecting a set of arguments which are processed by an asynchronous operation. The result of this asynchronous operation will be feed to the next operation, and so on until we achieve &lt;code&gt;processResults&lt;/code&gt; function that will handle the final result. This is a refactored version of the code exposed in the previous post:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function operation(params) {
  var promise = new Promise(this)
  async_task(params, function() {
    // ...
    promise.resolve(params);
  });
  return promise;
}

function processResults(results) {
  // ...
}

operation1 = operation;
operation2 = operation;
operation3 = operation;

operation1(params1).then(operation2).then(operation3).then(processResults);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Every operation creates a promise object that will be returned as result of the invocation to the operation. Furthermore, this promise object is used to store the future value that will result from the asynchronous call. This value is stored in the promise object using the &lt;code&gt;resolve&lt;/code&gt; method.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;operation1(params1).then(operation2).then(operation3).then(processResults);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This line is were all the magic is done: we invoke the first operation, which returns a promise object, and over this object we are invoking the &lt;code&gt;then&lt;/code&gt; method, passing a function as its argument, &lt;strong&gt;which will be invoked when the promise object is resolved&lt;/strong&gt;. Then we repeat this invocation to the &lt;code&gt;then&lt;/code&gt; method in order to chain more callbacks, each of them being invoked by successive promise &lt;code&gt;resolve&lt;/code&gt; invocations.&lt;/p&gt;
&lt;p&gt;This may appear simple, but it’s kind of tricky: we pretend to receive the results of every operation as argument of the following callback. That works ok for &lt;code&gt;operation1&lt;/code&gt;, but promises objects from operations 2 and 3 still don’t exist so there is no way to attach those promises to its correspondent callback. In other words, invoking the &lt;code&gt;then&lt;/code&gt; method of the promise object doesn’t actually invoke operation2 and operation3 (in fact, the parameters they need are still not available). What really happens is that they are chained into the operation1 promise object.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;operation1: return promise1
-&amp;gt; invoke then (operation2): return promise1
-&amp;gt; invoke then (operation3): return promise1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So how does JPP resolve this? Well, the trick can be discovered paying attention to the instantiation of the promise objects: we passed &lt;code&gt;this&lt;/code&gt; as first argument, which in fact turns to be global object &lt;code&gt;Window&lt;/code&gt; for &lt;code&gt;promise1&lt;/code&gt; and operation1 promise object for the &lt;em&gt;promise2&lt;/em&gt; and &lt;em&gt;promise3&lt;/em&gt; instantiations. That’s because &lt;strong&gt;resolve method invokes callbacks functions applying itself as the current scope&lt;/strong&gt;. Maybe it’s easier to see in code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function Promise(promise) {
    if (promise instanceof Promise) {
        return promise;
    } else {
        // this is a new promise chain
        this.callbacks = [];
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Having this idea clear, we can try to develop our own implementation for this pattern. We already have defined the constructor function, let’s go for the &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;resolve&lt;/code&gt; methods:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Promise.prototype.then = function(callback_ok) {
    this.callbacks.push({
        ok: callback_ok
    });
    return this;
};

Promise.prototype.resolve = function() {
    var callback = this.callbacks.shift();
    if (callback &amp;amp;&amp;amp; callback.ok) {
        callback.ok.apply(this, arguments);
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we said, &lt;code&gt;then&lt;/code&gt; just store the function to call when the &lt;code&gt;resolve&lt;/code&gt; method is invoked. &lt;code&gt;resolve&lt;/code&gt; then just pops the callback function to invoke, applying current promise object (&lt;code&gt;this&lt;/code&gt;) as its scope, so when the next operation tries to create a new promise object, it gets the actual promise object instead of a new one, which turns to be the one used to define the chain of callbacks.&lt;/p&gt;
&lt;p&gt;Well, better than to read code to understand it, is to play with it, so &lt;a href=&#34;http://jsfiddle.net/dpecos/HDbBa/&#34; target=&#34;_blank&#34;&gt;here you have a fiddle&lt;/a&gt; ready to go. It’s a litlle more complex implementation than the exposed here, because I defined a &lt;code&gt;reject&lt;/code&gt; method, but the main idea stands.&lt;/p&gt;
&lt;p&gt;I would love to hear feedback from you about the pattern itself or the implementation, so don’t hesitate to post comments!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Javascript Promises Pattern – 101</title>
      <link>https://danielpecos.com/2013/01/08/javascript-promises-pattern-101/</link>
      <pubDate>Tue, 08 Jan 2013 11:03:59 +0100</pubDate>
      
      <guid>https://danielpecos.com/2013/01/08/javascript-promises-pattern-101/</guid>
      
      <description>&lt;p&gt;I am sure you have heard about the javascript Promises Pattern, but if you haven&amp;rsquo;t, here is a quick and simple definition: a promise or future is an object that represents a future result, not yet obtained or calculated (&lt;a href=&#34;http://en.wikipedia.org/wiki/Futures_and_promises&#34;&gt;here&lt;/a&gt; you have a more complete definition). In fact, what is really nice about it is that allows you to define callbacks for async code in and more elegant and readable way.&lt;/p&gt;
&lt;p&gt;But wait a moment, what&amp;rsquo;s the problem with the actual callbacks system? Well, they work, but they become a big mess when you try to chain two or more of them, resulting in a code looking like a pyramid. Let&amp;rsquo; see an example.&lt;/p&gt;
&lt;p&gt;Suppose you have several async operations: operation1, operation2 and operation3 and they must be execute in strict sequence, that is, operation 2 must wait for operation1 to finish and so on. The resulting code will look like something like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;operation1(params1) {
  async_task(params1, function() {
    operation2(params2) {
      async_task(params2, function() {
        operation3(params3) {
          async_task(params3, function() {
            // here we have the results of the three operations
          }
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code is, at least, hard to follow and thus to understand (and in my opinion quite ugly), but it has been the common way to deal with asynchronism in javascript… until now. Look how the same code would look like using Promise Pattern:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function operation1(params1) {
  var promise = new Promise()
  async_task(params1, function() {
    // ...
    promise.resolve(params2);
  });
  return promise;
}

function operation2(params2) {
  var promise = new Promise(this)
  async_task(params2, function() {
    // ...
    promise.resolve(params3);
  });
  return promise;
}

function operation3(params3) {
  var promise = new Promise(this)
  async_task(params3, function() {
    // ...
    promise.resolve(allResults);
  });
  return promise;
}

function processResults(allResults) {
  // ...
}
operation1(params1).then(operation2).then(operation3).then(processResults);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here you can clearly see that there are three different operations, that don&amp;rsquo;t appear to be tight one to another. The chainability of the three functions is established in the last line of code, making it clear with a glimpse that every operations depends on the result of the previous one, and thus, they must be executed in strict order. This line is the key of the Promise Pattern and it works because every operation return a promise object. We&amp;rsquo;ll deep into this in further posts.&lt;/p&gt;
&lt;p&gt;This code can be heavy refactored, but I prefer to keep it like this to make it easy to understand how promises work. Anyway, I think you will agree with me that this code is much elegant and easy to understand than the previous one.&lt;/p&gt;
&lt;p&gt;So far, so good. In further posts I will show you how to easily implement this pattern in plain javascript, and we will deep into the tricks that promises use to make this code work. By the moment enjoy using the implementations provided by the main javascript libraries (much more powerfull than the one we will create) like &lt;a href=&#34;http://api.jquery.com/category/deferred-object/&#34;&gt;jQuery&amp;rsquo;s deferreds&lt;/a&gt; (they are the same concept as promises).&lt;/p&gt;
&lt;p&gt;See you in following posts!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Retrospectiva 2012</title>
      <link>https://danielpecos.com/2012/12/31/retrospectiva-2012/</link>
      <pubDate>Mon, 31 Dec 2012 16:02:37 +0100</pubDate>
      
      <guid>https://danielpecos.com/2012/12/31/retrospectiva-2012/</guid>
      
      <description>&lt;p&gt;31 de Diciembre, otro año más. Y uno nuevo a punto de llegar.&lt;/p&gt;
&lt;p&gt;En mi caso es fácil resumir 2012 en un par de palabras: &lt;strong&gt;cambio&lt;/strong&gt; y &lt;strong&gt;aprendizaje&lt;/strong&gt;. Ha sido un año en el que profesionalmente he tomado un cambio de dirección y del cual estoy realmente satisfecho, aunque en su momento fue una decisión díficil, sobre todo por el momento de crisis en el que nos encontramos. Y es que este cambio me ha hecho aprender. Mucho.&lt;/p&gt;
&lt;p&gt;Ha sido el año en el que he descubierto el &lt;em&gt;Agilismo&lt;/em&gt; como técnica de trabajo, y que me ha permitido conocer muchos otros puntos de vista, distintos y muchos de ellos muy interesantes. Y esto me ha permitido hacerme una auto-crítica (o retrospectiva) de la cual puedo sacar una idea muy clara: &lt;strong&gt;más cambio&lt;/strong&gt;. Y es que, pesar de las técnicas que he podido descubrir y de las tecnologías que he podido aprender, solo he encontrado una constante: &lt;em&gt;Nunca dejes de aprender, lo que hoy sabes, cambiará, y debes estar preparado. No le tengas miedo y abrázalo como un reto constante.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Esto es más cierto, si cabe, en la informática, ya que el cambio ocurre en plazos realmente cortos, y los cambios que avecinan parecen no ser pequeños. ¿Quién me iba a decir a mi en Enero de este año que terminaría habiendo hecho formaciones sobre Agilismo y Scala y que el &lt;em&gt;hype&lt;/em&gt; tecnológico a finales de año se centraría en HTML5 y  Javascript? No way… pero así es, y la verdad es que es un mundo realmente emocionante el que nos espera este próximo año.&lt;/p&gt;
&lt;p&gt;Aunque sin duda el cambio más importante que he experimentado este año no se puede definir en palabras:&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;img class=&#34;aligncenter&#34; alt=&#34;Izan - 2012 / 10 / 11&#34; src=&#34;https://danielpecos.com/assets/2012/12/ecografia_20121011-300x174.png&#34; width=&#34;300&#34; height=&#34;174&#34; /&gt; Izan &amp;#8211; 2012 / 10 / 11
&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;¡Feliz año 2013!&lt;/strong&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Valencia – Global Day of Coderetreat 2012</title>
      <link>https://danielpecos.com/2012/12/08/valencia-global-day-of-coderetreat-2012/</link>
      <pubDate>Sat, 08 Dec 2012 18:36:29 +0100</pubDate>
      
      <guid>https://danielpecos.com/2012/12/08/valencia-global-day-of-coderetreat-2012/</guid>
      
      <description>&lt;p&gt;Creo que la mejor forma de iniciar este post es felicitando a los organizadores (&lt;a href=&#34;https://twitter.com/borillo&#34; target=&#34;_blank&#34;&gt;@borillo&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/XaV1uzz&#34; target=&#34;_blank&#34;&gt;@xaviuzz&lt;/a&gt;, hay que reconocer que os lo habéis currado) y dando las gracias a &lt;a href=&#34;http://peertransfer.com/&#34; target=&#34;_blank&#34;&gt;peerTransfer&lt;/a&gt; por hacer de host para este evento de forma totalmente altruista.&lt;/p&gt;
&lt;p&gt;Una pena para aquellos que no hayan podido asistir: ha resultado ser un evento muy dinámico, con opiniones y puntos de vista muy variados e interesantes y, sobretodo, divertido.&lt;/p&gt;
&lt;p&gt;El problema a resolver (&lt;a href=&#34;http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&#34; target=&#34;_blank&#34;&gt;Conway&amp;rsquo;s Game of Life&lt;/a&gt;), aunque simple en principio, ha dado mucho juego, y aunque un pomodoro no es suficiente para implementar una solución completa, ni mucho menos, ha sido la excusa perfecta para practicar pair programming, TDD y ya de paso, poner en práctica algún nuevo lenguaje y herramientas.&lt;/p&gt;
&lt;p&gt;¿Qué más se puede esperar de un Sábado de programación por el mero placer de programar y aprender?&lt;/p&gt;
&lt;p style=&#34;text-align: left;&#34;&gt;
  &lt;a href=&#34;https://danielpecos.com/assets/2012/12/IMG_20121208_153502.jpg&#34;&gt;&lt;img class=&#34;aligncenter &#34; title=&#34;GDCR2012&#34; alt=&#34;&#34; src=&#34;https://danielpecos.com/assets/2012/12/IMG_20121208_153502-1024x768.jpg&#34; width=&#34;467&#34; height=&#34;350&#34; /&gt;&lt;/a&gt;Y ahora a ver si consigo implementar una versión del juego medianamente completa, que al final me he quedado con las ganas. ¡Esto es puro vicio!
&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://coderetreat.org/events/global-day-of-coderetreat-valencia-spain&#34; target=&#34;_blank&#34;&gt;&lt;a href=&#34;http://coderetreat.org/events/global-day-of-coderetreat-valencia-spain&#34;&gt;http://coderetreat.org/events/global-day-of-coderetreat-valencia-spain&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Functional Programming &amp; Scala course finished</title>
      <link>https://danielpecos.com/2012/11/13/functional-programming-scala-course-finished/</link>
      <pubDate>Tue, 13 Nov 2012 09:12:15 +0100</pubDate>
      
      <guid>https://danielpecos.com/2012/11/13/functional-programming-scala-course-finished/</guid>
      
      <description>&lt;p&gt;Coursera Functional Programming has not been my first experience in an online course, but it has been the most satisfying by far. Many people were interested in it, and I think it created a great hype, not only in the course forums but in social networks like twitter. People all around the world were interacting in the same course, creating really interesting conversations and discussions about the subject. Really nice.&lt;/p&gt;
&lt;p&gt;Technically speaking, the course has consisted in an introduction Functional Programming principles and a more in deep look to the Scala language. But, in my opinion, one of the key points in this course was the lessons format: between 1 hour and 1.5 per week of video and slides from the professor Martin Odersky and one home assignment.&lt;/p&gt;
&lt;p&gt;The difficult of the assignments were in crescendo, making them a really funny challenge every week (I remember a couple of days staying up until really late at night because I was in flow with the current assignment and didn&amp;rsquo;t want to stop it).&lt;/p&gt;
&lt;p&gt;In conclusion, high quality content, teacher and classmates, really interesting stuff about FP and Scala and, more important, a really satisfying experience (nothing compared to the online course I took at the UNED, and for what I paid a considerable amount of money).&lt;/p&gt;
&lt;p&gt;PD: Did I mention that this Coursera FP &amp;amp; Scala course was for free? Thank you very much Coursera and Pr. Martin Odersky (and stuff)!&lt;/p&gt;
&lt;p&gt;Looking forward to a continuation course!&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.coursera.org/course/progfun&#34;&gt;Coursera Functional Programming Course&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Recipe: From SVN to Git without pain</title>
      <link>https://danielpecos.com/2012/01/13/recipe-from-svn-to-git-without-pain/</link>
      <pubDate>Fri, 13 Jan 2012 18:33:49 +0100</pubDate>
      
      <guid>https://danielpecos.com/2012/01/13/recipe-from-svn-to-git-without-pain/</guid>
      
      <description>&lt;p&gt;Are you already in love with Git? I&amp;rsquo;m pretty sure of that, that&amp;rsquo;s the reason why you are reading this, huh?&lt;/p&gt;
&lt;p&gt;These are the steps you should follow to migrate an existing SVN repository to a Git one:&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;1 – Create a file where you will map SVN users to Git users, following this pattern:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;svn_user = git_user&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This is the one I created to migrate some SVN repositories from Google Code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cat authors_mapping_googlecode
dpecos = Daniel Pecos Martinez
(no author) = Daniel Pecos Martinez
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The author &lt;em&gt;(no author)&lt;/em&gt; is required to match some commits made by Google in the SVN repository creation process.&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;2 – Now let&amp;rsquo;s import code from SVN:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git svn clone --username svn_user --authors-file=authors_mapping --no-metadata -s svn_url git_repo_path_tmp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The one I used to import my np-lib project was:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git svn clone --username dpecos --authors-file=authors_mapping_googlecode --no-metadata -s https://np-lib.googlecode.com/svn/ np-lib_tmp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can go into the just created Git repository and display its log in a pretty tree format:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git log --graph --decorate --pretty=oneline --abbrev-commit&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;3 – Next step is to clone this repository into a new one, just get ride of all SVN junk created by git-svn:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git clone git_repo_path_tmp git_repo_path&amp;lt;br /&amp;gt; $ rm -rf git_repo_path_tmp&amp;lt;br /&amp;gt; $ cd git_repo_path&amp;lt;br /&amp;gt; $ git remote rm origin&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;4 – We are ready, but maybe you want to push your repository to GitHub (or any other one), so what you&amp;rsquo;ll need to do as follows:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(At this point I suppose that you have created a Git repository in GitHub and that you have already setup your environment to push content to it, if not, you will have troubles from now on)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git remote add remote_name git_url&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In my case it was:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git remote add github git@github.com:dpecos/NP-Lib.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Some clarifications about this last command: many people use as default remote Git repository name “&lt;em&gt;origin&lt;/em&gt;“, me too, but in this case, GitHub wasn&amp;rsquo;t my default remote Git repository, but I private one so I decided to create a “&lt;em&gt;github&lt;/em&gt;” remote.&lt;/p&gt;
&lt;p&gt;Now we only have to push local content to the remote repository:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git push remote_name master&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Which in my case was:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git push github master&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s all, we got a Git repository set up and ready to work with GitHub starting from a SVN one.&lt;/p&gt;
&lt;p&gt;Hope this recipe will help you. Time to enjoy!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Blog rollback</title>
      <link>https://danielpecos.com/2011/12/30/blog-rollback/</link>
      <pubDate>Fri, 30 Dec 2011 16:27:03 +0100</pubDate>
      
      <guid>https://danielpecos.com/2011/12/30/blog-rollback/</guid>
      
      <description>&lt;p&gt;A couple of months ago I took the decision to reset my blog and start it again from the beginning, creating a more professional computer technology oriented content. I wrote some technical articles and I feel really proud of them, but there was something left, some place where I could write about my thoughts or anything I would think it would deserve it.&lt;/p&gt;
&lt;p&gt;Some days ago I make a quick revision of a backed up previous blog where I found some articles I liked very much, some of them with several comments, containing really interesting stuff, and some others that were really crap articles. I started thinking that maybe the restart of the blog was not a good decision, that what my blog really needed was a good clean up and not a complete reset. And that&amp;rsquo;s what I&amp;rsquo;ve been doing for a couple of days, recovering articles that I feel are interesting or that made me feel in some special way when I wrote them.&lt;/p&gt;
&lt;p&gt;Now I am proud to present this refurbished version of my previous blog and the more recent one. It contains technical content, personal stuff, opinion articles and more written in Spanish and English. To make this change more noticeable, I have decided to give it a new name: &lt;a href=&#34;https://danielpecos.com/&#34;&gt;&lt;strong&gt;dpmWare, &lt;em&gt;just my stuff, nothing else&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; (just to show the influence of my recent blog &lt;em&gt;Debug yourself! Simply code, just that&lt;/em&gt;). I&amp;rsquo;m also planning to apply a new style to the site so maybe you&amp;rsquo;ll see some changes in a few days.&lt;/p&gt;
&lt;p&gt;Of course I will continue writing technical articles and finish some series of articles still pending. I hope you will enjoy these articles at least as much as I enjoyed writing them.&lt;/p&gt;
&lt;p style=&#34;text-align: right;&#34;&gt;
  &lt;em&gt;&lt;strong&gt;Daniel Pecos Martinez&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;PS: Happy new year 2012!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Git-SCM (Part 2)</title>
      <link>https://danielpecos.com/2011/08/28/git-scm-part2/</link>
      <pubDate>Sun, 28 Aug 2011 18:34:04 +0100</pubDate>
      
      <guid>https://danielpecos.com/2011/08/28/git-scm-part2/</guid>
      
      <description>&lt;p&gt;In a &lt;a href=&#34;https://danielpecos.com/2010/11/git-scm-part1&#34;&gt;previous post&lt;/a&gt;, we have seen what Git is and its main characteristics. Now, we&amp;rsquo;ll go more into detail about its functionality and we&amp;rsquo;ll see what a usual day working with Git looks like.&lt;/p&gt;
&lt;p&gt;But before, some initial concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Repository&lt;/strong&gt;: A &lt;em&gt;working tree&lt;/em&gt; of files and directories which can be versioned, keeping track of every single modification made over the working tree, been able to move forward and backward in its &lt;em&gt;history&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Branch&lt;/strong&gt;: it is an alternative image of the repository, keeping track of its own history of modifications. A repository has a main branch called &lt;em&gt;master&lt;/em&gt;, and it can have an undefined number of branches, some of them may be copies of &lt;em&gt;remote branches&lt;/em&gt; and the default name for the upstream repository is &lt;em&gt;origin&lt;/em&gt;. The current branch of the working copy can be always referenced as &lt;em&gt;HEAD&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Commit&lt;/strong&gt;: it is a concrete state of a branch, containing the modifications made to the entire working tree since the previous commit in the history, as well as author information and timestamps. It can be identified by its SHA hash, but a name or &lt;em&gt;tag&lt;/em&gt; can be associated to it in order to make thing easier.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merge&lt;/strong&gt;: it is the process of integrating changes or commits of two different branches. This integration is automatically carried by Git, if there are no &lt;em&gt;conflicts&lt;/em&gt; between commits.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Push&lt;/strong&gt;: the changes committed in a local branch into a remote branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are the basic concepts we are going to use in the rest of this post. Now let’s start with the fun!&lt;/p&gt;
&lt;h5 id=&#34;setting-up-the-repository-initialize-and-importing&#34;&gt;Setting up the repository: initialize and importing&lt;/h5&gt;
&lt;p&gt;First step is to create or to obtain a repository. In order to create a fresh new repository, this is the instructions we need to execute:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir hello_world
cd hello_world
git init
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, we can grab an already initialized remote repository with these instructions:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git clone git://url.to/hello_world
cd hello_world
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A Git repository is a normal directory that contains a .git directory inside, where all the necessary information to track changes will be stored.&lt;/p&gt;
&lt;h5 id=&#34;modifications-status-adding-committing-and-reverting&#34;&gt;Modifications: status, adding, committing and reverting&lt;/h5&gt;
&lt;p&gt;Once we have our repository ready to work (we can check that its clean by using the command status):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use &amp;#34;git add&amp;#34; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;we can start to work in the current directory, creating, modifying and deleting files and directories as we need to. For example, I will create a Hello World! in java (but a more complex one than the usual, to prove how to work with several files). First of all, I’m going to create two separate folders: one for sources and other for classes. Then I will create an empty Greetings.java and a HelloWorld.java and then I will make a commit with the initial structure:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir src bin
touch src/Greetings.java
touch src/HelloWorld.java
git add –A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can check the status of the current working tree and see that there are changes pending to be committed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use &amp;#34;git rm --cached ...&amp;#34; to unstage)
#
# new file: src/Greetings.java
# new file: src/HelloWorld.java
#
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So let’s commit these modifications. Every commit needs a commit message that identifies the contents of this commit:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git commit –m &amp;#34;Initial commit: project structure and source files created&amp;#34;
[master (root-commit) 8738922] Initial commit: project structure and source files created
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/Greetings.java
create mode 100644 src/HelloWorld.java
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, we have our prune project ready to be coded. Now it is time to type the necessary code to get the result expected, so open Greetings.java and HelloWorld.java with your preferred editor and paste the following code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Greetings.java&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Greetings {

	public int sayHello() {
		System.out.println(&amp;#34;Hello World!&amp;#34;);
	}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;HelloWorld.java&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class HelloWorld {

	public static void main(String[] args) {
		Greetings g = new Greetings();
		g.sayHello();
	}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now if we check the status of the working tree, we can see that these two files have modifications pending to be committed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git status
# On branch master
# Changes not staged for commit:
# (use &amp;#34;git add ...&amp;#34; to update what will be committed)
# (use &amp;#34;git checkout -- ...&amp;#34; to discard changes in working directory)
#
# modified: src/Greetings.java
# modified: src/HelloWorld.java
#
no changes added to commit (use &amp;#34;git add&amp;#34; and/or &amp;#34;git commit -a&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s commit it, it is a Hello World, what could it be wrong, huh?&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git commit –a –m &amp;#34;Java code for Greetings and HelloWorld classes&amp;#34;
[master 18e6ec5] Java code for Greetings and HelloWorld classes
 2 files changed, 13 insertions(+), 0 deletions(-)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can see that our repository history has two commits:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git log
commit 18e6ec54628a5f01f6beda8b30c64f61ab23585a
Author: Daniel Pecos Martinez
Date:   Sun Aug 28 22:42:45 2011 +0200

    Java code for Greetings and HelloWorld classes

commit 8738922a6193fbbeb4bcb67e663b0403a8fbdace
Author: Daniel Pecos Martinez
Date:   Sun Aug 28 19:33:36 2011 +0200

    Initial commit: project structure and source files created
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And if we want to see a diff output of the current HEAD revision with its previous commit we can do like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git diff HEAD^1
diff --git a/src/Greetings.java b/src/Greetings.java
index e69de29..aeff26c 100644
--- a/src/Greetings.java
+++ b/src/Greetings.java
@@ -0,0 +1,6 @@
+public class Greetings {
+
+       public void sayHello() {
+               System.out.println(&amp;#34;Hello World!&amp;#34;);
+       }
+}
\ No newline at end of file
diff --git a/src/HelloWorld.java b/src/HelloWorld.java
index e69de29..cbc10da 100644
--- a/src/HelloWorld.java
+++ b/src/HelloWorld.java
@@ -0,0 +1,7 @@
+public class HelloWorld {
+
+       public static int main(String[] args) {
+               Greetings g = new Greetings();
+               g.sayHello();
+       }
+}
\ No newline at end of file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Time to test it! Compilation is the first step (as you know for sure ;-)):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ javac src/Greetings.java -d bin/

$ javac src/HelloWorld.java -d bin/ -cp bin/
src\HelloWorld.java:6: missing return statement
        }
        ^
1 error
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ups! There was an error :-S Well, that one is easy to fix: let&amp;rsquo;s change return type of main method to void:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ javac src/HelloWorld.java -d bin/ -cp bin/
$ java -cp bin/ HelloWorld
Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So now everything seems fine, but our working tree is not clean, we have our last modifications pending to commit. But, if I commit them and I publish the repository, everyone could see what a fool I am because of that silly mistake, what should I do? Well, I &amp;rsquo;ll try to hide my failure so I will amend last commit and include modifications made later:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git commit -a --amend
[master a612cb0] Java code for Greetings and HelloWorld classes
 2 files changed, 13 insertions(+), 0 deletions(-)

$ git log
commit a612cb025664304586609700b9874eab19aab8b1
Author: Daniel Pecos Martinez
Date:   Sun Aug 28 22:42:45 2011 +0200

    Java code for Greetings and HelloWorld classes

commit 8738922a6193fbbeb4bcb67e663b0403a8fbdace
Author: Daniel Pecos Martinez
Date:   Sun Aug 28 19:33:36 2011 +0200

    Initial commit: project structure and source files created
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Perfect! I have included the necessary fix for my bug and nobody will notice it, great! But wait… my current working tree is not clean:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git status
# On branch master
# Untracked files:
#   (use &amp;#34;git add ...&amp;#34; to include in what will be committed)
#
#       bin/
nothing added to commit but untracked files present (use &amp;#34;git add&amp;#34; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well, these are the files resulting from compilation, so they can be deleted (in fact, is not correct to commit them), but this will happen again and again, any time I compile my project and don&amp;rsquo;t delete the resulting classes. The way to avoid this is to tell Git to ignore certain files that match a defined pattern, defined in a special file .gitignore:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cat &amp;gt; .gitignore
bin/*

$ git status
# On branch master
# Untracked files:
#   (use &amp;#34;git add ...&amp;#34; to include in what will be committed)
#
#       .gitignore
nothing added to commit but untracked files present (use &amp;#34;git add&amp;#34; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Done! now the only thing left is to commit the just created file (I let this to you, so you can practice a little bit with git)&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all folks! (for now ;-)). In following posts I will try to explain how to work with branches (remote and local) and how to resolve conflicts, as well as some nice tools provided by git.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>amCharts Javascript Tutorial: Parsing dates and styling up the chart</title>
      <link>https://danielpecos.com/2011/03/31/amcharts-javascript-tutorial-parsing-dates-and-styling-up-the-chart/</link>
      <pubDate>Thu, 31 Mar 2011 06:44:00 +0100</pubDate>
      
      <guid>https://danielpecos.com/2011/03/31/amcharts-javascript-tutorial-parsing-dates-and-styling-up-the-chart/</guid>
      
      <description>&lt;p&gt;Recently I began a collaboration with &lt;a href=&#34;http://amcharts.com&#34; target=&#34;_blank&#34;&gt;amCharts&lt;/a&gt;, writing some tutorials for their blog. This is my first contribution, and you can find the &lt;a href=&#34;http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-3.html&#34; target=&#34;_blank&#34;&gt;original post&lt;/a&gt; in &lt;a href=&#34;http://blog.amcharts.com&#34; target=&#34;_blank&#34;&gt;amCharts blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-3.html&#34; target=&#34;_blank&#34;&gt;&lt;a href=&#34;http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-3.html&#34;&gt;http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-3.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hope you&amp;rsquo;ll enjoy my first tutorial about this great graphs library! And, of course, feedback is wellcomed!&lt;/p&gt;
&lt;p&gt;In this tutorial we will enhance our previous example in order to parse dates. This will allow us to obtain date-based graphs displaying their data points using relative distance to each other and not placing them at regular spaces.&lt;/p&gt;
&lt;p&gt;We will apply some modifications to our previous example from &lt;a href=&#34;http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-2.html&#34;&gt;Part 2&lt;/a&gt;, so if you haven’t read that part, you should at least get the example source code that you can find at the end of the tutorial. Furthermore, you will need amCharts package. Once you’ll have it unzipped, you have to copy amcharts/javascript folder to your working directory (the rest of directories are not needed for this example).&lt;/p&gt;
&lt;p&gt;Now we are ready. Let’s start!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HANDLING DATES IN OUR DATA SOURCE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The very first step we need to accomplish in this tutorial is to create a function that converts date strings into Date objects. This could be achieved with the following code, where we define a function which requires a string with YYYY-MM-DD date format as first parameter, and returns a Date object created from that date string:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// method which parses a date string in the format YYYY-MM-DD and creates a Date object
function parseDate(dateString) {
     // split the string get each field
     var dateArray = dateString.split(&amp;#34;-&amp;#34;);
     // now lets create a new Date instance, using year, month and day as parameters
     // month count starts with 0, so we have to convert the month number
     var date = new Date(Number(dateArray[0]), Number(dateArray[1]) - 1, Number(dateArray[2]));
     return date;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next we have to locate the exact point in our previous example where this conversion should be done. If you remember, in Part 2 we set up a handler called &lt;em&gt;parseCSV&lt;/em&gt; to manage data loaded via an XMLHttpRequest. This is the perfect place to convert the date strings into javascript Date objects (I have removed some lines of code in order to focus on the changes):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// method which parses csv data
function parseCSV(data){
     // ...
     // loop through all rows
     for (var i = 0; i &amp;lt; rows.length; i++){
          // this line helps to skip empty rows
          if (rows[i]) {
               // our columns are separated by comma
               var column = rows[i].split(&amp;#34;,&amp;#34;);
               // column is array now
               // first item is date
               var date = parseDate(column[0]);

     // ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the data provider contains Date objects instead of strings. Next step is to configure the category axis of the chart to properly manage Date objects: this is achieved setting the property &lt;em&gt;parseDates&lt;/em&gt; of the axis to &lt;em&gt;true&lt;/em&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;var catAxis = chart.categoryAxis;
catAxis.parseDates = true;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These lines have to be added to the createChart function, just like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// method which creates chart
function createChart(){
     // chart variable is declared in the top
     chart = new AmCharts.AmSerialChart();
     // here we tell the chart name of category
     // field in our data provider.
     // we called it &amp;#34;date&amp;#34; (look at parseCSV method)
     chart.categoryField = &amp;#34;date&amp;#34;;
     // now we have to set up the category axis to parse dates
     var catAxis = chart.categoryAxis;
     catAxis.parseDates = true;

     // chart must have a graph
     var graph = new AmCharts.AmGraph();
     // graph should know at what field from data
     // provider it should get values.
     // let&amp;amp;#39;s assign value1 field for this graph
     graph.valueField = &amp;#34;value1&amp;#34;;
     // and add graph to the chart
     chart.addGraph(graph);
     // &amp;amp;#39;chartdiv&amp;amp;#39; is id of a container
     // where our chart will be
     chart.write(&amp;amp;#39;chartdiv&amp;amp;#39;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we launch our HTML file in the browser, we should get the following result:&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; title=&#34;chart3_1&#34; src=&#34;https://danielpecos.com/assets/2011/03/chart3_1.png&#34; alt=&#34;&#34; width=&#34;584&#34; height=&#34;392&#34; /&gt;
&lt;p&gt;Hey, wait a moment! Our graph has changed! That&amp;rsquo;s because our data has different size time gaps between data points, and now amCharts is able to understand dates in our data, rendering them in their relative position.&lt;/p&gt;
&lt;p&gt;If we want to draw a graph like the previous one (using regular intervals between data points), we have to set to true the property &lt;em&gt;equalSpacing&lt;/em&gt; of the category Axis:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// now we have to set up the category axis to parse dates
var catAxis = chart.categoryAxis;
catAxis.parseDates = true;
catAxis.equalSpacing = true;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And now the resulting graph looks more like the one we got in Part 2 of this tutorial series, but now the labels on the category axis are displayed using a date format, instead of using directly the string from our data:&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;img class=&#34;aligncenter size-full&#34; title=&#34;chart3_2&#34; src=&#34;https://danielpecos.com/assets/2011/03/chart3_2.png&#34; alt=&#34;&#34; width=&#34;587&#34; height=&#34;397&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MAKING-UP OUR CHART&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To finish this Part 3 of our amChart Javascript turorials, we will style-up our chart to get a fancier one. All the following code has to be added to the already defined &lt;em&gt;createChart&lt;/em&gt; function.&lt;/p&gt;
&lt;p&gt;First of all we will apply some general styles to the chart so we can set up margins, set a general color and add an initial animation:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// styles applied to the chart
// default general color used in the chart
chart.color = &amp;#34;#AAAAAA&amp;#34;;
// length of the animation
chart.startDuration = 2;
// margins between graph and canvas border
chart.marginLeft = 15;
chart.marginRight = 80;
chart.marginBottom = 40;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we will style both axes. We will set our category axis to use bluish colors for the axis and grid lines:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// styles applied to the category axis
// color of the axis line
catAxis.axisColor = &amp;#34;#2d66bb&amp;#34;;
// color of the grid lines
catAxis.gridColor = &amp;#34;#2d66bb&amp;#34;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To set up the value axis, we need an instance of ValueAxis, but we haven&amp;rsquo;t created one until now, so our first step is to get a fresh instance. Then, in a similar way as before, we will set our value axis using also bluish colors but this time we don&amp;rsquo;t want to show the grid lines, just the background colors. Finally, we add our new styled value axis to the chart:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// styles applied to value axis
// we haven&amp;amp;#39;t set up a value axis until now,
// so we create one and apply styles to it
var valAxis = new AmCharts.ValueAxis();
// we want to display the value axis on the right side
valAxis.position = &amp;#34;right&amp;#34;;
// color of the axis line
valAxis.axisColor = &amp;#34;#2d66bb&amp;#34;;
// as we set fillAlpha, and fillColor we don&amp;amp;#39;t want grid to be visible
valAxis.gridAlpha = 0;
// each second gap between grid lines will be filled with this color
valAxis.fillColor = &amp;#34;#2d66bb&amp;#34;;
// fill alpha
valAxis.fillAlpha = 0.1;
// length of each dash
valAxis.dashLength = 3;
// and finally we add the value axis to the chart
chart.addValueAxis(valAxis);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Last step is to apply some styles to our graph line:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// styles applied to the graph line
// color of the graph line
graph.lineColor = &amp;#34;#3a81ec&amp;#34;;
// thicknes of the graph line
graph.lineThickness = 2;
// show round bullets for each point
graph.bullet = &amp;#34;round&amp;#34;;
// length of each dash
graph.dashLength = 1;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And the resulting chart should look like this one:&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; title=&#34;chart3_3&#34; src=&#34;https://danielpecos.com/assets/2011/03/chart3_3.png&#34; alt=&#34;&#34; width=&#34;584&#34; height=&#34;388&#34; /&gt;
&lt;p&gt;Here you have full source code as it should look like once all changes we have talked about in this tutorial have been applied:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;#34;-//W3C//DTD HTML 4.01//EN&amp;#34; &amp;#34;http://www.w3.org/TR/html4/strict.dtd&amp;#34;&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta http-equiv=&amp;#34;Content-Type&amp;#34; content=&amp;#34;text/html; charset=utf-8&amp;#34;&amp;gt;
        &amp;lt;title&amp;gt;amCharts Example&amp;lt;/title&amp;gt;
        &amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;style.css&amp;#34; type=&amp;#34;text/css&amp;#34;&amp;gt;
        &amp;lt;script src=&amp;#34;javascript/amcharts.js&amp;#34; type=&amp;#34;text/javascript&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script src=&amp;#34;javascript/raphael.js&amp;#34; type=&amp;#34;text/javascript&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
        // declaring variables
        var chart;
        var dataProvider;
        // this method called after all page contents are loaded
        window.onload = function() {
            createChart();
            loadCSV(&amp;#34;data.txt&amp;#34;);
        }
        // method which loads external data
        function loadCSV(file) {
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari
                var request = new XMLHttpRequest();
            }
            else {
                // code for IE6, IE5
                var request = new ActiveXObject(&amp;amp;#39;Microsoft.XMLHTTP&amp;amp;#39;);
            }
            // load
            request.open(&amp;amp;#39;GET&amp;amp;#39;, file, false);
            request.send();
            parseCSV(request.responseText);
        }
          // method which parses a date string in the format YYYY-MM-DD and creates a Date object
          function parseDate(dateString) {
               // split the string get each field
               var dateArray = dateString.split(&amp;#34;-&amp;#34;);
               // now lets create a new Date instance, using year, month and day as parameters
               // month count starts with 0, so we have to convert the month number
               var date = new Date(Number(dateArray[0]), Number(dateArray[1]) - 1, Number(dateArray[2]));
               return date;
          }
        // method which parses csv data
        function parseCSV(data){
            //replace UNIX new line
            data = data.replace (/rn/g, &amp;#34;n&amp;#34;);
            //replace MAC new lines
            data = data.replace (/r/g, &amp;#34;n&amp;#34;);
            //split into rows
            var rows = data.split(&amp;#34;n&amp;#34;);
            // create array which will hold our data:
            dataProvider = [];
            // loop through all rows
            for (var i = 0; i &amp;lt; rows.length; i++){
                // this line helps to skip empty rows
                if (rows[i]) {
                    // our columns are separated by comma
                    var column = rows[i].split(&amp;#34;,&amp;#34;);
                    // column is array now
                    // first item is date
                    var date = parseDate(column[0]);
                    // second item is value of the second column
                    var value1 = column[1];
                    // third item is value of the fird column
                    var value2 = column[2];
                    // create object which contains all these items:
                    var dataObject = {date:date, value1:value1, value2:value2};
                    // add object to dataProvider array
                    dataProvider.push(dataObject);
                }
            }
            // set data provider to the chart
            chart.dataProvider = dataProvider;
            // this will force chart to rebuild using new data
            chart.invalidateData();
        }
        // method which creates chart
        function createChart(){
            // chart variable is declared in the top
            chart = new AmCharts.AmSerialChart();
            // here we tell the chart name of category
            // field in our data provider.
            // we called it &amp;#34;date&amp;#34; (look at parseCSV method)
            chart.categoryField = &amp;#34;date&amp;#34;;
            // styles applied to the chart
            // default general color used in the chart
            chart.color = &amp;#34;#AAAAAA&amp;#34;;
            // length of the animation
            chart.startDuration = 2;
            // margins between graph and canvas border
            chart.marginLeft = 15;
            chart.marginRight = 80;
            chart.marginBottom = 40;
            // now we have to set up the category axis to parse dates
            var catAxis = chart.categoryAxis;
            catAxis.parseDates = true;
            //catAxis.equalSpacing = true;
            // styles applied to the category axis
            // color of the axis line
            catAxis.axisColor = &amp;#34;#2d66bb&amp;#34;;
            // color of the grid lines
            catAxis.gridColor = &amp;#34;#2d66bb&amp;#34;;
            // styles applied to value axis
            // we haven&amp;amp;#39;t set up a value axis until now,
            // so we create one and apply styles to it
            var valAxis = new AmCharts.ValueAxis();
            // we want to display the value axis on the right side
            valAxis.position = &amp;#34;right&amp;#34;;
            // color of the axis line
            valAxis.axisColor = &amp;#34;#2d66bb&amp;#34;;
            // as we set fillAlpha, and fillColor we don&amp;amp;#39;t want grid to be visible
            valAxis.gridAlpha = 0;
            // each second gap between grid lines will be filled with this color
            valAxis.fillColor = &amp;#34;#2d66bb&amp;#34;;
            // fill alpha
            valAxis.fillAlpha = 0.1;
            // length of each dash
            valAxis.dashLength = 3;
            // and finally we add the value axis to the chart
            chart.addValueAxis(valAxis);
            // chart must have a graph
            var graph = new AmCharts.AmGraph();
            // graph should know at what field from data
            // provider it should get values.
            // let&amp;amp;#39;s assign value1 field for this graph
            graph.valueField = &amp;#34;value1&amp;#34;;
            // and add graph to the chart
            // styles applied to the graph line
            // color of the graph line
            graph.lineColor = &amp;#34;#3a81ec&amp;#34;;
            // thicknes of the graph line
            graph.lineThickness = 2;
            // show round bullets for each point
            graph.bullet = &amp;#34;round&amp;#34;;
            // length of each dash
            graph.dashLength = 1;
            chart.addGraph(graph);
            // &amp;amp;#39;chartdiv&amp;amp;#39; is id of a container
            // where our chart will be
            chart.write(&amp;amp;#39;chartdiv&amp;amp;#39;);
        }
        &amp;lt;/script&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body style=&amp;#34;background-color:#EEEEEE&amp;#34;&amp;gt;
        &amp;lt;div id=&amp;#34;chartdiv&amp;#34; style=&amp;#34;width:600px; height:400px; background-color:#FFFFFF&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>HTTP connection &#43; HTTP Authenticacion &#43; Proxy &#43; SSL</title>
      <link>https://danielpecos.com/2010/12/08/http-connection-http-authenticacion-proxy-ssl/</link>
      <pubDate>Wed, 08 Dec 2010 17:20:19 +0100</pubDate>
      
      <guid>https://danielpecos.com/2010/12/08/http-connection-http-authenticacion-proxy-ssl/</guid>
      
      <description>&lt;p&gt;Many times during your life as a java developer, you will face the situation of retrieving some resources using an HTTP connection. At first, it will seem easy, but probably some problems will arise such as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Needing to use an HTTP Proxy (maybe authentication would be required)&lt;/li&gt;
&lt;li&gt;Establishing an HTTP authenticated connection&lt;/li&gt;
&lt;li&gt;Connecting to a server that uses SSL self-signed certificates&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’m sure you will quickly find the Apache Commons solution: &lt;em&gt;commons-httpclient&lt;/em&gt;. In this article I will show you some code that, I hope, will ease you the  resolution of the previous obstacles using this great API from Apache.&lt;/p&gt;
&lt;p&gt;First of all I will show you the basic code needed to establish an HTTP GET connection using &lt;em&gt;commons-httpclient&lt;/em&gt; and then we will add continuous enhancements step by step:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;GetMethod httpget = null;
String result = null;
try {
    httpget = new GetMethod(url);

    HttpClient client = new HttpClient();
    int status = client.executeMethod(httpget);
    if (status == 200) {
        result = httpget.getResponseBodyAsString();
    } else {
        System.err.println(&amp;#34;Error accessing to URL &amp;#34; + status + &amp;#34;: &amp;#34; +  httpget.getStatusLine());
    }

} catch (MalformedURLException e) {
    System.err.println(&amp;#34;Malformed URL: &amp;#34; + e.getMessage());
} catch (IOException e) {
    System.err.println(&amp;#34;I/O problems: &amp;#34; + e.getMessage());
} catch (Exception e) {
    System.err.println(&amp;#34;URL not found: &amp;#34; + e.getMessage());
} finally {
    if (httpget != null) {
        httpget.releaseConnection();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;&lt;strong&gt;1. Use an HTTP Proxy (maybe authentication would be required)&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now lets add the necessary code to establish the HTTP connection using a Proxy. I will use a static method to configure proxy settings in our &lt;em&gt;HttpClient&lt;/em&gt; instance:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void configureProxy(HttpClient client, HttpMethodBase method, String proxyHost, int proxyPort, String proxyUsername, String proxyPassword, String proxyNTDomain) {

    client.getHostConfiguration().setProxy(proxyHost, proxyPort);

    if (proxyUsername != null &amp;amp;&amp;amp; proxyUsername.length() &amp;amp;gt; 0) {

        if (proxyNTDomain != null &amp;amp;&amp;amp; proxyNTDomain.length() &amp;amp;gt; 0)  {
            // use NT Domain authentication
            NTCredentials credentials = new NTCredentials(proxyUsername, proxyPassword, proxyHost, proxyNTDomain);
            HttpState state = client.getState();
            state.setProxyCredentials(new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM), credentials);
        } else {
            // use plain user/password authentication
            Credentials defaultcreds = new UsernamePasswordCredentials(proxyUsername, proxyPassword);
            client.getState().setProxyCredentials(new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM), defaultcreds);
        }
        method.setDoAuthentication(true);
    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then we will have to insert this line of code in our previous example (I have inserted it between lines 6-7):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;configureProxy(client, httpget, proxyHost, proxyPort, proxyUsername, proxyPassword, proxyNTDomain);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this moment, we have point 1 solved, so let’s go for point 2: Basic HTTP Authentication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;2. Establish an HTTP authenticated connection&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order to keep code as clean as possible, I will create another static method to set HTTP authentication:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void configureHTTPAuthentication(HttpClient client, String host, int port, String httpUsername, String httpPassword) {
    client.getState().setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(httpUsername, httpPassword));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the required call to this method, just after the previous one:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;configureHTTPAuthentication(client, httpget.getURI().getHost(), httpget.getURI().getPort(), httpUsername, httpPassword);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This one was easy 😉&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;&lt;strong&gt;3. Connect to a server that uses SSL self-signed certificates&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now lets solve the last point, probably the more difficult of all of them. We will need two implementations of &lt;em&gt;ProtocolSocketFactory&lt;/em&gt; and &lt;em&gt;X509TrustManager&lt;/em&gt; that accept self-signed certificates: &lt;em&gt;EasySSLProtocolSocketFactory&lt;/em&gt; and &lt;em&gt;EasyX509TrustManager&lt;/em&gt;, which you can find in httpclient-contrib (I have grabbed them from &lt;a href=&#34;mailto:adrian.sutton@ephox.com&#34;&gt;Adrian Sutton&lt;/a&gt; and &lt;a href=&#34;mailto:oleg@ural.ru&#34;&gt;Oleg Kalnichevski&lt;/a&gt; and you can also find them attached at the end of this article). Once in our &lt;em&gt;classpath&lt;/em&gt;, we have to insert the following code in our first example, just below the call to &lt;em&gt;configureHTTPAuthentication&lt;/em&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if (url.startsWith(&amp;#34;https&amp;#34;)) {
    Protocol protocol = new Protocol(&amp;#34;https&amp;#34;, new EasySSLProtocolSocketFactory(), 443);
    client.getHostConfiguration().setHost(httpget.getURI().getHost(), 443, protocol);
    // we also can set this socketfactory as global for all the connections
    //Protocol.registerProtocol(&amp;#34;https&amp;#34;, protocol);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we should be able to connect to a HTTP-Authenticaded SSL URL, using an http (authenticated-?)proxy. Isn’t it cool? This is how our final code looks like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void configureProxy(HttpClient client, HttpMethodBase method, String proxyHost, int proxyPort, String proxyUsername, String proxyPassword, String proxyNTDomain) {

    client.getHostConfiguration().setProxy(proxyHost, proxyPort);

    if (proxyUsername != null &amp;amp;&amp;amp; proxyUsername.length() &amp;amp;gt; 0) {

        if (proxyNTDomain != null &amp;amp;&amp;amp; proxyNTDomain.length() &amp;amp;gt; 0)  {
            // use NT Domain authentication
            NTCredentials credentials = new NTCredentials(proxyUsername, proxyPassword, proxyHost, proxyNTDomain);
            HttpState state = client.getState();
            state.setProxyCredentials(new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM), credentials);
        } else {
            // use plain user/password authentication
            Credentials defaultcreds = new UsernamePasswordCredentials(proxyUsername, proxyPassword);
            client.getState().setProxyCredentials(new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM), defaultcreds);
        }
        method.setDoAuthentication(true);
    }

}

private static void configureHTTPAuthentication(HttpClient client, String host, int port, String httpUsername, String httpPassword) {
    client.getState().setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(httpUsername, httpPassword));
}

public static String doGETConnection(String url, String proxyHost, int proxyPort, String proxyUsername, String proxyPassword, String proxyNTDomain, String httpUsername, String httpPassword) {

    GetMethod httpget = null;
    String result = null;
    try {
        httpget = new GetMethod(url);

        HttpClient client = new HttpClient();
        configureProxy(client, httpget, proxyHost, proxyPort, proxyUsername, proxyPassword, proxyNTDomain);
        configureHTTPAuthentication(client, httpget.getURI().getHost(), httpget.getURI().getPort(), httpUsername, httpPassword);

        if (url.startsWith(&amp;#34;https&amp;#34;)) {
            Protocol protocol = new Protocol(&amp;#34;https&amp;#34;, new EasySSLProtocolSocketFactory(), 443);
            client.getHostConfiguration().setHost(httpget.getURI().getHost(), 443, protocol);
            // we also can set this socketfactory as global for all the connections
            //Protocol.registerProtocol(&amp;#34;https&amp;#34;, protocol);
        }

        int status = client.executeMethod(httpget);
        if (status == 200) {
            result = httpget.getResponseBodyAsString();
        } else {
            System.err.println(&amp;#34;Error accessing to URL &amp;#34; + status + &amp;#34;: &amp;#34; +  httpget.getStatusLine());
        }

    } catch (MalformedURLException e) {
        System.err.println(&amp;#34;Malformed URL: &amp;#34; + e.getMessage());
    } catch (IOException e) {
        System.err.println(&amp;#34;I/O problems: &amp;#34; + e.getMessage());
    } catch (Exception e) {
        System.err.println(&amp;#34;URL not found: &amp;#34; + e.getMessage());
    } finally {
        if (httpget != null) {
            httpget.releaseConnection();
        }
    }

    return result;

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;&lt;strong&gt;Possible exceptions&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But, if we haven’t been lucky, we can find one of this two exceptions (if not both) when trying to establish connection:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This one is due to the JDK can not verify the self-signed certificate. We have to add it to a trusted keystore and make it available to the JDK, using &lt;a href=&#34;https://danielpecos.com/assets/2010/12/InstallCert.zip&#34;&gt;InstallCert&lt;/a&gt; java standalone application.&lt;/p&gt;
&lt;p&gt;Another different problem that I got while developing this code, was the next one:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;javax.net.ssl.SSLKeyException: RSA premaster secret error
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s related to this size of the certificate and the JDK cryptographic capabilities. To resolve this issue, download and install the &lt;a href=&#34;http://java.sun.com/j2se/1.5.0/download.jsp&#34;&gt;Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files version 5.0.&lt;/a&gt; Extracted from its README file:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div id=&#34;_mcePaste&#34;&gt;
  &lt;div id=&#34;_mcePaste&#34;&gt;
    Due to import control restrictions, the version of JCE policy files that are bundled in the JDK(TM) 5.0 environment allow &amp;#8220;strong&amp;#8221; but limited cryptography to be used. This download bundle (the one including this README file) provides &amp;#8220;unlimited strength&amp;#8221; policy files which contain no restrictions on cryptographic strengths.
  &lt;/div&gt;
  &lt;div id=&#34;_mcePaste&#34;&gt;
    Please note that this download file does NOT contain any encryption functionality since such functionality is supported in Sun&amp;#8217;s JDK 5.0.Thus, this installation applies only to Sun&amp;#8217;s JDK 5.0, and assumes that the JDK 5.0 is already installed.
  &lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;And finally…&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I hope this article would help you to resolve your HTTP connection issues. If not, please post a comment and I will try to reply you ASAP. You can also find me at twitter @danielpecos&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;&lt;span style=&#34;color: #339966;&#34;&gt;&lt;em&gt;Feedback is welcomed!&lt;/em&gt;&lt;/span&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Files used for this demo:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Full sources of the example developed here: &lt;a href=&#34;https://danielpecos.com/assets/2010/12/httpclient-example.zip&#34;&gt;httpclient-example&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Standalone java application to create a keystor__e: &lt;a href=&#34;https://danielpecos.com/assets/2010/12/InstallCert.zip&#34;&gt;InstallCert&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;I also provide a mirror for the needed &lt;a href=&#34;https://danielpecos.com/assets/2010/12/jce_policy-1_5_0.zip&#34;&gt;policy files&lt;/a&gt; in case of RSA premaster secret error.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Git-SCM (Part 1)</title>
      <link>https://danielpecos.com/2010/11/18/git-scm-part1/</link>
      <pubDate>Thu, 18 Nov 2010 21:03:11 +0100</pubDate>
      
      <guid>https://danielpecos.com/2010/11/18/git-scm-part1/</guid>
      
      <description>&lt;p&gt;One of the key tools of a software project development is the repository where it&amp;rsquo;s hosted. During my experience as software developer I have been working with several flavors, such as &lt;a href=&#34;http://msdn.microsoft.com/en-us/vstudio/aa718670.aspx&#34;&gt;Visual SourceSafe&lt;/a&gt;, &lt;a href=&#34;http://www.nongnu.org/cvs/&#34;&gt;CVS&lt;/a&gt;, &lt;a href=&#34;http://mercurial.selenic.com/&#34;&gt;Mercurial&lt;/a&gt;, and of course, &lt;a href=&#34;http://subversion.tigris.org/&#34;&gt;SVN&lt;/a&gt;. But latetly I have found this little jewel called &lt;a href=&#34;http://git-scm.com/&#34;&gt;Git&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Git was initially developed by Linus Torvalds as a result of an unsuccessful research to replace the propietary &lt;a href=&#34;http://en.wikipedia.org/wiki/Software_Configuration_Management&#34;&gt;SCM&lt;/a&gt; BitKeeper, used back in 2005 in the Linux Kernel project (kinda strange that the opensource star project was hosted with a propietary software, huh?). Back then, the ability to freely use BitKeeper was withdrawn by its copyright holder, so Linus was forced to find a replacement for it. He was looking for a &lt;a href=&#34;http://en.wikipedia.org/wiki/Revision_control&#34;&gt;VCS&lt;/a&gt; with a high performance in the process of applying patches and keeping track of the changes, but he didn&amp;rsquo;t find any opensource solutions that fitted his requirements, so he started the developement of Git (as he says on &lt;a href=&#34;http://en.wikipedia.org/wiki/Git_(software)&#34;&gt;Git&amp;rsquo;s Wikipedia entry&lt;/a&gt;, Git was named after himself, because he considers himself an “egoistical bastard, and I name all my projects after myself”; &lt;em&gt;git&lt;/em&gt; is the British English slang word for an stupid or unpleasant person).&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why its main characteristics are oriented to help the development and management of a huge, distributed and collaborative project like the Linux Kernel. These are the most noticeable of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strong support for non-linear development&lt;/li&gt;
&lt;li&gt;Distributed development&lt;/li&gt;
&lt;li&gt;Efficient handling of large projects&lt;/li&gt;
&lt;li&gt;Cryptographic authentication of history&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But for me, the most shocking one is its decentralized structure in distributed development: there is no need for a central repository where all commits are sent by the people working in the project (but still, it is recommended to use a &lt;em&gt;main&lt;/em&gt; branch for that purpose).&lt;/p&gt;
&lt;p&gt;In following posts I will explain how to use Git in the lifecycle of a software project and how can it improve our performance.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nuevo foro de fotografía: enfocas.es</title>
      <link>https://danielpecos.com/2009/10/07/nuevo-foro-de-fotografia-enfocas-es/</link>
      <pubDate>Wed, 07 Oct 2009 11:26:50 +0100</pubDate>
      
      <guid>https://danielpecos.com/2009/10/07/nuevo-foro-de-fotografia-enfocas-es/</guid>
      
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a title=&#34;Enfocas&#34; href=&#34;http://enfocas.es&#34; target=&#34;_blank&#34;&gt;&lt;img class=&#34;aligncenter size-full&#34; title=&#34;Enfocas&#34; src=&#34;https://danielpecos.com/assets/2009/10/logo_100.png&#34; alt=&#34;Enfocas&#34; width=&#34;330&#34; height=&#34;100&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;a title=&#34;Enfocas&#34; href=&#34;http://enfocas.es&#34; target=&#34;_blank&#34;&gt;&lt;strong&gt;http://enfocas.es&lt;/strong&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;En origen, ENFOCAS, está formado por un grupo de amig@s de Castellón, unidos por su pasión hacia la fotografía. El foro en sí, nace como punto de encuentro de quienes como nosotros, sientan la necesidad de compartir esta afición, a través de las imágenes que podamos aportar, junto con los comentarios, dudas, informaciones de interés o cualquier otro aspecto que pueda surgir a lo largo de su vida.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;No pretendemos ser ningún referente, tan solo queremos disponer de una parcela de la red para poder compartir nuestra pasión por la fotografía, con quienes quieran acercarse a él, y lo hagan de forma respetuosa hacia las obras, aportaciones y opiniones de los demás.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Precisamente en este talante de respeto hacia las aportaciones, grandes o pequeñas, y de las opiniones de sus componentes, esperamos que surja un foro vivo y participativo, donde  el propio foro, su estructura, su estilo  sea fruto de la participación de quienes lo componemos.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Por último, no podemos evitar tener presente en nuestro pensamiento, que la comunicación a través de Internet, aún siendo deseable y de gran importancia, no puede ni debe suplir, en la medida de lo posible, un contacto directo y personal. Tratamos, pues, de conseguir una participación más cercana, buscando fomentar la presencia activa a través de puntos de encuentro, ya sean mediante KDD´s en nuestra comunidad o fuera de ella, si fuera posible, y a través de todos aquellos birrings que nos permitan compartir unos momentos de amigable camaradería y conversación.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>GNU HttpTunnel: Como saltarse un proxy HTTP</title>
      <link>https://danielpecos.com/2009/09/02/gnu-httptunnel-como-saltarse-un-proxy-http/</link>
      <pubDate>Wed, 02 Sep 2009 13:41:25 +0100</pubDate>
      
      <guid>https://danielpecos.com/2009/09/02/gnu-httptunnel-como-saltarse-un-proxy-http/</guid>
      
      <description>&lt;p&gt;Creo que es la primera vez que posteo sobre una aplicación, pero creo que en este caso merece la pena hacerlo. Se trata de GNU HttpTunnel, una pequeña aplicación que crea un túnel HTTP sobre el que podemos meter cualquier servicio. ¿Ventajas? Pues que al ser HTTP, si nos encontramos en una red que solo tiene salida a Internet mediante un proxy HTTP, con esta aplicación (y un PC fuera de la red), podemos salir de la red con el servicio que más nos interese.&lt;/p&gt;
&lt;img class=&#34;aligncenter size-full&#34; title=&#34;HTTP Tunnel&#34; src=&#34;https://danielpecos.com/assets/2009/09/httptunnel.gif&#34; alt=&#34;HTTP Tunnel&#34; width=&#34;300&#34; height=&#34;116&#34; /&gt;
&lt;p&gt;Aquí va el chuletario:&lt;/p&gt;
&lt;p&gt;En el PC al otro lado del proxy (fuera de la red) ejecutamos:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ hts -w -F host_remoto:puerto_remoto puerto_local_servidor
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;y en el cliente (detrás del proxy) ejecutamos:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ htc -P ip_proxy:puerto_proxy -F puerto_local_cliente ip_servidor:puerto_local_servidor
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Por ejemplo, si quisiera crear un tunel HTTP para el SSH que tengo en mi servidor de casa (cosa muy útil, por si tuviera que abrir nuevos túneles ;-)), tendría que ejecutar el siguiente comando en dicha máquina:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ hts -w -F localhost:22 7022
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;lo cual crearía un tunel a la expera de conexión en el puerto 8022 del servidor (este puerto tendría que hacerlo accesible desde internet, en caso de que nos encontremos detras de un router sin NAT), y en la máquina desde la que me quiero conectar ejecuto:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ htc -P ip_proyx:80 -F 22 ip_servidor:7022
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;de forma que ahora al conectarme al puerto 22 de la máquina local, realmente me estoy conectando al puerto 22 del servidor de mi casa.&lt;/p&gt;
&lt;p&gt;Pues espero que os sea útil!&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;
&lt;p&gt;Más info:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.nocrew.org/software/httptunnel.html&#34;&gt;http://www.nocrew.org/software/httptunnel.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.gnu.org/software/httptunnel/httptunnel.html&#34;&gt;http://www.gnu.org/software/httptunnel/httptunnel.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Adiós Gloria</title>
      <link>https://danielpecos.com/2009/04/24/adios-gloria/</link>
      <pubDate>Fri, 24 Apr 2009 18:48:48 +0100</pubDate>
      
      <guid>https://danielpecos.com/2009/04/24/adios-gloria/</guid>
      
      <description>&lt;p&gt;Me ha costado bastante escribir este post, pero finalmente creo que el recuerdo lo merece.&lt;/p&gt;
&lt;img class=&#34;size-full&#34; title=&#34;Gloria Martínez&#34; src=&#34;https://danielpecos.com/assets/2009/04/gloria.jpg&#34; alt=&#34;Gloria Martínez&#34; width=&#34;194&#34; height=&#34;243&#34; /&gt;
&lt;p&gt;Como homenaje, se están recogiendo firmas para dar su nombre a una de las aulas del ESTCE: &lt;a href=&#34;http://homenajeagloria.uji.es/&#34;&gt;http://homenajeagloria.uji.es/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;El pasado 14 de abril de 2009 falleció nuestra compañera y amiga Gloria Martínez. Gloria fue una de las profesoras encargadas de poner en marcha en 1991, fecha de su creación, los estudios de informática en la Universidad Jaume I. Desde entonces ha estado involucrada, muy activamente, en todos los aspectos tanto organizativos como docentes de dichos estudios. También fue una de las personas más destacadas en muchas de las actividades extraacadémicas de esta Universidad como son, por ejemplo, las jornadas iParty, o el grupo de Amnistía Internacional de la UJI. Además, también destacó a nivel nacional como impulsora de la Asociación de Enseñantes Universitarios de Informática (AENUI) de la cual era Coordinadora en el momento de su fallecimiento.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Muchas de las personas que tuvimos relación directa con Gloria, tanto estudiantes como profesores y amigos, consideramos que ha dejado una gran huella allí por donde ha pasado y desearíamos que su memoria no se olvidase fácilmente en el lugar al que dedicó gran parte de su energía. Para ello, todas las personas abajo firmantes, solicitamos que se dé su nombre a una de las aulas de la ESTCE donde ella desarrolló su actividad docente.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Gloria, gracias por enseñarme como lo hiciste y ser como fuiste. Tus clases son de de los mejores recuerdos que mantengo de la universidad. Gracias.&lt;/p&gt;
&lt;p&gt;(Si alguien quiere saber más sobre cómo era ella, aquí dejo la dirección de su blog donde posteaba con frecuencia: &lt;a href=&#34;http://servidora.blogspot.com/&#34;&gt;http://servidora.blogspot.com/&lt;/a&gt;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2009: Odisea con el funcionariado</title>
      <link>https://danielpecos.com/2009/01/13/2009-odisea-con-el-funcionariado/</link>
      <pubDate>Tue, 13 Jan 2009 19:46:31 +0100</pubDate>
      
      <guid>https://danielpecos.com/2009/01/13/2009-odisea-con-el-funcionariado/</guid>
      
      <description>&lt;p&gt;Tiemblo cada vez que tengo que tratar con un funcionario, es como si te echaran una maldición:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;De entrada tienes pocas esperanzas de poder hacer el trámite a la primera, sin que te toque volver n-mil veces a tratar con el/la individu@ en cuestión.&lt;/li&gt;
&lt;li&gt;Una vez te decides a intentarlo, siempre te queda la duda de si ir al edificio público en el que ejerce su profesión o si acudir directamente a la cafetería de al lado (lo cual me hace reflexionar si su profesión es aquella por la que recibe un sueldo, o la que ejerce donde pasa la mayor parte de su jornada laboral… puede ser un tema de reflexión bastante interesante).&lt;/li&gt;
&lt;li&gt;Por último, si has tenido suerte, los astros se encuentran en la conjunción adecuada y encuentras al funcionario en su sitio, tienes que poner la sonrisa más agradable para que el/la personaje, con su cara de estreñido (o de “deja de joderme, que yo a ti no te voy a buscar a tu trabajo y me pongo a darte por el culo”), se digne a darte un trato poco despreciable y a conseguir un mínimo de información, que con suerte, puede llegar a ser hasta útil (porque hay veces que se contradicen, o mejor aún, se dedican a pasarse la pelota, osea tú, de unos a otros).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Posibles motivos de que esta gente se comporte de este modo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Porque no les gusta lo que hacen: pues tuvieron que estudiar bastante tiempo y disputárselo entre muchos para conseguir lo que tienen, por lo que estoy más que seguro que conocían lo que se iban a encontrar (tal vez, con toda la idea, de tocarse las pelotas durante los restos).&lt;/li&gt;
&lt;li&gt;Porque el sentimiento de seguridad y de ser intocables en el trabajo les hace descuidarlo: poco más que decir, si no rindes cuentas a nadie y tampoco te motiva lo que haces, es obvio que cada vez lo vas a hacer peor y con menos ganas (siempre existe la posibilidad de que se dejen el trabajo, pero también existe la posibilidad de que llueva hacia arriba).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Concretando, todo esto se solucionaría &lt;strong&gt;eliminando la permanencia asegurada de un funcionario en su puesto de trabajo&lt;/strong&gt; e implantando unos controles y seguimientos de los rendimientos de su trabajo. ¿Por qué no se hace? Pues porque seguramente lo tendría que tramitar un funcionario y es probable que se le fundieran los sesos al intentar averiguar qué impresos son necesarios.&lt;/p&gt;
&lt;p&gt;Como bien dice mi padre, un funcionario es alguien que hace un esfuerzo en un momento de su vida y se pasa el resto de ella descansando. O como dice un amigo funcionario, que entran a las 8 al puesto de trabajo, pero trabajar nunca se sabe a qué hora se comienza (igualito que en mi empresa 🙁 )&lt;/p&gt;
&lt;p&gt;Y es que francamente, ¿quién no ha pensado que la tarea que realizan 5 funcionarios administrativos la podrían hacer perfectamente 1, como mucho 2, personas trabajadoras como cualquiera? Da la sensación que cuando entran les hacen un test de aptitud y a los que lo superan les rechazan para el puesto (de hecho, el amigo que he comentado justo antes, fue acusado de trepa por sus compañeros funcionarios porque rendía demasiado 😮 !?!?!?!?! 😮 ).&lt;/p&gt;
&lt;p&gt;Nota: he intentado referirme concretamente a funcionarios de caracter administrativo, de los que te atienden tras un mostrador o mesa, aunque, por sorprendente que parezca, estoy convencido que hay funcionarios de gran calidad tanto personal como profesional, por lo que tampoco es correcto generalizar.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ingeniero informático, to be or not to be?</title>
      <link>https://danielpecos.com/2008/11/11/ingeniero-informatico-to-be-or-not-to-be/</link>
      <pubDate>Tue, 11 Nov 2008 12:13:46 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/11/11/ingeniero-informatico-to-be-or-not-to-be/</guid>
      
      <description>&lt;p&gt;Desde hace un par de semanas está circulando una &lt;a href=&#34;http://www.huelgainformatica.es/&#34; target=&#34;_blank&#34;&gt;convocatoria de huelga&lt;/a&gt; para los ingenieros informáticos. Según comentan en la web, esta huelga se debe a la exclusión de las titulaciones de Informática de las propuestas de en las que se proponen los títulos habilitados para ejercer distintas profesiones. Concretamente se atribuyen a la Ingeniería en Telecomunicaciones muchas (por no decir prácticamente todas) las funciones que ejerce un Ingeniero Informático. Según comentan en dicha web, el Ministerio de Educación justifica esta decisión argumentando que:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“La informática se trata de una materia transversal, por lo que no puede concentrarse en una titulación concreta”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La cuestión es que se está levantando mucho revuelo (en parte con razón) y está ciruclando mucha rumorología que hace poco bien. Como bien explica Enrique Barreiro (profesor de Ingeniería Informática en la Universidad de Vigo) en &lt;a href=&#34;http://enriquebarreiro.blogspot.com/2008/11/qu-pasa-con-la-ingeniera-informtica.html&#34; target=&#34;_blank&#34;&gt;esta web&lt;/a&gt;, hay dos problemas que se están mezclando en toda esta rumorología:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;El diseño de los nuevos títulos adaptados al Espacio Europeo de Educación Superior, y&lt;/li&gt;
&lt;li&gt;La regulación de la profesión (que se nos asignen las atribuciones que ejerzamos).&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;em&gt;(En &lt;a href=&#34;https://danielpecos.com/assets/2008/11/comic_huelga.png&#34;&gt;esta imagen&lt;/a&gt; tenéis un resumen light de lo que comentan)&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;Dos problemas diferentes pero relacionados, y es que al parecer la adaptación no se ha llevado a cabo para el proceso de Bolonia debido a que la informática no es una profesión regulada. Entonces, ¿por qué no se regula la profesión de informática? Básicamente porque les resulta caro a los empresarios. Y es que ahora mismo el intrusismo laboral de nuestro sector es común, y lo peor, ampliamente aceptado por todos nosotros. ¿Os imagináis a un chaval que se haya leido un libro de arquitectura proyectando edificios? Claro que sí, por poder claro que puede y seguro que hay algún genio que es capaz de hacerlo, pero ¿se lo construirían sin una firma de un arquitecto? Claramente no.&lt;/p&gt;
&lt;p&gt;En informática no es raro encontrar químicos, telecos, matemáticos, físicos, aficionados o cualquier otra cosa. Seguramente sean perfectamente capaces de realizar el trabajo que realizan, gracias a la experiencia adquirida y la formación no homologada que hayan recibido, pero esto sería impensable en otros sectores como Derecho, Industriales o Medicina (por capaz que fueras de desarrollar la tarea).&lt;/p&gt;
&lt;p&gt;En resumen, mi inquietud personal es: &lt;strong&gt;¿Por qué se me considera menos ingeniero que a un industrial?&lt;/strong&gt; La respuesta es sencilla: &lt;strong&gt;por que no nos hacemos valer&lt;/strong&gt;, triste pero cierto. No tenemos conciencia de grupo, somos individualistas por lo que &lt;strong&gt;nuestro poder sindical es nulo&lt;/strong&gt;. Además, por lo mismo, no tenemos un Colegio Oficial que defienda la profesión, al contrario de como ocurre con otras profesiones.&lt;/p&gt;
&lt;p&gt;En fin como buen informático no me queda otra que la resignación (o hablando claro, bajarme los pantalones y que me hagan lo que quieran que yo seguiré tragando lo que me toque)… Triste pero como no lo hagas, a la puta calle que seguro que hay otro informático detrás de ti (aunque tampoco es necesario que sea informático) que por menos dinero que lo que tu pides, tiene los pantalones más abajo.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>GDD MAD 2008… ¡Estuve allí!</title>
      <link>https://danielpecos.com/2008/09/28/gdd-mad-2008-estuve-alli/</link>
      <pubDate>Sun, 28 Sep 2008 10:32:01 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/09/28/gdd-mad-2008-estuve-alli/</guid>
      
      <description>&lt;p&gt;&lt;a href=&#34;http://www.flickr.com/photos/dpecos/2890140334/&#34;&gt;&lt;img class=&#34;alignleft&#34; style=&#34;margin: 10px 30px;&#34; src=&#34;https://danielpecos.com/assets/2008/09/2890140334_d25df7b543.jpg&#34; alt=&#34;1003&#34; width=&#34;227&#34; height=&#34;340&#34; /&gt;&lt;/a&gt;{.tt-flickr.tt-flickr-Medium}&lt;/p&gt;
&lt;p&gt;Fue un día agotador, pero valió la pena. Mucha gente, mucho nivel (no tanto en los talleres, pero bueno) y muy buen ambiente. No voy a hacer más resumenes acerca del evento (ya he leído unos cuantos en un rato), simplemente recomendar que si tenéis la posibilidad de asistir al GDD MAD 2009 no dejéis pasar la oportunidad.&lt;/p&gt;
&lt;p&gt;Temas principales sobre los que se hablaron:&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Android (tema estrella sin duda)&lt;/li&gt;
&lt;li&gt;Chrome&lt;/li&gt;
&lt;li&gt;AppEngine&lt;/li&gt;
&lt;li&gt;Gears&lt;/li&gt;
&lt;li&gt;Opensocial&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A continuación os dejo un enlace al &lt;a href=&#34;http://www.flickr.com/photos/dpecos/sets/72157607516896979/&#34;&gt;álbum en flickr&lt;/a&gt; con las fotos que tomé.&lt;/p&gt;
&lt;p&gt;¡Un saludo!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¿Look &amp; Feel? ¿Qué es eso?</title>
      <link>https://danielpecos.com/2008/09/03/look-and-feel-que-es-eso/</link>
      <pubDate>Wed, 03 Sep 2008 09:43:30 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/09/03/look-and-feel-que-es-eso/</guid>
      
      <description>&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;a href=&#34;https://danielpecos.com/assets/2008/09/bordesventan_winxp.png&#34;&gt;&lt;img class=&#34;alignnone size-full&#34; title=&#34;bordesventan_winxp&#34; src=&#34;https://danielpecos.com/assets/2008/09/bordesventan_winxp.png&#34; alt=&#34;L&amp;F de varias aplicaciones en WinXP&#34; width=&#34;500&#34; height=&#34;172&#34; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Éste es el aspecto de varias aplicaciones ejecutándose en Windows XP. Como se puede ver en la imagen últimamente las empresas optan por una diferenciación en cuanto a aspecto de la ventana (Look &amp; Feel), perdiéndose la integración a la que estábamos habituados con el sistema operativo. De hecho, en la captura de pantalla, la única aplicación que mantiene el L&amp;F de Windows XP es el Explorador de Ficheros.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Y tú qué opinas acerca de ésto: ¿es bueno? ¿es malo? ¿te la suda?
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Google anuncia Chrome</title>
      <link>https://danielpecos.com/2008/09/02/google-anuncia-chrome/</link>
      <pubDate>Tue, 02 Sep 2008 06:49:09 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/09/02/google-anuncia-chrome/</guid>
      
      <description>&lt;p&gt;Tras varios años de rumorología acerca de si Google iba a publicar un navegador web propio o no, finalmente se ha aclarado: su nombre es Chrome. Será un proyecto opensource basado en WebKit de Apple (el motor de renderizado de Safari) y según comentan, incluye un motor Javascript escrito desde cero, con el fin de mejorar el desempeño tanto en tiempo de ejecución como en consumo de memoria, con respecto a los navegadores que actualmente hay en el mercado. Otras características que incorpora son la navegación anónima, un sistema “Speed Dial” como el de Opera o una barra de autocompletado basada en el buscador.&lt;/p&gt;
&lt;p&gt;¿Qué es lo que pretende Google con esto? Según ellos, aportan innovación de cara al usuario, aunque personalmente lo que quieren conseguir es convertir al navegador en un sistema operativo (bueno, a lo mejor es un poco exagerado, pero sí en una fuente completa de aplicaciones), ya que supongo que uno de sus puntos fuertes será el poder ser ejecutado sin barra de herramientas ni menús, al estilo de Prism de Mozilla, consiguiendo que las aplicaciones web tengan un aspecto de aplicación de escritorio. Además, con la inclusión de Gears en Chrome, se ofrece la posibilidad de que las aplicaciones web almacenen datos en el propio navegador, abriendo un gran abanico de posibilidades para la tecnología web.&lt;/p&gt;
&lt;p&gt;Como nota curiosa, comentar que Google ha utilizado su estilo característico en la publicación de Chrome utilizando &lt;a href=&#34;http://www.google.com/googlebooks/chrome/&#34;&gt;viñetas de cómic&lt;/a&gt; para ello.&lt;/p&gt;
&lt;p&gt;Habrá que ver cómo afecta esto a los otros grandes navegadores y que implicaciones creará en el desarrollo de aplicaciones web. Renovarse o morir…&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://estilohacker.com/foro/dev-null/topic45.html&#34;&gt;Enlace a noticia en EstiloHacker.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;ACTUALIZACIÓN (02/09/2008 @ 23:05):&lt;/span&gt; El &lt;a href=&#34;http://www.google.com/chrome&#34;&gt;sitio&lt;/a&gt;{.postlink} ya está disponible… ¡a bajar!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Debian vs. Ubuntu</title>
      <link>https://danielpecos.com/2008/06/10/debian-vs-ubuntu/</link>
      <pubDate>Tue, 10 Jun 2008 21:33:04 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/06/10/debian-vs-ubuntu/</guid>
      
      <description>&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;img class=&#34;size-full&#34; title=&#34;Debian vs. Ubuntu&#34; src=&#34;https://danielpecos.com/assets/2008/06/debian_vs_ubuntu.jpg&#34; alt=&#34;&#34; width=&#34;325&#34; height=&#34;147&#34; /&gt;
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  &lt;strong&gt;¡30 minutos!&lt;/strong&gt; Eso es exactamente lo que he tardado en instalar &lt;a href=&#34;http://ubuntu.com&#34;&gt;Ubuntu&lt;/a&gt; con incluso más funcionalidades de las que tenía en mi &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  ¿Por qué este cambio? Bueno, supongo que la edad tendrá algo que ver y uno ya no tiene tanta paciencia como antes. Y es que en mi humilde opinión, disponer de un sistema &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt; con todo correctamente configurado, resulta una tarea tremendamente tediosa, además de que si deseas estar un poco al día con los programas que tienes instalados, te implica estar en una versión &lt;em&gt;testing&lt;/em&gt; o &lt;em&gt;unstable&lt;/em&gt; de &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt;, con el riesgo que ello conlleva.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Concretamente y por poner un ejemplo de lo último que me había ocurrido con mi &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt; &lt;em&gt;sid&lt;/em&gt;: tenía que asistir a unos talleres de programación, y tuve disponible toda la tarde anterio al día en cuestión, por lo que decidí actualizar el sistema.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Actualizo, y pierdo el driver propietario de NVidia (que lo instalé yo por mi cuenta ya que &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt; no lo incluye y &lt;em&gt;&lt;a href=&#34;http://compiz.org&#34;&gt;Compiz&lt;/a&gt; &lt;/em&gt;es un gustazo del que no se puede prescindir una vez lo pruebas). Total que lo reinstalo y resulta que la versión de &lt;em&gt;gcc &lt;/em&gt;que hay ahora en el sistema es una superior a la que utilicé para compilar el kernel en su día, por lo que no me deja compilar el módulo de nvidia. Solución: recompilar el kernel, y ya de paso, actualizarlo a la última versión disponible, que, casualidades de la vida, da errores de compilación con la versión nueva del &lt;em&gt;gcc&lt;/em&gt;. Mi gozo en un pozo.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Opto por downgradear el &lt;em&gt;gcc &lt;/em&gt;a la versión que tenía previamente, y además me quedo con la versión que utilizaba hasta el momento del kernel, pero seguía con el problema del módulo nvidia, por lo que vuelvo a intentar compilar el kernel, pero en este caso sin actualizar las fuentes. Compila todo sin problemas ¡uff!
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Reinicio, y veo que no tengo conexión inalámbrica. Bueno, no es problema ya que el módulo lo compilo por separado, así que lo hago y lo cargo, pero por lo que sea, no consigo conectar a mi red wifi configurada con WPA (que en su momento ya me costó unas 3 o 4 horas configurar) :&#39;(
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Finalmente y tras rehacer toda la configuración que ya hice en su día, consigo volver a conectar. ¡Todo listo y actualizado para el taller!
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Pues bien, llego al taller, me dan la configuración para conectar a la red WPA y no lo consigo, que no cunda el pánico&amp;#8230; Solución tumbar y levantar la interfaz wifi sucesivas veces (como durante unos 30 minutos) hasta que finalmente consigo IP, todo esto sin tocar configuración sino simplemente repitiendo el proceso una y otra vez. A todo esto, los compañeros de mesa arrancan su &lt;a href=&#34;http://ubuntu.com&#34;&gt;Ubuntu&lt;/a&gt;, y con un pequeño desplegable seleccionan la red wifi y meten &lt;em&gt;user/password&lt;/em&gt; y a trabajar 😮
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  Sinceramente, situaciones como ésta te hacen plantearte si realmente merece la pena dedicar tantísimo tiempo a la configuración de un ordenador, en detrimento de tiempo de uso. Está claro que no está mal conocer cómo hacer estas cosas a &amp;#8220;&lt;em&gt;bajo nivel&lt;/em&gt;&amp;#8220;, pero llega un punto que resulta excesivo.
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  En resumen, ahora mismo soy un novato total en &lt;a href=&#34;http://ubuntu.com&#34;&gt;Ubuntu&lt;/a&gt;, aunque es realmente parecido a &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt;, por lo que no creo que me cueste adaptarme (aún así, si tengo en cuenta todo el tiempo ahorrado en configuraciones, por el mero hecho de haber optado por &lt;a href=&#34;http://ubuntu.com&#34;&gt;Ubuntu&lt;/a&gt;, creo que dispongo de tiempo más que de sobra para adaptarme).
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  &lt;small&gt;PD: Soy usuario de &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt; desde hace aproximadamente 8 años (allá por el 2000 instalé mi primera Potato) y por el momento la voy a mantener en mi servidor, que cariño todavía me queda hacia &lt;a href=&#34;http://debian.org&#34;&gt;Debian&lt;/a&gt;.&lt;/small&gt;
&lt;/p&gt;
&lt;p style=&#34;text-align: justify;&#34;&gt;
  ¡Un saludo a todos!
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¡Feliz aniversario BASIC!</title>
      <link>https://danielpecos.com/2008/05/02/feliz-aniversario-basic/</link>
      <pubDate>Fri, 02 May 2008 07:29:36 +0100</pubDate>
      
      <guid>https://danielpecos.com/2008/05/02/feliz-aniversario-basic/</guid>
      
      <description>&lt;p&gt;El 1 de Mayo de 1964 se ejecutó el primer programa en BASIC. Los creadores de este lenguaje de programación, los profesores &lt;a href=&#34;http://es.wikipedia.org/wiki/John_Kemeny&#34;&gt;John G. Kemeny&lt;/a&gt; y &lt;a href=&#34;http://es.wikipedia.org/wiki/Thomas_Eugene_Kurtz&#34;&gt;Thomas E. Kurtz&lt;/a&gt; del Dartmouth College, hace 44 años ejecutaron por primera vez un código escrito en BASIC (&lt;span style=&#34;font-style: italic;&#34;&gt;Beginner&amp;rsquo;s All-Purpose Symbolic Instruction Code&lt;/span&gt;).&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;a href=&#34;https://danielpecos.com/assets/2008/05/kemeny_and_kurtz.jpg&#34;&gt;&lt;img class=&#34;alignnone size-medium&#34; title=&#34;John G. Kemeny y Thomas E. Kurtz&#34; src=&#34;https://danielpecos.com/assets/2008/05/kemeny_and_kurtz.jpg&#34; alt=&#34;Los creadores de BASIC&#34; width=&#34;250&#34; height=&#34;227&#34; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;La búsqueda de un lenguaje potente y sencillo de usar (por aquellas fechas se solía utilizar Fortran y Algol) comenzó en el año 1956, con el fin de facilitar a sus estudiantes el aprendizaje de los métodos de programación.&lt;/p&gt;
&lt;p&gt;Posteriormente en 1975, &lt;a href=&#34;http://es.wikipedia.org/wiki/Paul_Allen&#34;&gt;Paul Allen&lt;/a&gt; y &lt;a href=&#34;http://es.wikipedia.org/wiki/Bill_Gates&#34;&gt;Bill Gates&lt;/a&gt; adaptaron este lenguaje a los computadores personales. Como resultado, BASIC fue ampliamente utilizado y evolucionado hasta hoy en día (Visual BASIC .NET).&lt;/p&gt;
&lt;p&gt;Personalmente, éste fue el primer lenguaje que utilicé para desarrollar mi primera aplicación medianamente grande, un tablero de parchís (cuando lo miro hoy en día me da hasta vergüenza. no utilicé ni una sola función y todo el código estaba lleno de GOTOs). Para ello utilicé un intérprete de QuickBasic. Qué tiempos aquellos…&lt;/p&gt;
&lt;p&gt;¡Felicidades BASIC!&lt;/p&gt;
&lt;p&gt;PD: ¿Y tú con qué lenguaje distes tus primeros pasos en el mundo de la programación?&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Fuentes:&lt;/small&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;small&gt;&lt;a href=&#34;http://www.wired.com/science/discoveries/news/2008/04/dayintech_0501&#34;&gt;&lt;a href=&#34;http://www.wired.com/science/discoveries/news/2008/04/dayintech_0501#&#34;&gt;http://www.wired.com/science/discoveries/news/2008/04/dayintech_0501#&lt;/a&gt;&lt;/a&gt;&lt;/small&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>JavaServerFaces, Spring WebFlow y Struts Tiles, todo en uno</title>
      <link>https://danielpecos.com/2007/05/10/javaserverfaces-spring-webflow-y-struts-tiles-todo-en-uno/</link>
      <pubDate>Thu, 10 May 2007 11:54:42 +0100</pubDate>
      
      <guid>https://danielpecos.com/2007/05/10/javaserverfaces-spring-webflow-y-struts-tiles-todo-en-uno/</guid>
      
      <description>&lt;p&gt;¿Mezclar la versatilidad de JSF con la definición de flujos de negocio de SWF, todo ello con una estética semejante gracias a Tiles? Pues es posible, aunque resulta realmente tedioso y complicado para aquel que es relativamente nuevo a algunas (más bien todas) de estas tecnologías del mundo Java JEE.&lt;/p&gt;
&lt;p&gt;A esto es a lo que me he dedicado la última semana de trabajo, a intentar comprender el funcionamiento y buscar por Internet la forma de poder conjugar estas tres tecnologías. He conseguido hacerme una idea del complejo funcionamiento de JSF, SWF me ha sorprendido gratamente por la gran potencia que se consigue con tan pocas líneas de código, y Tiles, aunque ni tan avanzado tecnológicamente ni tan sorprendente, ofrece unas posibilidades de diseño visual que unifica toda la aplicación web con tan solo unos poco ficheros.&lt;/p&gt;
&lt;p&gt;Espero poder publicar un tutorial con los pasos a seguir y las aclaraciones necesarias lo antes posible.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://java.sun.com/javaee/javaserverfaces/&#34;&gt;JSF Sun Reference Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://myfaces.apache.org/&#34;&gt;JSF Apache MyFaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.springframework.org/webflow&#34;&gt;Spring WebFlow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://struts.apache.org/1.3.8/struts-tiles/index.html&#34;&gt;Struts Tiles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>¿Por qué sigo con Debian?</title>
      <link>https://danielpecos.com/2006/09/13/por-que-sigo-con-debian/</link>
      <pubDate>Wed, 13 Sep 2006 14:39:17 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/09/13/por-que-sigo-con-debian/</guid>
      
      <description>&lt;p&gt;La verdad es que ni yo mismo lo sé. Si por lógica fuera, ya haría un tiempo que estaría trabajando con otra distribución más simple y en la que la configuración de los dispositivos no ocupase varios días, realizando cientos de búsquedas por Internet y leyendo varios foros.&lt;/p&gt;
&lt;p&gt;Pero la realidad es que aquí sigo, peleando con el &lt;code&gt;apt-get&lt;/code&gt; y actualizando contra la versión &lt;em&gt;unstable&lt;/em&gt; de esta distribución.&lt;/p&gt;
&lt;center&gt;
  &lt;br /&gt; &lt;a href=&#34;http://debian.org&#34;&gt;&lt;img src=&#34;https://danielpecos.com/assets/2006/09/debian-1001.png&#34; alt=&#34;Debian&#34; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/center&gt;
&lt;p&gt;Y tampoco será por falta de alternativas: he probado &lt;a href=&#34;http://www.opensuse.org/&#34;&gt;OpenSuse&lt;/a&gt;, &lt;a href=&#34;http://www.gentoo.org/&#34;&gt;Gentoo&lt;/a&gt;, &lt;a href=&#34;http://www.ubuntu.com/&#34;&gt;Ubuntu&lt;/a&gt;, y pese a tener muchas ventajas sobre Debian, les faltaba algo… Puede que sea esa sensación de control y orden, o bien un cariño adquirido durante nuestras largas horas de pelea, pero la verdad es que por más que lo intento no soy capaz de dejarla.&lt;/p&gt;
&lt;p&gt;¿Os pasa esto también a vosotros?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>El escritorio del futuro</title>
      <link>https://danielpecos.com/2006/06/23/el-escritorio-del-futuro/</link>
      <pubDate>Fri, 23 Jun 2006 12:00:41 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/06/23/el-escritorio-del-futuro/</guid>
      
      <description>&lt;p&gt;Ésto me lo acabo de encontrar navegando por internet. La verdad es que es muy impresionante:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Se trata de un sistema semejante a un escritorio físico, de los de verdad. Tendremos una especie de mesa con los documentos, los archivos sobre ella. Con el ratón podremos moverlos de un lado a otro de nuestra mesa virtual, y gracias a diversos gestos, podremos agruparlos, apilarlos, ordenarlos, moverlos, y multitud de opciones de la Vida Real, pero con nuestro ordenador y de un modo virtual.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Este escritorio virtual lo está desarrollando BumpTop, y por ahora es un prototipo que tiene muy, muy buena pinta. Estaremos informados acerca de actualizaciones y nuevos lanzamientos, ya que la cosa parece que va a ser más que sobresaliente.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&#34;embed-youtube&#34; style=&#34;text-align:center; display: block;&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Fuente: &lt;a&gt;&lt;a href=&#34;http://xataka.com/archivos/2006/06/23-lo-que-sera-el-escritorio-del.php&#34;&gt;http://xataka.com/archivos/2006/06/23-lo-que-sera-el-escritorio-del.php&lt;/a&gt;&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;¿Para cuándo lo tendremos en nuestros Linux? Yo me muero de ganas 😉&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mundo Java</title>
      <link>https://danielpecos.com/2006/05/30/mundo-java/</link>
      <pubDate>Tue, 30 May 2006 13:58:51 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/05/30/mundo-java/</guid>
      
      <description>&lt;p&gt;Desde hace cosa de unas semanas, el mundo Java está cambiando notablemente. Por un lado, Sun publicó Java EE 5.0, junto con Sun Application Server 9.0, primera versión estable del proyecto Glassfish, que pretende implementar un Application Server libre para la especificación de JEE 5. En esta nueva versión se ha incluido, a parte de un cambio de la nomeclatura para las versiones, la especificación de EJB 3.0, Java Persistence API, una mejora en el desarrollo de webservices o JSF entre &lt;a href=&#34;http://java.sun.com/javaee/sdk/features.jsp&#34;&gt;otras características&lt;/a&gt;.&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &lt;a href=&#34;http://java.sun.com/javaee/community/glassfish/&#34;&gt;&lt;img alt=&#34;GlassFish Project&#34; id=&#34;image60&#34; src=&#34;https://danielpecos.com/assets/2006/05/open_projectglassfish1.gif&#34; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Por otra parte, Sun también anunció en la &lt;em&gt;JavaOne 2006&lt;/em&gt; un cambio de licencia de distribución para el JDK y el JRE (&lt;em&gt;DLJ – Distributor License for Java&lt;/em&gt;), a fin de que las distribuciones de Linux que, hasta el momento rechazaban incluirlos en su distribución, cambiaran de parecer, aunque por el momento dicho cambio no está causando los efectos que Sun esperaba. Inicialmente fue RedHat la que mostró sus reticencias, uniéndose posteriormente &lt;a href=&#34;http://lists.debian.org/debian-legal/2006/05/msg00086.html&#34;&gt;Debian&lt;/a&gt;, la cual sí que incluyó paquetes para Java en un primer momento en sus versión experimental.&lt;/p&gt;
&lt;p&gt;Lo que sí parece claro es que por fin Sun está redirigiendo su filosofía y se está orientando más hacia el software libre. Según se comenta, no cabe duda de que Java se convierta en un proyecto libre, la cuestión en estos momentos es &lt;strong&gt;cuándo y cómo&lt;/strong&gt;. Ese momento será seguramente uno de los más importantes, si no el que más, en mucho tiempo de la historia de Java.&lt;/p&gt;
&lt;p&gt;Creo que va a ser hora de ponerse en serio con la certificación y volver a los libros, a pesar de la pereza que da el hacerlo. Todo lo bueno requiere un pequeño sacrificio ;).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hipocresía Total o Semana Santa</title>
      <link>https://danielpecos.com/2006/04/18/hipocresia-total-o-semana-santa/</link>
      <pubDate>Tue, 18 Apr 2006 14:44:10 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/04/18/hipocresia-total-o-semana-santa/</guid>
      
      <description>&lt;p&gt;Acaba de terminar la semana en el que mucha gente se auto-inflije castigos a fin de contentar o conseguir el favor de la deidad en la que creen. Es curiosa esta tradición y lo mucho que se sigue por los medios de comunicación. Hay gente capaz de hacerse auténticas animaladas, como clavarse unos clavos en pies y manos o flagelarse la espalda (cuanto más sangrienta quede, mayor y mejor es tu fervor religioso).&lt;/p&gt;
&lt;p&gt;Luego, a parte de las lesiones auto-inflijidas existe también la costumbre de cargar a cuestas entre varias personas enormes trozos de madera decorado con costosos vestidos y alguna que otra joya, los cuales representan a su dios (o hijo) local y exhibirlos por su barrio, mientras que el resto del vecindario se dedica a cantar a dichos maderos y a llorarles rogando algún favor.&lt;/p&gt;
&lt;p&gt;Lo curioso de todo esto es que, si no tengo mal entendido, se supone que el dios cristiano es bondadoso, por lo que no parece muy lógico ofrendarle con el sufrimiento propio. Es más, según creo lo que se debe hacer es tener fe y seguir los mandamientos (aunque algunas de las interpretaciones que da la Iglesia de ellos son un poco más que lastimosos), por lo que parece que crear ídolos de madera costosísimos y arrastrarlos delante de todo un gentío emocionado de ver lo gran creyente que eres no va muy en concordancia con compartir los bienes con los pobres, la humildad y el amor al prójimo (no creo que alguien que sea capaz de hacerse &lt;em&gt;eso&lt;/em&gt;, pueda luego ser capaz de tratar medianamente bien a otros).&lt;/p&gt;
&lt;p&gt;Aún así, si al menos la gente que hace todo esto fuera de la misma forma durante el resto del año, pues aún tendría un poco más de sentido (que seguiría siendo bastante incomprensible), pero es que la gran mayoría de la gente luego ni se acuerda de lo religioso que demostraron ser la semana santa anterior. Luego no me extraña que la gente llore cuando da la casualidad de que llueve (que falta hace, por otra parte) el día en el que iban a desfilar, teniendo que suspenderlo. Pobrecillos, les tocará esperar otro año para sacar el madero a ventilar.&lt;/p&gt;
&lt;p&gt;Pero lo que más me intriga de todo es que si se supone que la Santísima Trinidad son Uno solo, ¿cómo se explica que cada barrio tenga su propio Cristo y/o Virgen y que además el propio sea mejor que el ajeno? Toda una curiosidad religiosa 😉&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Magdalena a la valenciana</title>
      <link>https://danielpecos.com/2006/03/25/magdalena-a-la-valenciana/</link>
      <pubDate>Sat, 25 Mar 2006 14:07:45 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/03/25/magdalena-a-la-valenciana/</guid>
      
      <description>&lt;p&gt;Parece que alguien ha tenido la original idea de que el mejor final para los sensacionales y espectaculares monumentos que son las gaiatas es… ¡¡¡¡el fuego!!!!&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;a href=&#34;https://danielpecos.com/assets/2006/03/imgp17381.jpg&#34;&gt;&lt;img class=&#34;aligncenter &#34; title=&#34;imgp1738&#34; src=&#34;https://danielpecos.com/assets/2006/03/imgp17381-768x1024.jpg&#34; alt=&#34;&#34; width=&#34;385&#34; height=&#34;513&#34; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Ahora lo único que queda es que se salve algún &lt;em&gt;ninot&lt;/em&gt; 😉&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Reencuentro después de 11 años</title>
      <link>https://danielpecos.com/2006/03/08/reencuentro-despues-de-11-anos/</link>
      <pubDate>Wed, 08 Mar 2006 20:51:05 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/03/08/reencuentro-despues-de-11-anos/</guid>
      
      <description>&lt;p&gt;Ese es el tiempo que hacía que no nos encontrábamos los compañeros de 8º de EGB del colegio Izquierdo. Sí que me había encontrado con alguno de ellos alguna vez, pero no así como anoche, todos juntos recordando las muchas anécdotas que vivimos durante aquellos años.&lt;/p&gt;
&lt;p&gt;Conforme me acercaba al punto de encuentro, me iba encontrando más y más nervioso, pensando en quién y cómo encontraría y si los reconocería (11 años es muuuucho tiempo), pero cuando llegué allí pude ver que la mayor parte de compañeros y compañeras que había tenido estaban bastante cambiados, pero la mayor parte eran reconocibles. No acudieron algunos de los que me hubiera gustado volver a ver, pero espero que no pase mucho tiempo hasta que me los encuentre por ahí.&lt;/p&gt;
&lt;p&gt;Bueno, tampoco me voy a poner ahora a describir cómo fue la noche. Simplemente quería agradecer a todos los compañeros que siguen ahí a pesar del tiempo y de la distancia su cariño y complicidad.&lt;/p&gt;
&lt;p&gt;Una noche genial. Espero que no tardemos otros 11 años en repetirla.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2005 New Year&#39;s Eve at London</title>
      <link>https://danielpecos.com/2006/01/10/2005-new-years-eve-at-london/</link>
      <pubDate>Tue, 10 Jan 2006 18:12:19 +0100</pubDate>
      
      <guid>https://danielpecos.com/2006/01/10/2005-new-years-eve-at-london/</guid>
      
      <description>&lt;p&gt;¡Feliz año 2006!&lt;/p&gt;
&lt;p&gt;Un poco tarde, pero por fin he terminado la entrada que quería escribir sobre el viaje de nochevieja a Londres :-D. Es un pequeño resumen de lo que hemos hecho durante el viaje:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Día 1&lt;/strong&gt; – &lt;em&gt;28 Diciembre 2005&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tras levantarnos a las 6 de la mañana, coger el cercanías hasta Valencia, desde allí un autobús hasta Manises, cogiendo un &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82057101/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;avión hasta Stansted&lt;/a&gt;, y finalmente un de nuevo un autobús hasta Liverpool Station nos encontramos con Yolanda que nos muestra el camino hasta la residencia de estudiantes donde íbamos a pasar los siguientes días de estancia (previa caminata de 20 minutos con trastos en la mano y un autobús). A estas alturas María ya había perdido el saco de dormir y la botella de champán que traíamos desde España 🙁&lt;/p&gt;
&lt;p&gt;Tras haber comido unos macarrones que nos supieron a gloria, fuimos a ver el centro de la ciudad, pasando por Trafalgar Square y Piccaddilli Circus. Impresionante y bonito. Tras entrar en una tienda de juguetes, cuyo nombre no recuerdo, y probarnos una serie de &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82061407/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;pelucas y artículos de broma&lt;/a&gt;, decidimos volver a la residencia a descansar para poder aprovechar el siguiente día al máximo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 2&lt;/strong&gt; – &lt;em&gt;29 Diciembre 2005&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;El día del Támesis. Después de haber planeado levantarnos relativamente pronto (a las 9 a.m.), no lo hacemos, por lo que salimos de la residencia rumbo al Tate sobre las 11 a.m. Caminamos hasta el Tower of London, castillo que se encuentra a pocos metros del famoso &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82063353/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Tower Bridge&lt;/a&gt;, el cual atravesamos, conduciéndonos al linde opuesto del río. Siguiendo el río, encontramos el &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82064059/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;teatro&lt;/a&gt; donde Shakespeare estrenó sus famosas obras, llegando finalmente al &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82064530/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Tate&lt;/a&gt;. Como bien dijo Cris, &lt;em&gt;«tanta diversión me abruma»&lt;/em&gt; 😉&lt;/p&gt;
&lt;p&gt;Después de un par de horas observando las obras expuestas en su interior, decidimos ir rollo guiri total a ver el resto de monumentos y sitios típicos de la ciudad que nos de tiempo. Así pues, vamos en dirección &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82066014/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Big Ben&lt;/a&gt;, que se encuentra al lado de Westminister, y justo en frente de &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82066425/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;The Eye of London&lt;/a&gt;, la noria que construyeron conmemorando el nuevo siglo. La verdad es que fue curioso ver el contraste que se mostraba entre las dos riberas del río.&lt;/p&gt;
&lt;p&gt;A estas horas ya estaba anocheciendo, por lo que fuimos hacia el centro de la ciudad para dar una vuelta por las tiendas más rezagadas en el cierre, pasando previamente por Buckingham Palace ****donde pudimos ver los típicos soldados ingleses de guardia en las puertas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 3&lt;/strong&gt; – &lt;em&gt;30 Diciembre 2005&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Otro día que casi no vimos el Sol :-s, y es que a las 12:30 no es hora para desayunar. Fue un día de relax, para tomar un poco de fuerzas, visto la que se nos venía encima.&lt;/p&gt;
&lt;p&gt;Aún así no lo desaprovechamos del todo ya que a las ocho de la tarde nos &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82067642/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;fuimos&lt;/a&gt; al centro a ver una actuación de Stomp, el grupo de teatro que crea canciones rítmicas con escobas, mecheros, cubos o a base de arrastrar los pies y dar palmas. Sin palabras. Es increíble la cantidad de curro que debe llevar el coordinar todas las personas que actúan para que suene de esa forma. Os lo recomiendo si alguna vez tenéis la opción de ir a verlos.&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34; align=&#34;center&#34;&gt;
  &lt;img class=&#34;size-full aligncenter&#34; alt=&#34;Stomp&#34; src=&#34;https://danielpecos.com/assets/2006/01/stomp.jpg&#34; width=&#34;160&#34; height=&#34;230&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;Una vez terminada la actuación, nos fuimos de vuelta a la residencia para cenar y arreglarnos para nuestra &lt;a href=&#34;http://www.flickr.com/photos/dpecos/84552906/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;primera noche de fiesta&lt;/a&gt; por Londres. Estuvimos en una discoteca que le habían recomendado a Gael, un chico francés que también estaba en la residencia, la cual resultó ser un poco decepcionante: música hardcore, ambiente poco respirable y además un rollo muy raro, ya que te cacheaban antes de entrar y después veías cómo los vigilantes se daban vueltas buscando a quien sea con unas linternas con las que te enfocaban a la cara y te dejaban cegado. Un poco extraño.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 4&lt;/strong&gt; – &lt;em&gt;31 Diciembre 2005&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nos levantamos relativamente tarde, por lo que solo dio tiempo a ir a comprar para la cena de esa noche. Una vez llegamos con la compra, nos pusimos manos a la obra y preparamos la &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82070946/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;cena de nochevieja&lt;/a&gt;, que aunque no era muy espectacular, fue la mejor de toda la estancia en Londres (con diferencia!).&lt;/p&gt;
&lt;p&gt;Ya durante la cena empezamos con las risas y cuando nos dimos cuenta ya eran las 23:15, demasiado tarde para que llegáramos a tiempo al Big Ben, por lo que decidimos quedarnos allí y seguir con el cachondeo. Se nos fue el santo al cielo y de repente comenzamos a ver fuegos artificiales por la ventana ¡Eran las 0:05! María, en un alarde de inspiración, saca una sartén y una cuchara y comienza a dar las campanadas con los cuartos incluidos. ¡Impresionante!&lt;/p&gt;
&lt;p&gt;Una vez se nos pasaron las lágrimas de tanto llorar de la risa, fuimos a prepararnos para salir de fiesta. Esa noche iríamos al pub &lt;em&gt;&lt;a href=&#34;http://www.flickr.com/photos/dpecos/84560282/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;George&lt;/a&gt;&lt;/em&gt; donde había una fiesta privada y nos costó convencer a la portero de que nos dejara pasar, pero al final lo conseguimos. En cuanto al local… una rayada: una mezcla entre gótico, punk, popero… y la música HORRIBLE, pero no pasa nada, por que llevábamos una fiesta que con cualquier cosa nos lo habríamos pasado bien.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 5&lt;/strong&gt; – &lt;em&gt;1 Enero 2006&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;El día sin Sol. De este día poco hay que comentar, porque no se hizo prácticamente nada :-S Simplemente dormimos 😎&lt;/p&gt;
&lt;p&gt;Bueno, no todo fue dormir :-P. Cuando descansamos nos fuimos a patinar a una pista de patinaje que había a los pies del Tower of London. Cuando terminamos, nos acercamos a Candem, un barrio de Londres muy peculiar y donde encontramos tiendas y puestos de comida muy diversos.&lt;/p&gt;
&lt;p&gt;La verdad es que una de las cosas que más llaman la atención de Londres es la diferencia que hay entre los barrios, ya que da la impresión de cambiar de ciudad conforme vas caminando por las calles. Es una sensación muy curiosa.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 6&lt;/strong&gt; – &lt;em&gt;2 Enero 2006&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Último día completo antes de la vuelta. Éste era nuestro último día que podríamos aprovechar al máximo (también lo era el de María y el de Carol, hasta que decidieron quedarse unos días más :-o). Así que nada más levantarnos fuimos camino de &lt;a href=&#34;http://www.flickr.com/photos/dpecos/83374536/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Notting Hill&lt;/a&gt;, donde estuvimos paseando un rato y viendo las tiendas. También estuvimos en la librería que sale en la película con el mismo nombre que la zona.&lt;/p&gt;
&lt;p&gt;Cuando nos cansamos, fuimos hacia el famoso &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82075962/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Hyde Park&lt;/a&gt;, un parque gigantesco en pleno corazón de Londres. Allí pudimos ver una estatua dedicada a &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82078831/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Peter Pan&lt;/a&gt;, un lago lleno de patos y algún que otro gracioso &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82077737/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;animalillo&lt;/a&gt;. Nos acercamos hacia una feria de atracciones que habían instalado donde comimos unos &lt;em&gt;hot dog&lt;/em&gt; que nos supieron a gloria.&lt;/p&gt;
&lt;p&gt;Para terminar el día (no sin antes pasar por &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82079838/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Harrods&lt;/a&gt;), nos acercamos a un restaurante hindú, donde pudimos degustar la esquisitez de ese tipo de comida (vamos, asqueroso, por decirlo claro). Después de esto, nos fuimos a dormir.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Día 7&lt;/strong&gt; – &lt;em&gt;3 Enero 2006&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;El madrugón. Nos levantamos a las 8 de la mañana y nos vamos Cris, Irene y yo a ver el &lt;a href=&#34;http://www.flickr.com/photos/dpecos/82081393/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;Tower of London&lt;/a&gt;, no sea cosa que les fuera a dar algo a las pobres chiquillas 😛 La verdad es que no esperaba mucho de él, y el coste de la entrada me parecía un poco alto, pero tras haber entrado, me fui con la sensación de que me faltaba tiempo para verlo todo, y eso que estuvimos desde las 10:30 hasta las 14:00.&lt;/p&gt;
&lt;p&gt;Nos volvimos a la residencia, cogimos las maletas y nos fuimos a Liverpool Station a coger un autobús que nos llevara a Stansted para coger el avión de vuelta. Sinceramente todavía no sé cómo llegamos a cogerlo, porque yo estaba convencido de que no llegabamos.&lt;/p&gt;
&lt;p&gt;Finalmente, y sin problema alguno (salvo algunas turbulencias), &lt;a href=&#34;http://www.flickr.com/photos/dpecos/83366445/in/set-1761440/&#34; target=&#34;_blank&#34;&gt;llegamos a Manises&lt;/a&gt;, donde nada más bajar nos dieron la bienvenida «a la española», pero esto casi que lo dejo para otra entrada en weblog 😉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Estoy seguro de que me dejo cosas, pero ya me ha quedado un poco largo el post 😛 Si queréis ver más cosas sobre Londres, aquí os dejo el &lt;a href=&#34;http://www.flickr.com/photos/dpecos/sets/1761440/&#34;&gt;álbum de fotos&lt;/a&gt; del viaje.&lt;/p&gt;
&lt;p&gt;Resumiendo, ha sido un viaje que no olvidaré nunca, y en el que me lo he pasado genial. ¡Qué campanadas más espectaculares!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Web 2.0</title>
      <link>https://danielpecos.com/2005/12/14/web-20/</link>
      <pubDate>Wed, 14 Dec 2005 09:37:39 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/12/14/web-20/</guid>
      
      <description>&lt;p&gt;Es el término de moda en los entornos de programación web: &lt;a href=&#34;http://es.wikipedia.org/wiki/AJAX&#34;&gt;AJAX&lt;/a&gt;, consistente en la interacción de las tecnologías &lt;a href=&#34;http://es.wikipedia.org/wiki/JavaScript&#34;&gt;JavaScript&lt;/a&gt;, &lt;a href=&#34;http://es.wikipedia.org/wiki/HTML&#34;&gt;HTML&lt;/a&gt;/&lt;a href=&#34;http://es.wikipedia.org/wiki/CSS&#34;&gt;CSS&lt;/a&gt; y &lt;a href=&#34;http://es.wikipedia.org/wiki/XML&#34;&gt;XML&lt;/a&gt;. Aunque en sí misma esta conjunción resulta bastante reciente, las tecnologías implicadas son ya viejas glorias entre los programadores.&lt;/p&gt;
&lt;p&gt;El concepto básico en el que se basa esta técnica de programación es bastante simple: cuando se produce un evento en el navegador web que está mostrando el código HTML, en vez de realizar una petición HTTP al servidor, tal y como se suele realizar normalmente, se crea un objeto JavaScript &lt;a href=&#34;http://es.wikipedia.org/wiki/XMLHttp&#34;&gt;XMLHttpRequest&lt;/a&gt;, encargado de realizar dicha petición, la cual devolverá unos datos que serán pasados al manejador del evento que se haya definido.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://danielpecos.com/assets/2005/12/ajax.png&#34;&gt;&lt;img src=&#34;https://danielpecos.com/assets/2005/12/ajax.png&#34; alt=&#34;&#34; title=&#34;ajax&#34; width=&#34;394&#34; height=&#34;377&#34; class=&#34;aligncenter size-full&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sencillo ¿verdad?. La gracia del tema (puesto que hasta ahora lo único que se ha hecho es complicar lo que antes se hacía de forma sencilla) es que la petición HTTP y la ejecución del manejador del evento se realizan en un segundo plano y de forma asíncrona, de forma que el efecto producido por el evento es percibido por el usuario sólo cuando la comunicación con el servidor ya ha terminado. Además, no resulta necesario realizar una recarga del código HTML, ya que es el propio manejador javascript el que edita el árbol &lt;a href=&#34;http://es.wikipedia.org/wiki/Document_Object_Model&#34;&gt;DOM&lt;/a&gt; de la página web, lo que a efectos de interfaz resulta en una web dinámica que responde a eventos sin repetidas esperas entre cargas de páginas.&lt;/p&gt;
&lt;p&gt;Una vez visto en qué consiste esta técnica, es momento de ver algunas de las &lt;em&gt;killer app&lt;/em&gt; actuales que utilizan AJAX:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gmail.google.com&#34;&gt;Gmail&lt;/a&gt;: Sin lugar a dudas es la aplicación que lanzó a la fama AJAX, asombrando con la navegación entre emails sin necesidad de hacer recargas, o del autocompletado a la hora de escribir una dirección de email o de la corrección de sintaxis en la edición.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://maps.google.com/&#34;&gt;Google Maps&lt;/a&gt;: Otra aplicación de &lt;a href=&#34;http://google.com&#34;&gt;Google&lt;/a&gt; que permite navegar por el mundo a través de un mapa capaz de superponer fotos satélite.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.flickr.com&#34;&gt;Flickr!&lt;/a&gt;: Perteneciente a &lt;a href=&#34;http://yahoo.com&#34;&gt;Yahoo!&lt;/a&gt;, ofrece la posibilidad de organizar y etiquetar nuestras fotos preferidas, a través de una interfaz &lt;a href=&#34;http://es.wikipedia.org/wiki/Macromedia_Flash&#34;&gt;Flash&lt;/a&gt; y técnicas AJAX.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.meebo.com&#34;&gt;Meebo&lt;/a&gt;: Cliente de mensajería instántanea via web, con capacidad para hacer login en la red de IM que se prefiera. Personalmente, la simulación de ventanas de chat que tiene me parece que es realmente impresionante.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.writely.com/&#34;&gt;Writely&lt;/a&gt;: Editor de textos &lt;a href=&#34;http://es.wikipedia.org/wiki/WYSIWYG&#34;&gt;WYSIWYG&lt;/a&gt; que permite guardar los documentos en formato word, además de una organización por etiquetas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por el momento el punto más flojo de la cuestión es idear qué nuevas funcionalidades pueden sacar un mayor partido a esta reciente técnica, por lo que a pensar se ha dicho ;-).&lt;/p&gt;
&lt;p&gt;Y tú, ¿ya has programado una aplicación web utilizando AJAX?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Google ofrece IM/Jabber</title>
      <link>https://danielpecos.com/2005/08/24/google-ofrece-im-jabber/</link>
      <pubDate>Wed, 24 Aug 2005 07:54:30 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/08/24/google-ofrece-im-jabber/</guid>
      
      <description>&lt;p&gt;Pues parece ser que los tan sonados rumores de que &lt;a href=&#34;http://google.com&#34;&gt;Google&lt;/a&gt; iba a ofrecer un servicio de mensajería instántanea &lt;a href=&#34;http://talk.google.com&#34;&gt;se han hecho realidad&lt;/a&gt;. Es más, también se ha confirmado que utiliza el protocolo &lt;a href=&#34;http://jabber.org&#34;&gt;Jabber&lt;/a&gt;, lo cual supondrá un fuerte empujón a esta tecnología libre. El nombre con el que se ha bautizado este servicio es &lt;a href=&#34;http://talk.google.com&#34;&gt;Google Talk&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://talk.google.com&#34;&gt;&lt;img src=&#34;https://danielpecos.com/assets/2005/08/Google-Talk-Logo.jpg&#34; alt=&#34;&#34; title=&#34;Google-Talk-Logo&#34; width=&#34;243&#34; height=&#34;99&#34; class=&#34;size-full&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Podemos ver que ofrecen un cliente, por el momento únicamente para sistemas Windows, con el cual podremos realizar tanto conversaciones vía texto o vía voz.&lt;/p&gt;
&lt;p&gt;El único inconveniente es que por el momento sólo aquéllos que dispongan de una cuenta de correo &lt;a href=&#34;http://gmail.google.com&#34;&gt;GMail&lt;/a&gt; podrán probar el nuevo sistema de IM.&lt;/p&gt;
&lt;p&gt;Podemos seguir los comentarios que se realicen en &lt;a href=&#34;http://barrapunto.com/articles/05/08/24/0658222.shtml&#34;&gt;Barrapunto&lt;/a&gt; y en &lt;a href=&#34;http://it.slashdot.org/it/05/08/23/2316223.shtml?tid=217&amp;amp;tid=218&#34;&gt;Slashdot&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¿Alcohol = Diversión?</title>
      <link>https://danielpecos.com/2005/04/12/alcohol-diversion/</link>
      <pubDate>Tue, 12 Apr 2005 20:46:44 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/04/12/alcohol-diversion/</guid>
      
      <description>&lt;p&gt;El Sábado por la noche, camino de vuelta a casa sobre las 6 de la mañana, después de una noche de fiesta con los amigos, pasaba por delante de la biblioteca de Rafalafena, desde donde se podía observar el cielo totalmente despejado (cosa bastante normal en las noches con viento, como fue ésta), teniendo una visión impresionante de la constelación Cassiopea justo encima del edificio de la biblioteca. No sé muy bien por qué, pero esa situación activó el «modo meditación» durante el resto del camino, lo que me hizo pensar en un concepto que se suele dar por supuesto y es el asociar el alcohol con la diversión.&lt;/p&gt;
&lt;p&gt;Lo curioso del tema no es que el beber alcohol implique diversión (que si se controla bien, en la mayoría de los casos suele ser así) sino la dependencia e incredulidad que se genera en el «bebedor festero habitual».&lt;/p&gt;
&lt;p&gt;Me explico:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Por un lado, se es incapaz de salir sin haber hecho un botellón previo o haberte gastado una pasta en algún que otro bareto, ya que de ser así, la noche va promete ser un coñazo de cuidado. Resulta intrigante ver a dos personas sin haber bebido una gota de alcohol, vacilándose mutuamente por la calle, diciendo que hasta que no se hagan 5 litros entre los dos, no se mueven del bar. ¿Por qué? La respuesta que obtuve en una ocasión fue que parece ser que cuánto más se bebe, menos probabilidades de que te acuerdes a la mañana siguiente de lo que hiciste (lo cual me llevó a pensar que tal vez fuera poco recomendable estar cerca de quien me lo dijo). Pensando concienzudamente en esta respuesta tan … respuesta, me pareció una actitud aún más rídicula, pero eso ya es cuestión personal de cada uno.&lt;/li&gt;
&lt;li&gt;Por otro lado, no es posible comprender cómo puede haber gente que no beba y se lo pase bien. Es más, se da por supuesto la implicación biyectiva entre no beber y muermo. De hecho es pecado mortal decir que no bebes alcohol por no hablar de las nefastas implicaciones político-religioso-social-festeras que conlleva pedir un botellín de agua en la discoteca (no hace falta hablar sobre las realmente preocupantes consecuencias presupuestarias que de hecho conlleva el infame acto).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y por mucho que pueda resultar extraño, esto es así, o por lo menos es lo que me ha tocado sufrir en más de una ocasión. De hecho, no han sido pocas las veces que me presentan a alguien y me pregunta que si me pasa algo cuando pedimos bebida en la barra. ¿No resulta un poco fuerte el hecho de que se dé este nivel de aceptación del alcohol e incluso la sorpresa producida por el hecho de no consumirlo? Supongo que la mejor respuesta a esta pregunta se puede encontrar en el refranero: Cree el ladrón que todos son de su condición.&lt;/p&gt;
&lt;p&gt;Supongo que en este punto es normal suponer que soy un abscemio total, y el caso es que cuando salgo me suelo tomar algo cuando salgo por ahí, poca cosa, pero es que realmente no siento la necesidad social de que llegue el Lunes y mis compañeros me pregunten por el fin de semana y no les pueda contestar que me pillé un ciego increíble (de hecho tampoco acabo de entender qué mérito tiene gastarse más de 30 € en bebida para luego no saber qué es exactamente lo que hiciste, se ve que es cuestión de aguante, ya que no todo el mundo es capaz de hacerlo, y, por lo que se ve, eso está bien valorado).&lt;/p&gt;
&lt;p&gt;En fin, el camino de vuelta no dio para mucho más, y como sólo era el «modo filosófico» pues no pude encontrar alguna respuesta razonable al tema, sino que solo encontraba más situaciones éticamente pobres en relación con el alcohol. Simplemente me gustaría sugerir que se hiciese la sencilla prueba ante alguien que no te conoce de decir que no sueles beber cuando sales, resulta realmente curioso ver la cara extraño que se le queda a quien lo escucha. Si alguien lo hace, que no dude en postearlo.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;¿Y tú, bebes para pasártelo bien o simplemente bebes lo que te apetece cuando te lo pasas bien?&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Magdalena Vítol y sus daños colaterales</title>
      <link>https://danielpecos.com/2005/03/07/magdalena-vitol-y-sus-danos-colaterales/</link>
      <pubDate>Mon, 07 Mar 2005 00:17:01 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/03/07/magdalena-vitol-y-sus-danos-colaterales/</guid>
      
      <description>&lt;p&gt;Al final todo lo bueno llega a su fin, y las fiestas de la Magdalena no han sido una excepción. Tras 10 días de frío y sufrimiento por pasarlo bien, volvemos a la rutinaria vida del trabajo diario. En general han estado bastante bien, aunque como siempre, he acabado bastante “quemado” con la organización y lo elitistas que pueden llegar a ser, pero bueno, prefiero no escribir sobre ello, no creo que ni tan siquiera lo merezcan.&lt;/p&gt;
&lt;p&gt;Aunque lo que sí que voy a denunciar es la fatal organización que hubo durante el acto de la Magdalena Vítol, el cual tras retrasarse durante casi tres cuartos de hora, se extendió casi una hora más, gracias a una pobre actuación teatral, en la cual no se tuvo en cuenta el estado meteorológico (que no es que acompañara mucho) y que casí hace acabar a una actriz que estaba colgada en un globo-luna, acabar en la punta del Fadrí. Pero lo peor estaba aún por llegar cuando a los organizadores les dio por lanzar un mini-castillo de fuegos artificiales hacia el público lo que produjo la consecuente avalancha de gente y sus correspondientes heridos y daños colaterales. Además, y para más inri, una carcasa cayó justo al lado de donde estabamos nosotros, causando una escena un tanto dantesca. Las consecuencias, pues mi amigo Héctor con una ampolla en el cuello, Guillermo oliendo a pollo quemado y yo con un par de quemones en la chaqueta. El resto de gente que venía con nosotros creo que salió más o menos intactos, salvo por el mal rato pasado.&lt;/p&gt;
&lt;p&gt;Creo y espero que será dificil de &lt;em&gt;mejorar&lt;/em&gt; en próximos años, aunque si hay algo que no deja de sorprenderme año tras año son los organizadores y sus geniales ideas festivas. A ver con que nos &lt;em&gt;premian&lt;/em&gt; en el 2006.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sospechas conspiracionistas</title>
      <link>https://danielpecos.com/2005/01/13/sospechas-conspiracionistas/</link>
      <pubDate>Thu, 13 Jan 2005 22:46:56 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/01/13/sospechas-conspiracionistas/</guid>
      
      <description>&lt;p&gt;Hoy he podido escuchar y ver en diversos medios de comunicación el anuncio de que la NASA realizaba el lanzamiento de su última misión espacial, &lt;em&gt;Deep Impact&lt;/em&gt;, que transportará una nave cuya misión será estreyarse con el cometa Tempel 1 a una velocidad de nada menos que 37.000 km/h. El aplastante suceso ocurrirá el 4 de Julio del presente año, a una distancia 431 millones de kilómetros, un poco lejos para que cierto país pueda usar la explosión como si de fuegos artificiales se tratasen para celebrar la fiesta nacional que acontece el mismo día.&lt;/p&gt;
&lt;p&gt;Según la NASA, esta misión despierta el interés científico ya que se supone que el cometa está compuesto por los materiales primigéneos que formaban el sistema solar, por lo que se desvelarían muchos secretos aún por descubrir. Si a esto le añadimos que no se sabe si el cometa quedará totalmente destruido a causa del impacto, o si únicamente se creará un &lt;em&gt;pequeño&lt;/em&gt; cráter del tamaño de un campo de fútbol y de unos 10 pisos de altura, obtenemos lo que puede ser una de las experiencias científico-espaciales más populares del año que comienza.&lt;/p&gt;
&lt;p&gt;La inquietud surge cuando uno comienza a darle vueltas a unas cuantas ideas …&lt;/p&gt;
&lt;p&gt;Una misión de este tipo debe ser, y realmente lo es, un poco cara de subvencionar, por lo que para que haya sido agraciada con tal cantidad de dinero, debe ser debidamente justificado el por qué es necesario realizar dicha inversión. Así pues, si yo fuera el inversor, y vinieran una serie de científicos a pedirme dinero para estrellar una nave contra un cometa para descubrir de qué esta compuesto, pero que cabe la posibilidad de que al chocar nos carguemos al susodicho cometa y que, por lo tanto, no se pueda realizar el estudio, pues como que tendría muy claro lo que tendría que hacer: Señores, estrellen sus vehículos contra la Casa Blanca para intentar descubrir lo que hay dentro de ella (por ejemplo).&lt;/p&gt;
&lt;p&gt;Ahora hablando en serio, huele un poco raro que se le dé tanto revuelo a una misión tan «pobre» como la Deep Impact. Además curioso nombre el asignado, referente a una película en la que un cometa se estrella contra la Tierra. Parece como si hubieran querido acallar las posibles ideas catastróficas ironizando precisamente sobre ellas. Y es que, a mi parecer, la NASA ha puesto dicho nombre a la misión, por no poner el nombre de la otra película de cometas protagonizada por Bruce Willis, &lt;em&gt;Armageddon&lt;/em&gt;, con lo que más que apaciguar a las masas, lo que haría sería cundir el pánico por la posible asociación de objetivos entre la misión y la película mencionada, es decir, el destruir o desviar un cometa en dirección hacia la Tierra.&lt;/p&gt;
&lt;p&gt;Por otro lado, me consuela (o al menos eso el lo que deseo), pensar que existen diversos laboratorios independientes de la NASA que podrían realizar los cálculos para descartar o confirmar el posible destino terrestre del cometa Tempel 1, por lo que, en caso de que nos fuera ha realizar una visita &lt;em&gt;demasiado&lt;/em&gt; cercana, supongo que se correría la voz como si de una mecha se tratase.&lt;/p&gt;
&lt;p&gt;Bueno, pues como toda buena teoría conspiracionista, no se puede ni afirmar ni desmentir que lo dicho sea así, ya que tan lógico es pensar lo uno como lo otro. Así que cada cual saque sus propias conclusiones.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fin de Año en Benidorm</title>
      <link>https://danielpecos.com/2005/01/04/fin-de-ano-en-benidorm/</link>
      <pubDate>Tue, 04 Jan 2005 22:33:20 +0100</pubDate>
      
      <guid>https://danielpecos.com/2005/01/04/fin-de-ano-en-benidorm/</guid>
      
      <description>&lt;p&gt;¡Feliz año 2005 a todo el mundo!&lt;/p&gt;
&lt;p&gt;Hoy mismo he llegado de pasar este mini-puente de fin de año en Benidorm con los colegas de Benicassim. La verdad es que no ha estado nada mal el fin de semana, a pesar de haber trabajado hasta instantes antes de coger el coche, aunque hubiera sido mejor ir un poco más descansado y salir un poco más tarde el Domingo, ya que tuvimos que dejar las habitaciones sobre las 10 de la mañana, por lo que el Sábado tuve que acostarme no muy tarde para poder conducir en condiciones a la mañana siguiente (mejor no arriesgar con el coche).&lt;/p&gt;
&lt;p&gt;En total éramos 8 personas: Rafa, César, Alejandro, Julen, Natalia, Noelia, Carlos (que vino un día más tarde y se fue uno antes con Noelia) y yo, repartidos en dos habitaciones de 4 (Rafa, César, Alejandro y Carlos en una y Julen, Natalia, Noelia y yo en la otra). La verdad es que el hotel estaba muy bien para el precio que nos dieron, ya que el viaje al final me ha salido por unos 90 € aproximadamente, incluidos estancia, entrada a las discotecas Penélope, KM y Hacienda (antes Pachá), comida y gasolina. Muy bien de precio, sin lugar a dudas.&lt;/p&gt;
&lt;p&gt;En cuanto al ambiente, sencillamente genial. Sólo vi una ambulancia en toda la noche y no se vio ninguna bronca en ninguna de las discotecas, cosa realmente extraña. La gente por lo general te felicitaba el año, aunque probablemente fuera por lo pedo que iban.&lt;/p&gt;
&lt;p&gt;En cuanto a las tías, pues para variar, poca cosa, aunque tampoco estuvo mal del todo. Pero, eso sí, cachondeo mogollón.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Inicio astrofotográfico</title>
      <link>https://danielpecos.com/2004/06/09/inicio-astrofotografico/</link>
      <pubDate>Wed, 09 Jun 2004 09:16:26 +0100</pubDate>
      
      <guid>https://danielpecos.com/2004/06/09/inicio-astrofotografico/</guid>
      
      <description>&lt;p&gt;Ya llevaba tiempo tratando de empezar con la astrofotografía con webcam, pero entre unas cosas y otras siempre lo dejaba para otro momento. Al final el pasado día 6 de Junio me decidí a intentarlo.&lt;/p&gt;
&lt;center&gt;
  &lt;br /&gt; &lt;img src=&#34;https://danielpecos.com/assets/2004/06/06-Jun-2004.jpg&#34; alt=&#34;&#34; /&gt;
&lt;/center&gt;
&lt;p&gt;Tras unos cuantos intentos por usar un adaptado hecho con la funda de un carrete de fotos, acabé sujetando la webcam al portaocular con una simple goma que me dieron mis abuelos la última vez que estuve en Madrid (¡hay que ver lo que a uno le puede hacer falta en algunos momentos!), lo cual, aunque no es una forma muy ortodoxa, dio buenos resultados, como se puede ver en la foto anterior.&lt;/p&gt;
&lt;p&gt;Entre Alfredo y yo hicimos unas cuantas tomas de Jupiter con sus lunas (por primera vez pude apreciar las bandas de este planeta), así como otras cuantas de la Luna, pero dado a mi alto nivel de novatez, no caí en la cuenta de que cada vez que grababa un vídeo, estaba borrando el anterior, ya que se usaba el mismo archivo. Aún así conseguimos una foto de la que me siento muy orgulloso, ya que fue la foto que me inició formalmente en el mundo de la astrofotografía con webcam.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mono: ¡Hola Mundo!</title>
      <link>https://danielpecos.com/2004/03/29/mono-hola-mundo/</link>
      <pubDate>Mon, 29 Mar 2004 13:07:46 +0100</pubDate>
      
      <guid>https://danielpecos.com/2004/03/29/mono-hola-mundo/</guid>
      
      <description>&lt;p&gt;Para retomar de nuevo la marcha del blog, he decidido comenzar mostrando algunos ejemplos de programación en C#. Por el momento os dejo el obligatorio programa para todo aquel que empieza con algún lenguaje.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hola Mundo!&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;using System;

namespace HolaMundo {

   public class HolaMundo {
      public static void Main (string [] args) {
         Console.WriteLine (&amp;#34;Hola Mundo!&amp;#34;);
      }
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sencillo, ¿verdad? Tiene mucha semejanza con Java, exceptuando que las palabras reservadas difieren y que Java no posee el concepto de &lt;em&gt;espacios con nombre&lt;/em&gt; o &lt;em&gt;NameSpaces&lt;/em&gt;, entre otras.&lt;/p&gt;
&lt;p&gt;Bueno, prometo que el próximo ejemplo será más interesante que éste.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Funcionamiento de .NET</title>
      <link>https://danielpecos.com/2003/08/08/funcionamiento-de-net/</link>
      <pubDate>Fri, 08 Aug 2003 09:27:59 +0100</pubDate>
      
      <guid>https://danielpecos.com/2003/08/08/funcionamiento-de-net/</guid>
      
      <description>&lt;p&gt;En los artículos anteriores hemos hablado de conceptos como CTS, CLI (CLS), IL o JIT, los cuales pueden resultar bastante confusos. A continuación daremos una aclaración del significado de cada uno de ellos, y explicaremos su función dentro de la plataforma .NET, para lo cual se hará una explicación más a fondo de su funcionamiento.&lt;/p&gt;
&lt;p&gt;Hemos comentado en artículos anteriores que cuando compilas un código fuente a un binario de .NET, éste binario no contiene código máquina de la arquitectura en la que se compiló, sino que se genera un código para una máquina virtual, al estilo del bytecode de Java.&lt;/p&gt;
&lt;p&gt;Además se comentó que era posible utilizar un objeto escrito en un lenguaje .NET desde otro lenguaje .NET. La explicación a ésto es un poco más compleja: cuando tú compilas un código, se genera un &lt;strong&gt;Assembly&lt;/strong&gt; o &lt;em&gt;ensamblaje&lt;/em&gt;, que es la unidad mínima de compilación en .NET (que además es autosuficiente y autodescriptiva), el cual puede contenerse en un fihcero .exe o .dll, dependiendo del tipo de código que contenga y de la función a realizar. Dicho assembly está formado por un código que entenderá la máquina virtual, llamado &lt;strong&gt;IL&lt;/strong&gt; o &lt;strong&gt;Interpreted Language&lt;/strong&gt;, y es lo que denominaremos &lt;strong&gt;CLI&lt;/strong&gt; o &lt;strong&gt;Common Language Interface&lt;/strong&gt;, que, junto con el uso exclusivo de los tipos definidos en el &lt;strong&gt;CTS&lt;/strong&gt; o &lt;strong&gt;Common Type System&lt;/strong&gt;, permitirán que cualquier compilador .NET pueda entender dicho assembly al generar otros programas o librerías.&lt;/p&gt;
&lt;p&gt;Hasta este momento hemos conseguido unificar el lenguaje pseudo-ensamblador que usarán los compiladores .NET, de forma que será posible la interacción entre distintos lenguajes. Pero, ¿cómo se resuelve el problema de que distintas arquitecturas y sistemas operativos puedan ejecutar un mismo código máquina?. Pues la respuesta es parecida a la que da Java. Java implementa una máquina virtual que interpreta el bytecode. .NET hace una precompilación del IL para proceder a su ejecución. A esta técnica se le denomina &lt;strong&gt;JIT Compilation&lt;/strong&gt; o &lt;strong&gt;Just In Time Compilation&lt;/strong&gt;. ¿Ventajas? Pues como la compilación resulta que se reduce practicamente una traducción entre lenguajes máquina, ésta requiere muy poco tiempo, por lo que el resultado final es que es más eficiente que la interpretación del código (de todas formas Mono también dispone de un intérprete de IL, llamado &lt;strong&gt;mint&lt;/strong&gt;)&lt;/p&gt;
&lt;p&gt;Como comentario final al artículo, decir que me resultó realmente extraño que Microsoft diseñara una plataforma que fuera capaz de de correr en diferentes arquitecturas y más aún, en diferentes sistemas operativos. La explicación es que Microsoft no buscaba la portabilidad, sino que buscaba la integración de distintos lenguajes de programación (C#, C++.NET, VisualBasic.NET, etc), consiguiendo como «daño colateral» dicha portabilidad.&lt;/p&gt;
&lt;p&gt;Pues eso ha sido todo por el momento. Nos vemos en los próximos artículos.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pasado, presente y futuro de Mono</title>
      <link>https://danielpecos.com/2003/07/31/pasado-presente-y-futuro-de-mono/</link>
      <pubDate>Thu, 31 Jul 2003 11:42:19 +0100</pubDate>
      
      <guid>https://danielpecos.com/2003/07/31/pasado-presente-y-futuro-de-mono/</guid>
      
      <description>&lt;p&gt;En este artículo os comentaré un poco de historia sobre la evolución de la tecnología .NET y del proyecto Mono, que a pesar de su corta existencia, ha sido un proyecto muy vivo, y en el cual han participado y participan muchas personas de todo el mundo.&lt;/p&gt;
&lt;p&gt;.NET es una tecnología desarrollada por Microsoft, que ha sido estandarizada en el ECMA (&lt;a href=&#34;https://danielpecos.com/assets/2003/07/Ecma-334.pdf&#34;&gt;C#&lt;/a&gt;, &lt;a href=&#34;https://danielpecos.com/assets/2003/07/Ecma-335.pdf&#34;&gt;CLI&lt;/a&gt;), ofreciendo la posibilidad de crear utilidades que trabajen con este entorno, sin miedo a que un día Microsoft interponga una demanda o que simplemente cambie las especificaciones a su antojo.&lt;/p&gt;
&lt;p&gt;Así pues, Ximian Inc., empresa dirigida por Miguel de Icaza, decidió el 9 de Julio de 2001 crear un runtime y un compilador para la plataforma .NET en sistemas Unix. Dicho entorno fue bautizado como Mono.&lt;/p&gt;
&lt;p&gt;Las utilidades del proyecto (runtime = &lt;strong&gt;mono&lt;/strong&gt;; compilador de C# = &lt;strong&gt;mcs&lt;/strong&gt;) están escritos en C#, el lenguaje estrella de la plataforma .NET, por lo que su desarrollo inicial se realizó en el entorno .NET de Microsoft, hasta que el 3 de Enero de 2002 se anunció que el proyecto era auto-suficiente, es decir, que era capaz de compilarse y ejecutarse a sí mismo, con lo cual ya no fue necesario el uso del compilador de Microsoft (&lt;strong&gt;csc&lt;/strong&gt;), pudiendo continuar el desarrollo usando el propio proyecto.&lt;/p&gt;
&lt;p&gt;Desde entonces el desarrollo del proyecto ha estado centrado en el desarrollo de la librería estándar, el desarrollo de compiladores para otros lenguajes, como por ejemplo VisualBasic (&lt;strong&gt;mbas&lt;/strong&gt;), la adaptación del sistema de interfaz de usuario de windows (&lt;em&gt;System.Windows.Forms&lt;/em&gt; o &lt;em&gt;SWF&lt;/em&gt;) al resto de sistemas operativos, usando para ello las librerías del proyecto Wine (&lt;a href=&#34;http://www.winehq.com&#34;&gt;http://www.winehq.com&lt;/a&gt;), y el desarrollo de ASP.NET y los servicios web, habiendo desarrollado un mini servidor web (&lt;strong&gt;xsp&lt;/strong&gt;) para su uso en entorno .NET (aunque también existe un módulo para Apache llamado &lt;strong&gt;mod_mono&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;El futuro immediato de Mono está orientado a completar y depurar la librería estándar, sin perder de vista las nuevas características incluidas en la nueva estandarización del entorno, .NET 1.1 (C# 2.0), en donde se incluyen, entre otras cosas, la implementación de genéricos en C#.&lt;/p&gt;
&lt;p&gt;Éstos han sido los pasos, a grandes rasgos, de lo sucedido en torno al proyecto. Para obtener más información, remitiros a las archivos de las listas de correos que podreis encontrar en la &lt;a href=&#34;http://www.go-mono.com&#34;&gt;web&lt;/a&gt; del proyecto.&lt;/p&gt;
&lt;p&gt;En el siguiente artículo os haré una breve descripción de las principales utilidades de Mono, así como un pequeño glosario de los acrónimos más utilizados en relación con .NET.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>¿Qué es Mono?</title>
      <link>https://danielpecos.com/2003/07/30/que-es-mono/</link>
      <pubDate>Wed, 30 Jul 2003 13:30:31 +0100</pubDate>
      
      <guid>https://danielpecos.com/2003/07/30/que-es-mono/</guid>
      
      <description>&lt;p&gt;Mono (&lt;a href=&#34;http://www.go-mono.com&#34;&gt;http://www.go-mono.com&lt;/a&gt;) es la implementación libre de la tecnología .NET, capaz de correr en Linux, sistemas *NIX, MacOS, y Windows. Gracias a este proyecto, los usuarios de sistemas *NIX podremos contar con los últimos avances en lo que a tecnología del software se refiere.&lt;/p&gt;
&lt;p&gt;Y es que Mono no es simplemente un compilador y su correspondiente runtime, sino que también se incluyen una serie de utilidades que nos facilitarán mucho la vida a la hora de programar, como un explorador de documentación –&lt;strong&gt;MonoDoc&lt;/strong&gt;-, o un mini servidor web –&lt;strong&gt;XSP&lt;/strong&gt;-, con capacidad de procesar programas escritos para ASP.NET o de ofrecer un servicio web para el resto de Internet, entre otras.&lt;/p&gt;
&lt;p&gt;Además con Mono no estás limitado a un solo lenguaje, sino que puedes programar la parte que más te interese de un proyecto en un determinado lenguaje, programando el resto de éste en otro, facilitando con ello el diseño de rutinas que podrían ser más fáciles de implementar en otros lenguajes. Por el momento puedes programar en C# y VisualBasic.NET, aunque ya se están desarrollando compiladores para otros lenguajes, como puede ser Python o Ruby.&lt;/p&gt;
&lt;p&gt;Esta homogeneidad en los lenguajes se consigue gracias a que un programa escrito para Mono o .NET no se compila directamente a código máquina, sino que es compilado a IL, un lenguaje ensamblador de alto nivel, el cual es traducido por el runtime (JIT) en el momento de la ejecución, realizando las optimizaciones que sean oportunas según el tipo de arquitectura en el que se esté ejecutando el runtime. Este IL tiene sus propia estructura (CLS) y sus propias estructuras de datos (CTS), de forma que los diferentes tipos de datos de los lenguajes .NET, deben ser mapeados a tipos de datos del CTS. Además, y como consecuencia directa de lo anterior, podemos conseguir portabilidad entre arquitecturas y entre sistemas operativos, únicamente con tener en cuenta que no se deben realizar tareas específicas para un determinado entorno (como lecturas de registro, carga de librerías que no estén portadas a otros sistemas, etc.).&lt;/p&gt;
&lt;p&gt;La verdad es que es que aunque es una tecnología que está dando sus primeros pasos, promete ser muy interesante. Y es por ello que, a partir de ahora, me dedicaré a contaros lo que me sea posible en este blog. De momento os recomiendo que os bajeis las fuentes de la página web, lo compileis, y echeis un vistazo a los ejemplos que se incluyen.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>