Crea notificaciones para Firefox con el Addon SDK

Hace unos días he publicado un artículo acerca de los Primeros pasos con el Addon SDK, el cual explica todo lo sencillo para tener listo y empezar a crear un Addon desde cero. Ahora como primer ejemplo enseñare como crear esa especie de barra de notificación que algunas veces nos aparece en Firefox avisándonos que nos falta algún plugin o que Firefox ha evitado que se abriera una ventana emergente. No es cosa de loco crearla y personalizarla a nuestro gusto. Al final de este articulo de seguro que sabrás como crear tus propias barras de notificaciones para darle mas personalidad a tus Addons o Just for fun! 🙂

Como primera medida es necesario que tengas claro y hallas cumplido con los pasos y detalles mencionados en este artículo. Y una vez que ya tengas todos los archivos generados para tu Addon siguiendo el articulo anterior, tendrás esta estructura que empezaras a editar:

* lib  
* data 
* test 
* doc 
* README.md 
* package.json 
* test/test-main.js 
* lib/main.js 
* doc/main.md

Nuestro archivo lib/main.js es el mas importante de todos, es el centro de comando de nuestro Addon, así que lo editamos y le escribimos la siguiente estructura:

var self = require("self");
var notification = require("notification-box").NotificationBox({
'value': 'important-message',
'label': 'Estas avisado',
'priority': 'WARNING_HIGH',
'image': self.data.url("gnu-icon.png"),
'buttons': [{'label': "Entiendo",
'onClick': function () { console.log("Has tocado algo importante!"); }}]
});

Como vemos no es gran cosa, ni nada del otro mundo, es algo muy sencillo y que parece bastante lógico de entender, es una estructura nada compleja. En el contenido del archivo main.js si nos fijamos en la segunda linea en donde dice require(«notification-box»), hablamos de que necesitamos una librería aparte para que todo pueda funcionar en el mismo directorio de donde se encuentra el main.js.

Nuestro lib/notification-box.js se ve de la siguiente manera:

"use strict";

const { Cc, Ci } = require("chrome");
const { getMostRecentBrowserWindow } = require('api-utils/window/utils');

let isString = function (str) {
return typeof(str) == 'string' || str instanceof String;
};

let isArray = function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};

exports.NotificationBox = function (options) {
options = options || {};
let mainWindow = getWindow();
let nb = mainWindow.gBrowser.getNotificationBox();
let notification, priority, label, image, value, buttons = [];

if (options.value && isString(options.value)) {
notification = nb.getNotificationWithValue(options.value);
value = options.value;
}
else {
notification = nb.getNotificationWithValue('');
value = '';
}

if (options.label && isString(options.label))
label = options.label;
else
label = "";

if (options.priority && options.priority in PRIORITY)
priority = nb[PRIORITY[options.priority]];
else
priority = nb[PRIORITY.INFO_LOW];

if (options.image && isString(options.image))
image = options.image;
else
image = 'chrome://browser/skin/Info.png';

if (isArray(options.buttons)) {
for (let i = 0, length = options.buttons.length; i < length; i++) {
buttons.push(NotificationButton(options.buttons[i]));
}
}
else if (typeof(options.buttons) === 'object') {
buttons.push(NotificationButton(options.buttons));
}
else {
buttons = null;
}

nb.appendNotification(label, value,
image,
priority, buttons);
return notification;
};

var NotificationButton = function (options) {

options = options || {};
let accessKey, onClick, label, popup;

if (options.accessKey)
accessKey = options.accessKey;
else
accessKey = '';

if (options.onClick)
onClick = options.onClick;
else
onClick = function () {};

if (options.label)
label = options.label;
else
label = "";

popup = null;

return {label: label,
accessKey: accessKey,
callback: onClick,
popup: popup};

};

const PRIORITY = {
'INFO_LOW': 'PRIORITY_INFO_LOW',
'INFO_MEDIUM': 'PRIORITY_INFO_MEDIUM',
'INFO_HIGH': 'PRIORITY_INFO_HIGH',
'WARNING_LOW': 'PRIORITY_WARNING_LOW',
'WARNING_MEDIUM': 'PRIORITY_WARNING_MEDIUM',
'WARNING_HIGH': 'PRIORITY_WARNING_HIGH',
'CRITICAL_LOW': 'PRIORITY_CRITICAL_LOW',
'CRITICAL_MEDIUM': 'PRIORITY_CRITICAL_MEDIUM',
'CRITICAL_HIGH': 'PRIORITY_CRITICAL_HIGH',
'CRITICAL_BLOCK': 'PRIORITY_CRITICAL_BLOCK'
};

let getWindow = function () {
return getMostRecentBrowserWindow();
};

exports.PRIORITY = PRIORITY;

De hecho estas librerías y pequeñas adiciones muchas veces no son necesarias que las crees tu o que te rompas el coco haciéndolas, aunque son divertidas y sencillas de hacer, tenemos un directorio repleto de todo tipo de librerías listas para ser usadas que puedes agregar y usar fácilmente.

Ademas de la libreria notification-box.js adicional, si nos fijamos en nuestro archivo principal el main.js en la linea sexta linea nos encontramos con self.data.url(icon.png»), lo cual nos pide que en nuestra carpeta data tengamos una imagen con el nombre de icon.png.

Nuestra imagen icon.png es esta:

https://i0.wp.com/i.imgur.com/8F8LFvn.png

Luego modificamos nuestro archivo package.json con algunas de nuestras preferencias, tendríamos algo como esto:

{
    "name": "notification-example", 
    "license": "MPL 2.0", 
    "author": "Gioyik", 
    "version": "0.1", 
    "fullName": "notification-example", 
    "id": "jid1-dyFGGJB0CjoDMA", 
    "description": "un ejemplo de notificacion en un Addon"
}

Podemos modificarlo a nuestro gusto, son apenas unos pocos campos a rellenar y cambiar a preferencia. Finalmente ejecutamos el siguiente comando para ver como va quedando nuestro Addon:

cfx run

Nos mostrará algo como esto:

https://i0.wp.com/i.imgur.com/uEyvqqR.png

Vemos que todo nos esta saliendo tal cual lo queríamos, ahora como ya esta todo listo, si el resultado nos ha convencido y queremos empaquetar nuestro Addon en un xpi para instalarlo en donde queramos, simplemente ejecutamos:

cfx xpi

Sencillo! Ya se nos ha generado nuestro XPI para que lo ejecutamos y compartamos con quien queramos. Ademas, todo este procedimiento que he realizado en todo el articulo puedes descargarlo desde uno de mis Repos en Github.

Anuncio publicitario

Primeros pasos con el Addon SDK

Una de las cosas mas importantes en Firefox en cuanto a personalización por parte del Desarrollador – Usuarios son los Addons, por eso mismo hoy he decidido hacer una pequeña guía de como instalar y configurar el Addon SDK para su primer uso.

  • Requisitos del Addon SDK

El Addon SDK es una gran utilidad, tal vez muchos ya lo han usado, aunque tal vez otros no. No necesitamos de una maquina muy grande para usarlo, simplemente necesitamos cumplir estos requisitos:

  • Python 2.5 o 2.6 (a mi me sirve con el 2.7 también). Las versiones 3.0 y 3.1 de Python no son soportadas, así que no te esfuerces, ni te lleves dolores de cabeza haciéndolo correr con estas versiones.
  • Una versión de Firefox compatible. (No se muy bien que versión de Firefox no es compatible, o para mi, incapaz de corre el Addon SDK, sin embargo tengan en cuenta este paso).
  • La versión del Addon SDK en tarball o zip file, la que mejor les parezca. O si desean la versión en desarrollo también pueden obtenerla desde su repo en GitHub.
  • Instalación del Addon SDK

Una vez que tengamos todo esto listo, procederemos a descomprimir el archivo comprimido que descargamos del Addon SDK, de la manera que nos quede mas cómoda, ya sea en Windows, Linux o Mac. Simplemente descomprimimos el paquete. 😉

Ahora para activar el Addon SDK usaremos los siguiente comandos según sea nuestro sistema operativo:

  • Linux / MacOS X

Entramos al directorio en donde descomprimimos el Addon SDK desde la terminal:

cd addon-sdk

Y desde allí, ejecutamos el binario con el siguiente comando:

source bin/activate

Y en tu consola o terminal veras algo como esto:

(addon-sdk)~/mozilla/addon-sdk >
  • Windows

Igualmente entramos al directorio en donde descomprimimos el Addon SDK desde la consola de Windows (cmd):

cd addon-sdk

Y desde allí, ejecutamos el archivo .bat para activar el Addon SDK, con el siguiente comando:

bin\activate.bat

Y en tu consola veras algo como esto:

(C:\Users\mozilla\sdk\addon-sdk) C:\Users\Work\sdk\addon-sdk>

Como ven, hay ciertos cambios dependiendo de la plataforma pero el resultado es el mismo. Ahora para saber si el Addon SDK se ha ejecutado correctamente, simplemente corremos en nuestra terminal o consola el siguiente comando:

cfx

Y no mostraría algo como esto:

Usage: cfx [options] [command]

Ya tenemos todo para empezar a trabajar en el código de nuestro Addon a crear. Ahora una de las utilidades que posee el Addon SDK es que con un comando te genera la estructura básica que debe tener el Addon nuevo que crearás. Esto nos adelante mucho trabajo, aunque no es la cosa mayor, es bueno contar con estas herramientas que nos ahorra algo de tiempo.

  • Crear el lugar de trabajo de nuestro Addon

Simplemente creamos el directorio en donde trabajaremos con nuestro Addon, ya sea desde el Explorador de archivos que tengas o desde la terminal, yo lo haré desde la terminal así que ejecutare lo siguiente:

mkdir my-addon

Entramos en el directorio o carpeta que acabamos de crear:

cd my-addon

Y para que nos cree todo los archivos basicos que necesitamos para iniciar, ejecutamos:

cfx init

Y la consola o terminal nos mostrara los siguiente:

* lib directory created
* data directory created
* test directory created
* doc directory created
* README.md written
* package.json written
* test/test-main.js written
* lib/main.js written
* doc/main.md written

Your sample add-on is now ready for testing:
      try "cfx test" and then "cfx run". Have fun!"

Sencillo no? Aunque no es todo. Todos lo Addons tienen un id en los archivos que genera Addon SDK, este id se encuentra vacío en el archivo package.json, asi que lo tienes que modificar y poner el id que quieras manualmente con un editor de texto. PERO! si quieres evitarte abrir el editor y modificarlo manualmente, puedes hacerlo a la manera mas sencilla posible, una vez que ya hallas hecho cfx init anteriormente y se hallan generado los archivos base para que crees tu Addon, simplemente ejecuta:

cfx run

La consola te mostrará algo como esto:

No 'id' in package.json: creating a new ID for you.
package.json modified: please re-run 'cfx run'

Lo que quiere decir, que si revisas tu archivo package.json una vez más y en la linea en donde aparecía el campo id vacío, ahora se te ha generado automáticamente gracias a ese comando un id aleatorio y ya tendrás todo listo para empezar a crear Addons!

Este ha sido apenas un articulo de como configurar e instalar correctamente el Addon SDK, mas adelante habrán artículos en donde aprendas a crear widgets o paneles, ademas como sacarle todo el provecho a la Addon bar de Firefox. Nos leemos en el próximo articulo.

WebActivity SMS en acción

Hoy, he querido hablar acerca de una de las WebActivities que tan popularmente están de moda, que a mi parecer es muy interesante trabajarla, ya que nos da un vistazo de lo que podemos hacer con el poder de la web y nuestros smartphones que vienen equipados con Firefox para Android (Que para estas fechas son la gran mayoría) y los próximos a lanzarse con FirefoxOS.

Aquí tenemos un ejemplo simple y concreto de como funciona esta WebActivity, como quedaría el código en nuestro archivo .js en donde declararíamos nuestro hermoso Javascript:

var sendSMS = document.querySelector("#send-sms");
if (sendSMS) {
    sendSMS.onclick = function () {
        var sms = new MozActivity({
            name: "new",
            data: {
                type: "websms/sms",
                number: "+57123456789"
                }
            });
     }
}

Si vemos el código es muy sencillo y bastante claro, modificarlo es muy practico. Lo que nos resta es agregar nuestro botón que activara la Webactivity de SMS, con algo parecido a esto:

<button id="send-sms">Send SMS</button>

Seguramente el código de su HTML tendrá una estructura distinta y su botón sera distinto, pero lo pueden aplicar simplemente agregando el id=»send-sms» a su etiqueta y funcionara igual. Ademas de no olvidar de agregar nuestro archivo .js en donde escribimos toda la función de nuestra WebActivity al principio del HTML con la etiqueta <script>, pero bueno son cosas que posiblemente ya debes tener hechas o debes saber. Otra forma de ver en acción esta y otras WebActivities puedes probar el FirefoxOS Boilerplate App.

Como podemos ver es una estructura limpia y clara, las posibilidades con esta y las demás WebActivities parecen infinitas. Próximamente escribiré algunos artículos en donde veamos esta WebActivity y otras mas a profundidad.

Empezando con Rust

Hace algunos días Mozilla hacia el anuncio de Servo, su nuevo trabajo en compañía de Samsung para las arquitecturas ARM. Lo que mas ha llamado la atención es que para este nuevo proyecto el lenguaje de programación que se usaría principalmente no seria ni C, ni python, ni Perl, ni alguno de los tan conocidos lenguajes de programación a los cuales estamos tan acostumbrados programar. Seria Rust el que tenga los créditos esta vez.

Como todo lo nuevo no siempre es malo, hoy quiero darles una pequeña introducción al manejo y funcionamiento de Rust, como para sacar conclusiones a nivel Dev y no solo lo que podamos leer y suponer.

Rust

https://i0.wp.com/www.rust-lang.org/logos/rust-logo-128x128-blk.png

  • Instalar Rust en nuestros equipos:

Esta no es una parte complicada a decir verdad es un parte sencilla ya que muchas de las dependencias de las que necesita Rust son comunes tenerlas instaladas en nuestro equipo, podemos detallar un poco mas esta parte aqui, pero si repasamos un poco las dependencias no resulta ser algo del otro mundo, veamos:

  • g++ 4.4 or clang++ 3.x
  • python 2.6 or later (but not 3.x)
  • perl 5.0 or later
  • gnu make 3.81 or later
  • curl

Nada del otro mundo cierto? Encontraremos mas detalles de como correr Rust en nuestros equipos aquí, ya que tratare de no enfocarme en ello y pasar al código que es lo que quiero mostrar.

  • Nuestro primer programa en Rust

Rust genera un archivo .rs que a final de cuentas no es nada del otro mundo encontrarnos con extensiones nuevas para nuestros ficheros y archivos de salida. Ahora tenemos el archivo hola.rs que contiene lo siguiente:

fn main() {
    io::println("hola gio");
}

Si Rust esta instalado por completo y funcionando correctamente podremos correr nuestro archivo hola.rs con este sencillo comando:

rustc hola.rs

Lo cual nos generará un archivo binario llamado hola o hola.exe (Para Windows), el cual mostrara tal cual lo que esperas ver. Rust trata de dar una información completa sobre lo que ha salido mal, así que por ejemplo, llegado el caso de que Rust encuentre una función inexistente en el código te mostrara algo como esto:

hello.rs:2:4: 2:16 error: unresolved name: io::print_with_unicorns
hello.rs:2     io::print_with_unicorns("hola gio");

Siendo nuestro código erróneo para este caso el siguiente:

fn main() {
    io::print_with_unicorns("hola gio");
}

Interesante esta parte y es una de las que mas me llama la atención. Es muy importante que hallan cambios que tras de ser pequeños, hagan la diferencia a los desarrolladores que se arriesguen a probarlo.

Rust nos ofrece de igual forma herramientas para ejecutar nuestro archivo hola.rs sin tener que compilarlo, simplemente usando el comando:

rust run hola.rs

Asombroso parace su funcionamiento, aunque no es algo del otro mundo, claro esta. Para saber todas las funcionanlidades y prefijos de Rust puedes consultarlos ejecutando desde tu terminal el comando:

rust
  • Sintaxis en Rust

Si en algún momento hemos programado en C o en lenguajes como C++, Java, JavaScript, C#, o PHP, Rust no sera nada nuevo y complicado para ti. En Rust para las estructuras también puedes usar if y while para llamar funciones podemos usar myfunc(arg1, arg2); casi todo esta estructurado como lo encontraríamos en C; incluso si queremos comentar nuestro código también lo haríamos como lo hacemos con el código que tenemos en C. Veamos un pequeño ejemplo de como va la estructura con Rust:

fn main() {
    /* A simple loop */
    loop {
        // A tricky calculation
        if universe::recalibrate() {
            return;
        }
    }
}

Fácil no? De hecho nos encontramos con una estructura en el código muy conocida ya, lo que nos permite integrarnos y manejar muy bien Rust, aquellos que estamos acostumbrados al bueno y conocido C. Tenemos una documentación muy amplia sobre las estructuras, funciones y demás cosas con las que podemos trabajar en Rust, todo lo podremos encontrar aquí. No pienso extenderme mucho en este articulo porque a la mayoría de nosotros nos gusta ver cosas minimistas y simples que nos muestren resultados. Mas adelante tendré otros artículos en donde explique nuevas cosas y aplique código generando algunos demos, pero por ahora ha sido todo.

Rust aun sigue en desarrollo y es posible que cambie bastante de aquí a que llegue a algo estable, sin embargo funciones y comandos básicos como los que he mencionado en este articulo son poco probables que lleguen a cambiar o ha ser modificados en un futuro. Sin embargo, siempre estaré pendiente de cambios y mejoras que les pueda comentar y/o anunciar.

Que tiene Firefox 20 para los desarrolladores

Bueno, con el lanzamiento de Firefox 20 el pasado 2 de Abril de 2013, nos encontramos con algunas mejoras y cambios que quiero tengan en cuenta, como:

HTML5

  • Ha sido agregado el soporte del atributo download en las etiquetas <a><area>
  • Ha sido implementado el el valor auto al atributo dir

Javascript

  • Ha sido agregado el soporte para el método Weakmap.prototype.clear()recientemente agregado a Harmony (EcmaScript 6)
  • Soporte para el método Math.imul() , en una función C-style 32-bit. Ha sido propuesto para Harmony (EcmaScript 6), de hecho no ha sido aceptado ni estandarizado.
  • Web apps usando texto con Kinetic 3.x están funcionando ahora, incluso si usan Cairo canvas.
  • La sentencia for each…in ha sido declarada obsoleta y no deberías usarla. Considera usar mejor la nueva sentencia for…of.

CSS

  • CSS Flexbox ahora esta disponible por defecto solo en pre-release builds (excluyendo Beta). Puede ser activada desde las preferencias de about:config.
  • Ha sido agregada la propieda mask-type de CSS Masking specification.

DOM

  • HTMLMediaElement soporta ahora playbackRate (para leer y escribir), con pitch correction. Pitch correction puede ser controlado usando la propiedad mozPreservesPitch.
  • CSSOM: Ha sido agregado el soporte para CSSGroupingRule y CSSConditionRule.
  • CSSOM: En CSSRule la constante CSSRule.MOZ_KEYFRAME_RULE y CSSRule.MOZ_KEYFRAMES_RULE ha sido unprefixed para CSSRule.KEYFRAME_RULE y CSSRule.KEYFRAMES_RULE.
  • CSSOM: Ahora es posible usar el valor de conditionText para CSSMediaRule.
  • En DOMParser el parseFromStream y parseFromBuffer ya son son disponibles para los contenidos web.
  • En XMLSerializer el serializeToStream ya no esta disponible para los contenidos web.
  • TextDecoder y TextEncoder ahora están disponibles en Workers.
  • El soporte de CSS.supports() ha sido agregado.
  • Soporte para UndoManager ha sido agregado.
  • En CSSOM el document.caretPositionFromPoint que lanza CaretPosition ha sido implementado.

Addons

  • Para ayudar a los autores de MathML al hacer debugging sobre los errores «invalid-markup» en sus documentos, ahora MathML parsea errores y advertencias acerca de atributos obsoletos o atributos incorrectos en la Error Console.
  • El atributo scriptminsize ahora acepta valores sin unidades y valores con porcentajes. Son interpretados como múltiples valores del valor por defecto que es («8pt»).
  • Valores sin unidades ahora son aceptados por los atributos mathsize y fontsize; ellos multiplican el valor por defecto.

Bueno esto ha sido todo por ahora, este es un vistazo a los cambios que se han hecho en la versión 20 de Firefox. Nos veremos en otro articulo como este mas adelante, en el próximo lanzamiento de Firefox.

Menciones por el DevDerby :)

Bueno, unos momentos despues de saber que habia ganado el DevDerby y de difundir yo la noticia por todas las redes sociales 😀 he recibido algunas menciones y he aquí algunas de ellas:

De nuevo, muchísimas gracias, todos me animan a continuar! Aaaa y les he contado que apareceré en el proximo Q&A session en Mozilla Hacks? Bueno pues ahora ya lo saben! 🙂

Gioyik en Mozilla Hacks

Bueno he aquí el artículo que salió en el Blog de Mozilla Hacks, les cito el articulo:

Last month, web developers young and old showed us what they could do with Geolocation in the September Dev Derby contest. After looking through the entries, our three expert judges–David Walsh, Joe Stagner and John Hammink–have decided on our top picks.

Not a contestant? There are many other reasons to be excited. Most importantly, all of these demos are completely open-source, making them wonderful lessons in the exciting things you can do with Geolocation today.

Dev Derby

Winners

Runners-up

You may have noticed that Meet me there also ended in the top three last month. This marks a first for the Dev Derby. Because Patrick used both the Camera API and Geolocation in his demo, it was eligible for both contests. As if that weren’t interesting enough, this was one of the closest Derbies we have ever held, with GoGeoTweet and Around the World ending in a virtual photo finish.

Deciding on just a few winners is always difficult, so let’s not forget about our other amazing contestants. Every one of these participants has pushed this important mobile technology forward in ways we never imagined, and deserves a great deal of praise for doing so. I look forward to seeing what they create next.

Want to get a head start on an upcoming Derby? We are now accepting demos related to the CSS Media Queries (October), the Full Screen API (November) and offline technologies (December). Head over to the Dev Derby to get started.

Increible no? Yo aun no me las creo! 😀

¡Ganador del DevDerby del mes de Septiembre!

Hoy vengo escribiéndoles con una hermosa sonrisa en mi rostro que refleja una emoción incomparable y es gracias a que después de tanto trabajo y dedicación, mi primera vez concursando en el DevDerby de Mozilla he salido ganador en el primer puesto. Gracias a uno de los 3 demos que envié para dicho concurso y es «GoGeoTweet» (Tengo que aceptarlo, nunca pensé ganar con ese demo!)

Ha sido increíble y definitivamente lo mejor que hasta el momento he podido conseguir, aunque de por si también he conseguido bastantes méritos igualmente. Pero aceptemoslo, un dispositivo móvil para el primer puesto del Derby no esta nada mal eh?

4º Mención en Quality de Mozilla

Bueno una ves mas he salido en un Post en el planet de Quality de Mozilla, gracias no solo a la participación mia, si no el apoyo y presencia de Mozilla Hispano en estos. De hecho no fue mucho lo que colaboré (Lo digo porque no lo registre pero si ayude bastante con los Bugs en Bugzilla) pero siempre con el honor despues de una mención allí, una ves mas cito el Post del planet:

10/05 Testday Results

Last Friday we had a Firefox 17 Aurora testday. Together we tested the most recent Firefox features, Improve Display of Location Bar Results and HTML Tree Editor. We ran tests, investigated existing issues, and filed new ones. More details are available in the Test Plan.

Many thanks to all those who contributed to the testday – davids, fedepad, Aleksej, Gioyik, MiguelDavidQ, gaby2300, and FireChemist – and to all our moderators.

We look forward to seeing you in our next testdays. Keep an eye on QMO for details!

Esperemos que este proximo TestDay este cargado de mis aportes y con otra mencion en el Planet. 🙂

Otra mención en Quality

https://i0.wp.com/i.imgur.com/km353.jpg

El día viernes participe en el TestDay y como buen colaborador me faje un poco con el Etherpad, y gracias a esto me ha dado otra gratificante mención en un Post del Planet de Quality, se las cito:

Results of the Flash 11.4 Beta Testday

Last week on Friday we organized a testday to have people dogfood the latest beta version of Flash 11.4. I want to thank everyone who came out and helped. In particular, I’d like to thank Alex Mayorga and Gioyik for volunteering their time to help us try to identify problems with the upcoming Flash and Firefox versions.

If you missed the testday, we could still use your help in dogfooding Flash 11.4. Feel free to find me in the #qa channel on IRC to get involved (my nick is ashughes).

Our next testday will be this Friday, August 24, where we’ll be testing Web Apps in Firefox for Android. Please come out and help if you have time.

Thank you!

Definitivamente cada vez esto se pone mejor, y de por si crecen cada día mas mis aspiraciones a colaborar en estos TestDays.