diff --git a/amber/afi/js/AFI-Tests.deploy.js b/amber/afi/js/AFI-Tests.deploy.js
index 6571a1fdf3b72eaae22c7cda91d10dda3233f106..1345915c086ac98d5ad944758b22a60cc1ae0332 100644
--- a/amber/afi/js/AFI-Tests.deploy.js
+++ b/amber/afi/js/AFI-Tests.deploy.js
@@ -1,100 +1,140 @@
 smalltalk.addPackage('AFI-Tests', {});
-smalltalk.addClass('CycleTest', smalltalk.TestCase, [], 'AFI-Tests');
+smalltalk.addClass('BibNumAlbumTestCase', smalltalk.TestCase, ['ajax', 'container', 'album'], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_testCycleWithTwoElements'),
+unescape('_setUp'),
 smalltalk.method({
-selector: unescape('testCycleWithTwoElements'),
+selector: unescape('setUp'),
 fn: function (){
 var self=this;
-var cycle=nil;
-(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two"]]));
-smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_location", []), "_hash_", [" "]);
+(self['@ajax']=smalltalk.send((smalltalk.AMockWrapper || AMockWrapper), "_on_", [smalltalk.send((smalltalk.Ajax || Ajax), "_new", [])]));
+smalltalk.send(self['@ajax'], "_onMessage_answer_", ["send", self['@ajax']]);
+(self['@container']=smalltalk.send(smalltalk.send(unescape("%3Cdiv%3E%3C/div%3E"), "_asJQuery", []), "_width_", [(500)]));
+(self['@album']=(function($rec){smalltalk.send($rec, "_ajax_", [self['@ajax']]);return smalltalk.send($rec, "_container_", [self['@container']]);})(smalltalk.send((smalltalk.BibNumAlbum || BibNumAlbum), "_new", [])));
 return self;}
 }),
-smalltalk.CycleTest);
+smalltalk.BibNumAlbumTestCase);
 
 smalltalk.addMethod(
-unescape('_testCycleWithFourElements'),
+unescape('_tearDown'),
 smalltalk.method({
-selector: unescape('testCycleWithFourElements'),
+selector: unescape('tearDown'),
 fn: function (){
 var self=this;
-var cycle=nil;
-(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two", "three", "four"]]));
-smalltalk.send((3), "_timesRepeat_", [(function(){smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["three", smalltalk.send(cycle, "_next", [])]);return smalltalk.send(self, "_assert_equals_", ["four", smalltalk.send(cycle, "_next", [])]);})]);
+smalltalk.send(self['@container'], "_remove", []);
 return self;}
 }),
-smalltalk.CycleTest);
+smalltalk.BibNumAlbumTestCase);
 
 
 
-smalltalk.addClass('SouvignyBibleTest', smalltalk.TestCase, ['bible'], 'AFI-Tests');
+smalltalk.addClass('BibNumAlbumDonjonTest', smalltalk.BibNumAlbumTestCase, ['ajax', 'container', 'album'], 'AFI-Tests');
+smalltalk.addMethod(
+unescape('_donjonJSON'),
+smalltalk.method({
+selector: unescape('donjonJSON'),
+fn: function (){
+var self=this;
+return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A4%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Donjon%20Zenith%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22Une%20bonne%20bagarre%22%2C%0A%09%09%09%09%09%22width%22%3A%20200%2C%0A%09%09%09%09%09%22height%22%3A%2050%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Donjon%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/4/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/4/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/4.jpg%22%7D%0A%09%09%09%09%5D%0A%09%09%7D%20%7D");
+return self;}
+}),
+smalltalk.BibNumAlbumDonjonTest);
+
 smalltalk.addMethod(
 unescape('_setUp'),
 smalltalk.method({
 selector: unescape('setUp'),
+fn: function (){
+var self=this;
+smalltalk.send(self, "_setUp", [], smalltalk.BibNumAlbumTestCase);
+(function($rec){smalltalk.send($rec, "_url_", ["donjon.json"]);return smalltalk.send($rec, "_load", []);})(self['@album']);
+smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send(self, "_donjonJSON", [])]);
+return self;}
+}),
+smalltalk.BibNumAlbumDonjonTest);
+
+smalltalk.addMethod(
+unescape('_testAnchorToDownloadPDFShouldNotBePresent'),
+smalltalk.method({
+selector: unescape('testAnchorToDownloadPDFShouldNotBePresent'),
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", [(0), smalltalk.send(smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_at_", ["size"]), "_value", [])]);
+return self;}
+}),
+smalltalk.BibNumAlbumDonjonTest);
+
+
+
+smalltalk.addClass('BibNumAlbumTintinTest', smalltalk.BibNumAlbumTestCase, ['bible', 'album', 'container', 'ajax'], 'AFI-Tests');
+smalltalk.addMethod(
+unescape('_setUp'),
+smalltalk.method({
+selector: unescape('setUp'),
+fn: function (){
+var self=this;
+smalltalk.send(self, "_setUp", [], smalltalk.BibNumAlbumTestCase);
+(function($rec){smalltalk.send($rec, "_url_", [unescape("/bib-numerique/album/id/2.json")]);smalltalk.send($rec, "_scriptsRoot_", [unescape("http%3A//localhost/afi-opac3/amber/afi/souvigny/")]);return smalltalk.send($rec, "_load", []);})(self['@album']);
+smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send((typeof jQuery == 'undefined' ? nil : jQuery), "_parseJSON_", [smalltalk.send(self, "_tintinJSON", [])])]);
+return self;}
+}),
+smalltalk.BibNumAlbumTintinTest);
+
+smalltalk.addMethod(
+unescape('_testAnchorToDownloadPDFShouldBePresent'),
+smalltalk.method({
+selector: unescape('testAnchorToDownloadPDFShouldBePresent'),
 fn: function () {
     var self = this;
-    self['@bible'] = smalltalk.send(smalltalk.SouvignyBible || SouvignyBible, "_new", []);
+    smalltalk.send(self, "_assert_equals_", [unescape("http%3A//localhost/pdf/2"), smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_attr_", ["href"])]);
     return self;
 }
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolioOneShouldReturnPageOne'),
+unescape('_testBookletJSShouldBeLoadedOnce'),
 smalltalk.method({
-selector: unescape('testFolioOneShouldReturnPageOne'),
+selector: unescape('testBookletJSShouldBeLoadedOnce'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(self['@bible'], "_parseFolioNo_", ["1"])]);
+    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(smalltalk.send(smalltalk.send("head", "_asJQuery", []), "_find_", [unescape("script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D")]), "_length", [])]);
     return self;
 }
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolio150VShouldReturnPage306'),
+unescape('_testBookletPluginShouldBeLoaded'),
 smalltalk.method({
-selector: unescape('testFolio150VShouldReturnPage306'),
+selector: unescape('testBookletPluginShouldBeLoaded'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [306, smalltalk.send(self['@bible'], "_parseFolioNo_", ["150v"])]);
+    smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_at_", ["booklet"]), "_notNil", [])]);
     return self;
 }
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolio151RShouldReturnPage307'),
+unescape('_testChapterSelectorInitialHeightShouldBeZero'),
 smalltalk.method({
-selector: unescape('testFolio151RShouldReturnPage307'),
+selector: unescape('testChapterSelectorInitialHeightShouldBeZero'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [307, smalltalk.send(self['@bible'], "_parseFolioNo_", ["151r"])]);
+    smalltalk.send(self, "_assert_equals_", [0, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%3Eul")]), "_height", [])]);
     return self;
 }
 }),
-smalltalk.SouvignyBibleTest);
-
-
+smalltalk.BibNumAlbumTintinTest);
 
-smalltalk.addClass('BibNumAlbumTintinTest', smalltalk.TestCase, ['bible', 'album', 'container', 'ajax'], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_setUp'),
+unescape('_testChapterSelectorShouldContainsLinkToFirstPage'),
 smalltalk.method({
-selector: unescape('setUp'),
+selector: unescape('testChapterSelectorShouldContainsLinkToFirstPage'),
 fn: function () {
     var self = this;
-    smalltalk.send(smalltalk.send(typeof window == "undefined" ? nil : window, "_location", []), "_hash_", [" "]);
-    self['@ajax'] = smalltalk.send(smalltalk.AMockWrapper || AMockWrapper, "_on_", [smalltalk.send(smalltalk.Ajax || Ajax, "_new", [])]);
-    smalltalk.send(self['@ajax'], "_onMessage_answer_", ["send", self['@ajax']]);
-    self['@container'] = smalltalk.send(smalltalk.send(unescape("%3Cdiv%3E%3C/div%3E"), "_asJQuery", []), "_width_", [500]);
-    self['@album'] = function ($rec) {smalltalk.send($rec, "_url_", [unescape("/bib-numerique/album/id/2.json")]);smalltalk.send($rec, "_scriptsRoot_", [unescape("http%3A//localhost/afi-opac3/amber/afi/souvigny/")]);smalltalk.send($rec, "_ajax_", [self['@ajax']]);smalltalk.send($rec, "_container_", [self['@container']]);return smalltalk.send($rec, "_load", []);}(smalltalk.send(smalltalk.BibNumAlbum || BibNumAlbum, "_new", []));
-    smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send(typeof jQuery == "undefined" ? nil : jQuery, "_parseJSON_", [smalltalk.send(self, "_tintinJSON", [])])]);
+    smalltalk.send(self, "_assert_equals_", ["Origins", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%20%23selector-page-1")]), "_text", [])]);
     return self;
 }
 }),
@@ -129,73 +169,61 @@ fn: function () {
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_tearDown'),
-smalltalk.method({
-selector: unescape('tearDown'),
-fn: function () {
-    var self = this;
-    smalltalk.send(self['@container'], "_remove", []);
-    return self;
-}
-}),
-smalltalk.BibNumAlbumTintinTest);
-
-smalltalk.addMethod(
-unescape('_testBookletPluginShouldBeLoaded'),
+unescape('_testFirstPageImageFolioNumberShouldBeTwelveR'),
 smalltalk.method({
-selector: unescape('testBookletPluginShouldBeLoaded'),
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_at_", ["booklet"]), "_notNil", [])]);
-    return self;
-}
+selector: unescape('testFirstPageImageFolioNumberShouldBeTwelveR'),
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", ["12R", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-counter%20+%20.b-counter")]), "_text", [])]);
+return self;}
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testBookletJSShouldBeLoadedOnce'),
+unescape('_testFirstPageImageShouldLinkToOneDotJpg'),
 smalltalk.method({
-selector: unescape('testBookletJSShouldBeLoadedOnce'),
+selector: unescape('testFirstPageImageShouldLinkToOneDotJpg'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(smalltalk.send(smalltalk.send("head", "_asJQuery", []), "_find_", [unescape("script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D")]), "_length", [])]);
+    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D")]), "_length", [])]);
     return self;
 }
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_tintinJSON'),
+unescape('_testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
 smalltalk.method({
-selector: unescape('tintinJSON'),
+selector: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
 fn: function (){
 var self=this;
-return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D");
+smalltalk.send(self, "_assert_equals_", [unescape("userfiles/album/2/thumbs/media/1_small.jpg"), smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_first", []), "_navigatorThumbnailURL", [])]);
 return self;}
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testShouldContainsFourPages'),
+unescape('_testFirstPageZoomedImageShouldLinkToOneDotJpg'),
 smalltalk.method({
-selector: unescape('testShouldContainsFourPages'),
+selector: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [4, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_length", [])]);
+    smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-zoom-magnify%20a")]), "_click", []);
+    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D")]), "_length", [])]);
     return self;
 }
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageImageShouldLinkToOneDotJpg'),
+unescape('_testNextPageShouldSetMenuTextToFin'),
 smalltalk.method({
-selector: unescape('testFirstPageImageShouldLinkToOneDotJpg'),
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D")]), "_length", [])]);
-    return self;
-}
+selector: unescape('testNextPageShouldSetMenuTextToFin'),
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self['@container'], "_find_", [".book"]), "_booklet_", ["next"]);
+smalltalk.send(self, "_assert_equals_", ["Fin", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-current")]), "_text", [])]);
+return self;}
 }),
 smalltalk.BibNumAlbumTintinTest);
 
@@ -212,122 +240,145 @@ fn: function () {
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testPageWidthShouldBe165'),
+unescape('_testPageHeightShouldBe124'),
 smalltalk.method({
-selector: unescape('testPageWidthShouldBe165'),
+selector: unescape('testPageHeightShouldBe124'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [165, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_width", [])]);
+    smalltalk.send(self, "_assert_equals_", [124, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_height", [])]);
     return self;
 }
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testPageHeightShouldBe124'),
+unescape('_testPageWidthShouldBe165'),
 smalltalk.method({
-selector: unescape('testPageHeightShouldBe124'),
+selector: unescape('testPageWidthShouldBe165'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [124, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_height", [])]);
+    smalltalk.send(self, "_assert_equals_", [165, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_width", [])]);
     return self;
 }
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageZoomedImageShouldLinkToOneDotJpg'),
+unescape('_testSecondPageImageFolioNumberShouldBeXX'),
 smalltalk.method({
-selector: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg'),
-fn: function () {
-    var self = this;
-    smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-zoom-magnify%20a")]), "_click", []);
-    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D")]), "_length", [])]);
-    return self;
-}
+selector: unescape('testSecondPageImageFolioNumberShouldBeXX'),
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", ["XX", smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_last", []), "_foliono", [])]);
+return self;}
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testChapterSelectorShouldContainsLinkToFirstPage'),
+unescape('_testShouldContainsFourPages'),
 smalltalk.method({
-selector: unescape('testChapterSelectorShouldContainsLinkToFirstPage'),
+selector: unescape('testShouldContainsFourPages'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", ["Origins", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%20%23selector-page-1")]), "_text", [])]);
+    smalltalk.send(self, "_assert_equals_", [4, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_length", [])]);
     return self;
 }
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testChapterSelectorInitialHeightShouldBeZero'),
+unescape('_tintinJSON'),
 smalltalk.method({
-selector: unescape('testChapterSelectorInitialHeightShouldBeZero'),
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_equals_", [0, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%3Eul")]), "_height", [])]);
-    return self;
-}
+selector: unescape('tintinJSON'),
+fn: function (){
+var self=this;
+return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D");
+return self;}
 }),
 smalltalk.BibNumAlbumTintinTest);
 
+
+
+smalltalk.addClass('CycleTest', smalltalk.TestCase, [], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_testFirstPageImageFolioNumberShouldBeTwelveR'),
+unescape('_testCycleWithFourElements'),
 smalltalk.method({
-selector: unescape('testFirstPageImageFolioNumberShouldBeTwelveR'),
+selector: unescape('testCycleWithFourElements'),
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", ["12R", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-counter%20+%20.b-counter")]), "_text", [])]);
+var cycle=nil;
+(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two", "three", "four"]]));
+smalltalk.send((3), "_timesRepeat_", [(function(){smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["three", smalltalk.send(cycle, "_next", [])]);return smalltalk.send(self, "_assert_equals_", ["four", smalltalk.send(cycle, "_next", [])]);})]);
 return self;}
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.CycleTest);
 
 smalltalk.addMethod(
-unescape('_testSecondPageImageFolioNumberShouldBeXX'),
+unescape('_testCycleWithTwoElements'),
 smalltalk.method({
-selector: unescape('testSecondPageImageFolioNumberShouldBeXX'),
+selector: unescape('testCycleWithTwoElements'),
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", ["XX", smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_last", []), "_foliono", [])]);
+var cycle=nil;
+(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two"]]));
+smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
 return self;}
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.CycleTest);
+
 
+
+smalltalk.addClass('SouvignyBibleTest', smalltalk.TestCase, ['bible'], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_testAnchorToDownloadPDFShouldBePresent'),
+unescape('_setUp'),
 smalltalk.method({
-selector: unescape('testAnchorToDownloadPDFShouldBePresent'),
+selector: unescape('setUp'),
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [unescape("http%3A//localhost/pdf/2"), smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_attr_", ["href"])]);
+    self['@bible'] = smalltalk.send(smalltalk.SouvignyBible || SouvignyBible, "_new", []);
     return self;
 }
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 smalltalk.addMethod(
-unescape('_testNextPageShouldSetMenuTextToFin'),
+unescape('_testFolio150VShouldReturnPage306'),
 smalltalk.method({
-selector: unescape('testNextPageShouldSetMenuTextToFin'),
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self['@container'], "_find_", [".book"]), "_booklet_", ["next"]);
-smalltalk.send(self, "_assert_equals_", ["Fin", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-current")]), "_text", [])]);
-return self;}
+selector: unescape('testFolio150VShouldReturnPage306'),
+fn: function () {
+    var self = this;
+    smalltalk.send(self, "_assert_equals_", [306, smalltalk.send(self['@bible'], "_parseFolioNo_", ["150v"])]);
+    return self;
+}
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
+unescape('_testFolio151RShouldReturnPage307'),
 smalltalk.method({
-selector: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
-fn: function (){
-var self=this;
-smalltalk.send(self, "_assert_equals_", [unescape("userfiles/album/2/thumbs/media/1_small.jpg"), smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_first", []), "_navigatorThumbnailURL", [])]);
-return self;}
+selector: unescape('testFolio151RShouldReturnPage307'),
+fn: function () {
+    var self = this;
+    smalltalk.send(self, "_assert_equals_", [307, smalltalk.send(self['@bible'], "_parseFolioNo_", ["151r"])]);
+    return self;
+}
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
+
+smalltalk.addMethod(
+unescape('_testFolioOneShouldReturnPageOne'),
+smalltalk.method({
+selector: unescape('testFolioOneShouldReturnPageOne'),
+fn: function () {
+    var self = this;
+    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(self['@bible'], "_parseFolioNo_", ["1"])]);
+    return self;
+}
+}),
+smalltalk.SouvignyBibleTest);
 
 
 
diff --git a/amber/afi/js/AFI-Tests.js b/amber/afi/js/AFI-Tests.js
index 6a4e380bcf18c442baf3f8bef40bafdca5f8542f..7fb52cb304a8fd4ca25b1f3cd8a2c23e70178680 100644
--- a/amber/afi/js/AFI-Tests.js
+++ b/amber/afi/js/AFI-Tests.js
@@ -1,137 +1,197 @@
 smalltalk.addPackage('AFI-Tests', {});
-smalltalk.addClass('CycleTest', smalltalk.TestCase, [], 'AFI-Tests');
+smalltalk.addClass('BibNumAlbumTestCase', smalltalk.TestCase, ['ajax', 'container', 'album'], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_testCycleWithTwoElements'),
+unescape('_setUp'),
 smalltalk.method({
-selector: unescape('testCycleWithTwoElements'),
-category: 'tests',
+selector: unescape('setUp'),
+category: 'running',
 fn: function (){
 var self=this;
-var cycle=nil;
-(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two"]]));
-smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
-smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_location", []), "_hash_", [" "]);
+(self['@ajax']=smalltalk.send((smalltalk.AMockWrapper || AMockWrapper), "_on_", [smalltalk.send((smalltalk.Ajax || Ajax), "_new", [])]));
+smalltalk.send(self['@ajax'], "_onMessage_answer_", ["send", self['@ajax']]);
+(self['@container']=smalltalk.send(smalltalk.send(unescape("%3Cdiv%3E%3C/div%3E"), "_asJQuery", []), "_width_", [(500)]));
+(self['@album']=(function($rec){smalltalk.send($rec, "_ajax_", [self['@ajax']]);return smalltalk.send($rec, "_container_", [self['@container']]);})(smalltalk.send((smalltalk.BibNumAlbum || BibNumAlbum), "_new", [])));
 return self;},
 args: [],
-source: unescape('testCycleWithTwoElements%0A%09%7Ccycle%7C%0A%09cycle%20%3A%3D%20Cycle%20with%3A%20%23%28%27one%27%20%27two%27%29.%0A%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09'),
-messageSends: ["with:", "assert:equals:", "next"],
-referencedClasses: ["Cycle"]
+source: unescape('setUp%0A%09window%20location%20hash%3A%20%27%20%27.%0A%09ajax%20%3A%3D%20AMockWrapper%20on%3A%20Ajax%20new.%0A%09ajax%20onMessage%3A%20%27send%27%20answer%3A%20ajax.%0A%0A%09container%20%3A%3D%20%27%3Cdiv%3E%3C/div%3E%27%20asJQuery%20width%3A%20500.%0A%0A%09album%20%3A%3D%20BibNumAlbum%20new%20%0A%09%09ajax%3A%20ajax%3B%0A%09%09container%3A%20container'),
+messageSends: ["hash:", "location", "on:", "new", "onMessage:answer:", "width:", "asJQuery", "ajax:", "container:"],
+referencedClasses: ["AMockWrapper", "Ajax", "BibNumAlbum"]
 }),
-smalltalk.CycleTest);
+smalltalk.BibNumAlbumTestCase);
 
 smalltalk.addMethod(
-unescape('_testCycleWithFourElements'),
+unescape('_tearDown'),
 smalltalk.method({
-selector: unescape('testCycleWithFourElements'),
+selector: unescape('tearDown'),
+category: 'running',
+fn: function (){
+var self=this;
+smalltalk.send(self['@container'], "_remove", []);
+return self;},
+args: [],
+source: unescape('tearDown%0A%09container%20remove.'),
+messageSends: ["remove"],
+referencedClasses: []
+}),
+smalltalk.BibNumAlbumTestCase);
+
+
+
+smalltalk.addClass('BibNumAlbumDonjonTest', smalltalk.BibNumAlbumTestCase, ['ajax', 'container', 'album'], 'AFI-Tests');
+smalltalk.addMethod(
+unescape('_donjonJSON'),
+smalltalk.method({
+selector: unescape('donjonJSON'),
+category: 'accessing',
+fn: function (){
+var self=this;
+return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A4%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Donjon%20Zenith%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22Une%20bonne%20bagarre%22%2C%0A%09%09%09%09%09%22width%22%3A%20200%2C%0A%09%09%09%09%09%22height%22%3A%2050%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Donjon%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/4/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/4/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/4.jpg%22%7D%0A%09%09%09%09%5D%0A%09%09%7D%20%7D");
+return self;},
+args: [],
+source: unescape('donjonJSON%0A%09%5E%20%20%20%27%7B%22album%22%3A%20%7B%09%22id%22%3A4%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Donjon%20Zenith%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22Une%20bonne%20bagarre%22%2C%0A%09%09%09%09%09%22width%22%3A%20200%2C%0A%09%09%09%09%09%22height%22%3A%2050%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Donjon%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/4/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/4/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/4.jpg%22%7D%0A%09%09%09%09%5D%0A%09%09%7D%20%7D%27.'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BibNumAlbumDonjonTest);
+
+smalltalk.addMethod(
+unescape('_setUp'),
+smalltalk.method({
+selector: unescape('setUp'),
+category: 'running',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_setUp", [], smalltalk.BibNumAlbumTestCase);
+(function($rec){smalltalk.send($rec, "_url_", ["donjon.json"]);return smalltalk.send($rec, "_load", []);})(self['@album']);
+smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send(self, "_donjonJSON", [])]);
+return self;},
+args: [],
+source: unescape('setUp%0A%09super%20setUp.%0A%0A%09album%0A%09%09url%3A%20%27donjon.json%27%3B%0A%09%09load.%0A%0A%09%28ajax%20options%20at%3A%20%27success%27%29%20%20value%3A%20self%20donjonJSON.'),
+messageSends: ["setUp", "url:", "load", "value:", "at:", "options", "donjonJSON"],
+referencedClasses: []
+}),
+smalltalk.BibNumAlbumDonjonTest);
+
+smalltalk.addMethod(
+unescape('_testAnchorToDownloadPDFShouldNotBePresent'),
+smalltalk.method({
+selector: unescape('testAnchorToDownloadPDFShouldNotBePresent'),
 category: 'tests',
 fn: function (){
 var self=this;
-var cycle=nil;
-(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two", "three", "four"]]));
-smalltalk.send((3), "_timesRepeat_", [(function(){smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["three", smalltalk.send(cycle, "_next", [])]);return smalltalk.send(self, "_assert_equals_", ["four", smalltalk.send(cycle, "_next", [])]);})]);
+smalltalk.send(self, "_assert_equals_", [(0), smalltalk.send(smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_at_", ["size"]), "_value", [])]);
 return self;},
 args: [],
-source: unescape('testCycleWithFourElements%0A%09%7Ccycle%7C%0A%09cycle%20%3A%3D%20Cycle%20with%3A%20%23%28%27one%27%20%27two%27%20%27three%27%20%27four%27%29.%0A%093%20timesRepeat%3A%20%5B%0A%09%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27three%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27four%27%20equals%3A%20cycle%20next%20%5D.%0A%09'),
-messageSends: ["with:", "timesRepeat:", "assert:equals:", "next"],
-referencedClasses: ["Cycle"]
+source: unescape('testAnchorToDownloadPDFShouldNotBePresent%0A%09self%20assert%3A%200%20equals%3A%20%28%28container%20find%3A%20%27div.b-download-book%20a%27%29%20at%3A%20%27size%27%29%20value'),
+messageSends: ["assert:equals:", "value", "at:", "find:"],
+referencedClasses: []
 }),
-smalltalk.CycleTest);
+smalltalk.BibNumAlbumDonjonTest);
 
 
 
-smalltalk.addClass('SouvignyBibleTest', smalltalk.TestCase, ['bible'], 'AFI-Tests');
+smalltalk.addClass('BibNumAlbumTintinTest', smalltalk.BibNumAlbumTestCase, ['bible', 'album', 'container', 'ajax'], 'AFI-Tests');
 smalltalk.addMethod(
 unescape('_setUp'),
 smalltalk.method({
 selector: unescape('setUp'),
 category: 'running',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_setUp", [], smalltalk.BibNumAlbumTestCase);
+(function($rec){smalltalk.send($rec, "_url_", [unescape("/bib-numerique/album/id/2.json")]);smalltalk.send($rec, "_scriptsRoot_", [unescape("http%3A//localhost/afi-opac3/amber/afi/souvigny/")]);return smalltalk.send($rec, "_load", []);})(self['@album']);
+smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send((typeof jQuery == 'undefined' ? nil : jQuery), "_parseJSON_", [smalltalk.send(self, "_tintinJSON", [])])]);
+return self;},
+args: [],
+source: unescape('setUp%0A%09super%20setUp.%0A%0A%09album%0A%09%09url%3A%20%27/bib-numerique/album/id/2.json%27%3B%0A%09%09scriptsRoot%3A%20%27http%3A//localhost/afi-opac3/amber/afi/souvigny/%27%3B%0A%09%09load.%0A%0A%09%28ajax%20options%20at%3A%20%27success%27%29%20%20value%3A%20%28jQuery%20parseJSON%3A%20self%20tintinJSON%29.'),
+messageSends: ["setUp", "url:", "scriptsRoot:", "load", "value:", "at:", "options", "parseJSON:", "tintinJSON"],
+referencedClasses: []
+}),
+smalltalk.BibNumAlbumTintinTest);
+
+smalltalk.addMethod(
+unescape('_testAnchorToDownloadPDFShouldBePresent'),
+smalltalk.method({
+selector: unescape('testAnchorToDownloadPDFShouldBePresent'),
+category: 'tests',
 fn: function () {
     var self = this;
-    self['@bible'] = smalltalk.send(smalltalk.SouvignyBible || SouvignyBible, "_new", []);
+    smalltalk.send(self, "_assert_equals_", [unescape("http%3A//localhost/pdf/2"), smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_attr_", ["href"])]);
     return self;
 },
 args: [],
-source: unescape('setUp%0A%09bible%20%3A%3D%20SouvignyBible%20new'),
-messageSends: ["new"],
+source: unescape('testAnchorToDownloadPDFShouldBePresent%0A%09self%20assert%3A%20%27http%3A//localhost/pdf/2%27%20%20equals%3A%20%28%28container%20find%3A%20%27div.b-download-book%20a%27%29%20attr%3A%20%27href%27%20%29'),
+messageSends: ["assert:equals:", "attr:", "find:"],
 referencedClasses: []
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolioOneShouldReturnPageOne'),
+unescape('_testBookletJSShouldBeLoadedOnce'),
 smalltalk.method({
-selector: unescape('testFolioOneShouldReturnPageOne'),
+selector: unescape('testBookletJSShouldBeLoadedOnce'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(self['@bible'], "_parseFolioNo_", ["1"])]);
+    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(smalltalk.send(smalltalk.send("head", "_asJQuery", []), "_find_", [unescape("script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D")]), "_length", [])]);
     return self;
 },
 args: [],
-source: unescape('testFolioOneShouldReturnPageOne%0A%09self%20assert%3A%201%20equals%3A%20%28bible%20parseFolioNo%3A%20%271%27%29'),
-messageSends: ["assert:equals:", "parseFolioNo:"],
+source: unescape('testBookletJSShouldBeLoadedOnce%0A%09self%20assert%3A%201%20equals%3A%20%28%20%27head%27%20asJQuery%20find%3A%20%27script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D%27%29%20length%0A%09'),
+messageSends: ["assert:equals:", "length", "find:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolio150VShouldReturnPage306'),
+unescape('_testBookletPluginShouldBeLoaded'),
 smalltalk.method({
-selector: unescape('testFolio150VShouldReturnPage306'),
+selector: unescape('testBookletPluginShouldBeLoaded'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [306, smalltalk.send(self['@bible'], "_parseFolioNo_", ["150v"])]);
+    smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_at_", ["booklet"]), "_notNil", [])]);
     return self;
 },
 args: [],
-source: unescape('testFolio150VShouldReturnPage306%0A%09self%20assert%3A%20306%20equals%3A%28bible%20parseFolioNo%3A%20%27150v%27%29.'),
-messageSends: ["assert:equals:", "parseFolioNo:"],
+source: unescape('testBookletPluginShouldBeLoaded%0A%09self%20assert%3A%20%28%27body%27%20asJQuery%20at%3A%20%27booklet%27%29%20notNil%20'),
+messageSends: ["assert:", "notNil", "at:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.SouvignyBibleTest);
+smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFolio151RShouldReturnPage307'),
+unescape('_testChapterSelectorInitialHeightShouldBeZero'),
 smalltalk.method({
-selector: unescape('testFolio151RShouldReturnPage307'),
+selector: unescape('testChapterSelectorInitialHeightShouldBeZero'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [307, smalltalk.send(self['@bible'], "_parseFolioNo_", ["151r"])]);
+    smalltalk.send(self, "_assert_equals_", [0, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%3Eul")]), "_height", [])]);
     return self;
 },
 args: [],
-source: unescape('testFolio151RShouldReturnPage307%0A%09self%20assert%3A%20307%20equals%3A%28bible%20parseFolioNo%3A%20%27151r%27%29.'),
-messageSends: ["assert:equals:", "parseFolioNo:"],
+source: unescape('testChapterSelectorInitialHeightShouldBeZero%0A%09self%20assert%3A%200%20%20equals%3A%20%28container%20find%3A%20%27.b-selector-chapter%3Eul%27%29%20%20%20height%20'),
+messageSends: ["assert:equals:", "height", "find:"],
 referencedClasses: []
 }),
-smalltalk.SouvignyBibleTest);
-
-
+smalltalk.BibNumAlbumTintinTest);
 
-smalltalk.addClass('BibNumAlbumTintinTest', smalltalk.TestCase, ['bible', 'album', 'container', 'ajax'], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_setUp'),
+unescape('_testChapterSelectorShouldContainsLinkToFirstPage'),
 smalltalk.method({
-selector: unescape('setUp'),
-category: 'running',
+selector: unescape('testChapterSelectorShouldContainsLinkToFirstPage'),
+category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(smalltalk.send(typeof window == "undefined" ? nil : window, "_location", []), "_hash_", [" "]);
-    self['@ajax'] = smalltalk.send(smalltalk.AMockWrapper || AMockWrapper, "_on_", [smalltalk.send(smalltalk.Ajax || Ajax, "_new", [])]);
-    smalltalk.send(self['@ajax'], "_onMessage_answer_", ["send", self['@ajax']]);
-    self['@container'] = smalltalk.send(smalltalk.send(unescape("%3Cdiv%3E%3C/div%3E"), "_asJQuery", []), "_width_", [500]);
-    self['@album'] = function ($rec) {smalltalk.send($rec, "_url_", [unescape("/bib-numerique/album/id/2.json")]);smalltalk.send($rec, "_scriptsRoot_", [unescape("http%3A//localhost/afi-opac3/amber/afi/souvigny/")]);smalltalk.send($rec, "_ajax_", [self['@ajax']]);smalltalk.send($rec, "_container_", [self['@container']]);return smalltalk.send($rec, "_load", []);}(smalltalk.send(smalltalk.BibNumAlbum || BibNumAlbum, "_new", []));
-    smalltalk.send(smalltalk.send(smalltalk.send(self['@ajax'], "_options", []), "_at_", ["success"]), "_value_", [smalltalk.send(typeof jQuery == "undefined" ? nil : jQuery, "_parseJSON_", [smalltalk.send(self, "_tintinJSON", [])])]);
+    smalltalk.send(self, "_assert_equals_", ["Origins", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%20%23selector-page-1")]), "_text", [])]);
     return self;
 },
 args: [],
-source: unescape('setUp%0A%09window%20location%20hash%3A%20%27%20%27.%0A%09ajax%20%3A%3D%20AMockWrapper%20on%3A%20Ajax%20new.%0A%09ajax%20onMessage%3A%20%27send%27%20answer%3A%20ajax.%0A%0A%09container%20%3A%3D%20%27%3Cdiv%3E%3C/div%3E%27%20asJQuery%20width%3A%20500.%0A%0A%09album%20%3A%3D%20BibNumAlbum%20new%20%0A%09%09url%3A%20%27/bib-numerique/album/id/2.json%27%3B%0A%09%09scriptsRoot%3A%20%27http%3A//localhost/afi-opac3/amber/afi/souvigny/%27%3B%0A%09%09ajax%3A%20ajax%3B%0A%09%09container%3A%20container%3B%20%0A%09%09load.%0A%0A%09%28ajax%20options%20at%3A%20%27success%27%29%20%20value%3A%20%28jQuery%20parseJSON%3A%20self%20tintinJSON%29.'),
-messageSends: ["hash:", "location", "on:", "new", "onMessage:answer:", "width:", "asJQuery", "url:", "scriptsRoot:", "ajax:", "container:", "load", "value:", "at:", "options", "parseJSON:", "tintinJSON"],
-referencedClasses: ["AMockWrapper", "Ajax", "BibNumAlbum"]
+source: unescape('testChapterSelectorShouldContainsLinkToFirstPage%0A%09self%20assert%3A%20%27Origins%27%20%20equals%3A%20%28container%20find%3A%20%27.b-selector-chapter%20%23selector-page-1%27%29%20%20%20text%20'),
+messageSends: ["assert:equals:", "text", "find:"],
+referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
@@ -174,102 +234,85 @@ referencedClasses: []
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_tearDown'),
-smalltalk.method({
-selector: unescape('tearDown'),
-category: 'running',
-fn: function () {
-    var self = this;
-    smalltalk.send(self['@container'], "_remove", []);
-    return self;
-},
-args: [],
-source: unescape('tearDown%0A%09container%20remove.'),
-messageSends: ["remove"],
-referencedClasses: []
-}),
-smalltalk.BibNumAlbumTintinTest);
-
-smalltalk.addMethod(
-unescape('_testBookletPluginShouldBeLoaded'),
+unescape('_testFirstPageImageFolioNumberShouldBeTwelveR'),
 smalltalk.method({
-selector: unescape('testBookletPluginShouldBeLoaded'),
+selector: unescape('testFirstPageImageFolioNumberShouldBeTwelveR'),
 category: 'tests',
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_at_", ["booklet"]), "_notNil", [])]);
-    return self;
-},
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", ["12R", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-counter%20+%20.b-counter")]), "_text", [])]);
+return self;},
 args: [],
-source: unescape('testBookletPluginShouldBeLoaded%0A%09self%20assert%3A%20%28%27body%27%20asJQuery%20at%3A%20%27booklet%27%29%20notNil%20'),
-messageSends: ["assert:", "notNil", "at:", "asJQuery"],
+source: unescape('testFirstPageImageFolioNumberShouldBeTwelveR%0A%09self%20assert%3A%20%2712R%27%20equals%3A%20%28container%20find%3A%20%27.b-counter%20+%20.b-counter%27%29%20%20text'),
+messageSends: ["assert:equals:", "text", "find:"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testBookletJSShouldBeLoadedOnce'),
+unescape('_testFirstPageImageShouldLinkToOneDotJpg'),
 smalltalk.method({
-selector: unescape('testBookletJSShouldBeLoadedOnce'),
+selector: unescape('testFirstPageImageShouldLinkToOneDotJpg'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(smalltalk.send(smalltalk.send("head", "_asJQuery", []), "_find_", [unescape("script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D")]), "_length", [])]);
+    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D")]), "_length", [])]);
     return self;
 },
 args: [],
-source: unescape('testBookletJSShouldBeLoadedOnce%0A%09self%20assert%3A%201%20equals%3A%20%28%20%27head%27%20asJQuery%20find%3A%20%27script%5Bsrc*%3D%22booklet.1.2.0.min.js%22%5D%27%29%20length%0A%09'),
-messageSends: ["assert:equals:", "length", "find:", "asJQuery"],
+source: unescape('testFirstPageImageShouldLinkToOneDotJpg%0A%09self%20assert%3A%200%20%3C%20%28container%20find%3A%20%27img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D%27%29%20%20length'),
+messageSends: ["assert:", unescape("%3C"), "length", "find:"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_tintinJSON'),
+unescape('_testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
 smalltalk.method({
-selector: unescape('tintinJSON'),
-category: 'json',
+selector: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
+category: 'tests',
 fn: function (){
 var self=this;
-return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D");
+smalltalk.send(self, "_assert_equals_", [unescape("userfiles/album/2/thumbs/media/1_small.jpg"), smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_first", []), "_navigatorThumbnailURL", [])]);
 return self;},
 args: [],
-source: unescape('tintinJSON%0A%09%5E%20%20%20%27%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D%27.'),
-messageSends: [],
+source: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg%0A%09self%20assert%3A%20%27userfiles/album/2/thumbs/media/1_small.jpg%27%20equals%3A%20album%20pages%20first%20navigatorThumbnailURL%20'),
+messageSends: ["assert:equals:", "navigatorThumbnailURL", "first", "pages"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testShouldContainsFourPages'),
+unescape('_testFirstPageZoomedImageShouldLinkToOneDotJpg'),
 smalltalk.method({
-selector: unescape('testShouldContainsFourPages'),
+selector: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [4, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_length", [])]);
+    smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-zoom-magnify%20a")]), "_click", []);
+    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D")]), "_length", [])]);
     return self;
 },
 args: [],
-source: unescape('testShouldContainsFourPages%0A%09%222%20pages%20+%20covers%22%0A%09self%20assert%3A%204%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20length'),
-messageSends: ["assert:equals:", "length", "find:"],
+source: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg%0A%09%28container%20find%3A%20%27.b-zoom-magnify%20a%27%29%20click.%0A%09self%20assert%3A%200%20%3C%20%28container%20find%3A%20%27.iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D%27%29%20%20length'),
+messageSends: ["click", "find:", "assert:", unescape("%3C"), "length"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageImageShouldLinkToOneDotJpg'),
+unescape('_testNextPageShouldSetMenuTextToFin'),
 smalltalk.method({
-selector: unescape('testFirstPageImageShouldLinkToOneDotJpg'),
+selector: unescape('testNextPageShouldSetMenuTextToFin'),
 category: 'tests',
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D")]), "_length", [])]);
-    return self;
-},
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self['@container'], "_find_", [".book"]), "_booklet_", ["next"]);
+smalltalk.send(self, "_assert_equals_", ["Fin", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-current")]), "_text", [])]);
+return self;},
 args: [],
-source: unescape('testFirstPageImageShouldLinkToOneDotJpg%0A%09self%20assert%3A%200%20%3C%20%28container%20find%3A%20%27img%5Bsrc*%3D%22userfiles/album/2/thumbs/media/1.jpg%22%5D%27%29%20%20length'),
-messageSends: ["assert:", unescape("%3C"), "length", "find:"],
+source: unescape('testNextPageShouldSetMenuTextToFin%0A%09%28container%20find%3A%20%27.book%27%29%20booklet%3A%20%27next%27.%0A%09self%20assert%3A%20%27Fin%27%20equals%3A%20%28container%20find%3A%20%27.b-current%27%29%20text'),
+messageSends: ["booklet:", "find:", "assert:equals:", "text"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
@@ -292,172 +335,200 @@ referencedClasses: []
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testPageWidthShouldBe165'),
+unescape('_testPageHeightShouldBe124'),
 smalltalk.method({
-selector: unescape('testPageWidthShouldBe165'),
+selector: unescape('testPageHeightShouldBe124'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [165, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_width", [])]);
+    smalltalk.send(self, "_assert_equals_", [124, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_height", [])]);
     return self;
 },
 args: [],
-source: unescape('testPageWidthShouldBe165%0A%09%22resize%20to%20its%20container%20width%20%28500%29%20%20-%20margins%20%28170%29%20%20/%202%20pages%22%20%20%0A%09self%20assert%3A%20165%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20%20width'),
-messageSends: ["assert:equals:", "width", "find:"],
+source: unescape('testPageHeightShouldBe124%0A%09%22the%20width%20of%20page%20%28165%29%20*%20%20height%20of%20first%20image%20in%20json%20%28300%29%20/%20width%20of%20first%20image%20in%20json%20%28400%29%22%20%20%0A%09self%20assert%3A%20124%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20%20height'),
+messageSends: ["assert:equals:", "height", "find:"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testPageHeightShouldBe124'),
+unescape('_testPageWidthShouldBe165'),
 smalltalk.method({
-selector: unescape('testPageHeightShouldBe124'),
+selector: unescape('testPageWidthShouldBe165'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [124, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_height", [])]);
+    smalltalk.send(self, "_assert_equals_", [165, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_width", [])]);
     return self;
 },
 args: [],
-source: unescape('testPageHeightShouldBe124%0A%09%22the%20width%20of%20page%20%28165%29%20*%20%20height%20of%20first%20image%20in%20json%20%28300%29%20/%20width%20of%20first%20image%20in%20json%20%28400%29%22%20%20%0A%09self%20assert%3A%20124%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20%20height'),
-messageSends: ["assert:equals:", "height", "find:"],
+source: unescape('testPageWidthShouldBe165%0A%09%22resize%20to%20its%20container%20width%20%28500%29%20%20-%20margins%20%28170%29%20%20/%202%20pages%22%20%20%0A%09self%20assert%3A%20165%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20%20width'),
+messageSends: ["assert:equals:", "width", "find:"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageZoomedImageShouldLinkToOneDotJpg'),
+unescape('_testSecondPageImageFolioNumberShouldBeXX'),
 smalltalk.method({
-selector: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg'),
+selector: unescape('testSecondPageImageFolioNumberShouldBeXX'),
 category: 'tests',
-fn: function () {
-    var self = this;
-    smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-zoom-magnify%20a")]), "_click", []);
-    smalltalk.send(self, "_assert_", [0 < smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D")]), "_length", [])]);
-    return self;
-},
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", ["XX", smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_last", []), "_foliono", [])]);
+return self;},
 args: [],
-source: unescape('testFirstPageZoomedImageShouldLinkToOneDotJpg%0A%09%28container%20find%3A%20%27.b-zoom-magnify%20a%27%29%20click.%0A%09self%20assert%3A%200%20%3C%20%28container%20find%3A%20%27.iviewer%20img%5Bsrc*%3D%22bib-numerique/get-resource/id/1.jpg%22%5D%27%29%20%20length'),
-messageSends: ["click", "find:", "assert:", unescape("%3C"), "length"],
+source: unescape('testSecondPageImageFolioNumberShouldBeXX%0A%09self%20assert%3A%20%27XX%27%20equals%3A%20album%20pages%20last%20foliono'),
+messageSends: ["assert:equals:", "foliono", "last", "pages"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testChapterSelectorShouldContainsLinkToFirstPage'),
+unescape('_testShouldContainsFourPages'),
 smalltalk.method({
-selector: unescape('testChapterSelectorShouldContainsLinkToFirstPage'),
+selector: unescape('testShouldContainsFourPages'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", ["Origins", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%20%23selector-page-1")]), "_text", [])]);
+    smalltalk.send(self, "_assert_equals_", [4, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-page")]), "_length", [])]);
     return self;
 },
 args: [],
-source: unescape('testChapterSelectorShouldContainsLinkToFirstPage%0A%09self%20assert%3A%20%27Origins%27%20%20equals%3A%20%28container%20find%3A%20%27.b-selector-chapter%20%23selector-page-1%27%29%20%20%20text%20'),
-messageSends: ["assert:equals:", "text", "find:"],
+source: unescape('testShouldContainsFourPages%0A%09%222%20pages%20+%20covers%22%0A%09self%20assert%3A%204%20equals%3A%20%28container%20find%3A%20%27.b-page%27%29%20length'),
+messageSends: ["assert:equals:", "length", "find:"],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
 smalltalk.addMethod(
-unescape('_testChapterSelectorInitialHeightShouldBeZero'),
+unescape('_tintinJSON'),
 smalltalk.method({
-selector: unescape('testChapterSelectorInitialHeightShouldBeZero'),
-category: 'tests',
-fn: function () {
-    var self = this;
-    smalltalk.send(self, "_assert_equals_", [0, smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-selector-chapter%3Eul")]), "_height", [])]);
-    return self;
-},
+selector: unescape('tintinJSON'),
+category: 'json',
+fn: function (){
+var self=this;
+return unescape("%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D");
+return self;},
 args: [],
-source: unescape('testChapterSelectorInitialHeightShouldBeZero%0A%09self%20assert%3A%200%20%20equals%3A%20%28container%20find%3A%20%27.b-selector-chapter%3Eul%27%29%20%20%20height%20'),
-messageSends: ["assert:equals:", "height", "find:"],
+source: unescape('tintinJSON%0A%09%5E%20%20%20%27%7B%22album%22%3A%20%7B%09%22id%22%3A2%2C%20%0A%09%09%09%09%09%22titre%22%3A%22Tintin%20et%20Milou%22%2C%20%0A%09%09%09%09%09%22description%22%3A%22The%20real%20story%20of%20Tintin%22%2C%0A%09%09%09%09%09%22width%22%3A%20400%2C%0A%09%09%09%09%09%22height%22%3A%20300%2C%0A%09%09%09%09%09%22download_url%22%3A%20%22http%3A//localhost/pdf/2%22%2C%0A%09%09%09%09%09%22ressources%22%3A%5B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Origins%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%2212R%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Created%20in%201929%20by%20Herge%22%20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/1.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/1_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/1.jpg%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%7B%09%22id%22%3A13%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22titre%22%3A%20%22Haddock%22%2C%0A%09%09%09%09%09%09%09%09%09%09%09%09%22foliono%22%3A%20%22XX%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22link_to%22%3A%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22description%22%3A%22Captain%20living%20in%20Moulinsard%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22thumbnail%22%3A%22userfiles/album/2/thumbs/media/2.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22navigator_thumbnail%22%3A%22userfiles/album/2/thumbs/media/2_small.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%09%22original%22%3A%22bib-numerique/get-resource/id/2.jpg%22%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09%5D%0A%09%09%09%09%7D%20%7D%27.'),
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.BibNumAlbumTintinTest);
 
+
+
+smalltalk.addClass('CycleTest', smalltalk.TestCase, [], 'AFI-Tests');
 smalltalk.addMethod(
-unescape('_testFirstPageImageFolioNumberShouldBeTwelveR'),
+unescape('_testCycleWithFourElements'),
 smalltalk.method({
-selector: unescape('testFirstPageImageFolioNumberShouldBeTwelveR'),
+selector: unescape('testCycleWithFourElements'),
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", ["12R", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-counter%20+%20.b-counter")]), "_text", [])]);
+var cycle=nil;
+(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two", "three", "four"]]));
+smalltalk.send((3), "_timesRepeat_", [(function(){smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);smalltalk.send(self, "_assert_equals_", ["three", smalltalk.send(cycle, "_next", [])]);return smalltalk.send(self, "_assert_equals_", ["four", smalltalk.send(cycle, "_next", [])]);})]);
 return self;},
 args: [],
-source: unescape('testFirstPageImageFolioNumberShouldBeTwelveR%0A%09self%20assert%3A%20%2712R%27%20equals%3A%20%28container%20find%3A%20%27.b-counter%20+%20.b-counter%27%29%20%20text'),
-messageSends: ["assert:equals:", "text", "find:"],
-referencedClasses: []
+source: unescape('testCycleWithFourElements%0A%09%7Ccycle%7C%0A%09cycle%20%3A%3D%20Cycle%20with%3A%20%23%28%27one%27%20%27two%27%20%27three%27%20%27four%27%29.%0A%093%20timesRepeat%3A%20%5B%0A%09%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27three%27%20equals%3A%20cycle%20next.%0A%09%09self%20assert%3A%20%27four%27%20equals%3A%20cycle%20next%20%5D.%0A%09'),
+messageSends: ["with:", "timesRepeat:", "assert:equals:", "next"],
+referencedClasses: ["Cycle"]
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.CycleTest);
 
 smalltalk.addMethod(
-unescape('_testSecondPageImageFolioNumberShouldBeXX'),
+unescape('_testCycleWithTwoElements'),
 smalltalk.method({
-selector: unescape('testSecondPageImageFolioNumberShouldBeXX'),
+selector: unescape('testCycleWithTwoElements'),
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", ["XX", smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_last", []), "_foliono", [])]);
+var cycle=nil;
+(cycle=smalltalk.send((smalltalk.Cycle || Cycle), "_with_", [["one", "two"]]));
+smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["one", smalltalk.send(cycle, "_next", [])]);
+smalltalk.send(self, "_assert_equals_", ["two", smalltalk.send(cycle, "_next", [])]);
 return self;},
 args: [],
-source: unescape('testSecondPageImageFolioNumberShouldBeXX%0A%09self%20assert%3A%20%27XX%27%20equals%3A%20album%20pages%20last%20foliono'),
-messageSends: ["assert:equals:", "foliono", "last", "pages"],
+source: unescape('testCycleWithTwoElements%0A%09%7Ccycle%7C%0A%09cycle%20%3A%3D%20Cycle%20with%3A%20%23%28%27one%27%20%27two%27%29.%0A%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27one%27%20equals%3A%20cycle%20next.%0A%09self%20assert%3A%20%27two%27%20equals%3A%20cycle%20next.%0A%09'),
+messageSends: ["with:", "assert:equals:", "next"],
+referencedClasses: ["Cycle"]
+}),
+smalltalk.CycleTest);
+
+
+
+smalltalk.addClass('SouvignyBibleTest', smalltalk.TestCase, ['bible'], 'AFI-Tests');
+smalltalk.addMethod(
+unescape('_setUp'),
+smalltalk.method({
+selector: unescape('setUp'),
+category: 'running',
+fn: function () {
+    var self = this;
+    self['@bible'] = smalltalk.send(smalltalk.SouvignyBible || SouvignyBible, "_new", []);
+    return self;
+},
+args: [],
+source: unescape('setUp%0A%09bible%20%3A%3D%20SouvignyBible%20new'),
+messageSends: ["new"],
 referencedClasses: []
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 smalltalk.addMethod(
-unescape('_testAnchorToDownloadPDFShouldBePresent'),
+unescape('_testFolio150VShouldReturnPage306'),
 smalltalk.method({
-selector: unescape('testAnchorToDownloadPDFShouldBePresent'),
+selector: unescape('testFolio150VShouldReturnPage306'),
 category: 'tests',
 fn: function () {
     var self = this;
-    smalltalk.send(self, "_assert_equals_", [unescape("http%3A//localhost/pdf/2"), smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape("div.b-download-book%20a")]), "_attr_", ["href"])]);
+    smalltalk.send(self, "_assert_equals_", [306, smalltalk.send(self['@bible'], "_parseFolioNo_", ["150v"])]);
     return self;
 },
 args: [],
-source: unescape('testAnchorToDownloadPDFShouldBePresent%0A%09self%20assert%3A%20%27http%3A//localhost/pdf/2%27%20%20equals%3A%20%28%28container%20find%3A%20%27div.b-download-book%20a%27%29%20attr%3A%20%27href%27%20%29'),
-messageSends: ["assert:equals:", "attr:", "find:"],
+source: unescape('testFolio150VShouldReturnPage306%0A%09self%20assert%3A%20306%20equals%3A%28bible%20parseFolioNo%3A%20%27150v%27%29.'),
+messageSends: ["assert:equals:", "parseFolioNo:"],
 referencedClasses: []
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 smalltalk.addMethod(
-unescape('_testNextPageShouldSetMenuTextToFin'),
+unescape('_testFolio151RShouldReturnPage307'),
 smalltalk.method({
-selector: unescape('testNextPageShouldSetMenuTextToFin'),
+selector: unescape('testFolio151RShouldReturnPage307'),
 category: 'tests',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self['@container'], "_find_", [".book"]), "_booklet_", ["next"]);
-smalltalk.send(self, "_assert_equals_", ["Fin", smalltalk.send(smalltalk.send(self['@container'], "_find_", [unescape(".b-current")]), "_text", [])]);
-return self;},
+fn: function () {
+    var self = this;
+    smalltalk.send(self, "_assert_equals_", [307, smalltalk.send(self['@bible'], "_parseFolioNo_", ["151r"])]);
+    return self;
+},
 args: [],
-source: unescape('testNextPageShouldSetMenuTextToFin%0A%09%28container%20find%3A%20%27.book%27%29%20booklet%3A%20%27next%27.%0A%09self%20assert%3A%20%27Fin%27%20equals%3A%20%28container%20find%3A%20%27.b-current%27%29%20text'),
-messageSends: ["booklet:", "find:", "assert:equals:", "text"],
+source: unescape('testFolio151RShouldReturnPage307%0A%09self%20assert%3A%20307%20equals%3A%28bible%20parseFolioNo%3A%20%27151r%27%29.'),
+messageSends: ["assert:equals:", "parseFolioNo:"],
 referencedClasses: []
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 smalltalk.addMethod(
-unescape('_testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
+unescape('_testFolioOneShouldReturnPageOne'),
 smalltalk.method({
-selector: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg'),
+selector: unescape('testFolioOneShouldReturnPageOne'),
 category: 'tests',
-fn: function (){
-var self=this;
-smalltalk.send(self, "_assert_equals_", [unescape("userfiles/album/2/thumbs/media/1_small.jpg"), smalltalk.send(smalltalk.send(smalltalk.send(self['@album'], "_pages", []), "_first", []), "_navigatorThumbnailURL", [])]);
-return self;},
+fn: function () {
+    var self = this;
+    smalltalk.send(self, "_assert_equals_", [1, smalltalk.send(self['@bible'], "_parseFolioNo_", ["1"])]);
+    return self;
+},
 args: [],
-source: unescape('testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg%0A%09self%20assert%3A%20%27userfiles/album/2/thumbs/media/1_small.jpg%27%20equals%3A%20album%20pages%20first%20navigatorThumbnailURL%20'),
-messageSends: ["assert:equals:", "navigatorThumbnailURL", "first", "pages"],
+source: unescape('testFolioOneShouldReturnPageOne%0A%09self%20assert%3A%201%20equals%3A%20%28bible%20parseFolioNo%3A%20%271%27%29'),
+messageSends: ["assert:equals:", "parseFolioNo:"],
 referencedClasses: []
 }),
-smalltalk.BibNumAlbumTintinTest);
+smalltalk.SouvignyBibleTest);
 
 
 
diff --git a/amber/afi/js/AFI.deploy.js b/amber/afi/js/AFI.deploy.js
index 2967a6de25fae791dd043dea4c2a679642b08902..af155b233920dffd16b9e95d9d81c6a0360a0f33 100644
--- a/amber/afi/js/AFI.deploy.js
+++ b/amber/afi/js/AFI.deploy.js
@@ -475,13 +475,13 @@ smalltalk.addMethod(
 unescape('_buildBookFromJSon_'),
 smalltalk.method({
 selector: unescape('buildBookFromJSon%3A'),
-fn: function (aJSONObject){
+fn: function (aJSONObjectOrString){
 var self=this;
 var book=nil;
 var album=nil;
-(album=smalltalk.send(aJSONObject, "_album", []));
-(book=(function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(album, "_titre", [])]);smalltalk.send($rec, "_width_", [smalltalk.send(album, "_width", [])]);smalltalk.send($rec, "_height_", [smalltalk.send(album, "_height", [])]);smalltalk.send($rec, "_downloadUrl_", [smalltalk.send(album, "_at_", ["download_url"])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Book || Book), "_new", [])));
-smalltalk.send(smalltalk.send(album, "_ressources", []), "_do_", [(function(aRessource){return (function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(aRessource, "_titre", [])]);smalltalk.send($rec, "_description_", [smalltalk.send(aRessource, "_description", [])]);smalltalk.send($rec, "_thumbnailURL_", [smalltalk.send(aRessource, "_thumbnail", [])]);smalltalk.send($rec, "_fullImageURL_", [smalltalk.send(aRessource, "_original", [])]);smalltalk.send($rec, "_foliono_", [smalltalk.send(aRessource, "_foliono", [])]);return smalltalk.send($rec, "_navigatorThumbnailURL_", [smalltalk.send(aRessource, "_at_", ["navigator_thumbnail"])]);})(smalltalk.send(book, "_newPage", []));})]);
+(album=smalltalk.send(((($receiver = smalltalk.send(aJSONObjectOrString, "_isString", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_JSON", []), "_parse_", [aJSONObjectOrString]);})() : (function(){return aJSONObjectOrString;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_JSON", []), "_parse_", [aJSONObjectOrString]);}), (function(){return aJSONObjectOrString;})])), "_album", []));
+(book=(function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(album, "_at_", ["titre"])]);smalltalk.send($rec, "_width_", [smalltalk.send(album, "_at_", ["width"])]);smalltalk.send($rec, "_height_", [smalltalk.send(album, "_at_", ["height"])]);smalltalk.send($rec, "_downloadUrl_", [smalltalk.send(album, "_at_", ["download_url"])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Book || Book), "_new", [])));
+smalltalk.send(smalltalk.send(album, "_ressources", []), "_do_", [(function(aRessource){return (function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(aRessource, "_at_", ["titre"])]);smalltalk.send($rec, "_description_", [smalltalk.send(aRessource, "_at_", ["description"])]);smalltalk.send($rec, "_thumbnailURL_", [smalltalk.send(aRessource, "_at_", ["thumbnail"])]);smalltalk.send($rec, "_fullImageURL_", [smalltalk.send(aRessource, "_at_", ["original"])]);smalltalk.send($rec, "_foliono_", [smalltalk.send(aRessource, "_at_", ["foliono"])]);return smalltalk.send($rec, "_navigatorThumbnailURL_", [smalltalk.send(aRessource, "_at_", ["navigator_thumbnail"])]);})(smalltalk.send(book, "_newPage", []));})]);
 return book;
 return self;}
 }),
@@ -494,7 +494,7 @@ selector: unescape('loadBookFromJSONOnSuccess%3A'),
 fn: function (aBlock){
 var self=this;
 (function($rec){smalltalk.send($rec, "_onSuccessDo_", [(function(data){var book=nil;
-book=smalltalk.send(self, "_buildBookFromJSon_", [data]);return smalltalk.send(aBlock, "_value_", [book]);})]);return smalltalk.send($rec, "_send", []);})(smalltalk.send(self, "_ajax", []));
+(book=smalltalk.send(self, "_buildBookFromJSon_", [data]));return smalltalk.send(aBlock, "_value_", [book]);})]);return smalltalk.send($rec, "_send", []);})(smalltalk.send(self, "_ajax", []));
 return self;}
 }),
 smalltalk.BibNumLoader);
@@ -694,7 +694,7 @@ smalltalk.method({
 selector: unescape('downloadUrl'),
 fn: function (){
 var self=this;
-return self['@downloadUrl'];
+return (($receiver = self['@downloadUrl']) == nil || $receiver == undefined) ? (function(){return (self['@downloadUrl']="");})() : $receiver;
 return self;}
 }),
 smalltalk.Book);
diff --git a/amber/afi/js/AFI.js b/amber/afi/js/AFI.js
index 7e5b2442dd8d9a622a8a4ddd391f7e46c038f09a..2fc24b300b0f95acd0da84f2478996a62d83bc75 100644
--- a/amber/afi/js/AFI.js
+++ b/amber/afi/js/AFI.js
@@ -676,18 +676,18 @@ unescape('_buildBookFromJSon_'),
 smalltalk.method({
 selector: unescape('buildBookFromJSon%3A'),
 category: 'loading',
-fn: function (aJSONObject){
+fn: function (aJSONObjectOrString){
 var self=this;
 var book=nil;
 var album=nil;
-(album=smalltalk.send(aJSONObject, "_album", []));
-(book=(function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(album, "_titre", [])]);smalltalk.send($rec, "_width_", [smalltalk.send(album, "_width", [])]);smalltalk.send($rec, "_height_", [smalltalk.send(album, "_height", [])]);smalltalk.send($rec, "_downloadUrl_", [smalltalk.send(album, "_at_", ["download_url"])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Book || Book), "_new", [])));
-smalltalk.send(smalltalk.send(album, "_ressources", []), "_do_", [(function(aRessource){return (function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(aRessource, "_titre", [])]);smalltalk.send($rec, "_description_", [smalltalk.send(aRessource, "_description", [])]);smalltalk.send($rec, "_thumbnailURL_", [smalltalk.send(aRessource, "_thumbnail", [])]);smalltalk.send($rec, "_fullImageURL_", [smalltalk.send(aRessource, "_original", [])]);smalltalk.send($rec, "_foliono_", [smalltalk.send(aRessource, "_foliono", [])]);return smalltalk.send($rec, "_navigatorThumbnailURL_", [smalltalk.send(aRessource, "_at_", ["navigator_thumbnail"])]);})(smalltalk.send(book, "_newPage", []));})]);
+(album=smalltalk.send(((($receiver = smalltalk.send(aJSONObjectOrString, "_isString", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_JSON", []), "_parse_", [aJSONObjectOrString]);})() : (function(){return aJSONObjectOrString;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_JSON", []), "_parse_", [aJSONObjectOrString]);}), (function(){return aJSONObjectOrString;})])), "_album", []));
+(book=(function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(album, "_at_", ["titre"])]);smalltalk.send($rec, "_width_", [smalltalk.send(album, "_at_", ["width"])]);smalltalk.send($rec, "_height_", [smalltalk.send(album, "_at_", ["height"])]);smalltalk.send($rec, "_downloadUrl_", [smalltalk.send(album, "_at_", ["download_url"])]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Book || Book), "_new", [])));
+smalltalk.send(smalltalk.send(album, "_ressources", []), "_do_", [(function(aRessource){return (function($rec){smalltalk.send($rec, "_title_", [smalltalk.send(aRessource, "_at_", ["titre"])]);smalltalk.send($rec, "_description_", [smalltalk.send(aRessource, "_at_", ["description"])]);smalltalk.send($rec, "_thumbnailURL_", [smalltalk.send(aRessource, "_at_", ["thumbnail"])]);smalltalk.send($rec, "_fullImageURL_", [smalltalk.send(aRessource, "_at_", ["original"])]);smalltalk.send($rec, "_foliono_", [smalltalk.send(aRessource, "_at_", ["foliono"])]);return smalltalk.send($rec, "_navigatorThumbnailURL_", [smalltalk.send(aRessource, "_at_", ["navigator_thumbnail"])]);})(smalltalk.send(book, "_newPage", []));})]);
 return book;
 return self;},
-args: ["aJSONObject"],
-source: unescape('buildBookFromJSon%3A%20aJSONObject%0A%09%7Cbook%20album%7C%0A%09album%20%3A%3D%20aJSONObject%20album.%0A%09book%20%3A%3D%20Book%20new%0A%09%09%09%09title%3A%20album%20titre%3B%0A%09%09%09%09width%3A%20album%20width%3B%0A%09%09%09%09height%3A%20album%20height%3B%0A%09%09%09%09downloadUrl%3A%20%28album%20at%3A%20%27download_url%27%29%3B%0A%09%09%09%09yourself.%0A%09album%20ressources%20do%3A%20%5B%3AaRessource%7C%20%0A%20%20%20%20%20%20%20%20%09%09%09%09%09book%20newPage%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09title%3A%20aRessource%20titre%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09description%3A%20aRessource%20description%3B%0A%09%09%09%09%09%09%09thumbnailURL%3A%20aRessource%20thumbnail%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09fullImageURL%3A%20aRessource%20original%3B%0A%09%09%09%09%09%09%09foliono%3A%20aRessource%20foliono%3B%0A%09%09%09%09%09%09%09navigatorThumbnailURL%3A%20%28aRessource%20at%3A%20%27navigator_thumbnail%27%29%5D.%0A%09%5E%20book%0A%0A%09'),
-messageSends: ["album", "title:", "titre", "width:", "width", "height:", "height", "downloadUrl:", "at:", "yourself", "new", "do:", "ressources", "description:", "description", "thumbnailURL:", "thumbnail", "fullImageURL:", "original", "foliono:", "foliono", "navigatorThumbnailURL:", "newPage"],
+args: ["aJSONObjectOrString"],
+source: unescape('buildBookFromJSon%3A%20aJSONObjectOrString%0A%09%7Cbook%20album%7C%0A%09album%20%3A%3D%20%28aJSONObjectOrString%20isString%20%0A%09%09%09%09%09ifTrue%3A%20%5Bwindow%20JSON%20parse%3A%20aJSONObjectOrString%5D%20%0A%09%09%09%09%09ifFalse%3A%20%5BaJSONObjectOrString%5D%29%20album.%0A%09book%20%3A%3D%20Book%20new%0A%09%09%09%09title%3A%20%28album%20at%3A%20%27titre%27%29%3B%0A%09%09%09%09width%3A%20%28album%20at%3A%20%27width%27%29%3B%0A%09%09%09%09height%3A%20%28album%20at%3A%20%27height%27%29%3B%0A%09%09%09%09downloadUrl%3A%20%28album%20at%3A%20%27download_url%27%29%3B%0A%09%09%09%09yourself.%0A%09album%20ressources%20do%3A%20%5B%3AaRessource%7C%20%0A%20%20%20%20%20%20%20%20%09%09%09%09%09book%20newPage%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09title%3A%20%28aRessource%20at%3A%20%27titre%27%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09description%3A%20%28aRessource%20at%3A%20%27description%27%29%3B%0A%09%09%09%09%09%09%09thumbnailURL%3A%20%28aRessource%20at%3A%20%27thumbnail%27%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09%09fullImageURL%3A%20%28aRessource%20at%3A%20%27original%27%29%3B%0A%09%09%09%09%09%09%09foliono%3A%20%28aRessource%20at%3A%20%27foliono%27%29%3B%0A%09%09%09%09%09%09%09navigatorThumbnailURL%3A%20%28aRessource%20at%3A%20%27navigator_thumbnail%27%29%5D.%0A%09%5E%20book%0A%0A%09'),
+messageSends: ["album", "ifTrue:ifFalse:", "isString", "parse:", "JSON", "title:", "at:", "width:", "height:", "downloadUrl:", "yourself", "new", "do:", "ressources", "description:", "thumbnailURL:", "fullImageURL:", "foliono:", "navigatorThumbnailURL:", "newPage"],
 referencedClasses: ["Book"]
 }),
 smalltalk.BibNumLoader);
@@ -700,7 +700,7 @@ category: 'loading',
 fn: function (aBlock){
 var self=this;
 (function($rec){smalltalk.send($rec, "_onSuccessDo_", [(function(data){var book=nil;
-book=smalltalk.send(self, "_buildBookFromJSon_", [data]);return smalltalk.send(aBlock, "_value_", [book]);})]);return smalltalk.send($rec, "_send", []);})(smalltalk.send(self, "_ajax", []));
+(book=smalltalk.send(self, "_buildBookFromJSon_", [data]));return smalltalk.send(aBlock, "_value_", [book]);})]);return smalltalk.send($rec, "_send", []);})(smalltalk.send(self, "_ajax", []));
 return self;},
 args: ["aBlock"],
 source: unescape('loadBookFromJSONOnSuccess%3A%20aBlock%0A%09self%20ajax%0A%09%09onSuccessDo%3A%20%5B%3Adata%7C%20%7Cbook%7C%0A%09%09%09%09%09%09%09book%20%3A%3D%20self%20buildBookFromJSon%3A%20data.%0A%09%09%09%09%09%09%09aBlock%20value%3A%20book%5D%3B%0A%09%09send.'),
@@ -986,11 +986,11 @@ selector: unescape('downloadUrl'),
 category: 'accessing',
 fn: function (){
 var self=this;
-return self['@downloadUrl'];
+return (($receiver = self['@downloadUrl']) == nil || $receiver == undefined) ? (function(){return (self['@downloadUrl']="");})() : $receiver;
 return self;},
 args: [],
-source: unescape('downloadUrl%0A%09%5E%20downloadUrl'),
-messageSends: [],
+source: unescape('downloadUrl%0A%09%5E%20downloadUrl%20ifNil%3A%20%5BdownloadUrl%20%3A%3D%20%27%27%5D'),
+messageSends: ["ifNil:"],
 referencedClasses: []
 }),
 smalltalk.Book);
diff --git a/amber/afi/st/AFI-Tests.st b/amber/afi/st/AFI-Tests.st
index c096dd00b99c70f589d2ba4aa17c35aee44dfd32..cb19ace9df951302ac1727db4c01b0a001607547 100644
--- a/amber/afi/st/AFI-Tests.st
+++ b/amber/afi/st/AFI-Tests.st
@@ -1,56 +1,70 @@
 Smalltalk current createPackage: 'AFI-Tests' properties: #{}!
-TestCase subclass: #CycleTest
-	instanceVariableNames: ''
-	category: 'AFI-Tests'!
+TestCase subclass: #BibNumAlbumTestCase
+	instanceVariableNames: 'ajax container album'
+	package: 'AFI-Tests'!
 
-!CycleTest methodsFor: 'tests'!
+!BibNumAlbumTestCase methodsFor: 'running'!
 
-testCycleWithTwoElements
-	|cycle|
-	cycle := Cycle with: #('one' 'two').
-	self assert: 'one' equals: cycle next.
-	self assert: 'two' equals: cycle next.
-	self assert: 'one' equals: cycle next.
-	self assert: 'two' equals: cycle next.
+setUp
+	window location hash: ' '.
+	ajax := AMockWrapper on: Ajax new.
+	ajax onMessage: 'send' answer: ajax.
+
+	container := '<div></div>' asJQuery width: 500.
+
+	album := BibNumAlbum new 
+		ajax: ajax;
+		container: container
 !
 
-testCycleWithFourElements
-	|cycle|
-	cycle := Cycle with: #('one' 'two' 'three' 'four').
-	3 timesRepeat: [
-		self assert: 'one' equals: cycle next.
-		self assert: 'two' equals: cycle next.
-		self assert: 'three' equals: cycle next.
-		self assert: 'four' equals: cycle next ].
+tearDown
+	container remove.
 ! !
 
-TestCase subclass: #SouvignyBibleTest
-	instanceVariableNames: 'bible'
-	category: 'AFI-Tests'!
+BibNumAlbumTestCase subclass: #BibNumAlbumDonjonTest
+	instanceVariableNames: 'ajax container album'
+	package: 'AFI-Tests'!
 
-!SouvignyBibleTest methodsFor: 'running'!
+!BibNumAlbumDonjonTest methodsFor: 'accessing'!
 
-setUp
-	bible := SouvignyBible new
+donjonJSON
+	^   '{"album": {	"id":4, 
+					"titre":"Donjon Zenith", 
+					"description":"Une bonne bagarre",
+					"width": 200,
+					"height": 50,
+					"ressources":[ 
+                                                          				{	"id":1,
+                                                          					"titre": "Donjon",
+                                                          					"link_to":"",
+                                                          					"thumbnail":"userfiles/album/4/thumbs/media/1.jpg",
+                                                          					"navigator_thumbnail":"userfiles/album/4/thumbs/media/1_small.jpg",
+                                                          					"original":"bib-numerique/get-resource/id/4.jpg"}
+				]
+		} }'.
 ! !
 
-!SouvignyBibleTest methodsFor: 'tests'!
+!BibNumAlbumDonjonTest methodsFor: 'running'!
 
-testFolioOneShouldReturnPageOne
-	self assert: 1 equals: (bible parseFolioNo: '1')
-!
+setUp
+	super setUp.
 
-testFolio150VShouldReturnPage306
-	self assert: 306 equals:(bible parseFolioNo: '150v').
-!
+	album
+		url: 'donjon.json';
+		load.
 
-testFolio151RShouldReturnPage307
-	self assert: 307 equals:(bible parseFolioNo: '151r').
+	(ajax options at: 'success')  value: self donjonJSON.
+! !
+
+!BibNumAlbumDonjonTest methodsFor: 'tests'!
+
+testAnchorToDownloadPDFShouldNotBePresent
+	self assert: 0 equals: ((container find: 'div.b-download-book a') at: 'size') value
 ! !
 
-TestCase subclass: #BibNumAlbumTintinTest
+BibNumAlbumTestCase subclass: #BibNumAlbumTintinTest
 	instanceVariableNames: 'bible album container ajax'
-	category: 'AFI-Tests'!
+	package: 'AFI-Tests'!
 
 !BibNumAlbumTintinTest methodsFor: 'json'!
 
@@ -86,28 +100,38 @@ tintinJSON
 !BibNumAlbumTintinTest methodsFor: 'running'!
 
 setUp
-	window location hash: ' '.
-	ajax := AMockWrapper on: Ajax new.
-	ajax onMessage: 'send' answer: ajax.
-
-	container := '<div></div>' asJQuery width: 500.
+	super setUp.
 
-	album := BibNumAlbum new 
+	album
 		url: '/bib-numerique/album/id/2.json';
 		scriptsRoot: 'http://localhost/afi-opac3/amber/afi/souvigny/';
-		ajax: ajax;
-		container: container; 
 		load.
 
 	(ajax options at: 'success')  value: (jQuery parseJSON: self tintinJSON).
-!
-
-tearDown
-	container remove.
 ! !
 
 !BibNumAlbumTintinTest methodsFor: 'tests'!
 
+testAnchorToDownloadPDFShouldBePresent
+	self assert: 'http://localhost/pdf/2'  equals: ((container find: 'div.b-download-book a') attr: 'href' )
+!
+
+testBookletJSShouldBeLoadedOnce
+	self assert: 1 equals: ( 'head' asJQuery find: 'script[src*="booklet.1.2.0.min.js"]') length
+!
+
+testBookletPluginShouldBeLoaded
+	self assert: ('body' asJQuery at: 'booklet') notNil
+!
+
+testChapterSelectorInitialHeightShouldBeZero
+	self assert: 0  equals: (container find: '.b-selector-chapter>ul')   height
+!
+
+testChapterSelectorShouldContainsLinkToFirstPage
+	self assert: 'Origins'  equals: (container find: '.b-selector-chapter #selector-page-1')   text
+!
+
 testDivBkWidgetShouldBePresent
 	|bkWidget|
 	bkWidget := container children: '.bk-widget'.
@@ -120,30 +144,30 @@ testDivBookShouldBePresent
 	self assert: (0 < book length).
 !
 
-testBookletPluginShouldBeLoaded
-	self assert: ('body' asJQuery at: 'booklet') notNil
+testFirstPageImageFolioNumberShouldBeTwelveR
+	self assert: '12R' equals: (container find: '.b-counter + .b-counter')  text
 !
 
-testBookletJSShouldBeLoadedOnce
-	self assert: 1 equals: ( 'head' asJQuery find: 'script[src*="booklet.1.2.0.min.js"]') length
+testFirstPageImageShouldLinkToOneDotJpg
+	self assert: 0 < (container find: 'img[src*="userfiles/album/2/thumbs/media/1.jpg"]')  length
 !
 
-testShouldContainsFourPages
-	"2 pages + covers"
-	self assert: 4 equals: (container find: '.b-page') length
+testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg
+	self assert: 'userfiles/album/2/thumbs/media/1_small.jpg' equals: album pages first navigatorThumbnailURL
 !
 
-testFirstPageImageShouldLinkToOneDotJpg
-	self assert: 0 < (container find: 'img[src*="userfiles/album/2/thumbs/media/1.jpg"]')  length
+testFirstPageZoomedImageShouldLinkToOneDotJpg
+	(container find: '.b-zoom-magnify a') click.
+	self assert: 0 < (container find: '.iviewer img[src*="bib-numerique/get-resource/id/1.jpg"]')  length
 !
 
-testPageDescShouldContainsCreatedIn1929ByHerge
-	self assert: 'Created in 1929 by Herge' equals: (container find: '.page-desc') text
+testNextPageShouldSetMenuTextToFin
+	(container find: '.book') booklet: 'next'.
+	self assert: 'Fin' equals: (container find: '.b-current') text
 !
 
-testPageWidthShouldBe165
-	"resize to its container width (500)  - margins (170)  / 2 pages"  
-	self assert: 165 equals: (container find: '.b-page')  width
+testPageDescShouldContainsCreatedIn1929ByHerge
+	self assert: 'Created in 1929 by Herge' equals: (container find: '.page-desc') text
 !
 
 testPageHeightShouldBe124
@@ -151,37 +175,66 @@ testPageHeightShouldBe124
 	self assert: 124 equals: (container find: '.b-page')  height
 !
 
-testFirstPageZoomedImageShouldLinkToOneDotJpg
-	(container find: '.b-zoom-magnify a') click.
-	self assert: 0 < (container find: '.iviewer img[src*="bib-numerique/get-resource/id/1.jpg"]')  length
+testPageWidthShouldBe165
+	"resize to its container width (500)  - margins (170)  / 2 pages"  
+	self assert: 165 equals: (container find: '.b-page')  width
 !
 
-testChapterSelectorShouldContainsLinkToFirstPage
-	self assert: 'Origins'  equals: (container find: '.b-selector-chapter #selector-page-1')   text
+testSecondPageImageFolioNumberShouldBeXX
+	self assert: 'XX' equals: album pages last foliono
 !
 
-testChapterSelectorInitialHeightShouldBeZero
-	self assert: 0  equals: (container find: '.b-selector-chapter>ul')   height
-!
+testShouldContainsFourPages
+	"2 pages + covers"
+	self assert: 4 equals: (container find: '.b-page') length
+! !
 
-testFirstPageImageFolioNumberShouldBeTwelveR
-	self assert: '12R' equals: (container find: '.b-counter + .b-counter')  text
-!
+TestCase subclass: #CycleTest
+	instanceVariableNames: ''
+	package: 'AFI-Tests'!
 
-testSecondPageImageFolioNumberShouldBeXX
-	self assert: 'XX' equals: album pages last foliono
+!CycleTest methodsFor: 'tests'!
+
+testCycleWithFourElements
+	|cycle|
+	cycle := Cycle with: #('one' 'two' 'three' 'four').
+	3 timesRepeat: [
+		self assert: 'one' equals: cycle next.
+		self assert: 'two' equals: cycle next.
+		self assert: 'three' equals: cycle next.
+		self assert: 'four' equals: cycle next ].
 !
 
-testAnchorToDownloadPDFShouldBePresent
-	self assert: 'http://localhost/pdf/2'  equals: ((container find: 'div.b-download-book a') attr: 'href' )
+testCycleWithTwoElements
+	|cycle|
+	cycle := Cycle with: #('one' 'two').
+	self assert: 'one' equals: cycle next.
+	self assert: 'two' equals: cycle next.
+	self assert: 'one' equals: cycle next.
+	self assert: 'two' equals: cycle next.
+! !
+
+TestCase subclass: #SouvignyBibleTest
+	instanceVariableNames: 'bible'
+	package: 'AFI-Tests'!
+
+!SouvignyBibleTest methodsFor: 'running'!
+
+setUp
+	bible := SouvignyBible new
+! !
+
+!SouvignyBibleTest methodsFor: 'tests'!
+
+testFolio150VShouldReturnPage306
+	self assert: 306 equals:(bible parseFolioNo: '150v').
 !
 
-testNextPageShouldSetMenuTextToFin
-	(container find: '.book') booklet: 'next'.
-	self assert: 'Fin' equals: (container find: '.b-current') text
+testFolio151RShouldReturnPage307
+	self assert: 307 equals:(bible parseFolioNo: '151r').
 !
 
-testFirstPageNavigatorThumbnailShouldBeOneSmallDotJpg
-	self assert: 'userfiles/album/2/thumbs/media/1_small.jpg' equals: album pages first navigatorThumbnailURL
+testFolioOneShouldReturnPageOne
+	self assert: 1 equals: (bible parseFolioNo: '1')
 ! !
 
diff --git a/amber/afi/st/AFI.st b/amber/afi/st/AFI.st
index c876695ba7b57f913ae5e90331e21f1c5e667c77..af44a758099c6a6b6551a84d69670ef347020ee6 100644
--- a/amber/afi/st/AFI.st
+++ b/amber/afi/st/AFI.st
@@ -446,22 +446,24 @@ abort
 	self ajax abort
 !
 
-buildBookFromJSon: aJSONObject
+buildBookFromJSon: aJSONObjectOrString
 	|book album|
-	album := aJSONObject album.
+	album := (aJSONObjectOrString isString 
+					ifTrue: [window JSON parse: aJSONObjectOrString] 
+					ifFalse: [aJSONObjectOrString]) album.
 	book := Book new
-				title: album titre;
-				width: album width;
-				height: album height;
+				title: (album at: 'titre');
+				width: (album at: 'width');
+				height: (album at: 'height');
 				downloadUrl: (album at: 'download_url');
 				yourself.
 	album ressources do: [:aRessource| 
         					book newPage
-                                			title: aRessource titre;
-                              				description: aRessource description;
-							thumbnailURL: aRessource thumbnail;
-                             				fullImageURL: aRessource original;
-							foliono: aRessource foliono;
+                                			title: (aRessource at: 'titre');
+                              				description: (aRessource at: 'description');
+							thumbnailURL: (aRessource at: 'thumbnail');
+                             				fullImageURL: (aRessource at: 'original');
+							foliono: (aRessource at: 'foliono');
 							navigatorThumbnailURL: (aRessource at: 'navigator_thumbnail')].
 	^ book
 !
@@ -592,7 +594,7 @@ Object subclass: #Book
 !Book methodsFor: 'accessing'!
 
 downloadUrl
-	^ downloadUrl
+	^ downloadUrl ifNil: [downloadUrl := '']
 !
 
 downloadUrl: anUrl