1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-05 15:32:55 +02:00

Merge branch 'gh-pages'

This commit is contained in:
Fred Chasen 2013-03-02 18:37:01 -08:00
commit 688cbb8eb5
25 changed files with 168 additions and 471 deletions

BIN
.DS_Store vendored

Binary file not shown.

85
dev.html Executable file
View file

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="fpjs/libs/jquery-1.9.0.min.js"><\/script>')</script>
-->
<script src="fpjs/libs/jquery-1.9.0.js"></script>
<script src="fpjs/libs/modernizr-2.6.2.min.js"></script>
<script>
"use strict";
document.onreadystatechange = function () {
if (document.readyState == "complete") {
FPR.app.init();
}
};
</script>
<!--<script async src="fpjs/libs/jquery.touchy.min.js"></script>-->
<!-- Render -->
<script src="fpjs/render/base.js"></script>
<script src="fpjs/render/core.js"></script>
<script src="fpjs/render/queue.js"></script>
<script src="fpjs/render/unarchiver.js"></script>
<script src="fpjs/render/storage.js"></script>
<script src="fpjs/render/storage_ram.js"></script>
<script src="fpjs/render/storage_websql.js"></script>
<script src="fpjs/render/storage_indexeddb.js"></script>
<script src="fpjs/render/storage_filesystem.js"></script>
<script src="fpjs/render/events.js"></script>
<script src="fpjs/render/hooks.js"></script>
<script src="fpjs/render/book.js"></script>
<script src="fpjs/render/chapter.js"></script>
<!-- Plugins -->
<script async src="fpjs/hooks/transculsions.js"></script>
<!-- Reader -->
<script async src="fpjs/reader/utils.js"></script>
<script async src="fpjs/reader/app.js"></script>
</head>
<body>
<div id="sidebar">
<div id="controls">
<input id="search" placeholder="search">
<a id="network"><img id="store" src="img/save.png"></a>
<a id="setting"><img id="settings" src="img/settings.png"></a>
</div>
<div id="toc">
</div>
<div id="settingsPanel">
</div>
</div>
<div id="main">
<div id="opener">
<a id="open"><img src="img/menu-icon.png"></a>
</div>
<div id="titlebar">
<span id="book-title"></span>
<span id="title-seperator">&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span id="chapter-title"> </span>
</div>
<div id="prev" class="arrow"></div>
<div id="area"></div>
<div id="next" class="arrow"></div>
<div id="divider"></div>
<div id="loader"><img src="img/loader.gif"></div>
</div>
</body>
</html>

BIN
dist/.DS_Store vendored Normal file

Binary file not shown.

2
dist/hooks/transculsions.min.js vendored Normal file
View file

@ -0,0 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-02 */
FP.Hooks.register("beforeChapterDisplay").transculsions=function(e,t){var n=t.doc.querySelectorAll("[transclusion]"),r=Array.prototype.slice.call(n);r.forEach(function(e){function l(){u=i,a=s,u>t.colWidth&&(f=t.colWidth/u,u=t.colWidth,a*=f),r.width=u,r.height=a}var n=e.getAttribute("ref"),r=document.createElement("iframe"),i=e.getAttribute("width"),s=e.getAttribute("height"),o=e.parentNode,u=i,a=s,f;l(),t.book.listenUntil("book:resized","book:chapterDestroy",l),r.src=n,o.replaceChild(r,e)}),e&&e()};

BIN
dist/libs/.DS_Store vendored Normal file

Binary file not shown.

1
dist/libs/deflate.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/libs/inflate.js vendored Normal file

File diff suppressed because one or more lines are too long

4
dist/libs/jquery-1.9.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/libs/mime-types.js vendored Normal file

File diff suppressed because one or more lines are too long

4
dist/libs/modernizr-2.6.2.min.js vendored Executable file

File diff suppressed because one or more lines are too long

1
dist/libs/zip.js vendored Normal file

File diff suppressed because one or more lines are too long

2
dist/reader.min.js vendored Normal file
View file

@ -0,0 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-02 */
var FPR=FPR||{};FPR.app={},FPR.app.init=function(e){"use strict";function s(n){var s=window.location.search.match(/book=(.*)/),n=n||(s?s[1]:"moby-dick");FP.core.crossBrowserColumnCss(),i=e(window).width(),i>550?e("#main").width(i-r):e("#main").width(i),a(),t=new FP.Book("area"),t.listen("book:metadataReady",o),t.listen("book:tocReady",u),t.listen("book:bookReady",l),t.listen("book:chapterReady",p),t.listen("book:online",c),t.listen("book:offline",h),t.start(n),e(function(){d()})}function o(){var n=t.getTitle(),r=t.getCreator(),i=e("#book-title"),s=e("#chapter-title"),o=e("#title-seperator");document.title=n+" "+r,i.html(n),s.html(r),o.show()}function u(){var n=t.getTOC(),r=e("#toc"),i,s;r.empty(),s=f(n,1),r.append(s),i=e(".toc_link"),i.on("click",function(n){var r=e(this),i=r.data("url");e(".openChapter").removeClass("openChapter"),r.parents("li").addClass("openChapter"),t.useHash||(t.show(i),n.preventDefault())})}function a(){var t="";localStorage.getItem("fontSize")?t=localStorage.getItem("fontSize"):(t="medium",localStorage.setItem("fontSize",t));var n=e("#settingsPanel");n.append("<ul></ul>");var r=e("<li><h3></h3></li>"),i=e("<input type='radio' name='fontSize' value='x-small'><span class='font-size xsmall'>Extra Small</span><br><input type='radio' name='fontSize' value='small'><span class='font-size small'>Small</span><br><input type='radio' name='fontSize' value='medium'><span class='font-size medium'>Medium</span><br><input type='radio' name='fontSize' value='large'><span class='font-size large'>Large</span><br><input type='radio' name='fontSize' value='large'><span class='font-size xlarge'>Extra Large</span>");r.find("h3").text("Font Size").after(i),n.find("ul").append(r);var s=e('input[name="fontSize"]');s.each(function(){e(this).attr("value")==t&&e(this).attr("checked","checked"),e(this).on("click",function(){localStorage.setItem("fontSize",e(this).attr("value"))})})}function f(t,n){var r=e("<ul>"),i=n==1?"chapter":"section";return t.forEach(function(t){var s,o=e("<li id='toc-"+t.id+"'>"),u=e("<a class='toc_link "+i+"' href='#/"+t.href+"' data-url='"+t.href+"'>"+t.label+"</a>");o.append(u),t.subitems&&t.subitems.length&&(n++,s=f(t.subitems,n),o.append(s)),r.append(o)}),r}function l(){var t=e("#divider"),n=e("#loader");n.hide(),t.addClass("show")}function c(){var t=e("#store");n=!1,t.attr("src","img/save.png")}function h(){var t=e("#store");n=!0,t.attr("src","img/saved.png")}function p(t){var n=t.msg,r=e("#toc-"+n),i=e(".currentChapter");r.length&&(i.removeClass("currentChapter"),r.addClass("currentChapter"))}function d(){function y(){f.addClass("open"),u.addClass("closed"),c.attr("src","img/close.png")}function b(){a.css("pointer-events","visible"),f.removeClass("open"),u.removeClass("closed"),c.attr("src","img/menu-icon.png")}function w(){v.hide(),d.show()}function E(){d.hide(),v.show()}var s=e("#next"),o=e("#prev"),u=e("#main"),a=e("#area"),f=e("#sidebar"),l=e("#open"),c=l.find("img"),h=e("#network"),p=e("#setting"),d=e("#settingsPanel"),v=e("#toc"),m=e(window);m.on("resize",function(){i=e(window).width(),i>550?u.width(i-r):u.width(i)}),s.on("click",function(){t.nextPage()}),o.on("click",function(){t.prevPage()}),p.on("click",function(){d.is(":visible")?E():w()}),m.bind("touchy-swipe",function(e,n,r,i){(i.direction="left")&&t.nextPage(),(i.direction="right")&&t.prevPage()});var g=!1;e(document).keydown(function(e){if(g)return;if(e.keyCode==37)return o.trigger("click"),g=!0,setTimeout(function(){g=!1},100),!1;if(e.keyCode==39)return s.trigger("click"),g=!0,setTimeout(function(){g=!1},100),!1}),l.on("click",function(){f.hasClass("open")?b():y()}),h.on("click",function(){n=!n,t.fromStorage(n)})}var t,n=!1,r=0,i;return s}(jQuery),jQuery.fn.extend({clickOutside:function(e,t){var n=this;return jQuery(document).on("click.offer",function(r){if(t&&jQuery.inArray(r.target,t)>-1)return;if(jQuery.contains(n[0],r.target))return;jQuery(document).off("click.offer"),e(r,n)}),this}}),Modernizr.addTest("filesystem",function(){var e=Modernizr._domPrefixes;for(var t=-1,n=e.length;++t<n;)if(window[e[t]+"RequestFileSystem"])return!0;return"requestFileSystem"in window});

2
dist/render.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
dist/workers/loader_filesystem.js vendored Normal file
View file

@ -0,0 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-02 */
var _requestFileSystem=self.requestFileSystem||self.webkitRequestFileSystem;const DBSIZE=5242880,DBTYPE=TEMPORARY;self.onmessage=function(e){var t=e.data;self.request(t,function(e){self.save(t,e,function(){self.postMessage(t)})})},self.openFs=function(e){if(self._fs){e&&e(self._fs);return}_requestFileSystem(DBTYPE,DBSIZE,function(t){self._fs=t,e&&e(t)},self.failure)},self.request=function(e,t){var n=new self.loadFile(e);n.succeeded=function(e){t&&t(e)},n.failed=function(e){self.postMessage("failed: "+e.toString())},n.start()},self.save=function(e,t,n){self.openFs(function(r){var i=e.split("/").slice(0,-1);self.createDir(r.root,i),r.root.getFile(e,{create:!0},function(r){r.createWriter(function(r){r.onwriteend=function(e){n(e)},r.onerror=function(t){self.postMessage("write error:"+self.errorHandler(err)+" path="+e)},r.write(t)})},self.failure)})},self.createDir=function(e,t){if(t[0]=="."||t[0]=="")t=t.slice(1);e.getDirectory(t[0],{create:!0},function(e){t.length&&createDir(e,t.slice(1))},self.failure)},self.failure=function(e){self.postMessage("failed: "+self.errorHandler(e))},self.errorHandler=function(e){switch(e.code){case FileError.QUOTA_EXCEEDED_ERR:return"QUOTA_EXCEEDED_ERR";case FileError.NOT_FOUND_ERR:return"NOT_FOUND_ERR";case FileError.SECURITY_ERR:return"SECURITY_ERR";case FileError.INVALID_MODIFICATION_ERR:return"INVALID_MODIFICATION_ERR";case FileError.INVALID_STATE_ERR:return"INVALID_STATE_ERR";default:return"Unknown Error"}},self.loadFile=function(e,t){var n=new XMLHttpRequest;return this.succeeded=function(e){t&&t(e)},this.failed=function(e){console.log("Error:",e)},this.start=function(){var t=this;n.open("GET",e,!0),n.responseType="blob",n.onload=function(e){this.status==200&&t.succeeded(this.response)},n.onerror=function(e){t.failed(this.status)},n.send()},{start:this.start,succeeded:this.succeeded,failed:this.failed}},self.openFs();

BIN
fpjs/.DS_Store vendored

Binary file not shown.

View file

@ -1,197 +0,0 @@
FP.namespace('app').init = (function($){
function init(){
var fileInput = document.getElementById("file-input");
var area = document.getElementById("area");
var bookFiles = [],
bookImages = [],
bookCSS = [];
var pages = {},
images = {},
ordered = [];
//-- Tell zip where it is located
zip.workerScriptsPath = "js/libs/";
//-- Listen for the Input Change
fileInput.addEventListener('change', function(){
//-- Grab first file
var file = fileInput.files[0];
//-- Get all Entries in Zip file
FP.core.loadZip.getEntries(file, function(entries) {
//TODO: parse the rootfile to find files
var total = 0,
loaded = 0;
var total_img = 0,
loaded_img = 0;
//-- Split Entries into xhtml, images, css
entries.forEach(function(entry) {
if(entry.filename.search(".xhtml") != -1 ||
entry.filename.search(".html") != -1 ||
entry.filename.search(".htm") != -1){
//console.log("entry", entry);
bookFiles.push(entry);
total++;
}
if(entry.filename.search(".jpg") != -1 || entry.filename.search(".png") != -1){
bookImages.push(entry);
total_img++;
}
if(entry.filename.search(".css") != -1){
bookCSS.push(entry);
}
});
bookImages.forEach(function(file) {
var name = file.filename.replace("OPS/", '').replace("OEBPS/", '');
//console.log("name", name)
//Blob or File
FP.core.loadZip.getEntryFile(file, "Blob", function(blobURL, revokeBlobURL) {
images[name] = blobURL;
//console.log("images[name]", images[name])
//var img = document.createElement('img');
//img.src = blobURL;
//area.appendChild(img);
loaded_img++;
if(loaded_img == total_img){
imgReady();
}
}, function(current, total) {
//-- Progress Meter
});
});
bookFiles.forEach(function(file) {
var reg = /\/(.*)\./,
name = reg.exec(file.filename)[1];
//TEMP ORDER FIX
if(name === "cover") name = "1_"+name;
if(name === "TOC") name = "2_"+name;
//Blob or File
FP.core.loadZip.getEntryFile(file, "Blob", function(blobURL, revokeBlobURL) {
//console.log(file, blobURL)
// $.ajax({
// url: blobURL,
// success: function(data) {
// pages.push(data);
// }
// });
$.ajax({
url: blobURL,
dataType: "html",
cache: true,
success: function(data) {
//var section = $("<section>");
//$('#area').append(section);
pages[name] = data;
ordered.push(name);
loaded++;
if(loaded == total){
allReady();
}
},
error: function(e){
console.log("error:", e)
}
});
//var section = $("<section>");
//section.load(blobURL);
//$('#area').append(section);
// var iframe = document.createElement('iframe');
// iframe.src = window.webkitURL.createObjectURL(blobURL);
// iframe.type = "content";
// area.appendChild(iframe);
// FP.core.load(blobURL, function(data){
// //console.log("data", data);
// var iframe = document.createElement('iframe');
// iframe.src = blobURL;
// iframe.type = "content";
// area.appendChild(iframe);
// });
// var reader = new FileReader();
// reader.onloadend = function() {
// if (this.result) {
// console.log(this.result)
// }
// else if ( errorCallback ) {
// console.log("ERROR")
// }
// };
// reader.readAsText(file);
}, function(current, total) {
//-- Progress Meter
});
});
function allReady(){
FP.book.page.start($("#area"), pages, ordered);
$("#modal").fadeOut();
$("#next").fadeIn();
$("#prev").fadeIn();
$("#next").on("click", function(){
FP.book.page.next();
});
$("#prev").on("click", function(){
FP.book.page.prev();
});
$(document).keydown(function(e) {
if(e.keyCode == 37) { // left
FP.book.page.prev();
}
else if(e.keyCode == 39) { // right
FP.book.page.next();
}
});
}
function imgReady(){
FP.book.page.setImages(images);
}
//console.log(bookFiles, bookImages, bookCSS)
});
});
}
return init;
})(jQuery);

View file

@ -1,147 +0,0 @@
FP.namespace('core').load = (function(){
function load(url, callback){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
// Note: .response instead of .responseText
var blob = new Blob([this.response], {type: 'application/xhtml+xml'});
callback(blob);
}
};
xhr.send();
}
return load;
})();
FP.namespace('core').load2 = (function(){
/*
PDFJS.getPdf(
{
url: "http://google.com",
progress: function getPDFProgress(evt) {
handler.send('DocProgress', {
loaded: evt.loaded,
total: evt.lengthComputable ? evt.total : void(0)
});
},
error: function getPDFError(e) {
console.log('DocError', 'Unexpected server response of ' +
e.target.status + '.');
},
headers: source.httpHeaders
},
function(data) {
});
});
*/
function load(arg, callback){
var params = arg;
if (typeof arg === 'string'){
params = { url: arg };
}
var xhr = new XMLHttpRequest();
xhr.open('GET', params.url);
var headers = params.headers;
if (headers) {
for (var property in headers) {
if (typeof headers[property] === 'undefined')
continue;
xhr.setRequestHeader(property, params.headers[property]);
}
}
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
var protocol = params.url.substring(0, params.url.indexOf(':') + 1);
xhr.expected = (protocol === 'http:' || protocol === 'https:') ? 200 : 0;
if ('progress' in params)
xhr.onprogress = params.progress || undefined;
var calledErrorBack = false;
if ('error' in params) {
xhr.onerror = function errorBack() {
if (!calledErrorBack) {
calledErrorBack = true;
params.error();
}
}
}
xhr.onreadystatechange = function getPdfOnreadystatechange(e) {
if (xhr.readyState === 4) {
if (xhr.status === xhr.expected) {
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
xhr.responseArrayBuffer || xhr.response);
callback(data);
} else if (params.error && !calledErrorBack) {
calledErrorBack = true;
params.error(e);
}
}
};
xhr.send(null);
}
return load;
})();
FP.namespace("core").loadZip = (function(){
var URL = webkitURL || mozURL || URL;
function getEntries(file, onend) {
//console.log("file", file)
// FP.utils.createTempFile(function(temp){
// console.log("temp", temp)
// });
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(onend);
}, function(error){ console.log("Error:", error) });
}
function getEntryFile(entry, creationMethod, onend, onprogress) {
var writer, zipFileEntry;
function getData() {
entry.getData(writer, function(blob) {
var blobURL = creationMethod == "Blob" ? URL.createObjectURL(blob) : zipFileEntry.toURL();
onend(blobURL, function() {
if (creationMethod == "Blob")
URL.revokeObjectURL(blobURL);
});
}, onprogress);
}
if (creationMethod == "Blob") {
writer = new zip.BlobWriter();
getData();
} else {
FP.utils.createTempFile(function(fileEntry) {
zipFileEntry = fileEntry;
writer = new zip.FileWriter(zipFileEntry);
getData();
});
}
}
return {
"getEntries" : getEntries,
"getEntryFile" : getEntryFile
}
})();

View file

@ -1,71 +0,0 @@
FP.namespace('book').page = (function($){
var _bookPages,
_ordered,
_$el,
_currentPage = 0,
_images;
function start($el, pages, order){
_$el = $el;
_bookPages = pages;
_ordered = order;
_ordered.sort(function(a, b) {
var textA = a.toUpperCase();
var textB = b.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
loadIn(0)
}
function loadIn(pageNum){
var page;
_currentPage = pageNum;
page = _bookPages[_ordered[_currentPage]];
_$el.html(page);
if(_images){
scanImages();
}
}
function next(){
if(_currentPage <= _ordered.length){
loadIn(_currentPage+1);
}
}
function prev(){
if(_currentPage > 0){
loadIn(_currentPage-1);
}
}
function setImages(images){
_images = images;
//scanImages();
}
function scanImages(){
_$el.find("img").each(function(){
var $this = $(this),
src = $this.attr("src");
$this.attr("src", _images[src]);
})
}
return {
"start" : start,
"loadIn" : loadIn,
"prev" : prev,
"next" : next,
"setImages": setImages
};
})(jQuery);

View file

@ -1,23 +0,0 @@
FP.namespace("utils").createTempFile = (function(){
var requestFileSystem = webkitRequestFileSystem || mozRequestFileSystem || requestFileSystem;
function createTempFile(callback) {
var tmpFilename = "tmp.dat";
requestFileSystem(TEMPORARY, 4 * 1024 * 1024 * 1024, function(filesystem) {
function create() {
filesystem.root.getFile(tmpFilename, {
create : true
}, function(zipFile) {
callback(zipFile);
});
}
filesystem.root.getFile(tmpFilename, null, function(entry) {
entry.remove(create, create);
}, create);
});
}
return createTempFile
})();

View file

@ -2,7 +2,7 @@ FP.store = FP.store || {};
FP.store.filesystem = function() {
var _urls = {},
_queue = new FP.Queue("fpjs/render/loader_filesystem.js", 6),
_queue = new FP.Queue("fpjs/render/workers/loader_filesystem.js", 6),
_requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
_fs;

View file

@ -1,5 +1,5 @@
FP.Unarchiver = function(url, callback){
this.libPath = "fpjs/libs/";
this.libPath = (this.fpjsPath || "fpjs/" ) + "/libs/";
this.zipUrl = url;
this.callback = callback;
this.loadLib(function(){

View file

@ -1,5 +1,3 @@
importScripts('core.js');
var _requestFileSystem = self.requestFileSystem || self.webkitRequestFileSystem;
const DBSIZE = 5*1024*1024;
@ -34,7 +32,7 @@ self.openFs = function(callback){
}
self.request = function(path, callback) {
var xhr = new FP.core.loadFile(path);
var xhr = new self.loadFile(path);
xhr.succeeded = function(file) {
if(callback) callback(file);
@ -113,5 +111,46 @@ self.errorHandler = function(e) {
break;
}
}
self.loadFile = function(url, callback){
var xhr = new XMLHttpRequest();
this.succeeded = function(response){
if(callback){
callback(response);
}
}
this.failed = function(err){
console.log("Error:", err);
}
this.start = function(){
var that = this;
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
that.succeeded(this.response);
}
};
xhr.onerror = function(e) {
that.failed(this.status); //-- TODO: better error message
};
xhr.send();
}
return {
"start": this.start,
"succeeded" : this.succeeded,
"failed" : this.failed
}
}
self.openFs();

View file

@ -8,13 +8,19 @@ module.exports = function(grunt) {
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
min: {
dist: {
src: ['<banner>', 'fpjs/render/*.js'],
dest: 'dist/built.min.js'
}
'dist/render.min.js': ['<banner>', 'fpjs/render/*.js'],
'dist/workers/loader_filesystem.js': ['<banner>', 'fpjs/render/workers/loader_filesystem.js'],
'dist/reader.min.js': ['<banner>', 'fpjs/reader/*.js'],
'dist/hooks/transculsions.min.js': ['<banner>', 'fpjs/hooks/transculsions.js'],
'dist/libs/zip.js': ['fpjs/libs/zip.js'],
'dist/libs/deflate.js': ['fpjs/libs/deflate.js'],
'dist/libs/inflate.js': ['fpjs/libs/inflate.js'],
'dist/libs/mime-types.js': ['fpjs/libs/mime-types.js']
}
});
// Default task(s).
grunt.registerTask('default', ['min']);

View file

@ -10,44 +10,29 @@
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> -->
<script src="fpjs/libs/jquery-1.9.0.js"></script>
<script>window.jQuery || document.write('<script src="fpjs/libs/jquery-1.9.0.min.js"><\/script>')</script>
<script src="fpjs/libs/modernizr-2.6.2.min.js"></script>
<script src="dist/libs/jquery-1.9.0.min.js"></script>
<script src="dist/libs/modernizr-2.6.2.min.js"></script>
<script>
"use strict";
document.onreadystatechange = function () {
if (document.readyState == "complete") {
FPR.fpjsPath = "dist/"
FPR.app.init();
}
};
</script>
<!--<script async src="fpjs/libs/jquery.touchy.min.js"></script>-->
<!-- Render -->
<script src="fpjs/render/base.js"></script>
<script src="fpjs/render/core.js"></script>
<script src="fpjs/render/queue.js"></script>
<script src="fpjs/render/unarchiver.js"></script>
<script src="fpjs/render/storage.js"></script>
<script src="fpjs/render/storage_ram.js"></script>
<script src="fpjs/render/storage_websql.js"></script>
<script src="fpjs/render/storage_indexeddb.js"></script>
<script src="fpjs/render/storage_filesystem.js"></script>
<script src="fpjs/render/events.js"></script>
<script src="fpjs/render/hooks.js"></script>
<script src="fpjs/render/book.js"></script>
<script src="fpjs/render/chapter.js"></script>
<script src="dist/render.min.js"></script>
<!-- Plugins -->
<script async src="fpjs/render/transculsions.js"></script>
<!-- Hooks -->
<script async src="dist/hooks/transculsions.min.js"></script>
<!-- Reader -->
<script async src="fpjs/reader/utils.js"></script>
<script async src="fpjs/reader/app.js"></script>
<script src="dist/reader.min.js"></script>
</head>
<body>