<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Adobe User Group Granada &#187; artículos</title>
	<atom:link href="http://www.adobe-user-group-granada.es/category/articulos/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adobe-user-group-granada.es</link>
	<description>Grupo de usuarios de Adobe orientado a Dreamweaver y Spry en la ciudad de Granada</description>
	<lastBuildDate>Sat, 21 Jan 2012 19:10:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Progreso de subida de ficheros únicamente con HTML5</title>
		<link>http://www.adobe-user-group-granada.es/progreso-de-subida-de-ficheros-unicamente-con-html5/</link>
		<comments>http://www.adobe-user-group-granada.es/progreso-de-subida-de-ficheros-unicamente-con-html5/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 12:42:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutoriales]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=1023</guid>
		<description><![CDATA[Uno de los mayores problemas con los que nos hemos encontrado a la  hora de hacer aplicaciones que suben ficheros, es mostrar al usuario  cuánto se ha subido y así poder saber cuánto queda. Ahora con HTML5 y  XMLHttpRequest Level 2 podemos mostrarlo sin necesidad de parte del  servidor.
El script hace [...]]]></description>
			<content:encoded><![CDATA[<p>Uno de los mayores problemas con los que nos hemos encontrado a la  hora de hacer aplicaciones que suben ficheros, es mostrar al usuario  cuánto se ha subido y así poder saber cuánto queda. Ahora con HTML5 y  XMLHttpRequest Level 2 podemos mostrarlo sin necesidad de parte del  servidor.</p>
<p>El script hace uso de <a href="http://www.w3.org/TR/progress-events/">Evento de Progreso</a> de HTML5 para poder mostrar:</p>
<ul>
<li><strong>total</strong>: total de bytes</li>
<li><strong>loaded</strong>: bytes subidos</li>
<li><strong>lengthComputable</strong>: indica si el tamaño del fichero es conocido</li>
<li><strong>transferSpeed</strong>: velocidad de transferencia</li>
<li><strong>timeRemaining</strong>: tiempo que falta (en formato Date)</li>
</ul>
<p>Por ahora solo es compatible con Firefox, Chrome y Safari.</p>
<p>En el post lo explican con gran detalle.</p>
<p><a href="http://www.matlus.com/html5-file-upload-with-progress/">Html5 File Upload with Progress </a></p>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/11/19/progreso-de-subida-de-ficheros-unicamente-con-html5.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/progreso-de-subida-de-ficheros-unicamente-con-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guía de supervivencia con Apache</title>
		<link>http://www.adobe-user-group-granada.es/guia-de-supervivencia-con-apache/</link>
		<comments>http://www.adobe-user-group-granada.es/guia-de-supervivencia-con-apache/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 18:31:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[artículos]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutoriales]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=1019</guid>
		<description><![CDATA[El servidor web Apache es uno de los más extendidos y con más opciones de configuración, esto implica que es complejo. Vamos a ver cómo sobrevivir con Apache.


Guía de supervivencia con Apache

Otras veces ya hemos visto como realizar una instalación de Apache con PHP y eAccelerator, una vez instalado los ficheros ejecutables importantes son:

apachectl: Mediante [...]]]></description>
			<content:encoded><![CDATA[<p>El <strong>servidor web Apache</strong> es uno de los más extendidos y con más opciones de configuración, esto implica que es complejo. Vamos a ver <strong>cómo sobrevivir con Apache</strong>.</p>
<p><span id="more-1019"></span></p>
<div id="attachment_3639">
<p><a href="http://systemadmin.es/wp-content/uploads/2011/11/supervivencia-con-Apache.jpg"></a>Guía de supervivencia con Apache</p>
</div>
<p>Otras veces ya hemos visto como realizar una <a href="http://systemadmin.es/2009/08/instalacion-de-un-servidor-lamp-v-apache-con-php-y-eaccelerator">instalación de Apache con PHP y eAccelerator</a>, una vez instalado los ficheros ejecutables importantes son:</p>
<ul>
<li><strong>apachectl</strong>: Mediante este script podremos:
<ul>
<li>Gestionar el arranque y parada del daemon (<strong>start</strong>/<strong>stop</strong>)</li>
<li>Comprobar la configuración (<strong>configtest</strong>):
<pre># /usr/local/apache22/bin/apachectl configtest
Syntax OK</pre>
</li>
<li>Recargar la configuración en caliente, sin apagar el daemon (<strong>graceful</strong>)</li>
</ul>
</li>
<li><strong>httpd</strong>: Binario del daemon, con dicho fichero podemos:
<ul>
<li>Indicar que fichero de configuración cargar (<strong>opción -f</strong>)</li>
<li>Ver el listado de módulos que carga (<strong>opción -M</strong>):
<pre># /usr/local/apache22/bin/httpd -M
Loaded Modules:
 core_module (static)
(...)
 jrun_module (shared)</pre>
</li>
<li>Al igual que con <strong>apachectl</strong>, comprobar la configuración con la <strong>opción -t</strong>:
<pre># /usr/local/apache22/bin/httpd -t
Syntax OK</pre>
</li>
<li>Ver el resumen de configuración de los <strong>VirtualHosts</strong> con la <strong>opción -S</strong>:
<pre># /usr/local/apache22/bin/httpd -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server shuvak.systemadmin.es (/usr/local/apache22/conf/extra/httpd-vhosts.conf:7)
         port 80 namevhost shuvak.systemadmin.es (/usr/local/apache22/conf/extra/httpd-vhosts.conf:7)
         port 80 namevhost systemadmin.es (/usr/local/apache22/conf/extra/vhosts/systemadmin.es.conf:1)
         port 80 namevhost foro.systemadmin.es (/usr/local/apache22/conf/extra/vhosts/foro.systemadmin.es.conf:1)
Syntax OK</pre>
</li>
</ul>
</li>
</ul>
<p>Un ejemplo de <strong>configuración típica de un VirtualHost</strong> sería la siguiente:</p>
<pre>&lt;VirtualHost *:80&gt;
        DocumentRoot "/var/www/systemadmin.es/htdocs"
        DirectoryIndex index.php
        ServerName systemadmin.es
        ServerAlias foro.systemadmin.es

        &lt;Directory /var/www/systemadmin.es/htdocs&gt;
            Options FollowSymLinks
            AllowOverride all
            Order deny,allow
            Allow from all
        &lt;/Directory&gt;

        ErrorLog  "| /usr/local/sbin/cronolog -S /var/www/systemadmin.es/logs/current.error.log /var/www/systemadmin.es/logs/%Y/%m/%d/error.log"
        CustomLog "| /usr/local/sbin/cronolog -S /var/www/systemadmin.es/logs/current.custom.log /var/www/systemadmin.es/logs/%Y/%m/%d/custom.log" combined

&lt;/VirtualHost&gt;</pre>
<p>Las directivas importantes son:</p>
<ul>
<li><strong>DocumentRoot</strong>: Directorio base desde el cual  serviremos el contenido. Deberemos acompañarlo de la directiva Directory  para establecer si se puede servir o no su contenido</li>
<li><strong>DirectoryIndex</strong>: Cuando se intente servir la raíz o  cualquier directorio (sin especificar fichero), cual se debería servir.  Típicamente se usa index.algo, pero podría ser cualquier fichero. Esta  directiva indica que fichero servir y en que orden de prioridad. Por  ejemplo:
<pre>DirectoryIndex index.php index.html index.htm</pre>
<p>Primero miraría si existe un fichero <strong>index.php</strong>, en caso que no exista buscaría el siguiente (<strong>index.html</strong>) y así el listado que indiquemos. En caso que no exista ninguno, <strong>se serviría un 404</strong></li>
<li><strong>ServerName</strong> y <strong>ServerAlias</strong>: Nombres a los que responde según el <a href="http://systemadmin.es/2010/08/especificar-que-host-header-debe-usar-el-curl">header Host</a>. Se pueden <strong>especificar wildcards</strong> tanto pode delante (<strong>*.systemadmin.es</strong>) como por detrás (<strong>webmail.*</strong>). La diferencia entre <strong>ServerName</strong> y <strong>ServerAlias</strong> a la practica tiene poca importancia.</li>
</ul>
<p>En cuanto a la <strong>gestión de logs</strong>, personalmente uso <a href="http://systemadmin.es/2009/01/rotacion-de-logs-de-apache-mediante-cronolog">cronolog</a> ya que una vez configurado cómo queremos almacenar los logs no  deberemos hacer mantenimiento a no se que queramos eliminar los  antiguos. Para ello suelo emplear un simple script que haga limpieza:</p>
<pre>#!/bin/bash
for i in $(find /var/www/ -maxdepth 2 -iname logs);
do

        #eliminacion de los mas antiguos de 10 dias
        find $i -mtime +10 -type f -exec rm {} \;

        #eliminacion de directios vacios
        find $i -empty -type d -exec rmdir {} \; 2&gt;/dev/null

        #compresión de logs ya rotados
        find $i -type f -iname \*\.log -mtime +2 -exec gzip {} \;

done</pre>
<p>Deberemos <strong>adaptar el find del for</strong> para que encuentre los directorios raíz dónde tenemos los logs.</p>
<p>Para conocer el estado del Apache existe el <a href="http://systemadmin.es/2009/02/instalacion-del-server-status-mod_status-de-apache">modulo mod_status</a>, que nos indica que esta haciendo dicho daemon. Generalmente se instala en <strong>/server-staus</strong> con <strong>acceso limitado por IP de origen</strong>.</p>
<p>En el <strong>scoreboard</strong> veremos los estado del los <strong>apachitos</strong> (procesos apache) y podremos ver si existe algún problema con algún VirtualHost. Típicamente podremos ver:</p>
<ul>
<li>Se nos llena el scoreboard de <strong>W</strong>: Cuando un slot esta en estado W significa que esta contestando, pero si vemos que se nos acumulan <strong>W</strong> posiblemente esta contestando muy lentamente por algún motivo o bien  simplemente se queda colgado. Generalmente indica problemas en la base  de datos.Si habilitamos la opción
<pre>ExtendedStatus On</pre>
<p>Tendremos un listado de todas las peticiones y su estado, para cuanto  tiempo lleva un slot en el estado actual deberemos fijarnos en la  columna <strong>SS</strong>. Por lo tanto, las peticiones <strong>en estado W que tenga el SS alto</strong> son las primeras que deberemos investigar. Evidentemente, si servimos contenido estático (un <strong>mp3</strong>) es lógico que tarde en ser entregado y por lo tanto que <strong>su SS sea alto</strong>.</li>
<li>Se nos llena el scoreboard de <strong>K</strong>: Tendremos que ver  si nos interesa reducir el tiempo de KeepAlive de las conexiones. Por  defecto lo tenemos a 5 segundos, pero lo podemos dejar en 1 o 2 segundos  según la aplicación.</li>
</ul>
<p>En otra ocasión ya hablamos de en que debemos fijarnos para <a href="http://systemadmin.es/2010/04/encontrar-la-raiz-del-problema-en-un-entorno-lamp-i">entender el problema que tenga un entorno LAMP</a></p>
<p>Otra cosa a tener en cuenta es la <a href="http://systemadmin.es/2009/04/diferencia-entre-serverlimit-y-maxclients-de-apache">diferencia entre ServerLimit y MaxClients</a>: <strong>ServerLimit</strong> es el límite fijo que no puede ser modificado mediante una recarga de configuración (graceful) mientras que <strong>MaxClients</strong> es el límite actual.</p>
<p>Actualmente <strong>mod_status</strong> no muestra los slots de Apache que quedan deshabilitados por la directiva <strong>MaxClients</strong>, por lo que nos puede dar pie a error al suponerlos libres. En su momento hice un patch para evitar esto y <strong>será incluido en la próxima release de Apache</strong> (2.4), actualmente <a href="http://systemadmin.es/2011/03/apache-2-4-beta-httpd-2-3-11">ya se encuentra disponible en la versión beta desde la versión 2.3.11</a>.</p>
<p>Nuestra fuente: <a href="http://systemadmin.es/2011/11/guia-de-supervivencia-con-apache" target="_blank">Systemadmin</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/guia-de-supervivencia-con-apache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Crear ficheros ZIP mediante Javascript con JSZip</title>
		<link>http://www.adobe-user-group-granada.es/crear-ficheros-zip-mediante-javascript-con-jszip/</link>
		<comments>http://www.adobe-user-group-granada.es/crear-ficheros-zip-mediante-javascript-con-jszip/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 20:16:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[artículos]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=1012</guid>
		<description><![CDATA[Interesante librería que nos permite crear ficheros ZIP desde  Javascript, con unas simples líneas de código podemos crear zips con  ficheros de texto, imágenes, crear directorios…
var zip = new JSZip();
zip.add("Hello.txt", "Hello World\n");
img = zip.folder("images");
img.add("smile.gif", imgData, {base64: true});
content = zip.generate();
location.href="data:application/zip;base64,"+content;
El único problema que hay es a la hora de generar el nombre del  [...]]]></description>
			<content:encoded><![CDATA[<p>Interesante librería que nos permite crear ficheros ZIP desde  Javascript, con unas simples líneas de código podemos crear zips con  ficheros de texto, imágenes, crear directorios…</p>
<pre>var zip = new JSZip();
zip.add("Hello.txt", "Hello World\n");
img = zip.folder("images");
img.add("smile.gif", imgData, {base64: true});
content = zip.generate();
location.href="data:application/zip;base64,"+content;</pre>
<p>El único problema que hay es a la hora de generar el nombre del  fichero: Firefox crea un fichero con un nombre extraño y acabado en  .part, Safari lo nombra “Unknown” sin extensión, Chrome “download.zip” e  IE directamente ni funciona la librería.</p>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/10/06/jszip-crear-ficheros-zip-mediante-javascript.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">SentidoWeb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/crear-ficheros-zip-mediante-javascript-con-jszip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Almacenar la salida de un comando SQL en formato CSV</title>
		<link>http://www.adobe-user-group-granada.es/almacenar-la-salida-de-un-comando-sql-en-formato-csv/</link>
		<comments>http://www.adobe-user-group-granada.es/almacenar-la-salida-de-un-comando-sql-en-formato-csv/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 18:35:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[tutoriales]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=1004</guid>
		<description><![CDATA[El formato CSV resulta muy cómodo tanto de generar  como leer, por eso muchos programas lo aceptan. Se trata simplemente de  valores separados por comas (Comma-Separated Values). Vamos a ver como generar un fichero desde MySQL para almacenar datos.
Para generar el fichero desde un comando SQL en MySQL deberemos indicar INTO OUTFILE con [...]]]></description>
			<content:encoded><![CDATA[<p>El <strong>formato CSV</strong> resulta muy cómodo tanto de generar  como leer, por eso muchos programas lo aceptan. Se trata simplemente de  valores separados por comas (<strong>Comma-Separated Values</strong>). Vamos a ver como generar un fichero desde <strong>MySQL</strong> para almacenar datos.</p>
<p>Para generar el fichero desde un comando <strong>SQL</strong> en <strong>MySQL</strong> deberemos indicar <strong>INTO OUTFILE</strong> con el nombre de fichero y las siguientes opciones:</p>
<ul>
<li><strong>FIELDS TERMINATED BY</strong>: Indicamos como terminan los campos, en este caso deben ser separados por comas <strong>‘,’</strong></li>
<li><strong>OPTIONALLY ENCLOSED BY</strong>: Como se deben indicar en el caso que tengan el separador como valor. En este caso mediante comillas dobles <strong>‘”‘</strong></li>
<li><strong>ESCAPED BY</strong>: Indicamos como debemos escapar los carácteres, en este caso mediante la contrabarra <strong>‘\\’</strong></li>
<li><strong>LINES TERMINATED BY</strong>: Indicamos como especificamos una nueva fila, en este caso mediante un intro <strong>‘\n’</strong></li>
</ul>
<p>Por lo tanto el comando <strong>SQL</strong> quedaría:</p>
<pre>mysql&gt;  select * from loquesea
INTO OUTFILE "/tmp/inventari.txt"
FIELDS TERMINATED BY  ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY  '\\'
LINES TERMINATED BY '\n' from RackObject;
Query OK, 168 rows affected (0.29 sec)</pre>
<p>Nuestra fuente: <a href="http://systemadmin.es/2011/06/almacenar-la-salida-de-un-comando-sql-en-formato-csv" target="_blank">Systemadmin.es</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/almacenar-la-salida-de-un-comando-sql-en-formato-csv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PDF.js librería Javascript para leer PDF en Canvas</title>
		<link>http://www.adobe-user-group-granada.es/pdf-js-libreria-javascript-para-leer-pdf-en-canvas/</link>
		<comments>http://www.adobe-user-group-granada.es/pdf-js-libreria-javascript-para-leer-pdf-en-canvas/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 07:47:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[móviles]]></category>
		<category><![CDATA[pdf]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=1001</guid>
		<description><![CDATA[Interesante librería Javascript que nos permite mostrar en Canvas  (HTML5) el contenido de un PDF. Puede venir muy bien para aplicaciones  móviles, ya que en navegación en escritorio normalmente la gente tiene  instalado un visor de PDFs.

&#60;html&#62;
&#60;head&#62;
  &#60;title&#62;Simple pdf.js page viewer&#60;/title&#62;
  &#60;script type="text/javascript"
        [...]]]></description>
			<content:encoded><![CDATA[<p>Interesante librería Javascript que nos permite mostrar en Canvas  (HTML5) el contenido de un PDF. Puede venir muy bien para aplicaciones  móviles, ya que en navegación en escritorio normalmente la gente tiene  instalado un visor de PDFs.</p>
<p><span id="more-1001"></span></p>
<pre><a href="http://december.com/html/4/element/html.html">&lt;html&gt;</a>
<a href="http://december.com/html/4/element/head.html">&lt;head&gt;</a>
  <a href="http://december.com/html/4/element/title.html">&lt;title&gt;</a>Simple pdf.js page viewer&lt;/title&gt;
  <a href="http://december.com/html/4/element/script.html">&lt;script</a> type="text/javascript"
          src="pdf.js"&gt;&lt;/script&gt;
  <a href="http://december.com/html/4/element/style.html">&lt;style</a> type"text/css"&gt;
body {
  margin: 6px;
  padding: 0px;
  background-color: #c0bdb7;
}
#controls {
  border-bottom: 1px solid black;
  position:fixed;
  left: 0px; top: 0px;
  width: 100%;
  padding: 7px;
  background-color: rgb(242, 240, 238);
}
span#info {
  float: right;
  font: 14px sans-serif;
  margin-right: 10px;
}
#viewer {
  margin: auto;
  border: 1px solid black;
  width: 8.5in;
  height: 11in;
}
#pageNumber {
  text-align: right;
}
  &lt;/style&gt;

<a href="http://december.com/html/4/element/script.html">&lt;script</a> type="text/javascript"&gt;
function queryParams() {
    var qs = window.location.search.substring(1);
    var kvs = qs.split("&amp;");
    var params = { };
    for (var i = 0; i &lt; kvs.length; ++i) {
        var kv = kvs[i].split("=");
        params[unescape(kv[0])] = unescape(kv[1]);
    }
    return params;
}

var canvas, numPages, pageDisplay, pageNum;
function load() {
    canvas = document.getElementById("canvas");
    canvas.mozOpaque = true;
    pageDisplay = document.getElementById("pageNumber");
    infoDisplay = document.getElementById("info");
    pageNum = parseInt(queryParams().page) || 1;
    fileName = queryParams().file || "compressed.tracemonkey-pldi-09.pdf";
    open(fileName);
}

function open(url) {
    document.title = url;
    req = new XMLHttpRequest();
    req.open("GET", url);
    req.mozResponseType = req.responseType = "arraybuffer";
    req.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200;
    req.onreadystatechange = xhrstate;
    req.send(null);
}

function xhrstate() {
    if (req.readyState == 4 &amp;&amp; req.status == req.expected) {
        var data = req.mozResponseArrayBuffer ||
                   req.mozResponse ||
                   req.responseArrayBuffer ||
                   req.response;
        pdf = new PDFDoc(new Stream(data));
        numPages = pdf.numPages;
        document.getElementById("numPages").innerHTML = numPages.toString();
        gotoPage(pageNum);
    }
}

function displayPage(num) {
    pageDisplay.value = num;

    var t0 = Date.now();

    var page = pdf.getPage(pageNum = num);

    var t1 = Date.now();

    var ctx = canvas.getContext("2d");
    ctx.save();
    ctx.fillStyle = "rgb(255, 255, 255)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.restore();

    var gfx = new CanvasGraphics(ctx);

    // page.compile will collect all fonts for us, once we have loaded them
    // we can trigger the actual page rendering with page.display
    var fonts = [];
    page.compile(gfx, fonts);

    var t2 = Date.now();

    // This should be called when font loading is complete
    page.display(gfx);

    var t3 = Date.now();

    infoDisplay.innerHTML = "Time to load/compile/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + " ms";
}

function nextPage() {
    if (pageNum &lt; numPages)
        ++pageNum;
    displayPage(pageNum);
}

function prevPage() {
    if (pageNum &gt; 1)
        --pageNum;
    displayPage(pageNum);
}
function gotoPage(num) {
    if (0 &lt;= num &amp;&amp; num &lt;= numPages)
        pageNum = num;
    displayPage(pageNum);
}
  &lt;/script&gt;
&lt;/head&gt;

<a href="http://december.com/html/4/element/body.html">&lt;body</a> onload="load();"&gt;
  <a href="http://december.com/html/4/element/div.html">&lt;div</a> id="controls"&gt;
    <a href="http://december.com/html/4/element/button.html">&lt;button</a> onclick="prevPage();"&gt;Previous&lt;/button&gt;
    <a href="http://december.com/html/4/element/button.html">&lt;button</a> onclick="nextPage();"&gt;Next&lt;/button&gt;
    <a href="http://december.com/html/4/element/input.html">&lt;input</a> type="text" id="pageNumber" onchange="gotoPage(this.value);"
           value="1" size="4"&gt;&lt;/input&gt;
    / <a href="http://december.com/html/4/element/span.html">&lt;span</a> id="numPages"&gt;--&lt;/span&gt;
    <a href="http://december.com/html/4/element/span.html">&lt;span</a> id="info"&gt;&lt;/span&gt;
  &lt;/div&gt;
  <a href="http://december.com/html/4/element/div.html">&lt;div</a> id="viewer"&gt;
    &lt;!-- Canvas dimensions must be specified in CSS pixels.  CSS pixels
      -- are always 96 dpi.  These dimensions are 8.5x11in at 96dpi. --&gt;
    &lt;canvas id="canvas" width="816" height="1056"&gt;&lt;/canvas&gt;
  &lt;/div&gt;
&lt;/body&gt;

&lt;/html&gt;</pre>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/06/15/pdf-js-libreria-javascript-para-leer-pdf-en-canvas.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/pdf-js-libreria-javascript-para-leer-pdf-en-canvas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Popcorn.js librería Javascript que permite sincronizar vídeo y contenido en HTML5</title>
		<link>http://www.adobe-user-group-granada.es/popcorn-js-libreria-javascript-que-permite-sincronizar-video-y-contenido-en-html5/</link>
		<comments>http://www.adobe-user-group-granada.es/popcorn-js-libreria-javascript-que-permite-sincronizar-video-y-contenido-en-html5/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 18:00:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=992</guid>
		<description><![CDATA[Popcorn.js es una librería que permite sincronizar la etiqueta &#60;video&#62; de HTML5 con contenido que deseemos mostrar. Para ello utiliza las propiedades, métodos y eventos nativos de HTMLMediaElement. Además ofrece un sistema de plugins desarrollados por la comunidad:

document.addEventListener("DOMContentLoaded", function () {
      // Create a popcporn instance by calling Popcorn("#id-of-my-video")
  [...]]]></description>
			<content:encoded><![CDATA[<p>Popcorn.js es una librería que permite sincronizar la etiqueta &lt;video&gt; de HTML5 con contenido que deseemos mostrar. Para ello utiliza las propiedades, métodos y eventos nativos de HTMLMediaElement. Además ofrece un sistema de plugins desarrollados por la comunidad:</p>
<p><code></p>
<pre>document.addEventListener("DOMContentLoaded", function () {
      // Create a popcporn instance by calling Popcorn("#id-of-my-video")
      var pop = Popcorn("#video");
      // play the video right away
      pop.play()
      // add a footnote at 2 seconds
        .footnote({
          start: 2,
          end: 6,
          text: "This footnote is the stepping stone of progress!",
          target: "footnotediv"
        });
    }, false);</pre>
<p></code><br />
Podéis ver algunos <a href="http://popcornjs.org/demos">ejemplos</a> bastante interesantes. Una librería muy útil para presentaciones y vídeos corporativos.</p>
<p><a href="http://popcornjs.org/">Popcorn.js</a></p>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/06/08/popcorn-js-libreria-javascript-que-permite-sincronizar-video-y-contenido-en-html5.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/popcorn-js-libreria-javascript-que-permite-sincronizar-video-y-contenido-en-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Librería PHP para TwitPic</title>
		<link>http://www.adobe-user-group-granada.es/libreria-php-para-twitpic/</link>
		<comments>http://www.adobe-user-group-granada.es/libreria-php-para-twitpic/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 10:14:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[redes sociales]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=989</guid>
		<description><![CDATA[TwitPic es un servicio que se utiliza para subir fotos que luego publicas en Twitter. Si estás realizando una aplicación que tira de Twitter y quieres dar la oportunidad al usuario de subir sus fotos puedes hacer uso de esta aplicación y su API (es necesario darse de alta):


$twitpic = new TwitPic($api_key, $consumer_key, $consumer_secret, $oauth_token, [...]]]></description>
			<content:encoded><![CDATA[<p>TwitPic es un servicio que se utiliza para subir fotos que luego publicas en Twitter. Si estás realizando una aplicación que tira de Twitter y quieres dar la oportunidad al usuario de subir sus fotos puedes hacer uso de esta aplicación y su API (es necesario darse de alta):</p>
<p><span id="more-989"></span></p>
<p><code></p>
<pre>$twitpic = new TwitPic($api_key, $consumer_key, $consumer_secret, $oauth_token, $oauth_secret);
try {
  /*
  * Retrieves all images where the user is facetagged
  */
  $user = $twitpic-&gt;faces-&gt;show(<a href="http://www.php.net/array">array</a>('user'=&gt;'meltingice'));
  <a href="http://www.php.net/print_r">print_r</a>($user-&gt;images);

  $media = $twitpic-&gt;media-&gt;show(<a href="http://www.php.net/array">array</a>('id'=&gt;1234));
  <a href="http://www.php.net/echo">echo</a> $media-&gt;message;

  $user = $twitpic-&gt;users-&gt;show(<a href="http://www.php.net/array">array</a>('username'=&gt;'meltingice'), <a href="http://www.php.net/array">array</a>('process'=&gt;false, 'format'=&gt;'xml'));
  <a href="http://www.php.net/echo">echo</a> $user; // raw XML response data

  /*
  * Uploads an image to TwitPic
  */
  $resp = $twitpic-&gt;upload(<a href="http://www.php.net/array">array</a>('media'=&gt;'path/to/file.jpg', 'message'=&gt;'This is an example'));
  <a href="http://www.php.net/print_r">print_r</a>($resp);

  /*
  * Uploads an image to TwitPic AND posts a tweet
  * to Twitter.
  *
  * NOTE: this still uses v2 of the TwitPic API. This means that the code makes 2 separate
  * requests: one to TwitPic for the image, and one to Twitter for the tweet. Because of this,
  * understand this call may take a bit longer than simply uploading the image.
  */
  $resp = $twitpic-&gt;uploadAndPost(<a href="http://www.php.net/array">array</a>('media'=&gt;'path/to/file.jpg', 'message'=&gt;'Another example'));
  <a href="http://www.php.net/print_r">print_r</a>($resp);

} catch (TwitPicAPIException $e) {
  <a href="http://www.php.net/echo">echo</a> $e-&gt;getMessage();
}</pre>
<p></code><br />
<a href="https://github.com/meltingice/TwitPic-API-for-PHP">TwitPic API for PHP</a></p>
<p>Nuestra fuente: <a title="Libreria PHP para TwitPic" href="http://sentidoweb.com/2011/05/31/libreria-php-para-twitpic.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/libreria-php-para-twitpic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL en modo bootstrap (similar a single user)</title>
		<link>http://www.adobe-user-group-granada.es/mysql-en-modo-bootstrap-similar-a-single-user/</link>
		<comments>http://www.adobe-user-group-granada.es/mysql-en-modo-bootstrap-similar-a-single-user/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 17:59:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=980</guid>
		<description><![CDATA[Una opción interesante del mysqld es la opción –bootstrap, esta se usa para inicializar la base de datos sin arrancar totalmente la instancia. Vamos a ver como funciona y como podemos usarla para tener el MySQL en un modo similar a lo que sería el single user de Unix.
Con dicha opción –bootstrap arranca el mínimo de la instancia sin tener [...]]]></description>
			<content:encoded><![CDATA[<p>Una opción interesante del <strong>mysqld</strong> es la opción<strong> –bootstrap</strong>, esta se usa para inicializar la base de datos sin arrancar totalmente la instancia. Vamos a ver como funciona y como podemos usarla para tener el <strong>MySQL</strong> en un modo similar a lo que sería el <strong>single user</strong> de Unix.</p>
<p>Con dicha <strong>opción –bootstrap</strong> arranca el mínimo de la instancia <strong>sin tener disponible ni el socket ni el puerto TCP</strong> para conexiones de clientes, sino que <strong>únicamente se comunica con el usuario por stdin</strong>.</p>
<p>Por lo tanto, deberemos pasar los comandos que queremos que ejecute. Cuando le mandemos el <strong>EOF</strong>, se cerrará la base de datos y terminará la aplicación. Por ejemplo, con el <strong>MySQL</strong> apagado ejecutamos el <strong>mysqld</strong> con la opción <strong>bootstap</strong> y le mandamos crear una base de datos:</p>
<p><span id="more-980"></span></p>
<pre><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; white-space: pre;"># /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --bootstrap</span>
create database test_single_user;</pre>
<p>Finalizando la entrada de comandos con <strong>control-D</strong> (<strong>EOF</strong>).</p>
<p>Una vez arranquemos de nuevo el <strong>MySQL</strong> normalmente, podremos comprobar como se ha ejecutado el comando que hemos indicado:</p>
<pre># mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.10-log Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test_single_user   |
+--------------------+
4 rows in set (0.00 sec)

mysql&gt;</pre>
<p>Evidentemente, podemos ejecutar más de un comando, siendo de esta forma una buena manera de ejecutar ciertas operaciones delicadas que no queremos que <strong>nadie nos pueda molestar</strong>:</p>
<pre># /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --bootstrap
use test_single_user
create table a2 as select * from a1;</pre>
<p>Nuestra fuente:  <a href="http://systemadmin.es/2011/04/mysql-en-modo-bootstrap-similar-a-single-user" target="_blank">systemadmin.es</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/mysql-en-modo-bootstrap-similar-a-single-user/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MathJax: librería javascript para mostrar fórmulas matemáticas</title>
		<link>http://www.adobe-user-group-granada.es/mathjax-libreria-javascript-para-mostrar-formulas-matematicas/</link>
		<comments>http://www.adobe-user-group-granada.es/mathjax-libreria-javascript-para-mostrar-formulas-matematicas/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 19:09:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=974</guid>
		<description><![CDATA[MathJax es una librería javascript que permite mostrar fórmulas LaTeX y MathML en nuestras páginas. Es compatible con casi todos los navegadores (menos IE5.5 lógicamente), permite copiar el código TeX y MathML de la página, utiliza fuentes CSS y no imágenes o Flash y muchas cosas más.


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;title&#62;MathJax TeX Test Page&#60;/title&#62;
&#60;script type="text/x-mathjax-config"&#62;
  MathJax.Hub.Config({tex2jax: {inlineMath: [...]]]></description>
			<content:encoded><![CDATA[<p><strong>MathJax</strong> es una librería javascript que permite mostrar fórmulas LaTeX y MathML en nuestras páginas. Es compatible con casi todos los navegadores (menos IE5.5 lógicamente), permite copiar el código TeX y MathML de la página, utiliza fuentes CSS y no imágenes o Flash y muchas cosas más.<br />
<span id="more-974"></span></p>
<pre><code>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;MathJax TeX Test Page&lt;/title&gt;
&lt;script type="text/x-mathjax-config"&gt;
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\(','\)']]}});
&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/04/22/mathjax-libreria-javascript-para-mostrar-formulas-matematicas.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/mathjax-libreria-javascript-para-mostrar-formulas-matematicas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tres grandes tutoriales sobre HTML5</title>
		<link>http://www.adobe-user-group-granada.es/tres-grandes-tutoriales-sobre-html5/</link>
		<comments>http://www.adobe-user-group-granada.es/tres-grandes-tutoriales-sobre-html5/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 13:30:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[artículos]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.adobe-user-group-granada.es/?p=949</guid>
		<description><![CDATA[HTML5 Rocks ha publicado 3 tutoriales muy interesantes sobre desarrollo de HTML5.
El primero de ellos trata sobre cómo mejorar el rendimiento de las aplicaciones en HTML5, a parte de alguna que es puramente Javascript y no HTML5 (como guardar en una variable un elemento DOM y no buscarlo cada vez que vayamos usarlo), la mayoría [...]]]></description>
			<content:encoded><![CDATA[<p>HTML5 Rocks ha publicado 3 tutoriales muy interesantes sobre desarrollo de HTML5.</p>
<p>El primero de ellos trata sobre cómo mejorar el rendimiento de las aplicaciones en HTML5, a parte de alguna que es puramente Javascript y no HTML5 (como guardar en una variable un elemento DOM y no buscarlo cada vez que vayamos usarlo), la mayoría de ellas trata sobre el uso de transiciones CSS3 por parte del navegador y no mediante el uso de Javascript, ya que así sería el navegador el que se encargue de ello y pueda optimizar su ejecución, por ejemplo:</p>
<blockquote>
<pre>var elem = evt.target;
  // Modernizr es una librerÃ­a que nos indica que elementos CSS3 y HTML5 dispone el navegador
  if (Modernizr.csstransforms &amp;&amp; Modernizr.csstransitions) {
    // Mediante CSS3
    elem.style.transition = 'all 3s ease-out';
    elem.style.transform = 'translateX(600px)';
  } else {
    // Mediante jQuery
    jQuery(elem).animate({ 'left': '600px'}, 3000);
  }</pre>
</blockquote>
<p>El siguiente tutorial nos indica cómo meterle efectos CSS3 a nuestros textos, y la verdad es que alguno está muy currado. Claro que yo no soy muy partidario de usarlos según que tipo de publicación (se puede abusar mucho de ello), pero la verdad es que nos puede venir muy bien.<br />
Y por último consejos HTML5 y CSS para convertir nuestra web a formato adaptado para móviles. Algunos trucos de rencimiento como el uso del almacenamiento local y algo bastante interesante cómo indicar la orientación o el viewport de la página:</p>
<blockquote>
<pre>&lt;meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"&gt;
&lt;meta name=viewport content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0"&gt;
&lt;meta name="viewport" content="target-densitydpi=device-dpi"&gt;</pre>
</blockquote>
<p>Nuestra fuente: <a href="http://sentidoweb.com/2011/03/08/tres-grandes-tutoriales-sobre-html5.php?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+sentidoweb+%28Sentido+Web%29&amp;utm_content=Google+International" target="_blank">Sentidoweb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adobe-user-group-granada.es/tres-grandes-tutoriales-sobre-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

