<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Algo::rithmique</title>
  <link rel="alternate" type="text/html" href="http://algorithmique.net/" />
  <link rel="self" type="application/atom+xml" href="http://algorithmique.net/atom.xml" />
  <id>http://algorithmique.net/atom.xml</id>
  <updated>2010-03-11T17:48:25Z</updated>
  <subtitle>Algo::rithmique | [Why not ?]</subtitle>

  
  <entry>
    <title>RConsole</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2010/03/11/rconsole.html' />
    <id>http://algorithmique.net/Projets/2010/03/11/rconsole</id>
    <updated>2010-03-11T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;
  &lt;img src=&quot;/images/rConsole.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;
  Cela fait un bout de temps que je devais passer un peu de temps à tester &lt;a href=&quot;http://macruby.org&quot;&gt;MacRuby&lt;/a&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt;. C'est chose faite par le biais d'une nouvelle application (et donc d'un nouveau projet) : &lt;b&gt;RConsole&lt;/b&gt;.
&lt;/p&gt;

&lt;h2&gt;La genèse&lt;/h2&gt;
&lt;p&gt;
	Si vous êtes comme moi, il doit vous arriver, de temps en temps, de faire des scripts Ruby &lt;i&gt;post-it&lt;/i&gt;. C'est ce genre de petit script que l'on fait pour tester une chose en particulier et qui finit généralement sous forme de &lt;a href=&quot;http://gist.github.com/&quot;&gt;Gist&lt;/a&gt;. Pour faire cela, il existe plusieurs solutions. La plus courante étant certainement d'utiliser &lt;tt&gt;IRB&lt;/tt&gt;. Le problème, qu'y en découle, est le fait qu'il est difficile de faire des modifications. Il faut en effet à chaque fois retaper tout le code. Pour peu que celui-ci fasse plusieurs lignes, cela devient rapidement énervant. Une autre solution pour les utilisateurs de &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; consiste à placer le code dans un fichier et à l'exécuter directement depuis l'éditeur via un ⌘R. Cette dernière solution est plus simple, à condition &lt;a href=&quot;/Projets/2009/12/21/bye-bye-textmate-bonjour-coda.html&quot;&gt;d'utiliser TextMate&lt;/a&gt; et de ne pas avoir peur de se créer un répertoire de scripts que l'on oubliera de nettoyer de temps en temps. Bref, vous l'aurez compris, tout cela ne me plait pas beaucoup.
&lt;/p&gt;

&lt;p&gt;
	Comme vous le savez, je suis très &lt;a href=&quot;/Projets/2009/07/20/menugems.html&quot;&gt;flemmard&lt;/a&gt;. Et cela ne va pas en s'arrangeant... Et j'ai donc passé une petite soirée à développer une solution qui me va très bien. L'idée est d'avoir une fenêtre contenant un &lt;i&gt;pseudo&lt;/i&gt;éditeur de code, code que l'on pourra exécuter et voir le résultat, sans quitter l'application, sans perdre du temps à le sauvegarder on ne sais ou... Tout ceci donne &lt;b&gt;RConsole&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;center&gt;&lt;img src=&quot;/images/posts/rconsole_main.png&quot;&gt;&lt;/center&gt;
&lt;/p&gt;

&lt;h2&gt;Utilisation&lt;/h2&gt;
&lt;p&gt;
	Comme vous pouvez le voir sur la capture ci-dessus, &lt;b&gt;RConsole&lt;/b&gt; se présente sous forme d'une simple fenêtre permettant de taper un bout de code. Il suffit ensuite de cliquer sur le bouton &lt;tt&gt;Run&lt;/tt&gt; (ou de faire un ⌘R) pour afficher le résultat de la sortie standard et/ou la sortie d'erreur.
&lt;/p&gt;

&lt;p&gt;
	&lt;center&gt;&lt;img src=&quot;/images/posts/rconsole_output.png&quot;&gt;&lt;/center&gt;
&lt;/p&gt;

&lt;p&gt;
	Si vous utilisez plusieurs interpréteurs Ruby, vous pouvez les déclarer dans les préférences de l'application.
&lt;/p&gt;

&lt;p&gt;
	&lt;center&gt;&lt;img src=&quot;/images/posts/rconsole_prefs.png&quot;&gt;&lt;/center&gt;
&lt;/p&gt;

&lt;p&gt;
	Vous pouvez alors, via la boite de sélections située en haut à gauche de la fenêtre principale, choisir l'interpréteur à utiliser.
&lt;/p&gt;

&lt;p&gt;
	Souvenez-vous qu'il s'agit d'un simple outil de test, inutile donc d'espérer sauvegarder le code dans un fichier en vue d'une réutilisation ultérieure. Si c'est là votre besoin, reprenez votre éditeur favori.
&lt;/p&gt;

&lt;h2&gt;MacRuby&lt;/h2&gt;
&lt;p&gt;
	Comme je l'ai dit, ce petit outil a été développé avec &lt;a href=&quot;http://macruby.org&quot;&gt;MacRuby&lt;/a&gt;. Plutôt habitué à utiliser &lt;a href=&quot;http://rubycocoa.sourceforge.net&quot;&gt;RubyCocoa&lt;/a&gt;, je dois bien avouer que j'ai été véritablement bluffé par MacRuby. Il est beaucoup plus proche de Cocoa et donc beaucoup plus agréable à utiliser pour qui aime ce framework. C'est véritablement le mariage idéal entre Ruby et Cocoa !
&lt;/p&gt;

&lt;p&gt;
	Seul petit regret, qui s'excuse rapidement, MacRuby ne couvre pas encore totalement l'implémentation de Ruby (1.9). Un exemple : pour l'exécution du code, je souhaitais utiliser &lt;a href=&quot;http://ruby-doc.org/stdlib/libdoc/open3/rdoc/index.html&quot;&gt;Open3&lt;/a&gt;&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt;. Malheureusement, dans la version 0.6 (&lt;a href=&quot;http://macruby.icoretech.org/&quot;&gt;nightly build&lt;/a&gt;), &lt;tt&gt;Open3&lt;/tt&gt; n'est pas implémenté, simplement parce qu'il utilise &lt;tt&gt;Kernel#spawn&lt;/tt&gt; qui n'est lui-même pas implémenté... Mon positivisme me poussant à dire que cela me promet de belles évolutions à faire ;)
&lt;/p&gt;

&lt;p&gt;
	Je ne devrais pas tarder à publier RConsole sur &lt;a href=&quot;http://github.com/glejeune&quot;&gt;Github&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
	Parmi les petites choses que je voudrais y ajouter, il y a la possibilité de poster le code sous forme de &lt;a href=&quot;http://gist.github.com/&quot;&gt;Gist&lt;/a&gt;. Si de votre côté vous voyez d'autres choses, n'hésitez pas à m'en faire part !
&lt;/p&gt;

&lt;p&gt;
	&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; Autrement qu'en faisant un &lt;i&gt;Hello World!&lt;/i&gt;&lt;/small&gt;&lt;br /&gt;
	&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt; En doux réveur, j'espérait pouvoir utiliser &lt;a href=&quot;http://github.com/ujihisa/open5&quot;&gt;Open5&lt;/a&gt;, mais la encore, MacRuby ne le permet pas.&lt;/small&gt;
&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Mini Taj Mahal Lego</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2010/03/07/mini-taj-mahal-lego.html' />
    <id>http://algorithmique.net/Projets/2010/03/07/mini-taj-mahal-lego</id>
    <updated>2010-03-07T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;
  J'ai profité de ce weekend de fin de vacances (pour les enfants) pour me faire un petit &lt;a href=&quot;http://shop.lego.com/Product/Factory/Default.aspx?cn=301&quot;&gt;Design By Me&lt;/a&gt; Lego&lt;sup&gt;&amp;copy;&lt;/sup&gt;. Voici le plan, étape par étape. Pour ceux qui voudraient se vider le cerveau en passant à la construction, voici le fichier &lt;a href=&quot;/images/posts/MiniTaj.lxf&quot;&gt;LXF&lt;/a&gt; à utiliser avec &lt;a href=&quot;http://ldd.lego.com/&quot;&gt;LEGO Degital Designer&lt;/a&gt;. Sachez que vous pouvez commander ce modèle (pour 58,29 €) directement depuis LDD. Pour ma part, je ne manquerai pas de poster une photo du résultat dès que j'aurais reçu la boite ;)
&lt;/p&gt;


&lt;div id=&quot;lddContainer&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelNameContainer&quot;&gt;
			&lt;div id=&quot;modelTextMain&quot;&gt;
				&lt;ul&gt;
				&lt;li class=&quot;modelText&quot;&gt;&lt;p&gt;Model Name: &lt;span style=&quot;font-weight:bold&quot;&gt;Mini Taj Mahal&lt;/span&gt;&lt;br /&gt;Number of Bricks: &lt;span style=&quot;font-weight:bold&quot;&gt;464&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
				&lt;li class=&quot;modelImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step127.png&quot; /&gt;&lt;/li&gt;
				&lt;/ul&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;		
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 0&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step0.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 1&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick0.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick1.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step1.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 2&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick0.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick3.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step2.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 3&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step3.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 4&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick4.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick3.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step4.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 5&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick4.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick3.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step5.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 6&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick4.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick3.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step6.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 7&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step7.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 8&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step8.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 9&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step9.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 10&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step10.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 11&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step11.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 12&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick9.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step12.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 13&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick11.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick9.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step13.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 14&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step14.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 15&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick11.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick12.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step15.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 16&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step16.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 17&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step17.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 18&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step18.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 19&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step19.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 20&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step20.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 21&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick2.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step21.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 22&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step22.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 23&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step23.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 24&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step24.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 25&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick9.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step25.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 26&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick9.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step26.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 27&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick13.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick14.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step27.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 28&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step28.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 29&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step29.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 30&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick17.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick12.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step30.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 31&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick14.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step31.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 32&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick13.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step32.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 33&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick17.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick12.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step33.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 34&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick17.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick18.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step34.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 35&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick13.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step35.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 36&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick14.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step36.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 37&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step37.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 38&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick20.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step38.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 39&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick21.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick22.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step39.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 40&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick9.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step40.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 41&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick13.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick14.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step41.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 42&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step42.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 43&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick22.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step43.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 44&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick23.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick24.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick22.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step44.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 45&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick24.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step45.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 46&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick21.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick24.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step46.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 47&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick24.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step47.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 48&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick24.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step48.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 49&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step49.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 50&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step50.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 51&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step51.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 52&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step52.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 53&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step53.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 54&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step54.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 55&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step55.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 56&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step56.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 57&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick19.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step57.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 58&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step58.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 59&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick26.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step59.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 60&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick29.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step60.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 61&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step61.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 62&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step62.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 63&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step63.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 64&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick29.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step64.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 65&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick23.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step65.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 66&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step66.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 67&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick29.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step67.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 68&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;4 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step68.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 69&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick32.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step69.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 70&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step70.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 71&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step71.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 72&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick32.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step72.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 73&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;4 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step73.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 74&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick16.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick6.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step74.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 75&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick32.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick29.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step75.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 76&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick32.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step76.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 77&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step77.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 78&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step78.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 79&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick33.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step79.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 80&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step80.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 81&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick25.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step81.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 82&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step82.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 83&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step83.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 84&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step84.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 85&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step85.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 86&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step86.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 87&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick34.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick8.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step87.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 88&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick35.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick34.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick36.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step88.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 89&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick35.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick36.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step89.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 90&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick35.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick36.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step90.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 91&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick35.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step91.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 92&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick36.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step92.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 93&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step93.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 94&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick37.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick27.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step94.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 95&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick38.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick39.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step95.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 96&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick38.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick39.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step96.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 97&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step97.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 98&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step98.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 99&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step99.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 100&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step100.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 101&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step101.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 102&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick31.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step102.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 103&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;4 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step103.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 104&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;4 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step104.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 105&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick43.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step105.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 106&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick15.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick43.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step106.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 107&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick44.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick45.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step107.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 108&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick5.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick44.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick45.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step108.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 109&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step109.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 110&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step110.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 111&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick7.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick10.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick30.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;4 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step111.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 112&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step112.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 113&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step113.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 114&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step114.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 115&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;5 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step115.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 116&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step116.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 117&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step117.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 118&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step118.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 119&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;5 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step119.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 120&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step120.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 121&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step121.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 122&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step122.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 123&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;5 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step123.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 124&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;2 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step124.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 125&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step125.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 126&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step126.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	
	&lt;tr&gt;&lt;td&gt;
		&lt;div id=&quot;modelStepContainer&quot;&gt;
			&lt;div class=&quot;stepTextTop&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-weight:bold&quot;&gt;Step 127&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;div id=&quot;modelParts&quot;&gt;
				&lt;ul&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;5 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick40.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick42.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick41.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;3 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick28.png&quot; /&gt;&lt;/li&gt;
					&lt;li class=&quot;stepText&quot;&gt;&lt;p&gt;1 x&lt;/p&gt;&lt;/li&gt;
					&lt;li&gt;&lt;img height=&quot;64&quot; width=&quot;64&quot; src=&quot;/images/posts/minitaj/Brick46.png&quot; /&gt;&lt;/li&gt;

				&lt;/ul&gt;
			&lt;/div&gt;
			&lt;div class=&quot;stepImage&quot;&gt;&lt;img height=&quot;300&quot; width=&quot;400&quot; src=&quot;/images/posts/minitaj/Step127.png&quot; /&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/td&gt;&lt;/tr&gt;	


&lt;/table&gt;	
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title>Déployer une application Capcode dans un serveur d'application Java</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2010/01/27/deployer-une-application-capcode-dans-un-serveur-dapplication-java.html' />
    <id>http://algorithmique.net/Projets/2010/01/27/deployer-une-application-capcode-dans-un-serveur-dapplication-java</id>
    <updated>2010-01-27T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;
    &lt;img src=&quot;/images/projets.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;
    Depuis la naissance de &lt;a href=&quot;http://github.com/glejeune/Capcode&quot;&gt;Capcode&lt;/a&gt;, je l'ai pas mal utilisé dans le cadre de mon travail. Je pense que ce petit framework arrive à maturité, ce qui devrait être (j'espère) prouvé avec la sortie de la version 1.0. Jusque-là, outre les inévitables corrections de bugs, je ne prévois pas d'ajouter de nouvelle fonctionnalité majeure pour me concentrer sur les problématiques de déploiement. Ce travail a déjà été initié en &lt;a href=&quot;http://wiki.github.com/glejeune/Capcode/deploy-with-phusion-passenger&quot;&gt;validant l'utilisation de Capcode avec Passenger&lt;/a&gt;. Je vous propose aujourd'hui de compléter ce chapitre en regardant comment déployer une application Capcode dans un serveur d'application Java.
  &lt;/p&gt;

  &lt;h2&gt;JRuby-Rack et Warbler&lt;/h2&gt;  
  
  &lt;p&gt;
    &lt;tt&gt;JRuby-Rack&lt;/tt&gt; est un adaptateur vous permettant d'exécuter une application basée sur Rack dans un container d'application Java. Tout cela sans rien changer au code de votre application. &lt;tt&gt;Warbler&lt;/tt&gt; quant à lui est un gem qui vous permet de créer un fichier &lt;tt&gt;war&lt;/tt&gt; pour votre application Ruby. Le premier est une dépendance du second, et nous nous concentrerons donc sur ce dernier.
  &lt;/p&gt;
  
  &lt;h2&gt;Préparer l'application&lt;/h2&gt;
  
  &lt;p&gt;
    Afin de vous montrer que la &lt;i&gt;solution &lt;tt&gt;Warbler&lt;/tt&gt;&lt;/i&gt; n'impose pratiquement aucun changement dans l'application, je vais partir de l'exemple REST présent &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/&quot;&gt;dans les sources de Capcode&lt;/a&gt;.
  &lt;/p&gt;
  
  &lt;p&gt;
    Cet exemple est composé de deux fichiers : &lt;tt&gt;rest.rb&lt;/tt&gt; et &lt;tt&gt;rest.ru&lt;/tt&gt;. Le premier est le coeur de l'application. Le second est un fichier de configuration pour &lt;tt&gt;rackup&lt;/tt&gt;. Cela tombe bien, car ce sont justement les deux éléments nécessaires pour utiliser &lt;tt&gt;JRuby-Rack&lt;/tt&gt;. 
  &lt;/p&gt;
  
  &lt;p&gt;
    Dans les &lt;a href=&quot;http://github.com/nicksieger/jruby-rack/tree/master/examples/&quot;&gt;exemples&lt;/a&gt; qui accompagnent les sources de &lt;tt&gt;JRuby-Rack&lt;/tt&gt;, il semble y avoir une habitude pour l'organisation des sources. Le fichier de configuration de &lt;tt&gt;rackup&lt;/tt&gt; (nommé &lt;tt&gt;config.ru&lt;/tt&gt;) étant placé à la racine, le fichier de l'application est dans un répertoire &lt;tt&gt;lib&lt;/tt&gt; et il existe un répertoire &lt;tt&gt;config&lt;/tt&gt; dans lequel se trouve un fichier &lt;tt&gt;warble.rb&lt;/tt&gt;. Si nous suivons ce modèle, nous devons donc faire trois petits changements :
  &lt;/p&gt;
  
  &lt;ol&gt;
    &lt;li&gt;
      Réorganiser les fichiers de l'application de façon à obtenir ceci :
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;rest
|-- README_FIRST
|-- config
|-- rest.ru
&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- lib
    &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- rest.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
    &lt;/li&gt;
    &lt;li&gt;Ayant placé le fichier &lt;tt&gt;rest.rb&lt;/tt&gt; dans le répertoire &lt;tt&gt;lib&lt;/tt&gt;, nous devons légèrement modifier le fichier &lt;tt&gt;rest.ru&lt;/tt&gt; de façon à ce qu'il charge non plus &lt;tt&gt;rest&lt;/tt&gt; mais &lt;tt&gt;lib/rest&lt;/tt&gt;. Nous passons donc de ceci :
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rest&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Capcode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
      A cela :
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;./lib/rest&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Capcode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
    &lt;/li&gt;
    &lt;li&gt;Enfin, nous renommons le fichier &lt;tt&gt;rest.ru&lt;/tt&gt; en &lt;tt&gt;config.ru&lt;/tt&gt;.&lt;/li&gt;
  &lt;/ol&gt;
  
  &lt;p&gt;
    Il nous manque maintenant le fameux fichier &lt;tt&gt;warble.rb&lt;/tt&gt;. Ce fichier peut être généré automatiquement par &lt;tt&gt;Warbler&lt;/tt&gt;. Ce dernier est, en effet, une surcouche de &lt;tt&gt;rake&lt;/tt&gt; :
  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;warble -T
rake config             &lt;span class=&quot;c&quot;&gt;# Generate a configuration file to customize your war assembly&lt;/span&gt;
rake pluginize          &lt;span class=&quot;c&quot;&gt;# Unpack warbler as a plugin in your Rails application&lt;/span&gt;
rake version            &lt;span class=&quot;c&quot;&gt;# Display version of warbler&lt;/span&gt;
rake war                &lt;span class=&quot;c&quot;&gt;# Create rest.war&lt;/span&gt;
rake war:app            &lt;span class=&quot;c&quot;&gt;# Copy all application files into the .war&lt;/span&gt;
rake war:clean          &lt;span class=&quot;c&quot;&gt;# Clean up the .war file and the staging area&lt;/span&gt;
rake war:exploded       &lt;span class=&quot;c&quot;&gt;# Create an exploded war in the app&amp;#39;s public directory&lt;/span&gt;
rake war:gems           &lt;span class=&quot;c&quot;&gt;# Unpack all gems into WEB-INF/gems&lt;/span&gt;
rake war:jar            &lt;span class=&quot;c&quot;&gt;# Run the jar command to create the .war&lt;/span&gt;
rake war:java_classes   &lt;span class=&quot;c&quot;&gt;# Copy java classes into the .war&lt;/span&gt;
rake war:java_libs      &lt;span class=&quot;c&quot;&gt;# Copy all java libraries into the .war&lt;/span&gt;
rake war:public         &lt;span class=&quot;c&quot;&gt;# Copy all public HTML files to the root of the .war&lt;/span&gt;
rake war:war:java_libs  &lt;span class=&quot;c&quot;&gt;# Copy all java libraries into the .war&lt;/span&gt;
rake war:webxml         &lt;span class=&quot;c&quot;&gt;# Generate a web.xml file for the webapp&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;
    Il suffit donc de lancer la commande &lt;tt&gt;warble config&lt;/tt&gt; pour obtenir le fichier &lt;tt&gt;config/warble.rb&lt;/tt&gt;. Cette commande se contente de copier le fichier &lt;tt&gt;warble.rb&lt;/tt&gt; situé dans le répertoire &lt;tt&gt;generators/warble/templates/&lt;/tt&gt; du gem Warbler dans le répertoire &lt;tt&gt;config&lt;/tt&gt; de notre projet. Regardons donc ce qu'il contient :
  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Disable automatic framework detection by uncommenting/setting to false&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Warbler.framework_detection = false&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Warbler web application assembly configuration file&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Warbler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Temporary directory where the application is staged&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.staging_dir = &amp;quot;tmp/war&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Application directories to be included in the webapp.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(app config lib log vendor tmp)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Additional files/directories to include, above those in config.dirs&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.includes = FileList[&amp;quot;db&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Additional files/directories to exclude&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.excludes = FileList[&amp;quot;lib/tasks/*&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Additional Java .jar files to include.  Note that if .jar files are placed&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# in lib (and not otherwise excluded) then they need not be mentioned here.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# JRuby and JRuby-Rack are pre-loaded in this list.  Be sure to include your&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# own versions if you directly set the value&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.java_libs += FileList[&amp;quot;lib/java/*.jar&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Loose Java classes and miscellaneous files to be placed in WEB-INF/classes.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.java_classes = FileList[&amp;quot;target/classes/**.*&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# One or more pathmaps defining how the java classes should be copied into&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# WEB-INF/classes. The example pathmap below accompanies the java_classes&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# configuration above. See http://rake.rubyforge.org/classes/String.html#M000017&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# for details of how to specify a pathmap.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.pathmaps.java_classes &amp;lt;&amp;lt; &amp;quot;%{target/classes/,}p&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;33&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Gems to be included. You need to tell Warbler which gems your application needs&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# so that they can be packaged in the war file.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# The Rails gems are included by default unless the vendor/rails directory is present.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;36&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems += [&amp;quot;activerecord-jdbcmysql-adapter&amp;quot;, &amp;quot;jruby-openssl&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems &amp;lt;&amp;lt; &amp;quot;tzinfo&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;38&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;39&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Uncomment this if you don&amp;#39;t want to package rails gem.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;40&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems -= [&amp;quot;rails&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;41&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;42&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# The most recent versions of gems are used.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;43&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# You can specify versions of gems by using a hash assignment:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;44&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems[&amp;quot;rails&amp;quot;] = &amp;quot;2.0.2&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;45&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;46&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# You can also use regexps or Gem::Dependency objects for flexibility or&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;47&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# fine-grained control.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;48&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems &amp;lt;&amp;lt; /^merb-/&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;49&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.gems &amp;lt;&amp;lt; Gem::Dependency.new(&amp;quot;merb-core&amp;quot;, &amp;quot;= 0.9.3&amp;quot;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;50&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;51&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Include gem dependencies not mentioned specifically&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;52&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gem_dependencies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;53&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;54&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Files to be included in the root of the webapp.  Note that files in public&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;55&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# will have the leading &amp;#39;public/&amp;#39; part of the path stripped during staging.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;56&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.public_html = FileList[&amp;quot;public/**/*&amp;quot;, &amp;quot;doc/**/*&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;57&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;58&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Pathmaps for controlling how public HTML files are copied into the .war&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;59&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.pathmaps.public_html = [&amp;quot;%{public/,}p&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;60&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;61&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Name of the war file (without the .war) -- defaults to the basename&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;62&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# of RAILS_ROOT&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;63&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.war_name = &amp;quot;mywar&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;64&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;65&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Name of the MANIFEST.MF template for the war file. Defaults to the&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;66&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# MANIFEST.MF normally generated by `jar cf`.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;67&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.manifest_file = &amp;quot;config/MANIFEST.MF&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;68&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;69&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Value of RAILS_ENV for the webapp -- default as shown below&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;70&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.rails.env = ENV[&amp;#39;RAILS_ENV&amp;#39;] || &amp;#39;production&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;71&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;72&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Application booter to use, one of :rack, :rails, or :merb. (Default :rails)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;73&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.booter = :rails&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;74&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;75&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# When using the :rack booter, &amp;quot;Rackup&amp;quot; script to use.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;76&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# The script is evaluated in a Rack::Builder to load the application.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;77&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Examples:&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;78&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.rackup = %{require &amp;#39;./lib/demo&amp;#39;; run Rack::Adapter::Camping.new(Demo)}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;79&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.rackup = require &amp;#39;cgi&amp;#39; &amp;amp;&amp;amp; CGI::escapeHTML(File.read(&amp;quot;config.ru&amp;quot;))&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;80&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;81&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Control the pool of Rails runtimes. Leaving unspecified means&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;82&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# the pool will grow as needed to service requests. It is recommended&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;83&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# that you fix these values when running a production server!&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;84&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.jruby.min.runtimes = 2&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;85&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.jruby.max.runtimes = 4&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;86&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;87&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# JNDI data source name&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;88&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# config.webxml.jndi = &amp;#39;jdbc/rails&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;
    Vous me permettrez de faire l'impasse sur le détail complet des paramètres de ce fichier pour me concentrer uniquement sur ceux nécessaires dans le cas d'un déploiement d'application Capcode.
  &lt;/p&gt;
  
  &lt;p&gt;
    Ce fichier de configuration est prévu pour servir de base dans le cas d'une application Rails. Ainsi à la ligne 10, nous retrouvons la liste des répertoires d'une telle application. Dans notre cas, le seul répertoire utile est &lt;tt&gt;lib&lt;/tt&gt;. Nous remplacerons donc cette ligne par ceci :
  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(lib)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;
    Juste en dessous, nous avons le paramètre &lt;tt&gt;include&lt;/tt&gt; permettant de lister les fichiers devant être ajoutés dans la webapp. Dans notre cas, seul le fichier &lt;tt&gt;config.ru&lt;/tt&gt; est à prendre en compte. Nous ajoutons donc la ligne suivante :
  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;includes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FileList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;config.ru&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Les lignes 33 à 49 vous expliquent comment préciser la dépendance de gem pour faire fonctionner notre application. Dans notre exemple, nous en avons besoin de trois : &lt;tt&gt;Capcode&lt;/tt&gt;, &lt;tt&gt;capcode-render-markaby&lt;/tt&gt; et &lt;tt&gt;mime-types&lt;/tt&gt;. La dépendance avec &lt;tt&gt;mime-types&lt;/tt&gt; étant directement héritée de Capcode. Nous ajoutons donc la ligne suivante dans le fichier :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gems&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Capcode&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode-render-markaby&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mime-types&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Si vous continuez la lecture, vous verrez que le paramètre &lt;tt&gt;gem_dependencies&lt;/tt&gt; est par défaut positionné à &lt;tt&gt;true&lt;/tt&gt;. Ce qui indique que les dépendances de gem non spécifiées seront également prises en compte.&lt;/p&gt;
  
  &lt;p&gt;Les lignes 72-73 nous montrent comment indiquer le type de &lt;i&gt;laucher&lt;/i&gt; à utiliser. Ce choix se faut entre &lt;tt&gt;rack&lt;/tt&gt;, &lt;tt&gt;rails&lt;/tt&gt; ou &lt;tt&gt;merb&lt;/tt&gt;. Capcode étant basé sur &lt;tt&gt;rack&lt;/tt&gt;, nous positionnerons ce paramètre de la façon suivante :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gems&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Capcode&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode-render-markaby&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mime-types&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Et voilà. Nous sommes prêts à créer la webapp. Pour cela rien de plus simple :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;warble
mkdir -p tmp/war/WEB-INF/gems/specifications
cp /Library/Ruby/Gems/1.8/specifications/Capcode-0.9.2.gemspec tmp/war/WEB-INF/gems/specifications/Capcode-0.9.2.gemspec
mkdir -p tmp/war/WEB-INF/gems/gems
cp /Library/Ruby/Gems/1.8/specifications/rack-1.1.0.gemspec tmp/war/WEB-INF/gems/specifications/rack-1.1.0.gemspec
cp /Library/Ruby/Gems/1.8/specifications/mime-types-1.16.gemspec tmp/war/WEB-INF/gems/specifications/mime-types-1.16.gemspec
cp /Library/Ruby/Gems/1.8/specifications/capcode-render-markaby-0.2.0.gemspec tmp/war/WEB-INF/gems/specifications/capcode-render-markaby-0.2.0.gemspec
cp /Library/Ruby/Gems/1.8/specifications/Markaby-0.6.5.gemspec tmp/war/WEB-INF/gems/specifications/Markaby-0.6.5.gemspec
cp /Library/Ruby/Gems/1.8/specifications/builder-2.1.2.gemspec tmp/war/WEB-INF/gems/specifications/builder-2.1.2.gemspec
mkdir -p tmp/war/WEB-INF/lib
cp lib/rest.rb tmp/war/WEB-INF/lib/rest.rb
cp config.ru tmp/war/WEB-INF/config.ru
cp /Library/Ruby/Gems/1.8/gems/warbler-0.9.14/lib/jruby-rack-0.9.5.jar tmp/war/WEB-INF/lib/jruby-rack-0.9.5.jar
cp /Library/Ruby/Gems/1.8/gems/warbler-0.9.14/lib/jruby-rack-0.9.5.jar tmp/war/WEB-INF/lib/jruby-rack-0.9.5.jar
cp /Library/Ruby/Gems/1.8/gems/jruby-jars-1.4.0/lib/jruby-core-1.4.0.jar tmp/war/WEB-INF/lib/jruby-core-1.4.0.jar
cp /Library/Ruby/Gems/1.8/gems/jruby-jars-1.4.0/lib/jruby-core-1.4.0.jar tmp/war/WEB-INF/lib/jruby-core-1.4.0.jar
cp /Library/Ruby/Gems/1.8/gems/jruby-jars-1.4.0/lib/jruby-stdlib-1.4.0.jar tmp/war/WEB-INF/lib/jruby-stdlib-1.4.0.jar
cp /Library/Ruby/Gems/1.8/gems/jruby-jars-1.4.0/lib/jruby-stdlib-1.4.0.jar tmp/war/WEB-INF/lib/jruby-stdlib-1.4.0.jar
mkdir -p tmp/war/WEB-INF
jar cf rest.war  -C tmp/war .
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Comme vous pouvez le voir, Warbler se charge de créer notre webapp en y plaçant les fichiers de notre application, les gems dont elle dépend, mais également JRuby. Nous avons donc un fichier &lt;tt&gt;rest.war&lt;/tt&gt; totalement portable et donc extrêmement facile à déployer.&lt;/p&gt;
  
  &lt;h2&gt;Installer et déployer l'application&lt;/h2&gt;

  &lt;p&gt;Dans cet exemple, j'utilise la version 6.0.20 de &lt;a href=&quot;http://tomcat.apache.org/&quot;&gt;Tomcat&lt;/a&gt;. Je n'ai pas pris le temps de tester avec d'autre serveur Java, mais il n'y a pas de raison pour que cela ne fonctionne pas.&lt;/p&gt;
  
  &lt;p&gt;Pour installer l'application, il suffit simplement de copier le fichier &lt;tt&gt;rest.war&lt;/tt&gt; dans le répertoire &lt;tt&gt;webapps&lt;/tt&gt; de Tomcat. Le déploiement se fera de lui-même lors du lancement sur serveur. Pour cela, exécutez le script &lt;tt&gt;startup&lt;/tt&gt; situé dans le répertoire &lt;tt&gt;bin&lt;/tt&gt; de Tomcat. Si vous suivez en parallèle les logs inscrits dans &lt;tt&gt;logs/catalina.out&lt;/tt&gt;, vous devriez, à un moment, voir apparaitre l'information suivante :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;INFO: Déploiement de l&lt;span class=&quot;s1&quot;&gt;&amp;#39;archive rest.war de l&amp;#39;&lt;/span&gt;application web
JRuby limited openssl loaded. gem install jruby-openssl &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;full support.
http://jruby.kenai.com/pages/JRuby_Builtin_OpenSSL
...
INFO: Server startup in 32519 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;C'est parfait... Nous pouvons maintenant utiliser notre application. Pour cela, rendez-vous à l'adresse &lt;tt&gt;http://localhost:8080/rest&lt;/tt&gt;&lt;/p&gt;

  &lt;p&gt;Si vous poussez le test, vous verrez rapidement que quelque chose ne fonctionne pas :&lt;/p&gt;
  
  &lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/capcode-warbler.png&quot;&gt;&lt;/center&gt;&lt;/p&gt;
  
  &lt;p&gt;Rassurez-vous, ceci s'explique très bien. En effet, dans l'application, au niveau des vues, nous utilisons la méthode URL pour générer les valeurs des champs &lt;tt&gt;action&lt;/tt&gt; des formulaires. C'est une bonne pratique, mais qui, dans le cas présent renvoi sur l'url &lt;tt&gt;/action&lt;/tt&gt; alors que, étant dans une webapp, cette route devrait en fait être &lt;tt&gt;&lt;b&gt;/rest&lt;/b&gt;/action&lt;/tt&gt;.&lt;/p&gt;
  
  &lt;p&gt;Heureusement, tout a été prévu. En effet, la méthode &lt;tt&gt;URL&lt;/tt&gt; est prévue pour fonctionner avec un &lt;tt&gt;RACK_BASE_URI&lt;/tt&gt; spécifique. Dans notre cas, il s'agit de &lt;tt&gt;/rest&lt;/tt&gt;. Il suffit donc de positionner cette valeur avant de démarrer le serveur :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;RACK_BASE_URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/rest
./bin/startup.sh
open http://localhost:8080/rest
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  
  &lt;p&gt;
    Et cela fonctionne correctement !
  &lt;/p&gt;
  
  &lt;h2&gt;Attention !&lt;/h2&gt;
  
  &lt;p&gt;
    Lors de la rédaction de ce post, j'ai corrigé quelques bugs dans Capcode. Donc, à moins que la version 0.9.2 (ou supérieure) soit sortie, il faudra récupérer les &lt;a href=&quot;http://github.com/glejeune/Capcode/&quot;&gt;sources&lt;/a&gt; pour tester cela.
  &lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Créer son moteur de recherche avec Ruby et Xapian</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Dev/2009/12/29/creer-son-moteur-de-recherche-avec-ruby-et-xapian.html' />
    <id>http://algorithmique.net/Dev/2009/12/29/creer-son-moteur-de-recherche-avec-ruby-et-xapian</id>
    <updated>2009-12-29T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;&lt;img src=&quot;/images/dev.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Il y a quelque mois de cela, j'avais publié dans &lt;a href=&quot;http://www.gnulinuxmag.com/&quot;&gt;GNU/Linux Magazine France&lt;/a&gt; un article expliquant comment &lt;a href=&quot;http://www.unixgarden.com/index.php/programmation/creer-son-propre-moteur-de-recherche-avec-ruby&quot;&gt;créer son propre moteur de recherche avec Ruby&lt;/a&gt;. Je m'étais alors basé sur &lt;a href=&quot;http://ferret.davebalmain.com/trac/&quot;&gt;Ferret&lt;/a&gt;, inspiré de &lt;a href=&quot;http://lucene.apache.org/&quot;&gt;Lucene&lt;/a&gt;. Aujourd'hui, en lisant &lt;a href=&quot;http://railsmagazine.com/issues/5&quot;&gt;Rails Magazine #5&lt;/a&gt;, j'ai découvert &lt;a href=&quot;http://xapian.org&quot;&gt;Xapian&lt;/a&gt;.&lt;/p&gt;
  
  &lt;p&gt;&lt;tt&gt;Xapian&lt;/tt&gt; est une librairie permettant d'indexer des documents. Elle est écrite en C++ et propose des bindings pour différents langages, dont Ruby. Je vous propose donc de réécrire le moteur de recherche mis en place dans GLMF #107 en utilisant ce moteur.&lt;/p&gt;
  
  &lt;p&gt;La méthode utilisée sera exactement la même que celle mise en place dans mon premier article. Nous allons donc créer deux scripts : un crawler/indexer et une interface de recherche. Je ne vous réexpliquerai pas le rôle des différents éléments en vous laissant le soin de refaire un peu de &lt;a href=&quot;http://www.unixgarden.com/index.php/programmation/creer-son-propre-moteur-de-recherche-avec-ruby&quot;&gt;lecture&lt;/a&gt;, si besoin. Je vais me concentrer sur le code en mettant en avant les éléments à modifier pour passer de &lt;tt&gt;Ferret&lt;/tt&gt; à &lt;tt&gt;Xapian&lt;/tt&gt;&lt;/p&gt;
  
  &lt;h2&gt;Installer Xapian&lt;/h2&gt;
  
  &lt;p&gt;Avant de commencer, nous allons installer &lt;tt&gt;Xapian&lt;/tt&gt;. Ce travail se fera en deux étapes. Tout d'abord, nous devons récupérer, compiler et installer &lt;tt&gt;xapian-core&lt;/tt&gt; :&lt;/p&gt;
  
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;wget http://oligarchy.co.uk/xapian/1.0.17/xapian-core-1.0.17.tar.gz
tar zxvf xapian-core-1.0.17.tar.gz
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;xapian-core-1.0.17

./configure &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Il faut maintenant installer le binding pour Ruby. Vous avez plusieurs solutions pour cela. Soit récupérer &lt;a href=&quot;http://xapian.org/download&quot;&gt;xapian-bindings&lt;/a&gt;, soit (solution que je préfère), récupérer et installer le &lt;a href=&quot;http://github.com/xspond/xapian-ruby&quot;&gt;gem (non officiel)&lt;/a&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;git clone http://github.com/xspond/xapian-ruby.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;xapian-ruby

gem build xapian-ruby.gemspec
sudo gem install xapian-ruby-0.1.2.gem
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
  
  &lt;h2&gt;Crawler et Indexer&lt;/h2&gt;
  
  &lt;p&gt;La partie crawler est exactement la même et nous la reprendrons donc telle quelle.&lt;/p&gt;
  
  &lt;p&gt;Pour l'indexeur, nous avions vu à l'époque qu'il suffit de créer une instance de &lt;tt&gt;Ferret::Index::Index&lt;/tt&gt; et de lui ajouter les éléments à indexer :&lt;/p&gt;
  
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ferret&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Création de l&amp;#39;index&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Ferret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;index&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Ajout du premier document :&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://example.com/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A FooBar example&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget blandit tortor. Vestibulum vitae sem...&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Ajout du second document :&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://example.com/page.html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A second FooBar example&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Ut ornare euismod mauris quis molestie. Fusce eget metus sit amet justo pretium ullamcorper sit...&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Dans cet exemple, l’option &lt;tt&gt;:path&lt;/tt&gt; permet de préciser le répertoire dans lequel devront être stockés les différents fichiers permettant la persistance de l’index.&lt;/p&gt;
  
  &lt;p&gt;Si maintenant nous voulons faire la même chose avec &lt;tt&gt;Xapian&lt;/tt&gt;, voici le code que nous obtenons :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;xapian&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Création de la base&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WritableDatabase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DB_CREATE_OR_OPEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Création de l&amp;#39;index&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TermGenerator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Stem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;french&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Ajout du premier document :&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget blandit tortor. Vestibulum vitae sem...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Uhttp://example.com/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;TA FooBar example&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget blandit tortor. Vestibulum vitae sem...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Ajout du premier document :&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Ut ornare euismod mauris quis molestie. Fusce eget metus sit amet justo pretium ullamcorper sit...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Uhttp://example.com/page.html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;TA second FooBar example&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Ut ornare euismod mauris quis molestie. Fusce eget metus sit amet justo pretium ullamcorper sit...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;&lt;i&gt;Outch !&lt;/i&gt; &lt;tt&gt;Xapian&lt;/tt&gt; est, à première vue, un peu plus lourd que &lt;tt&gt;Ferret&lt;/tt&gt;. La première chose à faire est de créer la base (ligne 4) puis l'indexer (ligne 7) en lui affectant cette base (ligne 8). Vous remarquerez que l'indexer travaille en fonction d'une langue (ligne 9). Ceci fait l'ajout de document se fait en trois étapes :&lt;/p&gt;
  
  &lt;ul&gt;
    &lt;li&gt;Tout d'abord, nous créons ce document (ligne 12 à 15).&lt;/li&gt;
    &lt;li&gt;Nous le passons ensuite à l'indexer (ligne 16) auquel nous demandons d'indexer le contenu (ligne 17).&lt;/li&gt;
    &lt;li&gt;Pour terminer, nous ajoutons le document dans la base (ligne 18).&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;A partir de là, je suis certain que vous vous posez plein de questions...&lt;/p&gt;
  
  &lt;h3&gt;Pourquoi, alors que nous passons le document à l'indexer, fait-il utiliser &lt;tt&gt;index_text&lt;/tt&gt; ?&lt;/h3&gt;
  
  &lt;p&gt;Tout simplement parce que nous ne voulons peut-être pas toujours indexer le contenu complet du document. En effet, dans le cas d'un crawler web par exemple, nous pourrions indexer le document en ne prenant en compte que les mots clés (balise &lt;tt&gt;meta&lt;/tt&gt;, &lt;tt&gt;name=&quot;keywords&quot;&lt;/tt&gt;). Dans ce cas, nous ferons plutôt quelque chose comme cela :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# nous partons du principe que nous avons :&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#  body     = contenu de la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#  url      = l&amp;#39;URL de la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#  title    = le titre de la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#  keywords = les mots clés récupérés dans la balise meta&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;U&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;T&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keywords&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;increase_termpos&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Notez que nous pouvons pondérer nous même les mots clés. En effet, &lt;tt&gt;index_text&lt;/tt&gt; accepte, en second paramètre, un entier permettant de donner un poids à chacun. Par défaut il est à 1.&lt;/p&gt;

  &lt;h3&gt;Qu'est-ce donc que ces &lt;tt&gt;add_term&lt;/tt&gt; ?&lt;/h3&gt;
  
  &lt;p&gt;Avec &lt;tt&gt;Ferret&lt;/tt&gt;, nous passions notre document sous forme de &lt;tt&gt;Hash&lt;/tt&gt;. Et bien les &lt;tt&gt;terms&lt;/tt&gt; d'un document sont un peu la même chose. Mais afin de les différencier, nous les préfixons (ici &lt;tt&gt;U&lt;/tt&gt; pour l'URL, &lt;tt&gt;T&lt;/tt&gt; pour le titre). Ainsi lors de la recherche nous pourrons récupérer ces informations.&lt;/p&gt;
  
  &lt;p&gt;Maintenant que nous savons cela, nous pouvons coder notre crawler/indexer :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;  1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;digest/md5&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;net/http&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  3&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;uri&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  4&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;  5&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  6&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;hpricot&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  7&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;xapian&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;  8&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;  9&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 10&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 11&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HTTPDocument&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 12&lt;/span&gt;   &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:highlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:pages&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 13&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt; 14&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 15&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 16&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@highlevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 17&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@pages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 18&lt;/span&gt;      
&lt;span class=&quot;lineno&quot;&gt; 19&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WritableDatabase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DB_CREATE_OR_OPEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 20&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 21&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@indexer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TermGenerator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 22&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@indexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@database&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 23&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@indexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Stem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;french&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 24&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 25&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt; 26&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;indexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;digest&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 27&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[INDEX] - Index &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 28&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@highlevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@highlevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 29&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@pages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 30&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt; 31&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 32&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 33&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;U&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 34&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;T&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 35&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;M&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digest&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 36&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 37&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@indexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 38&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@indexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 39&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 40&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 41&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 42&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt; 43&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;crawler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;lineno&quot;&gt; 44&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[CRAWL] - Level #&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 45&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 46&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Récupération de la ressource&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 47&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 48&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt; 49&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Récupération du contenu&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 50&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 51&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt; 52&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# En cas d&amp;#39;erreur, nous ignorons la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 53&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTTPOK&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 54&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[ERROR] - &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : Bad URL!&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 55&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 56&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 57&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Récupération du contenu de la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 58&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 59&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 60&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Calcul du MD5 de la page&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 61&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;pageDigest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Digest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MD5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 62&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt; 63&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Si la page a déjà été indexé nous l&amp;#39;ignorons&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 64&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;M&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pageDigest&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 65&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[IGNORE] - &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : Already parsed!&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 66&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 67&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 68&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt; 69&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Indexation&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 70&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content_type&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 71&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 72&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;pageDocument&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Hpricot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 73&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pageDocument&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 74&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;?&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;:pageTitle.inner_html) # &amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 75&lt;/span&gt;         
&lt;span class=&quot;lineno&quot;&gt; 76&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;indexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageDigest&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 77&lt;/span&gt;         
&lt;span class=&quot;lineno&quot;&gt; 78&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# Parcour des liens&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 79&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pageDocument&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 80&lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 81&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 82&lt;/span&gt;             &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 83&lt;/span&gt;             &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 84&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 85&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 86&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 87&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;./&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;//&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 88&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 89&lt;/span&gt;             &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 90&lt;/span&gt;         
&lt;span class=&quot;lineno&quot;&gt; 91&lt;/span&gt;             &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 92&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 93&lt;/span&gt;               &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;U&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 94&lt;/span&gt;                 &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 95&lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;crawler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 96&lt;/span&gt;                 &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 97&lt;/span&gt;               &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 98&lt;/span&gt;             &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 99&lt;/span&gt;               &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[IGNORE] - &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : Host not match!&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;100&lt;/span&gt;             &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;101&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;102&lt;/span&gt;             &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[ERROR] - Error at &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;103&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;            
&lt;span class=&quot;lineno&quot;&gt;104&lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;105&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;text/plain&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;106&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;pageDocument&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;107&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;108&lt;/span&gt;         
&lt;span class=&quot;lineno&quot;&gt;109&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;indexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pageDigest&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;110&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;111&lt;/span&gt;         &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[IGNORE] - &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : Not Text or HTML!&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEBUG&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;112&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;113&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;114&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;115&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;116&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTTPDocument&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;117&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;118&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;119&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;crawler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;120&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;121&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;122&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; indexed :&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;123&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;124&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;- &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;125&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;126&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;High level : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlevel&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;127&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Time : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;s&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;h2&gt;L’interface de recherche&lt;/h2&gt;

  &lt;p&gt;Avec &lt;tt&gt;Ferret&lt;/tt&gt; voici ce que j'avais mis en place la dernière fois : &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;./index&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;content:&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt; &amp;lt;small&amp;gt;- [score of &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;]&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;highlights&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;content:&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                   &lt;span class=&quot;ss&quot;&gt;:field&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                   &lt;span class=&quot;ss&quot;&gt;:pre_tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;b&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                   &lt;span class=&quot;ss&quot;&gt;:post_tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;small&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlights&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/small&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;small&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Et voici comment nous faisons la même chose avec &lt;tt&gt;Xapian&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;QueryParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Stem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;french&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemming_strategy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;QueryParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STEM_SOME&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# On ne prend que les 10 premiers résultats.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matchset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matchset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;terms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^T/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^T/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^U/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^U/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;font size=&amp;#39;+1&amp;#39;&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;- [score of &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;percent&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;%]&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;small&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&amp;lt;font color=&amp;#39;green&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/font&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;&lt;i&gt;Outch !&lt;/i&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt; Là encore, le code est beaucoup plus long avec &lt;tt&gt;Xapian&lt;/tt&gt;. Il y a seulement deux petites choses importantes à voir ici :&lt;/p&gt;
  
  &lt;ol&gt;
    &lt;li&gt;ligne 8, nous définissons la statégie de recherche de termes en fixant la valeur de &lt;tt&gt;Xapian::QueryParser#stemming_strategy&lt;/tt&gt; à &lt;tt&gt;Xapian::QueryParser::STEM_SOME&lt;/tt&gt;. Cela veut tout simplement dire que nous ne prenons pas en compte les termes commençant par une majuscule, donc pas notre &lt;tt&gt;U&amp;lt;url&amp;gt;&lt;/tt&gt; ou notre &lt;tt&gt;T&amp;lt;titre&amp;gt;&lt;/tt&gt;. Ce qui est plutôt une bonne chose.&lt;/li&gt;
    &lt;li&gt;Pour récupérer l'URL et le titre justement, nous parcourons les termes rattachés à chaque document trouvé et nous extrayions celui préfixé, respectivement, par &lt;tt&gt;U&lt;/tt&gt; et &lt;tt&gt;T&lt;/tt&gt; (ligne 19 à 22).&lt;/li&gt;
  &lt;/ol&gt;
  
  &lt;p&gt;Bien entendu, je me suis limité à la plus courte explication. Mais si vous regardez la &lt;a href=&quot;http://xapian.org/docs/bindings/ruby/rdocs/&quot;&gt;documentation&lt;/a&gt; de Xapian, vous verrez que vous pouvez aller beaucoup plus loin, en gérant en particulier la correction orthographique ou la synonymie...&lt;/p&gt;
  
  &lt;p&gt;En attendant, voici le code complet de notre interface de recherche :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mongrel&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;xapian&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ResultHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mongrel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HttpHandler&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;       
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;         &lt;span class=&quot;no&quot;&gt;Mongrel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HttpRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query_parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;QUERY_STRING&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;s&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;         &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;meta http-equiv=content-type content=&amp;#39;text/html; charset=UTF-8&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;title&amp;gt;Mooteur&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;link rel=&amp;#39;stylesheet&amp;#39; href=&amp;#39;/style.css&amp;#39; type=&amp;#39;text/css&amp;#39; media=&amp;#39;screen&amp;#39; /&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;div id=&amp;#39;left&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;    &amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;      &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#39;/&amp;#39;&amp;gt;&amp;lt;img src=&amp;#39;/mooteur.gif&amp;#39; alt=&amp;#39;Mooteur...&amp;#39; width=&amp;#39;200&amp;#39; border=&amp;#39;0&amp;#39;&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;      &amp;lt;td&amp;gt;&amp;lt;form action=&amp;#39;/r&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;        &amp;lt;input type=&amp;#39;text&amp;#39; name=&amp;#39;s&amp;#39; size=&amp;#39;41&amp;#39; value=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39; /&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;        &amp;lt;input type=&amp;#39;submit&amp;#39; value=&amp;#39;Recherche Mooteur&amp;#39;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;      &amp;lt;/form&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;    &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;/div&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;34&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;36&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;38&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;QueryParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;39&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Stem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;french&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;40&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stemmer&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;41&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;42&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stemming_strategy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Xapian&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;QueryParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STEM_SOME&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;43&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;44&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Find the top 10 results for the query.&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;45&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;46&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;matchset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enquire&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;47&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;48&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;  &amp;lt;div id=&amp;#39;results&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;49&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;div id=&amp;#39;head&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matchset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches_estimated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; r&amp;amp;eacute;sultats pour &amp;lt;b&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_term&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;51&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;    &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;    &amp;lt;div id=&amp;#39;list&amp;#39;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;54&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt;55&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;matchset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;56&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;57&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;58&lt;/span&gt;         
&lt;span class=&quot;lineno&quot;&gt;59&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;terms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;60&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^T/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^T/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;61&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^U/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^U/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;62&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;63&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;64&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;font size=&amp;#39;+1&amp;#39;&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;small&amp;gt;- [score of &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;percent&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;%]&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;65&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;small&amp;gt;&amp;lt;a href=&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;gt;&amp;lt;font color=&amp;#39;green&amp;#39;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/font&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;66&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;67&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;68&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;69&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;    &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;70&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;  &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;71&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;73&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;74&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;75&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;76&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;77&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;78&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mongrel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HttpServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;0.0.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;3000&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;79&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mongrel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DirHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;./static/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/r&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ResultHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;81&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;center&gt;&lt;img src=&quot;/images/posts/xapian.png&quot;&gt;&lt;/center&gt;
  
  &lt;h2&gt;Conclusion&lt;/h2&gt;

  &lt;p&gt;Je terminerai, encore une fois, en vous précisant qu'il existe de très intéressants plugins &lt;tt&gt;Xapian&lt;/tt&gt; pour &lt;tt&gt;Rails&lt;/tt&gt; dont &lt;a href=&quot;http://github.com/frabcus/acts_as_xapian&quot;&gt;acts_as_xapian&lt;/a&gt; et &lt;a href=&quot;http://github.com/ryanb/xapit/&quot;&gt;xapit&lt;/a&gt; (à utiliser avec &lt;a href=&quot;http://github.com/ryanb/xapit-sync/&quot;&gt;xapit-sync&lt;/a&gt;).&lt;/p&gt;
  
  &lt;p&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; again !&lt;/small&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>SoapUI-3.5-beta1.app</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/12/28/soapui-35-beta1app.html' />
    <id>http://algorithmique.net/Projets/2009/12/28/soapui-35-beta1app</id>
    <updated>2009-12-28T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;&lt;img src=&quot;/images/dev.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Bien que cela fasse déjà plusieurs jours qu'Ediware a mis en ligne la première beta de &lt;a href=&quot;http://www.soapui.org/&quot;&gt;SoapUI&lt;/a&gt; 3.5, je viens seulement de prendre le temps de créer le .app pour MacOSX. Ce délai est principalement dû au fait que j'ai eu besoin de retravailler un peu le script utilisé pour créer ce .app. Quoi qu'il en soit, le &lt;a href=&quot;http://gregoire.lejeune.free.fr/SoapUI-3.5-beta1.dmg&quot;&gt;DMG est disponible&lt;/a&gt;. J'ai encore quelques modifications à apporter pour parfaire la génération. Mais s'agissant d'une beta de la part d'Ediware, mon build s'en tiendra au même statut. Ceci me laisse un peu de temps jusqu'à la sortie de la version finale ;)&lt;/p&gt;
  
  &lt;p&gt;Notez que comme toujours il ne s'agit ici que de la version Open Source. Pour la version pro ou la version packagée par Ediware, je vous &lt;a href=&quot;http://www.soapui.org/new_and_noteworthy_3_5.html&quot;&gt;laisse voir ici&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ruby Timer</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Snippets/2009/12/24/ruby-timer.html' />
    <id>http://algorithmique.net/Snippets/2009/12/24/ruby-timer</id>
    <updated>2009-12-24T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;
    &lt;img src=&quot;/images/dev.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;J'ai profité du calme de cette période festive pour travailler sur mes projets. Le nombre de &lt;a href=&quot;http://github.com/glejeune/Ruby-Graphviz/blob/master/AUTHORS&quot;&gt;contributeurs&lt;/a&gt; sur &lt;a href=&quot;http://github.com/glejeune/Ruby-Graphviz&quot;&gt;Ruby/GraphViz&lt;/a&gt; augmentant, &lt;span style=&quot;text-decoration: line-through;&quot;&gt;j'ai&lt;/span&gt; nous avons sorti une nouvelle version. Idem pour &lt;a href=&quot;http://github.com/glejeune/Capcode&quot;&gt;Capcode&lt;/a&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt; qui est passé en version 0.8.9. Mais le projet sur lequel j'ai passé le plus de temps est certainement &lt;a href=&quot;http://github.com/glejeune/rcomet&quot;&gt;RComet&lt;/a&gt;&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt;. 
    
  &lt;/p&gt;
  
  &lt;p&gt;
    - Mais pourquoi, sachant que tout cela devrait être rapidement déprécié par les &lt;a href=&quot;http://dev.w3.org/html5/websockets/&quot;&gt;WebSockets&lt;/a&gt; ?&lt;br /&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      if( &quot;WebSocket&quot; in window ) {
        document.write('- Parce que si WebSocket fonctionne dans ton navigateur, ce n\'est &lt;a href=&quot;http://jimbergman.net/tag/websocket/&quot;&gt;pas le cas pour tout le monde !&lt;/a&gt;.&lt;br /&gt;- Oui mais les autres aussi...');
      } else {
        document.write('- Ben oui, mais pour le moment, cela ne fonctionne pas dans ton navigateur !&lt;br /&gt;- Ha zut !')
      }
    &lt;/script&gt;
  &lt;/p&gt;
  
  &lt;p&gt;Anyway !&lt;/p&gt;
  
  &lt;p&gt;
    Tout cela pour en arriver au fait que j'ai eu besoin de gérer le timeout des connexion dans RComet afin de détecter la déconnexion d'un client qui n'aurait pas eu la &lt;a href=&quot;http://svn.cometd.org/trunk/bayeux/bayeux.html#toc_54&quot;&gt;politesse de prévenir&lt;/a&gt;. Et pour cela je me suis amusé à développer une petite classe permettant de gérer un timer avec Ruby. Je vous la livre ici, mais sachez qu'il existe également un &lt;a href=&quot;http://gist.github.com/261900&quot;&gt;Gist&lt;/a&gt;
  &lt;/p&gt;
  
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;eventmachine&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Timer&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@run&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@timeout_proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Run &amp;lt;tt&amp;gt;blk&amp;lt;/tt&amp;gt; every &amp;lt;tt&amp;gt;every&amp;lt;/tt&amp;gt; seconds during &amp;lt;tt&amp;gt;during&amp;lt;/tt&amp;gt; seconds &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;every&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;during&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Timer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;during&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Run &amp;lt;tt&amp;gt;blk&amp;lt;/tt&amp;gt; every &amp;lt;tt&amp;gt;every&amp;lt;/tt&amp;gt; seconds during &amp;lt;tt&amp;gt;during&amp;lt;/tt&amp;gt; seconds &lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;every&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;during&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@run&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;     &lt;span class=&quot;no&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;       &lt;span class=&quot;no&quot;&gt;EventMachine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;reschedule&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;during&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt;             &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt;             &lt;span class=&quot;vi&quot;&gt;@timeout_proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@timeout_proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt;             &lt;span class=&quot;vi&quot;&gt;@timer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;EM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reschedule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt;             &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt;           &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt;         &lt;span class=&quot;vi&quot;&gt;@timer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;EM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reschedule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;36&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;38&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Timeout !&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;39&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;40&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@timeout_proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blk&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;41&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;42&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;43&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;44&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Stop the timer&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;45&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;stop&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;46&lt;/span&gt;     &lt;span class=&quot;no&quot;&gt;EM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop_event_loop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@run&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;47&lt;/span&gt;     &lt;span class=&quot;vi&quot;&gt;@run&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;48&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;49&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;51&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;## Example&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;54&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Timer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;55&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Please, give me your name...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;56&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;57&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Too late rabbit !!!&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;58&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;59&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;60&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt;61&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readline&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;62&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;63&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;64&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;65&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;
    &lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; Il n'y a pas autant de contibuteurs :(&lt;/small&gt;&lt;br /&gt;
    &lt;small&gt;&lt;sup&gt;2&lt;/sup&gt; Guillaume, si tu m'entend...&lt;/small&gt;
  &lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Bye bye TextMate, Bonjour Coda</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/12/21/bye-bye-textmate-bonjour-coda.html' />
    <id>http://algorithmique.net/Projets/2009/12/21/bye-bye-textmate-bonjour-coda</id>
    <updated>2009-12-21T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;&lt;img src=&quot;/images/projets.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Comme vous avez pu le constater, je suis en pleine période de changement. Cela a commencé avec &lt;a href=&quot;/Site/2009/12/18/bye-bye-wordpress-bonjour-jekyll.html&quot;&gt;ce site&lt;/a&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt;. Mais j'ai profité de cette mutation pour abandonner &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; au profit de &lt;a href=&quot;http://www.panic.com/coda/&quot;&gt;Coda&lt;/a&gt;.&lt;/p&gt;
  
  &lt;p&gt;Coda est un éditeur de code qui se dit orienté Web, mais il n'en reste pas moins tout à fait utilisable pour le &lt;i&gt;reste&lt;/i&gt;. C'est cependant assez difficile de changer ses habitudes. Heureusement, Coda arrive avec un &lt;a href=&quot;http://www.panic.com/coda/developer/howto/plugins.php&quot;&gt;éditeur de plugins&lt;/a&gt; extrêmement simple à utiliser, qui m'a permis de démarrer le développement d'un plugin regroupant plusieurs petites choses que j'appréciais particulièrement dans TextMate. La première concerne l'exécution du code depuis l'éditeur (le fameux ⌘R). Je n'ai pas encore de solution satisfaisante pour cette action, mais cela prend forme. Idem pour l'intégration de Git qui commence à ressembler à quelque chose ;) &lt;/p&gt;
  
  &lt;p&gt;Du côté de la coloration syntaxique, Coda est assez pauvre. Bonne nouvelle, il utilise le format &lt;a href=&quot;http://www.codingmonkeys.de/subethaedit/mode.html&quot;&gt;Mode&lt;/a&gt; de &lt;a href=&quot;http://www.codingmonkeys.de/subethaedit/index.html&quot;&gt;SubEthaEdit&lt;/a&gt;. Il est donc possible de récupérer &lt;a href=&quot;http://www.codingmonkeys.de/subethaedit/modes.html&quot;&gt;tout le travail&lt;/a&gt; déjà réalisé pour ce dernier, mais également de créer ce qui nous manque. Ce n'est d'ailleurs pas la seule chose que Coda reprend de SubEthaEdit, puisqu'il intègre &lt;a href=&quot;http://www.codingmonkeys.de/subethaengine/&quot;&gt;Subetha Engine&lt;/a&gt; . J'ai eu l'occasion de le tester sur un petit développement et je dois avouer que si cela peut sembler un peu &lt;i&gt;gadget&lt;/i&gt;, cela s'avère extrêmement intéressant.&lt;/p&gt;
  
  &lt;p&gt;Pour terminer sur Coda, j'étais un grand utilisateur d'&lt;a href=&quot;http://henrik.nyh.se/2007/10/open-in-textmate-from-leopard-finder&quot;&gt;Open In Textmate&lt;/a&gt;. Et bien, pour ne pas rompre avec cette bonne habitude, je me suis amusé à développer &lt;a href=&quot;http://github.com/glejeune/OpenInCoda&quot;&gt;Open In Coda&lt;/a&gt; :&lt;/p&gt;
  
  &lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/openincoda.png&quot;&gt;&lt;/center&gt;&lt;/p&gt;
    
  &lt;p&gt;
    &lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; et il semble que ce sujet ne soit pas totalement clos.&lt;/small&gt;
  &lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Bye bye Wordpress, Bonjour Jekyll</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Site/2009/12/18/bye-bye-wordpress-bonjour-jekyll.html' />
    <id>http://algorithmique.net/Site/2009/12/18/bye-bye-wordpress-bonjour-jekyll</id>
    <updated>2009-12-18T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;&lt;img src=&quot;/images/dev.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Cela faisait longtemps que je voulais quitter le doux monde de &lt;a href=&quot;http://wordpress.org/&quot;&gt;Wordpress&lt;/a&gt; pour passer sur un nouveau système de blog plus proche de mes aspirations. Après ce n'est qu'une question de temps et de bonne volonté... Et bien c'est fait puisque ce site est maintenant &lt;i&gt;propulsé par &lt;/i&gt;&lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;
  
&lt;p&gt;Il existe pas mal de choix dans les outils de blog. Toute la question consiste à trouver celui qui est le plus en adéquations avec vos besoins, votre philosophie... Mon choix pour Jekyll s'explique par plusieurs raisons, dont principalement le fait qu'il s'agit en fait d'un générateur de site statique, à partir de templates. Cette solution présente de multiples avantages dont un véritablement différenciant : la possibilité de faire des modifications sans obligatoirement avoir accès à internet. C'est par exemple le cas de ce post que je rédige en ce moment même dans une salle d'attente. Je peux non seulement le rédiger, mais également voir comment tout s'articule. Avec un outil comme Wordpress, bien entendu vous pouvez faire la rédaction &quot;hors ligne&quot;, mais impossible de vérifier le rendu. A moins bien entendu d'avoir un Worpress installé localement.&lt;/p&gt;

&lt;p&gt;Dans la version Wordpress de ce site, j'utilisais pas mal de plug-ins. Une des premières questions que je me suis posées avant de faire un choix définitif était de savoir comment conserver la coloration syntaxique du code. En bon utilisateur de &lt;a href=&quot;http://github.com&quot;&gt;Github&lt;/a&gt;, j'ai bien entendu pensé à cette solution. Ce qui me dérangeait le plus était le fait que le code embarqué dans un article est alors obligatoirement détaché de ce dernier. Lors de ma recherche, j'ai vu que Jekyll propose de la coloration syntaxique via &lt;a href=&quot;http://pygments.org/&quot;&gt;Pygments&lt;/a&gt; \o/&lt;/p&gt;

&lt;p&gt;Côté plugins, j'utilisais également &lt;a href=&quot;http://forum.irisco.it/forum.php?id=1&quot;&gt;StatPress&lt;/a&gt;. Cela se remplace très bien par un &lt;a href=&quot;http://www.google.com/intl/fr_ALL/analytics/&quot;&gt;Google Analytics&lt;/a&gt; ;)&lt;/p&gt;

&lt;p&gt;Enfin, il y avait &lt;a href=&quot;http://www.blaenkdenum.com/wp-recaptcha/&quot;&gt;WP-reCAPTCHA&lt;/a&gt; pour éviter le spam dans les commentaires. Eh oui, un blog ne serait pas un blog sans commentaires. Pour cette partie, j'utilise &lt;a href=&quot;http://disqus.com&quot;&gt;Disqus&lt;/a&gt;. Non seulement il permet d'ajouter les commentaires, mais en plus de les gérer.&lt;/p&gt;

&lt;p&gt;Donc, bienvenu à vous sur cette nouvelle version d'algo::rithmique. Il n'est pas impossible que lors de la phase de migration je sois passé à côté de certaines petites choses (images ou liens cassés, ...) n'hésitez pas à m'en faire part.&lt;/p&gt;

&lt;blockquote&gt;Au fait, n'oubliez pas de changer l'URL du fil RSS si vous lisez ce blog à travers un lecteur de news.&lt;/blockquote&gt;
</content>
  </entry>
  
  <entry>
    <title>Server side Faye’s client ou le protocole Bayeux</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/11/24/server-side-fayes-client-ou-le-protocole-bayeux.html' />
    <id>http://algorithmique.net/Projets/2009/11/24/server-side-fayes-client-ou-le-protocole-bayeux</id>
    <updated>2009-11-24T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">  &lt;p&gt;
  &lt;img src=&quot;/images/dev.png&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Dans mon &lt;a href=&quot;/Projets/2009/11/21/notification-comet--capcode.html&quot;&gt;précédent article&lt;/a&gt;, je vous ai montré comment mettre en place un &lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_(programming)&quot;&gt;Comet&lt;/a&gt; avec &lt;a href=&quot;http://github.com/glejeune/Capcode&quot;&gt;Capcode&lt;/a&gt;. J'ai découvert que certains d'entre vous lisent ce que j'écris&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt; par le biais de quelques mails dans ma boite aux lettres. L'un d'entre vous m'a même demandé comment faire pour envoyer des évènements sur le bus Comet sans passer par l'application Web. Bonne question, sachant qu'en effet, &lt;a href=&quot;http://github.com/jcoglan/faye&quot;&gt;faye&lt;/a&gt; ne propose aucune solution pour cela. Et bien je me suis amusé à en développer une...&lt;/p&gt;

  &lt;h3&gt;Faye&lt;/h3&gt;

  &lt;p&gt;Pour comprendre ce que nous allons faire, il faut prendre le temps de regarder comment fonctionne &lt;tt&gt;faye&lt;/tt&gt;. Mais avant, nous devons choisir la solution à adopter pour écrire notre librairie. En effet, nous avons deux choix possibles : soit nous pouvons &lt;i&gt;parler&lt;/i&gt; directement au serveur &lt;tt&gt;faye&lt;/tt&gt;, soit nous pouvons &lt;i&gt;simuler&lt;/i&gt; le comportement d'un client. En fonction de ce choix, nous regarderons telle ou telle partie du code de &lt;tt&gt;faye&lt;/tt&gt;. Bon et puisque c'est moi qui choisis&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt;, j'opte pour la seconde solution.&lt;/p&gt;

  &lt;p&gt;Avant de décortiquer le code, rappelons le cheminement par l'utilisateur lors de l'utilisation de &lt;tt&gt;soapbox&lt;/tt&gt;. Avant tout nous démarrons l'application&lt;small&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/small&gt;. Nous donnons notre &lt;i&gt;username&lt;/i&gt;. Ensuite nous indiquons qui nous voulons suivre. Enfin nous racontons notre vie. Ces deux dernières étapes pouvant se faire dans n'importe quel ordre, et autant de fois que nous voulons.&lt;/p&gt;

  &lt;p&gt;Regardons maintenant le code. Lors de l'accès à l'application (route &lt;tt&gt;/&lt;/tt&gt;) nous recevons la page mise en place par la vue &lt;tt&gt;views/index.rhtml&lt;/tt&gt;. Dans cette vue, ce qui nous intéresse ce sont les lignes suivantes :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;Comet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/comet&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;Comet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;Soapbox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Comet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Nous créons un client Comet (ligne 41) pour le bus accessible via la route &lt;tt&gt;/comet&lt;/tt&gt; puis nous établissons la connexion (ligne 42). Ensuite nous initialisons l'application (ligne 44).  Si nous regardons à quoi correspondent la création et la connexion du client Comet, il faut se plonger dans le code du script &lt;tt&gt;comet.js&lt;/tt&gt;. Ce fichier est généré lors de la création du gem &lt;tt&gt;faye&lt;/tt&gt; à partir de l'ensemble des fichiers contenus dans le répertoire &lt;a href=&quot;http://github.com/jcoglan/faye/tree/master/client/&quot;&gt;client&lt;/a&gt; des sources. Le fichier qui nous intéresse principalement ici est &lt;a href=&quot;http://github.com/jcoglan/faye/blob/master/client/client.js&quot;&gt;client/client.js&lt;/a&gt;. Dans ce fichier vous trouverez le code correspondant à la connexion entre les lignes &lt;a href=&quot;http://github.com/jcoglan/faye/blob/master/client/client.js#L75-L113&quot;&gt;75 et 113&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Si nous regardons maintenant le fichier &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js&quot;&gt;soapbox.js&lt;/a&gt; nous pouvons étudier ce qui se passe lors de l'initialisation de l'application. Nous voyons dans ce code que &lt;tt&gt;soapbox&lt;/tt&gt; &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L20-L24&quot;&gt;attend que l'utilisateur saisisse son &lt;i&gt;username&lt;/i&gt;&lt;/a&gt;. Une fois ceci fait, l'application &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L34&quot;&gt;&lt;i&gt;souscrit&lt;/i&gt; au channel &lt;tt&gt;/mentioning/&amp;lt;username&amp;gt;&lt;/tt&gt;&lt;/a&gt;, &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L37-L39&quot;&gt;elle masque la zone de saisie du &lt;i&gt;username&lt;/i&gt; et affiche les zones de saisie des personnes à suivre et des messages&lt;/a&gt;. Elle met ensuite en place les actions correspondantes pour ces deux zones de saisie. La première de ces actions se traduit par &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L43-L50&quot;&gt;la souscription au channel &lt;tt&gt;/from/&amp;lt;follow&amp;gt;&lt;/tt&gt; avec comme callback : &lt;tt&gt;accept&lt;/tt&gt;. La seconde &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L55&quot;&gt;revoie vers la méthode &lt;tt&gt;post&lt;/tt&gt;&lt;/a&gt; dont le rôle principal est de &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/soapbox/public/soapbox.js#L84&quot;&gt;publier le message sur le channel &lt;tt&gt;/from/&amp;lt;username&amp;gt;&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Outch !&lt;/p&gt;

  &lt;p&gt;Ce qui est important ici c'est de voir ce dont nous avons besoin pour faire cela. Nous en retiendrons donc la nécessité de développer une méthode de connexion, une méthode de souscription et une méthode de publication. Pour comprendre comment ces méthodes agissent, il suffit de regarder ce qui est fait dans les méthodes correspondantes de &lt;a href=&quot;http://github.com/jcoglan/faye/blob/master/client/client.js&quot;&gt;Faye.Client&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Je ne vais pas pouvoir, au risque de perdre plus de monde que ceux qui ont déjà lâché prise avant la fin du dernier paragraphe, entrer plus dans les détails. Il va donc falloir me croire sur parole ;) En fait, ce que nous allons faire c'est mettre en place une version cliente du protocole des échanges Comet appelé protocole Bayeux. Je vous engage donc à en lire &lt;a href=&quot;http://svn.cometd.com/trunk/bayeux/bayeux.html&quot;&gt;la documentation&lt;/a&gt; si vous souhaitez approfondir le sujet.&lt;/p&gt;

  &lt;h3&gt;Messages&lt;/h3&gt;

  &lt;p&gt;Les échanges entre le client Comet et le bus peuvent se faire de deux façons, soit en &lt;tt&gt;long-polling&lt;/tt&gt; soit en &lt;tt&gt;callback-polling&lt;/tt&gt;. Dans notre cas, nous utilisons la première solution en faisant un envoie en &lt;tt&gt;POST&lt;/tt&gt; du paramètre &lt;tt&gt;message&lt;/tt&gt;, ce dernier ayant pour valeur une chaine JSON.&lt;/p&gt;

  &lt;p&gt;Mettons cela en place :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post_form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;message&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Je place cette méthode en &lt;tt&gt;private&lt;/tt&gt; car elle n'a d'intérêt que pour les méthodes que nous allons écrire ensuite.&lt;/p&gt;

  &lt;p&gt;Comme vous pouvez le voir, le retour est également une structure JSON.&lt;/p&gt;

  &lt;h3&gt;&quot;Handshake&quot;&lt;/h3&gt;

  &lt;p&gt;Si vous regardez précisément ce qui se passe lors de l'initialisation de la connexion du client Comet, vous verrez qu'en fait, il n'y a pas de connexion véritable, mais un &lt;i&gt;handshake&lt;/i&gt;. Cela consiste en fait à se présenter au bus Comet et à obtenir de sa part, un identifiant. Nous devrons, par la suite toujours, utiliser cet identifiant pour communiquer avec le bus.&lt;/p&gt;

  &lt;p&gt;Le message du &lt;i&gt;handshake&lt;/i&gt; doit contenir au moins les champs suivants :&lt;/p&gt;
  
  &lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;channel&lt;/tt&gt; : le channel.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;version&lt;/tt&gt; : la version du protocole.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;supportedConnectionTypes&lt;/tt&gt; : les types de connexions supportées.&lt;/li&gt;
  &lt;/ul&gt;
  
  &lt;p&gt;Un &lt;tt&gt;channel&lt;/tt&gt; est représenté comme un chemin sous la forme &lt;tt&gt;/foo/bar/...&lt;/tt&gt; et doit systématiquement commencer par un &lt;tt&gt;/&lt;/tt&gt;. Il en existe deux types : ceux définis par l'application et ceux réservés par le protocole. Ces derniers commencent toujours par &lt;tt&gt;/meta/&lt;/tt&gt;. Dans le cas du &lt;i&gt;handshake&lt;/i&gt;, le channel doit être &lt;tt&gt;/meta/handshake&lt;/tt&gt;.&lt;/p&gt;

  &lt;p&gt;La version doit correspondre au numéro de version du protocole. 1.0 ici.&lt;/p&gt;

  &lt;p&gt;Le paramètre &lt;tt&gt;supportedConnectionTypes&lt;/tt&gt; contient la liste des types de transports supportés. Bien que nous ayons dit plus haut que nous emploierons du &lt;tt&gt;long-polling&lt;/tt&gt;, nous positionnerons la valeur &lt;tt&gt;[&quot;long-polling&quot;, &quot;callback-polling&quot;]&lt;/tt&gt;. Ceci simplement parce que si nous souhaitons implémenter le &lt;tt&gt;callback-polling&lt;/tt&gt; nous n'aurons pas de modification à faire ;)&lt;/p&gt;

  &lt;p&gt;Voici donc à quoi ressemblera la méthode de &lt;i&gt;handshake&lt;/i&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handshake&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HANDSHAKE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;BAYEUX_VERSION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;supportedConnectionTypes&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;long-polling&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;callback-polling&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      
      &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;advice&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;interval&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Dans cette méthode j'utilise &lt;tt&gt;Faye::Channel::HANDSHAKE&lt;/tt&gt; et &lt;tt&gt;Faye::BAYEUX_VERSION&lt;/tt&gt;, deux constantes déclarées dans &lt;tt&gt;faye&lt;/tt&gt;. Si vous souhaitez être indépendant de ce dernier, vous pouvez remplacer ces valeurs par celle que j'ai indiquée. Vous noterez également que j'ai ajouté dans le message le paramètre optionnel &lt;tt&gt;id&lt;/tt&gt;. Ce paramètre permettra de valider, dans certains cas, que la réponse que nous recevons est bien celle attendu. En effet, si en retour nous retrouvons ce même ID c'est que, à priori tout va bien. Je dis bien &quot;à priori&quot;...&lt;/p&gt;

  &lt;p&gt;Je vous ai indiqué que la raison d'être de ce &lt;t&gt;handshake&lt;/i&gt; était de récupérer un identifiant client. C'est ce que nous faisons en parsant la réponse. Cette réponse peut avoir deux structures différentes en fonctions ou non de la présence d'erreur. Je ne détaillerai pas la structure complète, retenez seulement quand dans le cas présent nous devons avoir récupéré les données suivantes :&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;successful&lt;/tt&gt; : suffisament parlant je pense ;)&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;id&lt;/tt&gt; : qui doit correspondre à l'ID envoyé.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;clientId&lt;/tt&gt; : le clientId a utiliser par la suite.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Je ne parlerai pas de la valeur &lt;tt&gt;interval&lt;/tt&gt; que je récupère simplement en pensant à une prochaine évolution de ce petit développement...&lt;/p&gt;

  &lt;h3&gt;Connexion&lt;/h3&gt;

  &lt;p&gt;La connexion se fait en envoyant un message contenant les données suivantes :&lt;/p&gt;
  
  &lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;channel&lt;/tt&gt; : dans le cas d'une connexion nous utiliserons &lt;tt&gt;/meta/connect&lt;/tt&gt; qui sera ici récupéré via la constante &lt;tt&gt;Faye::Channel::CONNECT&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;clientId&lt;/tt&gt; : est la valeur récupérée lors du &lt;i&gt;handshake&lt;/i&gt;&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;connectionType&lt;/tt&gt; : je n'y reviens pas, mais vous l'avez compris, nous faisons du &lt;tt&gt;long-polling&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;id&lt;/tt&gt; : là encore, ce n'est que mimétisme.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Voici donc comment nous pouvons implémenter cela :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONNECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;connectionType&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;long-polling&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;A ce niveau, si vous faites un petit test, vous vous rendrez compte que la connexion attend une réponse de la part du serveur. En effet cette connexion attend que le bus Comet envoie des données. C'est ainsi que nous simulons le push ! Ce sont ces données que nous devrons donc traiter en fonction des souscriptions.&lt;/p&gt;

  &lt;p&gt;Pour savoir si le retour est exact, nous devons retrouver dans la structure JSON le champ &lt;tt&gt;successful&lt;/tt&gt; à &lt;tt&gt;true&lt;/tt&gt; et le champ &lt;tt&gt;id&lt;/tt&gt; avec la même valeur que celle envoyée.&lt;/p&gt;

  &lt;p&gt;Si tout se passe bien, alors nous pouvons récupérer les données du message dans la structure &lt;tt&gt;data&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONNECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;connectionType&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;long-polling&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# traitement du message contenu dans r[1][&amp;quot;data&amp;quot;] pour la souscription au channel r[1][&amp;quot;channel&amp;quot;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      
      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Nous verrons au paragraphe souscription comment traiter le message de réponse. Avant cela, détaillons ce que nous devons faire en cas d'échec. Le protocole Bayeux nous indique que dans un tel cas, il faut refaire un &lt;i&gt;handshake&lt;/i&gt; puis refaire la connexion. Cependant, comme la connexion elle-même est bloquante, dans le sens où elle attend une réponse, il serait bon de l'isoler dans un thread afin de permettre le déroulement de notre programme. De plus, si la connexion est un succès, une fois le message traité, il faut en rouvrir une de façon à se remettre en attente d'un nouveau &lt;i&gt;push&lt;/i&gt; du serveur. Pour cela nous pouvons placer la connexion dans une boucle infinie. &lt;/p&gt;

  &lt;p&gt;Voici donc comment nous allons gérer cela :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONNECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;connectionType&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;long-polling&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;# traitement du message contenu dans r[1][&amp;quot;data&amp;quot;] pour la souscription au channel r[1][&amp;quot;channel&amp;quot;]&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

          &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;handshake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;h3&gt;Souscription&lt;/h3&gt;

  &lt;p&gt;La souscription se fait pour un ou plusieurs channels avec, en second paramètre, la méthode qui doit être utilisée pour traiter les massages venant de ces channels. Nous avons déjà parlé des channels. Bien entendu dans le cas présent il s'agira de channels spécifiques à l'application. Concernant le callback, nous utiliserons un block.&lt;/p&gt;

  &lt;p&gt;Le message envoyé au bus Comet doit contenir les informations suivantes :&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;channel&lt;/tt&gt; : il ne s'agit pas, ici, du channel auquel nous souhaitons souscrire, mais celui utilisé par le protocole pour déclarer une souscription : &lt;tt&gt;/meta/subscribe&lt;/tt&gt;, ou, dans notre cas ou nous utilisons &lt;tt&gt;faye&lt;/tt&gt; : &lt;tt&gt;Faye::Channel::SUBSCRIBE&lt;/tt&gt;. &lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;clientId&lt;/tt&gt; : le client ID récupéré lors du &lt;i&gt;handshake&lt;/i&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;subscription&lt;/tt&gt; : ce paramètre prend en valeur un tableau des channels auxquels nous souhaitons souscrire.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;id&lt;/tt&gt; : l'id du message.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Comme vous pouvez le voir, nulle part nous ne stockons le callback à utiliser pour traiter les messages renvoyés. C'est normal puisque le bus Comet n'en à que faire puisqu'il seront exécutés côté client. Il nous appartient donc de les stocker. Nous ferons cela en mettant en place un hashage ayant pour clé le channel et comme valeur le block.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uri_or_string&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@subscriptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@subscriptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SUBSCRIBE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;subscription&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Je ne prends pas la peine de gérer le retour. Ce n'est pas bien !&lt;/p&gt;

  &lt;h3&gt;Connexion&lt;/h3&gt;

  &lt;p&gt;Nous pouvons maintenant revenir sur la connexion afin de traiter les messages. Il suffit donc de passer le message au block correspond au channel qui l'a poussé :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONNECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;connectionType&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;long-polling&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;vi&quot;&gt;@subscriptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;faild&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;handshake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;h3&gt;Publication&lt;/h3&gt;

  &lt;p&gt;La publication se fait par l'envoi d'un message contenant les champs suivants :&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;channel&lt;/tt&gt; : le channel destinataire du message.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;data&lt;/tt&gt; : les données, sous forme d'une structure JSON.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;clientId&lt;/tt&gt; : le fameux client ID.&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;id&lt;/tt&gt; : par habitude ;)&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Ceci nous donne donc le code suivant :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Encore une fois, je ne prends pas le temps de traiter la réponse... Encore une fois, ce n'est pas bien !!!&lt;/p&gt;

  &lt;h3&gt;... et leur contraire&lt;/h3&gt;

  &lt;p&gt;Là où il y a connexion, il y a forcement &quot;déconnexion&quot;, de même la où il y a souscription, il y a désabonnement. Je pense que vous avez compris le principe, et je me permets donc de vous livrer sans autre explication les méthodes correspondantes :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Faye&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;disconnect&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DISCONNECT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;unsubscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@subscriptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Channel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UNSUBSCRIBE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;clientId&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;subscription&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;h3&gt;Let's play !&lt;/h3&gt;

  &lt;p&gt;Maintenant que nous avons notre librairie cliente, nous pouvons développer un petit client en ligne de commande pour &lt;tt&gt;soapbox&lt;/tt&gt;.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;http://localhost:3000/comet&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-- handshake&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handshake&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-- subscriptions&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/mentioning/daemon&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/from/greg&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;user&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-- connect&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;quit&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chomp&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;quit&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;channel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/from/daemon&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;user&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;daemon&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;message&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;successful&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;=&amp;gt; Message not send !&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disconnect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

  &lt;p&gt;Bon, OK, c'est très très rudimentaire, mais vous avez compris ! Et le principal c'est que cela fonctionne :&lt;/p&gt;

  &lt;p&gt;&lt;img src=&quot;/images/posts/soapbox-console.png&quot; alt=&quot;soapbox-console&quot; title=&quot;soapbox-console&quot; width=&quot;100%&quot; class=&quot;alignnone size-full wp-image-809&quot; /&gt;&lt;/p&gt;

  &lt;h3&gt;A+&lt;/h3&gt;

  &lt;p&gt;&lt;/p&gt;&lt;b&gt;Attention&lt;/b&gt;, n'oubliez pas la remarque faite sur la page du projet faye : &lt;i&gt;it's a toy&lt;/i&gt;. Donc, tout comme ce qui précède, n'utilisez pas cela en production&lt;small&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/small&gt;. Et bien cela s'applique, à plus forte raison, à ce qui est écrit ci-dessus. Maintenant, si vous êtes joueur, vous pouvez récupérer cela dans les sources de &lt;tt&gt;Capcode&lt;/tt&gt; ou &lt;a href=&quot;http://gist.github.com/241065&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Notez que si je me suis attaché à &lt;tt&gt;faye&lt;/tt&gt;, ce petit client devrait pouvoir fonctionner avec toute solution Comet respectant le protocole Bayeux.&lt;/p&gt;

  &lt;p&gt;
    &lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; Merci !&lt;/small&gt;&lt;br /&gt;
    &lt;small&gt;&lt;sup&gt;2&lt;/sup&gt; :P&lt;/small&gt;&lt;br /&gt;
    &lt;small&gt;&lt;sup&gt;3&lt;/sup&gt; Ca peut paraitre idiot, cela n'en reste pas moins vrai !&lt;/small&gt;&lt;br /&gt;
    &lt;small&gt;&lt;sup&gt;4&lt;/sup&gt; On vous aura prévenu !&lt;/small&gt;&lt;br /&gt;
  &lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Notification, Comet, ... Capcode</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/11/21/notification-comet--capcode.html' />
    <id>http://algorithmique.net/Projets/2009/11/21/notification-comet--capcode</id>
    <updated>2009-11-21T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;&lt;img src=&quot;/images/dev.png&quot; alt=&quot;dev&quot; title=&quot;dev&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Depuis que nous développons des sites Web, nous avons pris l'habitude du &lt;i&gt;mode connecté&lt;/i&gt; imposé par le protocole HTTP. Rien ne nous surprend plus quand nos serveurs ne répondent qu'à des demandes explicites. Et nous vivons avec l'habitude de ce &lt;i&gt;dialogue de sourds&lt;/i&gt; ou le serveur répond à une requête en oubliant totalement ce qu'il a &lt;i&gt;dit&lt;/i&gt; à la demande précédente. Nous pallions généralement à ce problème en utilisant des principes de session et autre cookie, mais n'oublions pas que ces artefacts sont en fait gérés par le client à qui le serveur demande de stocker des &lt;i&gt;souvenirs&lt;/i&gt;. Depuis l'apparition des frameworks JavaScript comme Dojo, prototype, jQuery et consorts, nous mettons de plus en plus de mécanismes dans les pages Web qui évitent de reloader toute une page. Là encore, cela ne fait plus rêver personne et nous restons toujours dans un mode &lt;i&gt;requête/réponse&lt;/i&gt;. Là où nous écarquillons un peu plus les yeux, c'est quand une page Web affiche, sans que nous n'ayons rien demandé, de nouvelles informations. C'est tout le principe des &lt;i&gt;notifications&lt;/i&gt; et c'est ce que nous allons mettre en place ici.&lt;/p&gt;

&lt;h3&gt;Notifications ?&lt;/h3&gt;

&lt;p&gt;Une notification intervient quand un serveur envoie des données au client &lt;i&gt;quand il en a envie&lt;/i&gt;, et donc sans aucune demande du client. En dehors du Web, tous les systèmes de messagerie instantanés, par exemple, fonctionnent sur ce principe. Mais de par son côté &lt;i&gt;stateful&lt;/i&gt;, le protocole HTTP ne permet pas ce genre de chose. &lt;i&gt;&lt;b&gt;Faux !&lt;/b&gt;&lt;/i&gt; me direz-vous. La preuve par Google, ou plutôt Google Mail qui non seulement ne nous oblige pas à reloader sa page pour découvrir de nouveaux messages, mais qui en plus propose un service de messagerie instantanée aussi efficace que n'importe quel Skype ou MSN ! Et bien malheureusement, c'est vrai. Et si nous arrivons à faire de la notification via le Web ce n'est que par le truchement de bidouillages plus ou moins subtils qui vont permettre de le simuler. Depuis plusieurs années, nous désignons les mécanismes permettant de &lt;i&gt;faire du push&lt;/i&gt; HTTP sous le terme &lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_(programming)&quot;&gt;Comet&lt;/a&gt;, inventé par &lt;a href=&quot;http://alex.dojotoolkit.org/2006/03/comet-low-latency-data-for-the-browser/&quot;&gt;Alex Russell&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Comet&lt;/h3&gt;

&lt;p&gt;Comet est une désignation peu claire. En effet, personne ne sait très bien ce que recouvre ce terme. Globalement on lui attribut tous les mécanismes permettant de faire de la notification.&lt;/p&gt;

&lt;p&gt;Oui mais comment faire cela justement ?&lt;/p&gt;

&lt;p&gt;Dans son fonctionnement classique, un serveur HTTP attend une requête du client et renvoie une réponse :&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/ClassicHTTP.png&quot; alt=&quot;ClassicHTTP&quot; title=&quot;ClassicHTTP&quot; width=&quot;463&quot; height=&quot;279&quot; class=&quot;alignnone size-full wp-image-744&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Avec AJAX, nous avons rajouté, côté client, une couche entre l'utilisateur et le serveur. C'est elle qui reçoit les demandes du client, qui les transmet au serveur, qui reçoit la réponse, et elle se charge de mettre à jour la page. Ceci fait que les chargements sur la page ne sont pas forcement synchronisés avec les échanges qui ont lieu entre le moteur AJAX et le serveur : &lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/AJAXHTTP.png&quot; alt=&quot;AJAXHTTP&quot; title=&quot;AJAXHTTP&quot; width=&quot;464&quot; height=&quot;359&quot; class=&quot;alignnone size-full wp-image-745&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Cela permet ainsi de mettre à jour des informations dans la page sans tout recharger. Avec AJAX, nous pouvons déjà simuler un comportement de notifications. En effet, il suffit de demander au moteur AJAX d'envoyer une requête, à intervalle régulier au serveur, et si ce dernier à une nouvelle information, de l'afficher. Mais ce n'est pas du Comet. En effet, dans ce cas, ce n'est pas le serveur qui est à l'initiative de l'envoi de données. De plus, l'envoi de données par le serveur est rythmé par les demandes du client. Et même si elles peuvent être très rapprochées, elles ne donneront pas toujours le même sentiment de fluidité que nous retrouverons avec un Comet bien fait.&lt;/p&gt;

Avec Comet, nous allons remplacer le serveur AJAX pas un client Comet qui se placera entre le client et le serveur. Côté serveur, nous allons placer un &lt;i&gt;bus Comet&lt;/i&gt; chargé de communiquer avec le &lt;i&gt;service&lt;/i&gt; :

&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/CometHTTP.png&quot; alt=&quot;CometHTTP&quot; title=&quot;CometHTTP&quot; width=&quot;514&quot; height=&quot;435&quot; class=&quot;alignnone size-full wp-image-746&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Côté client, la connexion Comet est initialisée. A partir de là, le service enverra des évènements au bus Comet qui se chargera d'envoyer les informations nécessaires au client Comet qui à son tour mettra à jour la page Web. Bien entendu le client peut lui même envoyer de l'information au service par l'intermédiaire du client puis du bus Comet. Vous l'aurez compris, nous utilisons aussi de l'AJAX. Quant au service, cela peut être &lt;i&gt;n'importe quoi&lt;/i&gt; : un service de messagerie instantané, un serveur de données, ... bref n'importe quel service capable lui-même de pousser des données.&lt;/p&gt;

&lt;h3&gt;Capcode&lt;/h3&gt;

&lt;p&gt;Avec &lt;a href=&quot;http://github.com/glejeune/Capcode&quot;&gt;Capcode&lt;/a&gt; nous pouvons &lt;i&gt;faire du Comet&lt;/i&gt; en utilisant un middleware &lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt;. Personnellement j'en ai trouvé 2 : &lt;a href=&quot;http://github.com/macournoyer/pusher/&quot;&gt;Pusher&lt;/a&gt; et &lt;a href=&quot;http://github.com/jcoglan/faye/&quot;&gt;faye&lt;/a&gt;. Bien qu'un peu moins aboutit que le premier, je vous propose d'utiliser &lt;tt&gt;faye&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;faye&lt;/tt&gt; arrive avec &lt;a href=&quot;http://github.com/jcoglan/faye/tree/master/examples/soapbox/&quot;&gt;un exemple&lt;/a&gt; sous forme de messagerie instantanée &lt;i&gt;à la Twitter&lt;/i&gt;. Pour valider le fonctionnement de &lt;tt&gt;faye&lt;/tt&gt; avec &lt;tt&gt;Capcode&lt;/tt&gt;, je vous propose d'adapter cet exemple.&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;soapbox&lt;/tt&gt; est écrit comme une application &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;Sinatra&lt;/a&gt;. Le code de l'application est minimaliste :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;faye.server&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;erb&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:index&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;La seule chose remarquable ici est le fait que lors de l'accès à la racine de l'application, le serveur et modifié pour devenir le serveur &lt;tt&gt;faye&lt;/tt&gt; et que nous renvoyons la page &lt;tt&gt;index.erb&lt;/tt&gt;. Transformer cela en code &lt;tt&gt;Capcode&lt;/tt&gt; est ultra simple :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode/render/erb&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Capcode&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;views&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;       &lt;span class=&quot;vi&quot;&gt;@server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;faye.server&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:index&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Pour respecter ce qui est fait, nous créons un répertoire &lt;tt&gt;views&lt;/tt&gt; dans lequel nous placerons les templates &lt;tt&gt;Erb&lt;/tt&gt;, tout cela sans oublié de le déclarer (ligne 6).&lt;/p&gt;

&lt;p&gt;Si nous regardons maintenant le fichier de configuration pour &lt;tt&gt;Rack&lt;/tt&gt;, nous avons cela :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/../../lib/faye&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/app&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RackAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:mount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/comet&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sinatra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

Ajouter cela dans &lt;tt&gt;Capcode&lt;/tt&gt; est là encore trivial :

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode/render/erb&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;faye&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Capcode&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;views&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RackAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:mount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/comet&amp;#39;&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;faye.server&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:index&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si maintenant nous regardons le template &lt;tt&gt;Erb&lt;/tt&gt; nous voyons qu'il utilise une CSS et trois fichiers JavaScript :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.0 Transitional//EN&amp;quot;&amp;gt;&lt;/span&gt;
 
&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;http-equiv=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Content-type&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/html&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt; charset=utf-8&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Faye demo: chat client&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/style.css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;media=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;screen&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/jquery.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/comet.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/soapbox.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt; 

&lt;p&gt;Les fichiers &lt;tt&gt;style.css&lt;/tt&gt;, &lt;tt&gt;jquery.js&lt;/tt&gt; et &lt;tt&gt;soapbox.js&lt;/tt&gt; se trouvent dans le répertoire &lt;tt&gt;public&lt;/tt&gt;. Nous devons donc créer ce même répertoire et déclarer son existence dans &lt;tt&gt;Capcode&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;capcode/render/erb&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;faye&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Capcode&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;views&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:static&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;public&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Faye&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RackAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:mount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/comet&amp;#39;&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;faye.server&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:erb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:index&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Puis nous modifions le template &lt;tt&gt;Erb&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.0 Transitional//EN&amp;quot;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;http-equiv=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Content-type&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/html&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt; charset=utf-8&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Faye demo: chat client&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/public/style.css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;media=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;screen&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/public/jquery.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/comet.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/public/soapbox.js&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Oui, mais le fichier &lt;tt&gt;comet.js&lt;/tt&gt; ??? Et bien si vous regardez la documentation de &lt;tt&gt;faye&lt;/tt&gt;, vous verrez que le simple fait de déclarer l'utilisation du middleware &lt;tt&gt;faye&lt;/tt&gt; met automatiquement en place un bus Comet accessible via la route &lt;tt&gt;/comet&lt;/tt&gt; et met à disposition la librairie JavaScript cliente via la route &lt;tt&gt;/comet.js&lt;/tt&gt;. Donc, nous n'avons rien de plus à faire pour ce fichier.&lt;/p&gt;

&lt;p&gt;Vous pouvez maintenant démarrer l'application et tester :&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/comet-example.png&quot; alt=&quot;comet-example&quot; title=&quot;comet-example&quot; width=&quot;547&quot; height=&quot;800&quot; class=&quot;alignnone size-full wp-image-758&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Cet exemple a été &lt;a href=&quot;http://github.com/glejeune/Capcode/tree/master/examples/soapbox/&quot;&gt;ajouté dans les sources de Capcode&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Toute l'intelligence de l'exemple se trouve non seulement fans &lt;tt&gt;faye&lt;/tt&gt; mais également dans le fichier &lt;tt&gt;soapbox.js&lt;/tt&gt; que je vous engage vivement à regarder, tout comme la documentation de &lt;tt&gt;faye&lt;/tt&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Sequel sans... séquelle ;)</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/11/12/sequel-sans-sequelle.html' />
    <id>http://algorithmique.net/Projets/2009/11/12/sequel-sans-sequelle</id>
    <updated>2009-11-12T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;&lt;img src=&quot;/images/ruby.png&quot; alt=&quot;ruby&quot; title=&quot;ruby&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;alignleft size-full wp-image-566&quot; /&gt;Il y a quelques jours, je vous proposais une solution pour utiliser &lt;a href=&quot;/Projets/2009/11/07/activerecord-sans-rails.html&quot;&gt;ActiveRecord sans Rails&lt;/a&gt;. Comme je vous l'avais indiqué, cette idée n'avait pour seul but que de permettre une utilisation d'Active Record &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/lib/capcode/base/ar.rb&quot;&gt;dans&lt;/a&gt; &lt;a href=&quot;http://github.com/glejeune/Capcode&quot;&gt;Capcode&lt;/a&gt;. C'est maintenant au tour de &lt;a href=&quot;http://sequel.rubyforge.org/&quot;&gt;Sequel&lt;/a&gt;...&lt;/p&gt;

&lt;p&gt;Contrairement à &lt;tt&gt;ActiveRecord&lt;/tt&gt;, &lt;tt&gt;Sequel&lt;/tt&gt; n'a pas été développé &lt;i&gt;pour&lt;/i&gt; un framework. Ce n'est pas non plus (&lt;i&gt;initialement&lt;/i&gt;) un ORM, mais une librairie d'accès pour des bases de données, un peu comme &lt;a href=&quot;http://ruby-dbi.rubyforge.org/&quot;&gt;DBI&lt;/a&gt;. Cependant, contrairement à ce dernier, il se rapproche de &lt;tt&gt;DataMapper&lt;/tt&gt; ou &lt;tt&gt;ActiveRecord&lt;/tt&gt; par sont côté &lt;i&gt;SQL dissimulé&lt;/i&gt;. Bref, &lt;tt&gt;Sequel&lt;/tt&gt; se situe entre &lt;tt&gt;DBI&lt;/tt&gt; et &lt;tt&gt;ActiveRecord&lt;/tt&gt;/&lt;tt&gt;DataMapper&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Voici un petit exemple :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rubygems&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sequel&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Création d&amp;#39;une table &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Ajout de données dans la table&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Muriel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;leiruM&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Greg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gerG&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Affichage du contenu de la table &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;J'ai dit un peu plus haut que &lt;tt&gt;Sequel&lt;/tt&gt; n'était pas un ORM. Ce n'est pas tout à fait vrai. En effet, il offre la possibilité d'être utilisé comme tel :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rubygems&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sequel&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Création d&amp;#39;une table &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mapping&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Ajout de données dans la table&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Muriel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;leiruM&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Greg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gerG&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Affichage du contenu de la table &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Bon, mais quel est l'objectif recherché me demanderez-vous ? Et bien simplement de palier à certains petits défauts de conception qui me dérange dans &lt;tt&gt;Sequel&lt;/tt&gt;. &lt;/p&gt;

&lt;h3&gt;Déclaration des modèles&lt;/h3&gt;

&lt;p&gt;Il est impossible dans &lt;tt&gt;Sequel&lt;/tt&gt; de déclarer un modèle si la table correspondante n'existe pas, ou, tout au moins, si la connexion à la base n'a pas été faite avant cette déclaration. Ainsi, faire ceci provoque une erreur :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Mapping&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; Sequel::Error: No database associated with Sequel::Model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si par contre nous faisons la connexion avant, cela semble fonctionner :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mapping&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#:users&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Je dis bien &lt;i&gt;semble&lt;/i&gt;, car en fait le comportement de la classe &lt;tt&gt;User&lt;/tt&gt; n'est pas le même si la table existe avant la déclaration du modèle. Ainsi, si vous faites ceci :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mapping&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Vous pourrez utiliser la classe &lt;tt&gt;User&lt;/tt&gt; en considérant les champs de la table &lt;tt&gt;users&lt;/tt&gt; comme des accesseurs de cette classe :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si par contre vous créez la table &lt;i&gt;après&lt;/i&gt; avoir déclaré le modèle, votre classe &lt;tt&gt;User&lt;/tt&gt; n'a plus le même comportement et vous devez passer par la méthode &lt;tt&gt;values&lt;/tt&gt; de la classe &lt;tt&gt;User&lt;/tt&gt; qui renvoie un hashage des données :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mapping&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#:users&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Affichage du contenu de la table &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Tout cela n'est pas très &lt;i&gt;rigoureux&lt;/i&gt; et pas réellement exploitable.&lt;/p&gt;

&lt;h3&gt;Création de table et migration&lt;/h3&gt;

&lt;p&gt;Pour la création des tables, là encore j'ai un problème. En effet, comme vous avez pu le constater, la méthode &lt;tt&gt;create_table&lt;/tt&gt; est une méthode d'instance de &lt;tt&gt;Sequel::Database&lt;/tt&gt; récupérée via une connexion (&lt;tt&gt;Sequel.connect&lt;/tt&gt;). Ceci implique que nous ne pouvons &lt;i&gt;proposer&lt;/i&gt; un schéma de table qu'après avoir initialisé la connexion à la base. Si cela semble tout à fait logique, cela peut entrainer pas mal de contraintes dans certains cas. &lt;i&gt;Oui, mais pas avec Capcode !&lt;/i&gt; Effectivement, les méthodes &lt;tt&gt;Capcode.run&lt;/tt&gt; et &lt;tt&gt;Capcode.application&lt;/tt&gt; prenant en paramètre un bloc, il est possible de créer les tables dans ce bloc. Cependant, cela rompt avec la philosophie souhaitée pour l'utilisation de ce bloc&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt; qui veut que l'on réserve ce bloc pour y placer des éléments de configuration de l'application (remplissage de table, ...) et non pas du code pour l'application.&lt;/p&gt;

&lt;p&gt;Si vous avez l'habitude d'utiliser &lt;tt&gt;ActiveRecord&lt;/tt&gt; ou &lt;tt&gt;DataMapper&lt;/tt&gt; ce type de problème ne vous aura jamais dérangé parce que dans le premier cas vous utilisez les migrations, et donc vous générez le schéma à priori, et dans le second, le schéma fait partie intégrante du modèle et il est donc créé &lt;i&gt;automatiquement&lt;/i&gt;&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt;.&lt;/p&gt;

&lt;p&gt;Heureusement&lt;small&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/small&gt; &lt;tt&gt;Sequel&lt;/tt&gt; offre la possibilité d'utiliser des &lt;a href=&quot;http://sequel.rubyforge.org/rdoc/classes/Sequel/Migration.html&quot;&gt;migrations&lt;/a&gt;. Pour cela, vous avez plusieurs solutions. Soit définir vos migrations dans des fichiers et utiliser l'option &lt;tt&gt;-m&lt;/tt&gt; de l'outil &lt;tt&gt;sequel&lt;/tt&gt;, soit utiliser la méthode &lt;tt&gt;apply&lt;/tt&gt; de &lt;tt&gt;Sequel::Migration&lt;/tt&gt;. Grâce à cette dernière possibilité, nous pouvons résoudre le problème évoqué en décrivant le schéma dans une migration et en faisant la migration juste après la connexion :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rubygems&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sequel&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Chargement de l&amp;#39;extension permettant les migrations&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:migration&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Migration&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateUser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;primary_key&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;down&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;drop_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Connection à une base SQLite &lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite://test.db&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mise en place du schéma&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;CreateUser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:up&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3&gt;So what ?&lt;/h3&gt;

&lt;p&gt;Avec tout ce que nous venons de voir, nous sommes en mesure de mettre en place une classe mimant ce que nous &lt;a href=&quot;/Projets/2009/11/07/activerecord-sans-rails.html&quot;&gt;avons fait&lt;/a&gt; avec &lt;tt&gt;ActiveRecord&lt;/tt&gt; mais pour &lt;tt&gt;Sequel&lt;/tt&gt;. Donc nous pouvons repartir d'un exemple similaire&lt;small&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/small&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sq&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Mise en place des migrations (versionnées)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateUsers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Schema&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
 
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;down&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;drop_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreatePosts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Schema&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:posts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
 
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;down&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;drop_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:posts&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Création des modèles&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Connexion&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;test.yml&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;test.log&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Utilisation&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Muriel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;leiruM&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Greg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gerG&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;La mise en place des schémas est quasiment identique à ce que nous avons fait avec &lt;tt&gt;ActiveRecord&lt;/tt&gt; et nous allons encore une fois déclarer une méthode de classe qui renverra une classe qui sera, dans le cas présent, de type &lt;tt&gt;Sequel::Migration&lt;/tt&gt;. Par la suite, dans la méthode de connexion (&lt;tt&gt;SQ.db_connect&lt;/tt&gt;), nous suivrons exactement le même procédé que celui imaginé pour &lt;tt&gt;ActiveRecord&lt;/tt&gt;, en s'adaptant juste au comportement de &lt;tt&gt;Sequel&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SQ&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;meta_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;meta_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:inherited&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logfile&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;dbconfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YAML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys_to_sym&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:adapter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:adapter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite3&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      
      &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@cnx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table?&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;nb&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:up&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:down&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Nous allons cependant devoir faire quelques adaptations mineures dans ce code pour régler le cas des modèles. Il n'est en effet pas possible d'utiliser les modèles proposés par &lt;tt&gt;Sequel&lt;/tt&gt;, mais ceci ne nous empêche pas de les mimer. Pour cela nous allons créer de toutes pièces la classe &lt;tt&gt;SQ::Model&lt;/tt&gt; et nous ferons en sorte qu'elle réponde, via ses méthodes de classe, aux mêmes méthodes que &lt;a href=&quot;http://sequel.rubyforge.org/rdoc/classes/Sequel/Dataset.html&quot;&gt;Sequel::Dataset&lt;/a&gt;. Par example la classe &lt;tt&gt;User&lt;/tt&gt; répondra aux même méthodes que DB[:users]. Or &lt;tt&gt;:users == User.to_s.tableize.to_sym&lt;/tt&gt;, ce qui rende la mise en place de la classe &lt;tt&gt;SQ::Model&lt;/tt&gt; extrêmement simple :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SQ&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Model&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;block_given?&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tableize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__send__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tableize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__send__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Le seul élément vraiment remarquable dans ce code est l'utilisation de &lt;tt&gt;SQ::db&lt;/tt&gt; sensé représenter la connexion. Et c'est là que nous devons modifier le code de la partie schéma pour permettre de partager la connexion au sein du module &lt;tt&gt;SQ&lt;/tt&gt;. Pour cela nous mettons en place la méthode suivante :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SQ&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@dbconfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Puis nous supprimons la ligne &lt;tt&gt;db = Sequel.connect(@cnx)&lt;/tt&gt; dans &lt;tt&gt;SQ::db_connect&lt;/tt&gt;, nous remplaçons partout l'utilisation de la variable &lt;tt&gt;db&lt;/tt&gt; par &lt;tt&gt;SQ::db&lt;/tt&gt; et nous modifions la variable &lt;tt&gt; dbconfig&lt;/tt&gt; en la passant en variable d'instance. Finalement, le code complet est le suivant :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sequel&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt;   &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:migration&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;   &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:inflector&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LoadError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LoadError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sequel ne doit pas être installé : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;meta_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:define_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hash&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;keys_to_sym&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SQ&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Model&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;block_given?&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt;         &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tableize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__send__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt;         &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tableize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__send__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;32&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;35&lt;/span&gt;   
&lt;span class=&quot;lineno&quot;&gt;36&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;37&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;38&lt;/span&gt;       &lt;span class=&quot;vi&quot;&gt;@db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@dbconfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;39&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;40&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;41&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;42&lt;/span&gt;       &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;43&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;44&lt;/span&gt;       &lt;span class=&quot;no&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;45&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;meta_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;46&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;meta_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:inherited&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;47&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;48&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;49&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;50&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logfile&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;51&lt;/span&gt;       &lt;span class=&quot;vi&quot;&gt;@dbconfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YAML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys_to_sym&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;52&lt;/span&gt;       &lt;span class=&quot;vi&quot;&gt;@dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:adapter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:adapter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;sqlite3&amp;quot;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;53&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbconfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@final&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;54&lt;/span&gt;       
&lt;span class=&quot;lineno&quot;&gt;55&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;56&lt;/span&gt;         &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_table?&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;57&lt;/span&gt;           &lt;span class=&quot;nb&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;58&lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;59&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;60&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;61&lt;/span&gt;         &lt;span class=&quot;vi&quot;&gt;@migrations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;62&lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:up&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;63&lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:down&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;64&lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;65&lt;/span&gt;         &lt;span class=&quot;no&quot;&gt;SQ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:schema_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;si&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;66&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;67&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;68&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;69&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notez que nous utilisons l'extension &lt;tt&gt;inflector&lt;/tt&gt; afin de pouvoir utiliser la méthode &lt;tt&gt;String.tableize&lt;/tt&gt; et que nous prenons en compte (ligne 51) le fait que &lt;tt&gt;Sequel&lt;/tt&gt; permet d'utiliser SQLite en nommant sont adaptateur &lt;tt&gt;sqlite&lt;/tt&gt; là ou les &lt;i&gt;autres&lt;/i&gt; utilisent &lt;tt&gt;sqlite3&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Voilà, tout ceci a été &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/lib/capcode/base/sq.rb&quot;&gt;mis en place&lt;/a&gt; dans &lt;tt&gt;Capcode&lt;/tt&gt; et un &lt;a href=&quot;http://github.com/glejeune/Capcode/blob/master/examples/blog-sq.rb&quot;&gt;petit example&lt;/a&gt; illustre comment l'utiliser.&lt;/p&gt;

&lt;p&gt;
  &lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; Laquelle ?&lt;/small&gt;&lt;br /&gt;
  &lt;small&gt;&lt;sup&gt;2&lt;/sup&gt; Tout ceci est extrêmement schématique, je sais, mais je ne m'étendrais pas plus sur le sujet.&lt;/small&gt;&lt;br /&gt;
  &lt;small&gt;&lt;sup&gt;3&lt;/sup&gt; Faudrait savoir ! Un coup on aime, un coup on aime pas les migrations !&lt;/small&gt;&lt;br /&gt;
  &lt;small&gt;&lt;sup&gt;4&lt;/sup&gt; Pour des questions de bonne compréhension, nous placerons notre code dans le module &lt;tt&gt;SQ&lt;/tt&gt; là ou nous utilisions &lt;tt&gt;AR&lt;/tt&gt;...&lt;/small&gt;&lt;br /&gt;
&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Happy happymapper</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Dev/2009/11/09/happy-happymapper.html' />
    <id>http://algorithmique.net/Dev/2009/11/09/happy-happymapper</id>
    <updated>2009-11-09T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;&lt;img src=&quot;/images/dev.png&quot; alt=&quot;dev&quot; title=&quot;dev&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;alignleft size-full wp-image-562&quot; /&gt;Si vous suivez ce blog, vous savez que je &lt;a href=&quot;http://www.algorithmique.net/2009/04/10/cappuccino-capcode-vidal/&quot;&gt;travaille&lt;/a&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt; depuis plusieurs mois sur un outil permettant de montrer la puissance des APIs développées dans la &lt;a href=&quot;http://www.vidal.fr&quot;&gt;boite&lt;/a&gt; dans laquelle je travaille. L'outil en question, outre sont côté fonctionnel spécifique, présente la particularité de fonctionner avec l'ensemble des bases de données médicamenteuses proposées par VIDAL. J'entends par là le fait que les données étant diffusées à &lt;a href=&quot;http://www.vidal.fr/actualites/44-cap-a-linternational&quot;&gt;l'international&lt;/a&gt;, il existe, non seulement une version Française, mais également une version pour les Emirats Arabes Unis, pour l'Espagne, le Portugal, ... Et alors ?&lt;/p&gt;

&lt;p&gt;Et alors, ce besoin a des impacts non négligeables sur le développement de certaines fonctions. Je ne vais pas entrer dans les détails de la sécurisation d'une prescription, mais juste vous dire que pour la prise en compte de l'état pathologique d'un patient, nous codons cet état via la &lt;a href=&quot;http://fr.wikipedia.org/wiki/Classification_internationale_des_maladies&quot;&gt;CIM&lt;/a&gt;. Or l'utilisation de cette classification, et plus fortement sa diffusion, est soumise à une licence payante pour chaque pays. Or VIDAL n'ayant acquis qu'une licence pour la France, les versions internationales de la base n'intègrent pas les libellés de la CIM. Tout mon problème était de savoir comment permettre de travailler avec ces libellés quand la démo se fait à l'international ? Plus précisément, comment faire en sorte qu'une personne ayant acquis la licence puisse utiliser mon outil avec &lt;i&gt;sa&lt;/i&gt; CIM.&lt;/p&gt;

&lt;p&gt;Initialement, j'avais opté pour une solution consistant à déporter la classification dans une base &lt;a href=&quot;http://www.sqlite.org/&quot;&gt;SQLite&lt;/a&gt; ne contenant qu'une seule table avec trois colonnes :&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/images/posts/cim10.png&quot; alt=&quot;cim10&quot; title=&quot;cim10&quot; width=&quot;99&quot; height=&quot;99&quot; class=&quot;aligncenter size-full wp-image-705&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Par défaut cette base ne contenait que les codes CIM sans les libellés. Il suffisait, localement, de remplacer le fichier SQLite pour pouvoir accéder aux libellés.&lt;/p&gt;

&lt;p&gt;Tout cela était sans compter sur le fait que les personnes qui ont besoin de cet outil ont souvent une approche technique proche de l'état larvaire, et que leur demander de créer un fichier SQLite, aussi simple soit-il, tient du roman de science-fiction chez certains&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt;. J'ai donc dû chercher du côté des outils plus &lt;i&gt;classiques&lt;/i&gt; de cette population chez qui Excel est un prolongement synaptique. J'ai alors découvert que ce merveilleux outil est &lt;a href=&quot;http://dj.joss.free.fr/xml.htm&quot;&gt;capable de générer des fichiers XML&lt;/a&gt;. Sauvé&lt;small&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/small&gt; !&lt;/p&gt;

&lt;p&gt;Maintenant que nous savons que nous pouvons utiliser du XML, un simple fichier formaté comme ce qui suit suffit :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;cims&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;cim10&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;code&amp;gt;&lt;/span&gt;A00.-&lt;span class=&quot;nt&quot;&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;parent&amp;gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Cholera&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/cim10&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;cim10&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;code&amp;gt;&lt;/span&gt;A00.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;A00.-&lt;span class=&quot;nt&quot;&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Choléra classique&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/cim10&amp;gt;&lt;/span&gt;

  ...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/cims&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Parcourir un fichier XML est une chose relativement facile avec Ruby. Il existe un grand nombre de modules pour nous y aider. Dans le cas présent, j'ai choisis &lt;a href=&quot;http://github.com/jnunemaker/happymapper&quot;&gt;HappyMapper&lt;/a&gt;. Ce dernier permet mapper du XML dans des objets. Ainsi, avec le fichier XML des codes CIM, il suffit de créer l'objet suivant :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cim10&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HappyMapper&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si ensuite nous parsons le contenu du fichier XML (via &lt;tt&gt;Cim10.parser&lt;/tt&gt; nous obtenons un tableau d'objets &lt;tt&gt;Cim10&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;cims&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Cim10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cim10-fr.xml&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Tout le problème maintenant c'est de pouvoir faire des recherches dans ce tableau. Pour cela je me suis amusé à transformer le tableau de sortie en utilisant une nouvelle classe : &lt;tt&gt;HappyArray&lt;/tt&gt; :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rubygems&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;active_record/dynamic_finder_match&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HappyArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HappyArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cim&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cim&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cim&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keep&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DynamicFinderMatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;finder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attribute_names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;finder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HappyMapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Cette classe me permet ainsi de faire ceci :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;cims&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Cim10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cim10-fr.xml&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;happyCims&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HappyArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;happyCims&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;choléra&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; Tableau des objets Cim10 dont le libellé contient le terme &amp;quot;choléra&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;happyCims&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_by_label_and_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;choléra&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;vaccin&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A00&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; Tableau des objets Cim10 dont le libellé contient &amp;quot;choléra&amp;quot; ou &amp;quot;vaccin&amp;quot; et dont le code contient &amp;quot;A00&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Je n'ai pas voulu ajouter les méthodes de la classe &lt;tt&gt;HappyArray&lt;/tt&gt; à la classe &lt;tt&gt;Array&lt;/tt&gt; car finalement elles ne peuvent servir que dans le cas d'une utilisation avec &lt;tt&gt;HappyMapper&lt;/tt&gt;. La question maintenant c'est de savoir si je sécurise un peu ce code et le propose comme patch pour &lt;tt&gt;HappyMapper&lt;/tt&gt; ou pas ?&lt;/p&gt;

&lt;p&gt;
  &lt;small&gt;&lt;sup&gt;1&lt;/sup&gt; Vous pouvez aussi regarder &lt;a href=&quot;http://www.algorithmique.net/2009/09/18/carte-heuristique-et-base-de-donnees/&quot;&gt;ceci&lt;/a&gt; ;)&lt;/small&gt;&lt;br /&gt;
  &lt;small&gt;&lt;sup&gt;2&lt;/sup&gt; &lt;a href=&quot;http://www.algorithmique.net/2009/10/06/semaine-23/&quot;&gt;Suivez mon regard...&lt;/a&gt;&lt;/small&gt;&lt;br /&gt;
  &lt;small&gt;&lt;sup&gt;3&lt;/sup&gt; Enfin presque... Le problème, maintenant, va être d'expliquer comment faire :(&lt;/small&gt;
&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>ActiveRecord sans Rails</title>
    <link rel='alternate' type='text/html' href='http://algorithmique.net/Projets/2009/11/07/activerecord-sans-rails.html' />
    <id>http://algorithmique.net/Projets/2009/11/07/activerecord-sans-rails</id>
    <updated>2009-11-07T00:00:00Z</updated>

    <author>
      <name>Gregoire Lejeune</name>
      <uri>http://algorithmique.net</uri>
      <email>gregoire.lejeune@free.fr</email>
    </author>

    <content type="html">&lt;p&gt;&lt;img src=&quot;/images/ruby.png&quot; alt=&quot;ruby&quot; title=&quot;ruby&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;alignleft size-full wp-image-566&quot; /&gt;Si vous recherchez sur Google comment utiliser &lt;a href=&quot;http://www.google.com/search?client=safari&amp;rls=en&amp;q=activerecord+without+rails&amp;ie=UTF-8&amp;oe=UTF-8&quot;&gt;ActiveRecord sans Rails&lt;/a&gt;, vous verrez qu'il existe pas mal de pages sur le sujet. Le problème est que l'on vous y raconte toujours la même histoire, à savoir comment établir une connexion vers une base existante. Quant à savoir comment créer le schéma de la base, c'est une autre histoire. Là encore, Google nous permet de trouver &lt;a href=&quot;http://www.google.com/search?client=safari&amp;rls=en&amp;q=activerecord+migration+without+rails&amp;ie=UTF-8&amp;oe=UTF-8&quot;&gt;quelques pistes&lt;/a&gt;, mais rien de bien satisfaisant. A part peut-être le &lt;a href=&quot;http://blog.aizatto.com/2007/05/27/activerecord-migrations-without-rails/&quot;&gt;premier résultat&lt;/a&gt; qui propose d'utiliser les migrations dans des fichiers séparés, un Rakefile, bref une artillerie un peu lourde&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/small&gt;. Voyons comment faire &lt;i&gt;plus simple&lt;/i&gt;.&lt;/p&gt;

&lt;h3&gt;ActiveRecord&lt;/h3&gt;

&lt;p&gt;Pour utiliser &lt;tt&gt;ActiveRecord&lt;/tt&gt; nous avons besoin d'au moins&lt;small&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/small&gt; deux choses : un schéma et un modèle. En général les schémas sont mis en place via les &lt;a href=&quot;http://v-dubois.developpez.com/ruby-on-rails/active-record-migrations/&quot;&gt;migrations&lt;/a&gt;. Pour cela, Rails créés dans le répertoire &lt;tt&gt;db/migrate&lt;/tt&gt; des fichiers définissant des classes héritant de &lt;tt&gt;ActiveRecord::Migration&lt;/tt&gt;. Les modèles sont, eux, placés dans le répertoire &lt;tt&gt;app/models&lt;/tt&gt; de l'application Rails. Ils définissent des classes héritant d'&lt;tt&gt;ActiveRecord::Base&lt;/tt&gt;. En général, modèles et migrations sont créés &lt;i&gt;en même temps&lt;/i&gt;. Quand vous créez un modèle, Rails génère en même temps une migration :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ruby script/generate model user
      exists  app/models/
      exists  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/
      exists  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/fixtures/
      create  app/models/user.rb
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/user_test.rb
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/fixtures/users.yml
      create  db/migrate
      create  db/migrate/20091106191317_create_users.rb
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Le fichier de migration ainsi généré contiendra le code suivant :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateUsers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timestamps&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;down&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;drop_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Le fichier du modèle sera lui beaucoup plus court :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si nous voulons utiliser notre modèle, il faut maintenant faire deux petites choses.&lt;/p&gt;

&lt;b&gt;1. Compléter le schéma&lt;/b&gt;

&lt;p&gt;En fait de schéma, c'est bien au fichier de migration que je pense. En effet, pour le moment notre table &lt;tt&gt;users&lt;/tt&gt; ne contient que les champs de &lt;tt&gt;timestamps&lt;/tt&gt;, et il faut donc y ajouter les champs permettant de définir un utilisateur.&lt;/p&gt;

&lt;b&gt;2. Faire la migration&lt;/b&gt;

&lt;p&gt;Pour cela il faut lancer un &lt;tt&gt;rake db:migrate&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;Une fois cela fait, nous pouvons utiliser le modèle &lt;tt&gt;User&lt;/tt&gt; dans nos contrôleurs.&lt;/p&gt;

&lt;p&gt;Comme vous avez dû le comprendre au début de ce post, je trouve tout cela un peu lourd. Non seulement il faut, exploser les choses en une multitude de fichiers, mais il faut en plus un &lt;tt&gt;Rackfile&lt;/tt&gt;. En ce qui me concerne j'aimerai pouvoir lancer une application Ruby utilisant &lt;tt&gt;ActiveRecord&lt;/tt&gt;, que la base soit créée (ou mise à jour) s'il y a besoin, et tout cela, en ayant la possibilité de tout mettre dans un seul fichier... Bref, idéalement je voudrais pouvoir faire cela :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;active_record&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DBSchema&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;down&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;drop_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;establish_connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;test.yml&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:login&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Muriel&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;leiruM&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot