diff --git a/dist/epub.js b/dist/epub.js index c7e500cfb..04c5ea0e5 100644 --- a/dist/epub.js +++ b/dist/epub.js @@ -2174,6 +2174,7 @@ EPUBJS.Queue = function(_context){ this.context = _context; this.tick = EPUBJS.core.requestAnimationFrame; this.running = false; + this.paused = false; }; // Add an item to the queue @@ -2215,7 +2216,11 @@ EPUBJS.Queue.prototype.enqueue = function() { this._q.push(queued); // Wait to start queue flush - setTimeout(this.flush.bind(this), 0); + if (this.paused == false && !this.running) { + // setTimeout(this.flush.bind(this), 0); + // this.tick.call(window, this.run.bind(this)); + this.run(); + } return queued.promise; }; @@ -2268,25 +2273,46 @@ EPUBJS.Queue.prototype.dump = function(){ // Run all sequentially, at convince EPUBJS.Queue.prototype.run = function(){ - if(!this.running && this._q.length) { + + if(!this.running){ this.running = true; - this.dequeue().then(function(){ - this.running = false; - }.bind(this)); + this.defered = new RSVP.defer(); + } + + this.tick.call(window, function() { + + if(this._q.length) { + + this.dequeue() + .then(function(){ + this.run(); + }.bind(this)); + + } else { + this.defered.resolve(); + this.running = undefined; + } + + }.bind(this)); + + // Unpause + if(this.paused == true) { + this.paused = false; } - this.tick.call(window, this.run.bind(this)); + return this.defered.promise; }; // Flush all, as quickly as possible EPUBJS.Queue.prototype.flush = function(){ + if(this.running){ return this.running; } if(this._q.length) { - this.running = this.dequeue(). - then(function(){ + this.running = this.dequeue() + .then(function(){ this.running = undefined; return this.flush(); }.bind(this)); @@ -2306,6 +2332,10 @@ EPUBJS.Queue.prototype.length = function(){ return this._q.length; }; +EPUBJS.Queue.prototype.pause = function(){ + this.paused = true; +}; + // Create a new task from a callback EPUBJS.Task = function(task, args, context){ @@ -2793,10 +2823,10 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) { 'tagName' : node.tagName, 'index' : children ? Array.prototype.indexOf.call(children, node) : 0 }); - + node = node.parentNode; } - + return stack; }; @@ -2835,21 +2865,21 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { text, parseStep = function(part){ var type, index, has_brackets, id; - + type = "element"; index = parseInt(part) / 2 - 1; has_brackets = part.match(/\[(.*)\]/); if(has_brackets && has_brackets[1]){ id = has_brackets[1]; } - + return { "type" : type, 'index' : index, 'id' : id || false }; }; - + if(typeof cfiStr !== "string") { return {spinePos: -1}; } @@ -2868,7 +2898,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { if(!chapterComponent) { return {spinePos: -1}; } - + // Chapter segment is always the second one chapSegment = chapterComponent.split("/")[2] || ''; if(!chapSegment) return {spinePos:-1}; @@ -2891,7 +2921,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { path.forEach(function(part){ var step; - + if(part) { step = parseStep(part); cfi.steps.push(step); @@ -2901,7 +2931,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { //-- Check if END is a text node or element endInt = parseInt(end); if(!isNaN(endInt)) { - + if(endInt % 2 === 0) { // Even = is an element cfi.steps.push(parseStep(end)); } else { @@ -2921,7 +2951,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { } else { cfi.characterOffset = parseInt(charecterOffsetComponent); } - + return cfi; }; @@ -2932,7 +2962,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { var lastStep; var text; var split; - + if(typeof cfi === 'string') { cfi = this.parse(cfi); } @@ -2947,13 +2977,13 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { // Find the CFI elements parent parent = this.findParent(cfi, doc); - + if(!parent) { // CFI didn't return an element // Maybe it isnt in the current chapter? return false; } - + if(lastStep && lastStep.type === "text") { text = parent.childNodes[lastStep.index]; if(cfi.characterOffset){ @@ -2966,7 +2996,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { } else { parent.insertBefore(marker, parent.firstChild); } - + return marker; }; @@ -2975,7 +3005,7 @@ EPUBJS.EpubCFI.prototype.createMarker = function(_doc) { var element = doc.createElement('span'); element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid(); element.classList.add("EPUBJS-CFI-MARKER"); - + return element; }; @@ -3013,7 +3043,7 @@ EPUBJS.EpubCFI.prototype.findParent = function(cfi, _doc) { if(typeof cfi === 'string') { cfi = this.parse(cfi); } - + sections = cfi.steps.slice(0); // Clone steps array if(!sections.length) { return doc.getElementsByTagName('body')[0]; @@ -3058,8 +3088,8 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) { if(cfiOne.spinePos < cfiTwo.spinePos) { return -1; } - - + + // Compare Each Step in the First item for (var i = 0; i < cfiOne.steps.length; i++) { if(!cfiTwo.steps[i]) { @@ -3073,7 +3103,7 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) { } // Otherwise continue checking } - + // All steps in First present in Second if(cfiOne.steps.length < cfiTwo.steps.length) { return -1; @@ -3100,7 +3130,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) { var deferred = new RSVP.defer(); var epubcfi = new EPUBJS.EpubCFI(); var spineItem; - + if(typeof spinePos !== "undefined"){ spineItem = book.spine[spinePos]; loaded = book.loadXml(spineItem.url); @@ -3111,7 +3141,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) { deferred.resolve(cfi); }); } - + return deferred.promise; }; @@ -3134,7 +3164,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { var end, endElement, endSteps, endPath, endOffset, endIndex; start = range.startContainer; - + if(start.nodeType === 3) { // text node startElement = start.parentNode; //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); @@ -3145,18 +3175,18 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { } else { startSteps = this.pathTo(start); } - + startPath = this.generatePathComponent(startSteps); startOffset = range.startOffset; - + if(!range.collapsed) { end = range.endContainer; - + if(end.nodeType === 3) { // text node endElement = end.parentNode; - // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); + // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end)); - + endSteps = this.pathTo(endElement); } else { endSteps = this.pathTo(end); @@ -3165,8 +3195,15 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { endPath = this.generatePathComponent(endSteps); endOffset = range.endOffset; - return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + "/" + endIndex + ":" + endOffset + ")"; - + // Remove steps present in startPath + endPath = endPath.replace(startPath, ''); + + if (endPath.length) { + endPath = endPath + "/"; + } + + return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")"; + } else { return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")"; } @@ -3177,7 +3214,7 @@ EPUBJS.EpubCFI.prototype.generateXpathFromSteps = function(steps) { steps.forEach(function(step){ var position = step.index + 1; - + if(step.id){ xpath.push("*[position()=" + position + " and @id='" + step.id + "']"); } else if(step.type === "text") { @@ -3198,19 +3235,19 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) { var xpath; var startContainer; var textLength; - + if(typeof cfi === 'string') { cfi = this.parse(cfi); } - + // check spinePos if(cfi.spinePos === -1) { // Not a valid CFI return false; } - + xpath = this.generateXpathFromSteps(cfi.steps); - + // Get the terminal step lastStep = cfi.steps[cfi.steps.length-1]; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; @@ -3228,7 +3265,7 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) { } else { console.debug("offset greater than length:", cfi.characterOffset, textLength); range.setStart(startContainer, textLength - 1 ); - range.setEnd(startContainer, textLength ); + range.setEnd(startContainer, textLength ); } } else if(startContainer) { range.selectNode(startContainer); @@ -3245,6 +3282,7 @@ EPUBJS.EpubCFI.prototype.isCfiString = function(target) { return false; }; + EPUBJS.Navigation = function(_package, _request){ var navigation = this; var parse = new EPUBJS.Parser(); @@ -3349,7 +3387,7 @@ EPUBJS.Section = function(item){ this.url = item.url; this.next = item.next; this.prev = item.prev; - + this.epubcfi = new EPUBJS.EpubCFI(); this.cfiBase = item.cfiBase; @@ -3386,7 +3424,7 @@ EPUBJS.Section.prototype.load = function(_request){ loading.reject(error); }); } - + return loaded; }; @@ -3406,7 +3444,7 @@ EPUBJS.Section.prototype.replacements = function(_document){ } else { task.reject(new Error("No head to insert into")); } - + return task.promise; }; @@ -3418,7 +3456,7 @@ EPUBJS.Section.prototype.beforeSectionLoad = function(){ EPUBJS.Section.prototype.render = function(_request){ var rendering = new RSVP.defer(); var rendered = rendering.promise; - + this.load(_request).then(function(contents){ var serializer = new XMLSerializer(); var output = serializer.serializeToString(contents); @@ -3468,6 +3506,11 @@ EPUBJS.Section.prototype.reconcileLayoutSettings = function(global){ EPUBJS.Section.prototype.cfiFromRange = function(_range) { return this.epubcfi.generateCfiFromRange(_range, this.cfiBase); }; + +EPUBJS.Section.prototype.cfiFromElement = function(el) { + return this.epubcfi.generateCfiFromElement(el, this.cfiBase); +}; + EPUBJS.Spine = function(_request){ this.request = _request; this.spineItems = []; @@ -3580,6 +3623,10 @@ EPUBJS.Spine.prototype.remove = function(section) { } }; +EPUBJS.Spine.prototype.each = function() { + return this.spineItems.forEach.apply(this.spineItems, arguments); +}; + EPUBJS.replace = {}; EPUBJS.replace.links = function(view, renderer) { @@ -3623,7 +3670,7 @@ EPUBJS.replace.links = function(view, renderer) { }; -EPUBJS.Book = function(_url){ +EPUBJS.Book = function(_url, options){ // Promises this.opening = new RSVP.defer(); this.opened = this.opening.promise; @@ -3631,8 +3678,6 @@ EPUBJS.Book = function(_url){ this.url = undefined; - this.spine = new EPUBJS.Spine(this.request); - this.loading = { manifest: new RSVP.defer(), spine: new RSVP.defer(), @@ -3659,6 +3704,9 @@ EPUBJS.Book = function(_url){ this.request = this.requestMethod.bind(this); + this.spine = new EPUBJS.Spine(this.request); + this.locations = new EPUBJS.Locations(this.spine, this.request); + if(_url) { this.open(_url); } @@ -3689,7 +3737,7 @@ EPUBJS.Book.prototype.open = function(_url){ // Direct link to package, no container this.packageUrl = uri.href; this.containerUrl = ''; - + if(uri.origin) { this.url = uri.base; } else if(window){ @@ -3707,9 +3755,9 @@ EPUBJS.Book.prototype.open = function(_url){ this.url = ''; } - // Find the path to the Package from the container + // Find the path to the Package from the container else if (!uri.extension) { - + this.containerUrl = _url + containerPath; epubPackage = this.request(this.containerUrl). @@ -3720,7 +3768,7 @@ EPUBJS.Book.prototype.open = function(_url){ var packageUri = EPUBJS.core.uri(paths.packagePath); book.packageUrl = _url + paths.packagePath; book.encoding = paths.encoding; - + // Set Url relative to the content if(packageUri.origin) { book.url = packageUri.base; @@ -3731,7 +3779,7 @@ EPUBJS.Book.prototype.open = function(_url){ book.url = packageUri.directory; } - return book.request(book.packageUrl); + return book.request(book.packageUrl); }).catch(function(error) { // handle errors in either of the two requests console.error("Could not load book at: " + (this.packageUrl || this.containerPath)); @@ -3781,7 +3829,7 @@ EPUBJS.Book.prototype.unpack = function(packageXml){ book.toc = toc; book.loading.navigation.resolve(book.toc); }); - + // //-- Set Global Layout setting based on metadata // MOVE TO RENDER // book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata); @@ -3796,7 +3844,7 @@ EPUBJS.Book.prototype.section = function(target) { // Sugar to render a book EPUBJS.Book.prototype.renderTo = function(element, options) { - var renderer = (options && options.method) ? + var renderer = (options && options.method) ? options.method.charAt(0).toUpperCase() + options.method.substr(1) : "Rendition"; @@ -3808,7 +3856,7 @@ EPUBJS.Book.prototype.renderTo = function(element, options) { EPUBJS.Book.prototype.requestMethod = function(_url) { // Switch request methods if(this.archived) { - // TODO: handle archived + // TODO: handle archived } else { return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders); } @@ -3822,6 +3870,7 @@ EPUBJS.Book.prototype.setRequestCredentials = function(_credentials) { EPUBJS.Book.prototype.setRequestHeaders = function(_headers) { this.requestHeaders = _headers; }; + //-- Enable binding events to book RSVP.EventTarget.mixin(EPUBJS.Book.prototype); @@ -3837,6 +3886,7 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject RSVP.on('rejected', function(event){ console.error(event.detail.message, event.detail.stack); }); + EPUBJS.View = function(section, options) { this.settings = options || {}; @@ -6494,4 +6544,215 @@ EPUBJS.Map.prototype.rangeListToCfiList = function(view, columns){ } return map; -}; \ No newline at end of file +}; +EPUBJS.Locations = function(spine, request) { + this.spine = spine; + this.request = request; + + this.q = new EPUBJS.Queue(this); + this.epubcfi = new EPUBJS.EpubCFI(); + + this._locations = []; + this.total = 0; + + this.break = 150; + + this._current = 0; + +}; + +// Load all of sections in the book +EPUBJS.Locations.prototype.generate = function(chars) { + + if (chars) { + this.break = chars; + } + + this.q.pause(); + + this.spine.each(function(section) { + + this.q.enqueue(this.process, section); + + }.bind(this)); + + return this.q.run().then(function() { + this.total = this._locations.length-1; + + if (this._currentCfi) { + this.currentLocation = this._currentCfi; + } + + return this._locations; + // console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end)); + }.bind(this)); + +}; + +EPUBJS.Locations.prototype.process = function(section) { + + return section.load(this.request) + .then(function(contents) { + + var range; + var doc = contents.ownerDocument; + var counter = 0; + + this.sprint(contents, function(node) { + var len = node.length; + var dist; + var pos = 0; + + // Start range + if (counter == 0) { + range = doc.createRange(); + range.setStart(node, 0); + } + + dist = this.break - counter; + + // Node is smaller than a break + if(dist > len){ + counter += len; + pos = len; + } + + while (pos < len) { + counter = this.break; + pos += this.break; + + // Gone over + if(pos >= len){ + // Continue counter for next node + counter = len - (pos - this.break); + + // At End + } else { + // End the previous range + range.setEnd(node, pos); + cfi = section.cfiFromRange(range); + this._locations.push(cfi); + counter = 0; + + // Start new range + pos += 1; + range = doc.createRange(); + range.setStart(node, pos); + } + } + + + + }.bind(this)); + + // Close remaining + if (range) { + range.setEnd(prev, prev.length); + cfi = section.cfiFromRange(range); + this._locations.push(cfi) + counter = 0; + } + + }.bind(this)); + +}; + +EPUBJS.Locations.prototype.sprint = function(root, func) { + var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false); + + while ((node = treeWalker.nextNode())) { + func(node); + } + +}; + +EPUBJS.Locations.prototype.locationFromCfi = function(cfi){ + // Check if the location has not been set yet + if(this._locations.length === 0) { + return -1; + } + + return EPUBJS.core.locationOf(cfi, this._locations, this.epubcfi.compare); +}; + +EPUBJS.Locations.prototype.precentageFromCfi = function(cfi) { + // Find closest cfi + var loc = this.locationFromCfi(cfi); + // Get percentage in total + return this.precentageFromLocation(loc); +}; + +EPUBJS.Locations.prototype.precentageFromLocation = function(loc) { + return Math.ceil((loc / this.total ) * 1000) / 1000; +}; + +EPUBJS.Locations.prototype.cfiFromLocation = function(loc){ + var cfi = -1; + // check that pg is an int + if(typeof loc != "number"){ + loc = parseInt(pg); + } + + if(loc >= 0 && loc < this._locations.length) { + cfi = this._locations[loc]; + } + + return cfi; +}; + +EPUBJS.Locations.prototype.cfiFromPercentage = function(percent){ + var loc = Math.round(this.total * percent); + return this.cfiFromLocation(loc); +}; + +EPUBJS.Locations.prototype.load = function(locations){ + this._locations = JSON.parse(locations); + this.total = this._locations.length-1; + return this._locations; +}; + +EPUBJS.Locations.prototype.save = function(json){ + return JSON.stringify(this._locations); +}; + +EPUBJS.Locations.prototype.getCurrent = function(json){ + return this._current; +}; + +EPUBJS.Locations.prototype.setCurrent = function(curr){ + var loc; + + if(typeof curr == "string"){ + this._currentCfi = curr; + } else if (typeof curr == "number") { + this._current = curr; + } else { + return; + } + + if(this._locations.length === 0) { + return; + } + + if(typeof curr == "string"){ + loc = this.locationFromCfi(curr); + this._current = loc; + } else { + loc = curr; + } + console.log( this.precentageFromLocation(loc)) + this.trigger("changed", { + percentage: this.precentageFromLocation(loc) + }); +}; + +Object.defineProperty(EPUBJS.Locations.prototype, 'currentLocation', { + get: function () { + return this._current; + }, + set: function (curr) { + this.setCurrent(curr); + } +}); + +RSVP.EventTarget.mixin(EPUBJS.Locations.prototype); diff --git a/dist/epub.min.js b/dist/epub.min.js index 01434a80d..fadc87676 100644 --- a/dist/epub.min.js +++ b/dist/epub.min.js @@ -1,3 +1,3 @@ -(function(){"use strict";function t(t,e){for(var i=0,n=t.length;n>i;i++)if(t[i]===e)return i;return-1}function e(t){var e=t._promiseCallbacks;return e||(e=t._promiseCallbacks={}),e}function i(t,e){return"onerror"===t?(Y.on("error",e),void 0):2!==arguments.length?Y[t]:(Y[t]=e,void 0)}function n(t){return"function"==typeof t||"object"==typeof t&&null!==t}function o(t){return"function"==typeof t}function r(t){return"object"==typeof t&&null!==t}function s(){}function h(){}function a(t){try{return t.then}catch(e){return re.error=e,re}}function u(t,e,i,n){try{t.call(e,i,n)}catch(o){return o}}function c(t,e,i){Y.async(function(t){var n=!1,o=u(i,e,function(i){n||(n=!0,e!==i?d(t,i):g(t,i))},function(e){n||(n=!0,y(t,e))},"Settle: "+(t._label||" unknown promise"));!n&&o&&(n=!0,y(t,o))},t)}function l(t,e){e._state===ne?g(t,e._result):t._state===oe?y(t,e._result):m(e,void 0,function(i){e!==i?d(t,i):g(t,i)},function(e){y(t,e)})}function p(t,e){if(e.constructor===t.constructor)l(t,e);else{var i=a(e);i===re?y(t,re.error):void 0===i?g(t,e):o(i)?c(t,e,i):g(t,e)}}function d(t,e){t===e?g(t,e):n(e)?p(t,e):g(t,e)}function f(t){t._onerror&&t._onerror(t._result),v(t)}function g(t,e){t._state===ie&&(t._result=e,t._state=ne,0===t._subscribers.length?Y.instrument&&ee("fulfilled",t):Y.async(v,t))}function y(t,e){t._state===ie&&(t._state=oe,t._result=e,Y.async(f,t))}function m(t,e,i,n){var o=t._subscribers,r=o.length;t._onerror=null,o[r]=e,o[r+ne]=i,o[r+oe]=n,0===r&&t._state&&Y.async(v,t)}function v(t){var e=t._subscribers,i=t._state;if(Y.instrument&&ee(i===ne?"fulfilled":"rejected",t),0!==e.length){for(var n,o,r=t._result,s=0;sh;h++)s[h]=t[h];for(n=0;nn;n++)i[n-1]=t[n];return i}function N(t,e){return{then:function(i,n){return t.call(e,i,n)}}}function L(t,e,i,n){var o=R(i,n,e);return o===ge&&y(t,o.value),t}function V(t,e,i,n){return fe.all(e).then(function(e){var o=R(i,n,e);return o===ge&&y(t,o.value),t})}function q(t){return t&&"object"==typeof t?t.constructor===fe?!0:C(t):!1}function O(t,e,i){this._superConstructor(t,e,!1,i)}function F(t,e,i){this._superConstructor(t,e,!0,i)}function I(t,e,i){this._superConstructor(t,e,!1,i)}function A(){return function(){process.nextTick(z)}}function M(){var t=0,e=new Le(z),i=document.createTextNode("");return e.observe(i,{characterData:!0}),function(){i.data=t=++t%2}}function H(){var t=new MessageChannel;return t.port1.onmessage=z,function(){t.port2.postMessage(0)}}function j(){return function(){setTimeout(z,1)}}function z(){for(var t=0;Te>t;t+=2){var e=qe[t],i=qe[t+1];e(i),qe[t]=void 0,qe[t+1]=void 0}Te=0}function D(t,e){Y.async(t,e)}function W(){Y.on.apply(Y,arguments)}function X(){Y.off.apply(Y,arguments)}var Q={mixin:function(t){return t.on=this.on,t.off=this.off,t.trigger=this.trigger,t._promiseCallbacks=void 0,t},on:function(i,n){var o,r=e(this);o=r[i],o||(o=r[i]=[]),-1===t(o,n)&&o.push(n)},off:function(i,n){var o,r,s=e(this);return n?(o=s[i],r=t(o,n),-1!==r&&o.splice(r,1),void 0):(s[i]=[],void 0)},trigger:function(t,i){var n,o,r=e(this);if(n=r[t])for(var s=0;s1)throw new Error("Second argument not supported");if("object"!=typeof t)throw new TypeError("Argument must be an object");return s.prototype=t,new s},te=[],ee=function(t,e,i){1===te.push({name:t,payload:{guid:e._guidKey+e._id,eventName:t,detail:e._result,childGuid:i&&e._guidKey+i._id,label:e._label,timeStamp:Z(),stack:new Error(e._label).stack}})&&setTimeout(function(){for(var t,e=0;en;n++)this._eachEntry(i[n],n)},U.prototype._eachEntry=function(t,e){var i=this._instanceConstructor;r(t)?t.constructor===i&&t._state!==ie?(t._onerror=null,this._settledAt(t._state,e,t._result)):this._willSettleAt(i.resolve(t),e):(this._remaining--,this._result[e]=this._makeResult(ne,e,t))},U.prototype._settledAt=function(t,e,i){var n=this.promise;n._state===ie&&(this._remaining--,this._abortOnReject&&t===oe?y(n,i):this._result[e]=this._makeResult(t,e,i)),0===this._remaining&&g(n,this._result)},U.prototype._makeResult=function(t,e,i){return i},U.prototype._willSettleAt=function(t,e){var i=this;m(t,void 0,function(t){i._settledAt(ne,e,t)},function(t){i._settledAt(oe,e,t)})};var ae=function(t,e){return new he(this,t,!0,e).promise},ue=function(t,e){function i(t){d(r,t)}function n(t){y(r,t)}var o=this,r=new o(h,e);if(!G(t))return y(r,new TypeError("You must pass an array to race.")),r;for(var s=t.length,a=0;r._state===ie&&s>a;a++)m(o.resolve(t[a]),void 0,i,n);return r},ce=function(t,e){var i=this;if(t&&"object"==typeof t&&t.constructor===i)return t;var n=new i(h,e);return d(n,t),n},le=function(t,e){var i=this,n=new i(h,e);return y(n,t),n},pe="rsvp_"+Z()+"-",de=0,fe=x;x.cast=ce,x.all=ae,x.race=ue,x.resolve=ce,x.reject=le,x.prototype={constructor:x,_guidKey:pe,_onerror:function(t){Y.trigger("error",t)},then:function(t,e,i){var n=this,o=n._state;if(o===ne&&!t||o===oe&&!e)return Y.instrument&&ee("chained",this,this),this;n._onerror=null;var r=new this.constructor(h,i),s=n._result;if(Y.instrument&&ee("chained",n,r),o){var a=arguments[o-1];Y.async(function(){P(o,r,a,s)})}else m(n,r,t,e);return r},"catch":function(t,e){return this.then(null,t,e)},"finally":function(t,e){var i=this.constructor;return this.then(function(e){return i.resolve(t()).then(function(){return e})},function(e){return i.resolve(t()).then(function(){throw e})},e)}};var ge=new _,ye=new _,me=function(t,e){var i=function(){for(var i,n=this,o=arguments.length,r=new Array(o+1),s=!1,a=0;o>a;++a){if(i=arguments[a],!s){if(s=q(i),s===ye){var u=new fe(h);return y(u,ye.value),u}s&&s!==!0&&(i=N(s,i))}r[a]=i}var c=new fe(h);return r[o]=function(t,i){t?y(c,t):void 0===e?d(c,i):e===!0?d(c,k(arguments)):G(e)?d(c,T(arguments,e)):d(c,i)},s?V(c,r,t,n):L(c,r,t,n)};return i.__proto__=t,i},ve=function(t,e){return fe.all(t,e)};O.prototype=$(he.prototype),O.prototype._superConstructor=he,O.prototype._makeResult=B,O.prototype._validationError=function(){return new Error("allSettled must be called with an array")};var Se=function(t,e){return new O(fe,t,e).promise},Ee=function(t,e){return fe.race(t,e)},Pe=F;F.prototype=$(he.prototype),F.prototype._superConstructor=he,F.prototype._init=function(){this._result={}},F.prototype._validateInput=function(t){return t&&"object"==typeof t},F.prototype._validationError=function(){return new Error("Promise.hash must be called with an object")},F.prototype._enumerate=function(){var t=this.promise,e=this._input,i=[];for(var n in e)t._state===ie&&e.hasOwnProperty(n)&&i.push({position:n,entry:e[n]});var o=i.length;this._remaining=o;for(var r,s=0;t._state===ie&&o>s;s++)r=i[s],this._eachEntry(r.entry,r.position)};var we=function(t,e){return new Pe(fe,t,e).promise};I.prototype=$(Pe.prototype),I.prototype._superConstructor=he,I.prototype._makeResult=B,I.prototype._validationError=function(){return new Error("hashSettled must be called with an object")};var Be,Ue=function(t,e){return new I(fe,t,e).promise},be=function(t){throw setTimeout(function(){throw t}),t},Je=function(t){var e={};return e.promise=new fe(function(t,i){e.resolve=t,e.reject=i},t),e},xe=function(t,e,i){return fe.all(t,i).then(function(t){if(!o(e))throw new TypeError("You must pass a function as map's second argument.");for(var n=t.length,r=new Array(n),s=0;n>s;s++)r[s]=e(t[s]);return fe.all(r,i)})},_e=function(t,e){return fe.resolve(t,e)},Ce=function(t,e){return fe.reject(t,e)},Re=function(t,e,i){return fe.all(t,i).then(function(t){if(!o(e))throw new TypeError("You must pass a function as filter's second argument.");for(var n=t.length,r=new Array(n),s=0;n>s;s++)r[s]=e(t[s]);return fe.all(r,i).then(function(e){for(var i=new Array(n),o=0,r=0;n>r;r++)e[r]&&(i[o]=t[r],o++);return i.length=o,i})})},Te=0,ke=function(t,e){qe[Te]=t,qe[Te+1]=e,Te+=2,2===Te&&Be()},Ne="undefined"!=typeof window?window:{},Le=Ne.MutationObserver||Ne.WebKitMutationObserver,Ve="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,qe=new Array(1e3);Be="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?A():Le?M():Ve?H():j(),Y.async=ke;if("undefined"!=typeof window&&"object"==typeof window.__PROMISE_INSTRUMENTATION__){var Oe=window.__PROMISE_INSTRUMENTATION__;i("instrument",!0);for(var Fe in Oe)Oe.hasOwnProperty(Fe)&&W(Fe,Oe[Fe])}var Ie={race:Ee,Promise:fe,allSettled:Se,hash:we,hashSettled:Ue,denodeify:me,on:W,off:X,map:xe,filter:Re,resolve:_e,reject:Ce,all:ve,rethrow:be,defer:Je,EventTarget:Q,configure:i,async:D};"function"==typeof define&&define.amd?define(function(){return Ie}):"undefined"!=typeof module&&module.exports?module.exports=Ie:"undefined"!=typeof this&&(this.RSVP=Ie)}).call(this),"undefined"==typeof EPUBJS&&(("undefined"!=typeof window?window:this).EPUBJS={}),EPUBJS.VERSION="0.3.0",function(t){"use strict";var e=function(t){return new EPUBJS.Book(t)};"object"==typeof exports?(t.RSVP=require("rsvp"),module.exports=e):"function"==typeof define&&define.amd?define(e):t.ePub=e}(this),EPUBJS.core={},EPUBJS.core.request=function(t,e,i,n){function o(){if(this.readyState===this.DONE)if(200===this.status||this.responseXML){var t;t="xml"==e?this.responseXML?this.responseXML:(new DOMParser).parseFromString(this.response,"text/xml"):"json"==e?JSON.parse(this.response):"blob"==e?s?this.response:new Blob([this.response]):this.response,a.resolve(t)}else a.reject({status:this.status,message:this.response,stack:(new Error).stack})}var r,s=window.URL,h=s?"blob":"arraybuffer",a=new RSVP.defer,u=new XMLHttpRequest,c=XMLHttpRequest.prototype;"overrideMimeType"in c||Object.defineProperty(c,"overrideMimeType",{value:function(){}}),i&&(u.withCredentials=!0),u.open("GET",t,!0);for(r in n)u.setRequestHeader(r,n[r]);return u.onreadystatechange=o,"blob"==e&&(u.responseType=h),"json"==e&&u.setRequestHeader("Accept","application/json"),"xml"==e&&u.overrideMimeType("text/xml"),u.send(),a.promise},EPUBJS.core.uri=function(t){var e,i,n,o={protocol:"",host:"",path:"",origin:"",directory:"",base:"",filename:"",extension:"",fragment:"",href:t},r=t.indexOf("://"),s=t.indexOf("?"),h=t.indexOf("#");return-1!=h&&(o.fragment=t.slice(h+1),t=t.slice(0,h)),-1!=s&&(o.search=t.slice(s+1),t=t.slice(0,s),href=t),-1!=r?(o.protocol=t.slice(0,r),e=t.slice(r+3),n=e.indexOf("/"),-1===n?(o.host=o.path,o.path=""):(o.host=e.slice(0,n),o.path=e.slice(n)),o.origin=o.protocol+"://"+o.host,o.directory=EPUBJS.core.folder(o.path),o.base=o.origin+o.directory):(o.path=t,o.directory=EPUBJS.core.folder(t),o.base=o.directory),o.filename=t.replace(o.base,""),i=o.filename.lastIndexOf("."),-1!=i&&(o.extension=o.filename.slice(i+1)),o},EPUBJS.core.folder=function(t){var e=t.lastIndexOf("/");if(-1==e)var i="";return i=t.slice(0,e+1)},EPUBJS.core.queue=function(t){var e=[],i=t,n=function(t,i,n){return e.push({funcName:t,args:i,context:n}),e},o=function(){var t;e.length&&(t=e.shift(),i[t.funcName].apply(t.context||i,t.args))},r=function(){for(;e.length;)o()},s=function(){e=[]},h=function(){return e.length};return{enqueue:n,dequeue:o,flush:r,clear:s,length:h}},EPUBJS.core.isElement=function(t){return!(!t||1!=t.nodeType)},EPUBJS.core.uuid=function(){var t=(new Date).getTime(),e="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var i=(t+16*Math.random())%16|0;return t=Math.floor(t/16),("x"==e?i:7&i|8).toString(16)});return e},EPUBJS.core.values=function(t){for(var e=-1,i=Object.keys(t),n=i.length,o=Array(n);++eo;o++)if("undefined"!=typeof document.body.style[e[o]+i])return e[o]+i;return t},EPUBJS.core.defaults=function(t){for(var e=1,i=arguments.length;i>e;e++){var n=arguments[e];for(var o in n)void 0===t[o]&&(t[o]=n[o])}return t},EPUBJS.core.extend=function(t){var e=[].slice.call(arguments,1);return e.forEach(function(e){e&&Object.getOwnPropertyNames(e).forEach(function(i){Object.defineProperty(t,i,Object.getOwnPropertyDescriptor(e,i))})}),t},EPUBJS.core.insert=function(t,e,i){var n=EPUBJS.core.locationOf(t,e,i);return e.splice(n,0,t),n},EPUBJS.core.locationOf=function(t,e,i,n,o){var r,s=n||0,h=o||e.length,a=parseInt(s+(h-s)/2);return i||(i=function(t,e){return t>e?1:e>t?-1:(t=e)?0:void 0}),0>=h-s?a:(r=i(e[a],t),h-s===1?r>0?a:a+1:0===r?a:-1===r?EPUBJS.core.locationOf(t,e,i,a,h):EPUBJS.core.locationOf(t,e,i,s,a))},EPUBJS.core.indexOfSorted=function(t,e,i,n,o){var r,s=n||0,h=o||e.length,a=parseInt(s+(h-s)/2);return i||(i=function(t,e){return t>e?1:e>t?-1:(t=e)?0:void 0}),0>=h-s?-1:(r=i(e[a],t),h-s===1?0===r?a:-1:0===r?a:-1===r?EPUBJS.core.indexOfSorted(t,e,i,a,h):EPUBJS.core.indexOfSorted(t,e,i,s,a))},EPUBJS.core.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,EPUBJS.core.bounds=function(t){var e=window.getComputedStyle(t),i=["width","paddingRight","paddingLeft","marginRight","marginLeft","borderRightWidth","borderLeftWidth"],n=["height","paddingTop","paddingBottom","marginTop","marginBottom","borderTopWidth","borderBottomWidth"],o=0,r=0;return i.forEach(function(t){o+=parseFloat(e[t])||0}),n.forEach(function(t){r+=parseFloat(e[t])||0}),{height:r,width:o}},EPUBJS.core.borders=function(t){var e=window.getComputedStyle(t),i=["paddingRight","paddingLeft","marginRight","marginLeft","borderRightWidth","borderLeftWidth"],n=["paddingTop","paddingBottom","marginTop","marginBottom","borderTopWidth","borderBottomWidth"],o=0,r=0;return i.forEach(function(t){o+=parseFloat(e[t])||0}),n.forEach(function(t){r+=parseFloat(e[t])||0}),{height:r,width:o}},EPUBJS.core.windowBounds=function(){var t=window.innerWidth,e=window.innerHeight;return{top:0,left:0,right:t,bottom:e,width:t,height:e}},EPUBJS.core.cleanStringForXpath=function(t){var e=t.match(/[^'"]+|['"]/g);return e=e.map(function(t){return"'"===t?'"\'"':'"'===t?"'\"'":"'"+t+"'"}),"concat('',"+e.join(",")+")"},EPUBJS.core.indexOfTextNode=function(t){for(var e,i=t.parentNode,n=i.childNodes,o=-1,r=0;r=0;s--){var h=o.snapshotItem(s),a=h.getAttribute("id")||!1,u=h.querySelector("content"),c=u.getAttribute("src"),l=h.querySelector("navLabel"),p=l.textContent?l.textContent:"",d=c.split("#"),f=(d[0],e(h));n.unshift({id:a,href:c,label:p,subitems:f,parent:i?i.getAttribute("id"):null})}return n}var i=t.querySelector("navMap");return i?e(i):[]},EPUBJS.EpubCFI=function(t){return t?this.parse(t):void 0},EPUBJS.EpubCFI.prototype.generateChapterComponent=function(t,e,i){var n=parseInt(e),o=t+1,r="/"+o+"/";return r+=2*(n+1),i&&(r+="["+i+"]"),r},EPUBJS.EpubCFI.prototype.generatePathComponent=function(t){var e=[];return t.forEach(function(t){var i="";i+=2*(t.index+1),t.id&&(i+="["+t.id+"]"),e.push(i)}),e.join("/")},EPUBJS.EpubCFI.prototype.generateCfiFromElement=function(t,e){var i=this.pathTo(t),n=this.generatePathComponent(i);return n.length?"epubcfi("+e+"!"+n+"/1:0)":"epubcfi("+e+"!/4/)"},EPUBJS.EpubCFI.prototype.pathTo=function(t){for(var e,i=[];t&&null!==t.parentNode&&9!=t.parentNode.nodeType;)e=t.parentNode.children,i.unshift({id:t.id,tagName:t.tagName,index:e?Array.prototype.indexOf.call(e,t):0}),t=t.parentNode;return i},EPUBJS.EpubCFI.prototype.getChapterComponent=function(t){var e=t.split("!");return e[0]},EPUBJS.EpubCFI.prototype.getPathComponent=function(t){var e=t.split("!"),i=e[1]?e[1].split(":"):"";return i[0]},EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent=function(t){var e=t.split(":");return e[1]||""},EPUBJS.EpubCFI.prototype.parse=function(t){var e,i,n,o,r,s,h,a,u,c={},l=function(t){var e,i,n,o;return e="element",i=parseInt(t)/2-1,n=t.match(/\[(.*)\]/),n&&n[1]&&(o=n[1]),{type:e,index:i,id:o||!1}};return"string"!=typeof t?{spinePos:-1}:(c.str=t,0===t.indexOf("epubcfi(")&&")"===t[t.length-1]&&(t=t.slice(8,t.length-1)),i=this.getChapterComponent(t),n=this.getPathComponent(t)||"",o=this.getCharecterOffsetComponent(t),i?(e=i.split("/")[2]||"")?(c.spinePos=parseInt(e)/2-1||0,s=e.match(/\[(.*)\]/),c.spineId=s?s[1]:!1,-1!=n.indexOf(",")&&console.warn("CFI Ranges are not supported"),h=n.split("/"),a=h.pop(),c.steps=[],h.forEach(function(t){var e;t&&(e=l(t),c.steps.push(e))}),u=parseInt(a),isNaN(u)||(u%2===0?c.steps.push(l(a)):c.steps.push({type:"text",index:(u-1)/2})),r=o.match(/\[(.*)\]/),r&&r[1]?(c.characterOffset=parseInt(o.split("[")[0]),c.textLocationAssertion=r[1]):c.characterOffset=parseInt(o),c):{spinePos:-1}:{spinePos:-1})},EPUBJS.EpubCFI.prototype.addMarker=function(t,e,i){var n,o,r,s,h=e||document,a=i||this.createMarker(h);return"string"==typeof t&&(t=this.parse(t)),o=t.steps[t.steps.length-1],-1===t.spinePos?!1:(n=this.findParent(t,h))?(o&&"text"===o.type?(r=n.childNodes[o.index],t.characterOffset?(s=r.splitText(t.characterOffset),a.classList.add("EPUBJS-CFI-SPLIT"),n.insertBefore(a,s)):n.insertBefore(a,r)):n.insertBefore(a,n.firstChild),a):!1},EPUBJS.EpubCFI.prototype.createMarker=function(t){var e=t||document,i=e.createElement("span");return i.id="EPUBJS-CFI-MARKER:"+EPUBJS.core.uuid(),i.classList.add("EPUBJS-CFI-MARKER"),i},EPUBJS.EpubCFI.prototype.removeMarker=function(t,e){t.classList.contains("EPUBJS-CFI-SPLIT")?(nextSib=t.nextSibling,prevSib=t.previousSibling,nextSib&&prevSib&&3===nextSib.nodeType&&3===prevSib.nodeType&&(prevSib.textContent+=nextSib.textContent,t.parentNode.removeChild(nextSib)),t.parentNode.removeChild(t)):t.classList.contains("EPUBJS-CFI-MARKER")&&t.parentNode.removeChild(t)},EPUBJS.EpubCFI.prototype.findParent=function(t,e){var i,n,o,r=e||document,s=r.getElementsByTagName("html")[0],h=Array.prototype.slice.call(s.children);if("string"==typeof t&&(t=this.parse(t)),n=t.steps.slice(0),!n.length)return r.getElementsByTagName("body")[0];for(;n&&n.length>0;){if(i=n.shift(),"text"===i.type?(o=s.childNodes[i.index],s=o.parentNode||s):s=i.id?r.getElementById(i.id):h[i.index],"undefined"==typeof s)return console.error("No Element For",i,t.str),!1;h=Array.prototype.slice.call(s.children)}return s},EPUBJS.EpubCFI.prototype.compare=function(t,e){if("string"==typeof t&&(t=new EPUBJS.EpubCFI(t)),"string"==typeof e&&(e=new EPUBJS.EpubCFI(e)),t.spinePos>e.spinePos)return 1;if(t.spinePose.steps[i].index)return 1;if(t.steps[i].indexe.characterOffset?1:t.characterOffset=0?(r=o.length,t.characterOffset-1?(delete this.spineByHref[t.href],delete this.spineById[t.idref],this.spineItems.splice(e,1)):void 0},EPUBJS.replace={},EPUBJS.replace.links=function(t,e){for(var i=t.document.querySelectorAll("a[href]"),n=function(t){var i=t.getAttribute("href"),n=new EPUBJS.core.uri(i);n.protocol?t.setAttribute("target","_blank"):0===i.indexOf("#")||(t.onclick=function(){return e.display(i),!1})},o=0;o-1&&(this.observer=this.observe(this.document.body)),this.imageLoadListeners(),this.mediaQueryListeners(),this.addEventListeners(),this.addSelectionListeners()},EPUBJS.View.prototype.removeListeners=function(){this.removeEventListeners(),this.removeSelectionListeners()},EPUBJS.View.prototype.resizeListenters=function(){clearTimeout(this.expanding),this.expanding=setTimeout(this.expand.bind(this),350)},EPUBJS.View.prototype.mediaQueryListeners=function(){for(var t=this.document.styleSheets,e=function(t){t.matches&&!this._expanding&&setTimeout(this.expand.bind(this),1)}.bind(this),i=0;i-1&&(id=t.substring(t.indexOf("#")+1),el=this.document.getElementById(id),el&&(i=el.getBoundingClientRect())),{left:window.scrollX+e.left+i.left,top:window.scrollY+e.top+i.top}):void 0},EPUBJS.View.prototype.addCss=function(t){return new RSVP.Promise(function(e){var i,n=!1;return this.document?(i=this.document.createElement("link"),i.type="text/css",i.rel="stylesheet",i.href=t,i.onload=i.onreadystatechange=function(){n||this.readyState&&"complete"!=this.readyState||(n=!0,setTimeout(function(){e(!0)},1))},this.document.head.appendChild(i),void 0):(e(!1),void 0)}.bind(this))},EPUBJS.View.prototype.addStylesheetRules=function(t){var e,i;if(this.document){e=this.document.createElement("style"),this.document.head.appendChild(e),i=e.sheet;for(var n=0,o=t.length;o>n;n++){var r=1,s=t[n],h=t[n][0],a="";"[object Array]"===Object.prototype.toString.call(s[1][0])&&(s=s[1],r=0);for(var u=s.length;u>r;r++){var c=s[r];a+=c[0]+":"+c[1]+(c[2]?" !important":"")+";\n"}i.insertRule(h+"{"+a+"}",i.cssRules.length)}}},EPUBJS.View.prototype.addScript=function(t){return new RSVP.Promise(function(e){var i,n=!1;return this.document?(i=this.document.createElement("script"),i.type="text/javascript",i.async=!0,i.src=t,i.onload=i.onreadystatechange=function(){n||this.readyState&&"complete"!=this.readyState||(n=!0,setTimeout(function(){e(!0)},1))},this.document.head.appendChild(i),void 0):(e(!1),void 0)}.bind(this))},EPUBJS.View.prototype.addEventListeners=function(){this.document&&this.listenedEvents.forEach(function(t){this.document.addEventListener(t,this.triggerEvent.bind(this),!1)},this)},EPUBJS.View.prototype.removeEventListeners=function(){this.document&&this.listenedEvents.forEach(function(t){this.document.removeEventListener(t,this.triggerEvent,!1)},this)},EPUBJS.View.prototype.triggerEvent=function(t){this.trigger(t.type,t)},EPUBJS.View.prototype.addSelectionListeners=function(){this.document&&this.document.addEventListener("selectionchange",this.onSelectionChange.bind(this),!1)},EPUBJS.View.prototype.removeSelectionListeners=function(){this.document&&this.document.removeEventListener("selectionchange",this.onSelectionChange,!1)},EPUBJS.View.prototype.onSelectionChange=function(){this.selectionEndTimeout&&clearTimeout(this.selectionEndTimeout),this.selectionEndTimeout=setTimeout(function(){this.selectedRange=this.window.getSelection(),this.trigger("selected",this.selectedRange)}.bind(this),500)},RSVP.EventTarget.mixin(EPUBJS.View.prototype),EPUBJS.Views=function(t){this.container=t,this._views=[],this.length=0,this.hidden=!1},EPUBJS.Views.prototype.first=function(){return this._views[0]},EPUBJS.Views.prototype.last=function(){return this._views[this._views.length-1]},EPUBJS.Views.prototype.each=function(){return this._views.forEach.apply(this._views,arguments)},EPUBJS.Views.prototype.indexOf=function(t){return this._views.indexOf(t)},EPUBJS.Views.prototype.slice=function(){return this._views.slice.apply(this._views,arguments)},EPUBJS.Views.prototype.get=function(t){return this._views[t]},EPUBJS.Views.prototype.append=function(t){return this._views.push(t),this.container.appendChild(t.element),this.length++,t},EPUBJS.Views.prototype.prepend=function(t){return this._views.unshift(t),this.container.insertBefore(t.element,this.container.firstChild),this.length++,t},EPUBJS.Views.prototype.insert=function(t,e){return this._views.splice(e,0,t),e-1&&this._views.splice(e,1),this.destroy(t),this.length--},EPUBJS.Views.prototype.destroy=function(t){t.off("resized"),t.displayed&&t.destroy(),this.container.removeChild(t.element),t=null},EPUBJS.Views.prototype.clear=function(){var t,e=this.length;if(this.length){for(var i=0;e>i;i++)t=this._views[i],this.destroy(t);this._views=[],this.length=0}},EPUBJS.Views.prototype.find=function(t){for(var e,i=this.length,n=0;i>n;n++)if(e=this._views[n],e.displayed&&e.section.index==t.index)return e},EPUBJS.Views.prototype.displayed=function(){for(var t,e=[],i=this.length,n=0;i>n;n++)t=this._views[n],t.displayed&&e.push(t);return e},EPUBJS.Views.prototype.show=function(){for(var t,e=this.length,i=0;e>i;i++)t=this._views[i],t.displayed&&t.show();this.hidden=!1},EPUBJS.Views.prototype.hide=function(){for(var t,e=this.length,i=0;e>i;i++)t=this._views[i],t.displayed&&t.hide();this.hidden=!0},EPUBJS.Layout=EPUBJS.Layout||{},EPUBJS.Layout.Reflowable=function(){},EPUBJS.Layout.Reflowable.prototype.calculate=function(t,e,i,n){var o,r,s,h=n||1,a=Math.floor(t),u=a%2===0?a:a-1,c=Math.floor(u/8),l=i>=0?i:c%2===0?c:c-1;o=h>1?Math.floor((u-l)/h):u,r=o*h,s=(o+l)*h,this.columnAxis=EPUBJS.core.prefixed("columnAxis"),this.columnGap=EPUBJS.core.prefixed("columnGap"),this.columnWidth=EPUBJS.core.prefixed("columnWidth"),this.columnFill=EPUBJS.core.prefixed("columnFill"),this.width=u,this.height=e,this.spread=r,this.delta=s,this.column=o,this.gap=l,this.divisor=h},EPUBJS.Layout.Reflowable.prototype.format=function(t){var e=t.document.documentElement,i=t.document.body;e.style.overflow="hidden",e.style.width=this.width+"px",i.style.height=this.height+"px",i.style[this.columnAxis]="horizontal",i.style[this.columnFill]="auto",i.style[this.columnGap]=this.gap+"px",i.style[this.columnWidth]=this.column+"px",t.iframe.style.marginRight=this.gap+"px"},EPUBJS.Layout.Reflowable.prototype.count=function(t){var e=t.root().scrollWidth,i=Math.ceil(e/this.spread);return{spreads:i,pages:i*this.divisor}},EPUBJS.Layout.Fixed=function(){},EPUBJS.Layout.Fixed.prototype.calculate=function(){},EPUBJS.Layout.Fixed.prototype.format=function(t){var e,i,n=t.document.documentElement,o=documentElement.querySelector("[name=viewport");o&&o.hasAttribute("content")&&(content=o.getAttribute("content"),contents=content.split(","),contents[0]&&(e=contents[0].replace("width=","")),contents[1]&&(i=contents[1].replace("height=",""))),t.resize(e,i),n.style.overflow="auto"},EPUBJS.Layout.Fixed.prototype.count=function(){return{spreads:1,pages:1}},EPUBJS.Layout.Scroll=function(){},EPUBJS.Layout.Scroll.prototype.calculate=function(t){this.spread=t,this.column=t,this.gap=0},EPUBJS.Layout.Scroll.prototype.format=function(t){var e=t.document.documentElement;e.style.width="auto",e.style.height="auto"},EPUBJS.Layout.Scroll.prototype.count=function(){return{spreads:1,pages:1}},EPUBJS.Rendition=function(t,e){this.settings=EPUBJS.core.extend(this.settings||{},{infinite:!0,hidden:!1,width:!1,height:null,layoutOveride:null,axis:"vertical"}),EPUBJS.core.extend(this.settings,e),this.viewSettings={},this.book=t,this.views=null,this.hooks={},this.hooks.display=new EPUBJS.Hook(this),this.hooks.content=new EPUBJS.Hook(this),this.hooks.layout=new EPUBJS.Hook(this),this.hooks.render=new EPUBJS.Hook(this),this.hooks.show=new EPUBJS.Hook(this),this.hooks.content.register(EPUBJS.replace.links.bind(this)),this.hooks.content.register(this.passViewEvents.bind(this)),this.epubcfi=new EPUBJS.EpubCFI,this.q=new EPUBJS.Queue(this),this.q.enqueue(this.book.opened),this.q.enqueue(this.parseLayoutProperties)},EPUBJS.Rendition.prototype.initialize=function(t){{var e,i=t||{},n=i.height,o=i.width;i.hidden||!1}return i.height&&EPUBJS.core.isNumber(i.height)&&(n=i.height+"px"),i.width&&EPUBJS.core.isNumber(i.width)&&(o=i.width+"px"),e=document.createElement("div"),e.id="epubjs-container:"+EPUBJS.core.uuid(),e.classList.add("epub-container"),e.style.fontSize="0",e.style.wordSpacing="0",e.style.lineHeight="0",e.style.verticalAlign="top","horizontal"===this.settings.axis&&(e.style.whiteSpace="nowrap"),o&&(e.style.width=o),n&&(e.style.height=n),e.style.overflow=this.settings.overflow,e},EPUBJS.Rendition.wrap=function(t){var e=document.createElement("div");return e.style.visibility="hidden",e.style.overflow="hidden",e.style.width="0",e.style.height="0",e.appendChild(t),e},EPUBJS.Rendition.prototype.attachTo=function(t){return this.container=this.initialize({width:this.settings.width,height:this.settings.height}),EPUBJS.core.isElement(t)?this.element=t:"string"==typeof t&&(this.element=document.getElementById(t)),this.element?(this.settings.hidden?(this.wrapper=this.wrap(this.container),this.element.appendChild(this.wrapper)):this.element.appendChild(this.container),this.views=new EPUBJS.Views(this.container),this.attachListeners(),this.stageSize(),this.applyLayoutMethod(),this.trigger("attached"),void 0):(console.error("Not an Element"),void 0)},EPUBJS.Rendition.prototype.attachListeners=function(){EPUBJS.core.isNumber(this.settings.width)&&EPUBJS.core.isNumber(this.settings.height)||window.addEventListener("resize",this.onResized.bind(this),!1)},EPUBJS.Rendition.prototype.bounds=function(){return this.container.getBoundingClientRect()},EPUBJS.Rendition.prototype.display=function(t){return this.q.enqueue(this._display,t)},EPUBJS.Rendition.prototype._display=function(t){var e,i,n,o,r,s=new RSVP.defer,h=s.promise,a=this.epubcfi.isCfiString(t);return(e=this.book.spine.get(t))?(r=this.views.find(e),r?(n=i.locationOf(t),h=this.moveTo(n).then(function(){return this.check()})):(this.views.hide(),i=new EPUBJS.View(e,this.viewSettings),h=this.fill(i).then(function(){return"string"==typeof t&&t.indexOf("#")>-1&&(o=t.substring(t.indexOf("#")+1)),a||o?(n=i.locationOf(t),this.moveTo(n)):"function"==typeof this.check?this.check():void 0}.bind(this)).then(function(){return this.hooks.display.trigger(i)}.bind(this)).then(function(){this.views.show()}.bind(this))),h.then(function(){this.trigger("displayed",e)}.bind(this)),h):(s.reject(new Error("No Section Found")),h)},EPUBJS.Rendition.prototype.moveTo=function(t){this.scrollBy(t.left,t.top)},EPUBJS.Rendition.prototype.render=function(t,e){return t.create(),t.onLayout=this.layout.format.bind(this.layout),this.resizeView(t),t.render(this.book.request).then(function(){return this.hooks.content.trigger(t,this)}.bind(this)).then(function(){return this.hooks.layout.trigger(t,this)}.bind(this)).then(function(){return t.display()}.bind(this)).then(function(){return this.hooks.render.trigger(t,this)}.bind(this)).then(function(){e!==!1&&this.views.hidden===!1&&this.q.enqueue(function(t){t.show()},t),this.trigger("rendered",t.section)}.bind(this)).catch(function(t){this.trigger("loaderror",t)}.bind(this))},EPUBJS.Rendition.prototype.afterDisplayed=function(t){this.trigger("added",t.section)},EPUBJS.Rendition.prototype.fill=function(t){return this.views.clear(),this.views.append(t),t.onDisplayed=this.afterDisplayed.bind(this),this.render(t)},EPUBJS.Rendition.prototype.resizeView=function(t){"pre-paginated"===this.globalLayoutProperties.layout?t.lock("both",this.stage.width,this.stage.height):t.lock("width",this.stage.width,this.stage.height)},EPUBJS.Rendition.prototype.stageSize=function(t,e){var i,n=t||this.settings.width,o=e||this.settings.height;return n===!1&&(i=this.element.getBoundingClientRect(),i.width&&(n=i.width,this.container.style.width=i.width+"px")),o===!1&&(i=i||this.element.getBoundingClientRect(),i.height&&(o=i.height,this.container.style.height=i.height+"px")),n&&!EPUBJS.core.isNumber(n)&&(i=this.container.getBoundingClientRect(),n=i.width),o&&!EPUBJS.core.isNumber(o)&&(i=i||this.container.getBoundingClientRect(),o=i.height),this.containerStyles=window.getComputedStyle(this.container),this.containerPadding={left:parseFloat(this.containerStyles["padding-left"])||0,right:parseFloat(this.containerStyles["padding-right"])||0,top:parseFloat(this.containerStyles["padding-top"])||0,bottom:parseFloat(this.containerStyles["padding-bottom"])||0},this.stage={width:n-this.containerPadding.left-this.containerPadding.right,height:o-this.containerPadding.top-this.containerPadding.bottom},this.stage},EPUBJS.Rendition.prototype.applyLayoutMethod=function(){this.layout=new EPUBJS.Layout.Scroll,this.updateLayout(),this.map=new EPUBJS.Map(this.layout)},EPUBJS.Rendition.prototype.updateLayout=function(){this.layout.calculate(this.stage.width,this.stage.height)},EPUBJS.Rendition.prototype.resize=function(t,e){this.stageSize(t,e),this.updateLayout(),this.views.each(this.resizeView.bind(this)),this.trigger("resized",{width:this.stage.width,height:this.stage.height})},EPUBJS.Rendition.prototype.onResized=function(){this.resize()},EPUBJS.Rendition.prototype.createView=function(t){return new EPUBJS.View(t,this.viewSettings)},EPUBJS.Rendition.prototype.next=function(){return this.q.enqueue(function(){var t,e;return this.views.length?(t=this.views.last().section.next(),t?(e=this.createView(t),this.fill(e)):void 0):void 0})},EPUBJS.Rendition.prototype.prev=function(){return this.q.enqueue(function(){var t,e;return this.views.length?(t=this.views.first().section.prev(),t?(e=this.createView(t),this.fill(e)):void 0):void 0})},EPUBJS.Rendition.prototype.parseLayoutProperties=function(t){var e=t||this.book.package.metadata,i=this.layoutOveride&&this.layoutOveride.layout||e.layout||"reflowable",n=this.layoutOveride&&this.layoutOveride.spread||e.spread||"auto",o=this.layoutOveride&&this.layoutOveride.orientation||e.orientation||"auto";return this.globalLayoutProperties={layout:i,spread:n,orientation:o},this.globalLayoutProperties},EPUBJS.Rendition.prototype.current=function(){var t=this.visible();return t.length?t[t.length-1]:null},EPUBJS.Rendition.prototype.isVisible=function(t,e,i,n){var o=t.position(),r=n||this.container.getBoundingClientRect();return"horizontal"===this.settings.axis&&o.right>r.left-e&&o.leftr.top-e&&o.topthis.settings.offsetDelta||this.scrollDeltaHorz>this.settings.offsetDelta)&&(this.q.enqueue(this.check),this.scrollDeltaVert=0,this.scrollDeltaHorz=0),this.scrollDeltaVert+=Math.abs(scrollTop-this.prevScrollTop),this.scrollDeltaHorz+=Math.abs(scrollLeft-this.prevScrollLeft),this.settings.height?(this.prevScrollTop=this.container.scrollTop,this.prevScrollLeft=this.container.scrollLeft):(this.prevScrollTop=window.scrollY,this.prevScrollLeft=window.scrollX),clearTimeout(this.scrollTimeout),this.scrollTimeout=setTimeout(function(){this.scrollDeltaVert=0,this.scrollDeltaHorz=0}.bind(this),150),this.scrolled=!1),this.tick.call(window,this.onScroll.bind(this))},EPUBJS.Continuous.prototype.resizeView=function(t){"horizontal"===this.settings.axis?t.lock("height",this.stage.width,this.stage.height):t.lock("width",this.stage.width,this.stage.height)},EPUBJS.Continuous.prototype.currentLocation=function(){{var t,e,i=this.visible();this.container.getBoundingClientRect()}return 1===i.length?this.map.page(i[0]):i.length>1?(t=this.map.page(i[0]),e=this.map.page(i[i.length-1]),{start:t.start,end:e.end}):void 0},EPUBJS.Paginate=function(t,e){EPUBJS.Continuous.apply(this,arguments),this.settings=EPUBJS.core.extend(this.settings||{},{width:600,height:400,axis:"horizontal",forceSingle:!1,minSpreadWidth:800,gap:"auto",overflow:"hidden",infinite:!1}),EPUBJS.core.extend(this.settings,e),this.isForcedSingle=this.settings.forceSingle,this.viewSettings={axis:this.settings.axis},this.start()},EPUBJS.Paginate.prototype=Object.create(EPUBJS.Continuous.prototype),EPUBJS.Paginate.prototype.constructor=EPUBJS.Paginate,EPUBJS.Paginate.prototype.determineSpreads=function(t){return this.isForcedSingle||!t||this.bounds().width1?(t=h.left-s[0].position().left,i=t+this.layout.column,e=h.left+this.layout.spread-s[s.length-1].position().left,n=e+this.layout.column,o=this.map.page(s[0],t,i),r=this.map.page(s[s.length-1],e,n),{start:o.start,end:r.end}):void 0},EPUBJS.Paginate.prototype.resize=function(t,e){this.q.clear(),this.stageSize(t,e),this.updateLayout(),this.location&&this.display(this.location.start),this.trigger("resized",{width:this.stage.width,height:this.stage.height})},EPUBJS.Paginate.prototype.onResized=function(){this.views.clear(),clearTimeout(this.resizeTimeout),this.resizeTimeout=setTimeout(function(){this.resize()}.bind(this),150)},EPUBJS.Paginate.prototype.adjustImages=function(t){return t.addStylesheetRules([["img",["max-width",this.layout.spread+"px"],["max-height",this.layout.height+"px"]]]),new RSVP.Promise(function(t){setTimeout(function(){t()},1)})},EPUBJS.Map=function(t){this.layout=t},EPUBJS.Map.prototype.section=function(t){var e=this.findRanges(t),i=this.rangeListToCfiList(t,e);return i},EPUBJS.Map.prototype.page=function(t,e,i){var n=t.document.body;return this.rangePairToCfiPair(t.section,{start:this.findStart(n,e,i),end:this.findEnd(n,e,i)})},EPUBJS.Map.prototype.walk=function(t,e){for(var i,n,o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode:function(t){return t.data.trim().length>0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}},!1);(i=o.nextNode())&&!(n=e(i)););return n},EPUBJS.Map.prototype.findRanges=function(t){for(var e,i,n=[],o=this.layout.count(t),r=this.layout.column,s=this.layout.gap,h=0;h=e&&i>=n?t:o>e?t:(s=t,r.push(t),void 0)}))return this.findTextStartRange(o,e,i);return this.findTextStartRange(s,e,i)},EPUBJS.Map.prototype.findEnd=function(t,e,i){for(var n,o,r=[t],s=t;r.length;)if(n=r.shift(),o=this.walk(n,function(t){var e,n,o,h;return t.nodeType==Node.TEXT_NODE?(h=document.createRange(),h.selectNodeContents(t),o=h.getBoundingClientRect()):o=t.getBoundingClientRect(),e=o.left,n=o.right,e>i&&s?s:n>i?t:(s=t,r.push(t),void 0)}))return this.findTextEndRange(o,e,i);return this.findTextEndRange(s,e,i)},EPUBJS.Map.prototype.findTextStartRange=function(t,e){for(var i,n,o,r=this.splitTextNodeIntoRanges(t),s=0;s=e)return n;i=n}return r[0]},EPUBJS.Map.prototype.findTextEndRange=function(t,e,i){for(var n,o,r,s=this.splitTextNodeIntoRanges(t),h=0;hi&&n)return n;if(r.right>i)return o;n=o}return s[s.length-1]},EPUBJS.Map.prototype.splitTextNodeIntoRanges=function(t,e){var i,n=[],o=t.textContent||"",r=o.trim(),s=t.ownerDocument,h=e||" ";if(pos=r.indexOf(h),-1===pos||t.nodeType!=Node.TEXT_NODE)return i=s.createRange(),i.selectNodeContents(t),[i];for(i=s.createRange(),i.setStart(t,0),i.setEnd(t,pos),n.push(i),i=!1;-1!=pos;)pos=r.indexOf(h,pos+1),pos>0&&(i&&(i.setEnd(t,pos),n.push(i)),i=s.createRange(),i.setStart(t,pos+1));return i&&(i.setEnd(t,r.length),n.push(i)),n},EPUBJS.Map.prototype.rangePairToCfiPair=function(t,e){var i=e.start,n=e.end;return i.collapse(!0),n.collapse(!0),startCfi=t.cfiFromRange(i),endCfi=t.cfiFromRange(n),{start:startCfi,end:endCfi}},EPUBJS.Map.prototype.rangeListToCfiList=function(t,e){for(var i,n=[],o=0;oi;i++)if(t[i]===e)return i;return-1}function e(t){var e=t._promiseCallbacks;return e||(e=t._promiseCallbacks={}),e}function i(t,e){return"onerror"===t?(Y.on("error",e),void 0):2!==arguments.length?Y[t]:(Y[t]=e,void 0)}function n(t){return"function"==typeof t||"object"==typeof t&&null!==t}function o(t){return"function"==typeof t}function r(t){return"object"==typeof t&&null!==t}function s(){}function h(){}function a(t){try{return t.then}catch(e){return re.error=e,re}}function c(t,e,i,n){try{t.call(e,i,n)}catch(o){return o}}function u(t,e,i){Y.async(function(t){var n=!1,o=c(i,e,function(i){n||(n=!0,e!==i?d(t,i):g(t,i))},function(e){n||(n=!0,y(t,e))},"Settle: "+(t._label||" unknown promise"));!n&&o&&(n=!0,y(t,o))},t)}function p(t,e){e._state===ne?g(t,e._result):t._state===oe?y(t,e._result):m(e,void 0,function(i){e!==i?d(t,i):g(t,i)},function(e){y(t,e)})}function l(t,e){if(e.constructor===t.constructor)p(t,e);else{var i=a(e);i===re?y(t,re.error):void 0===i?g(t,e):o(i)?u(t,e,i):g(t,e)}}function d(t,e){t===e?g(t,e):n(e)?l(t,e):g(t,e)}function f(t){t._onerror&&t._onerror(t._result),S(t)}function g(t,e){t._state===ie&&(t._result=e,t._state=ne,0===t._subscribers.length?Y.instrument&&ee("fulfilled",t):Y.async(S,t))}function y(t,e){t._state===ie&&(t._state=oe,t._result=e,Y.async(f,t))}function m(t,e,i,n){var o=t._subscribers,r=o.length;t._onerror=null,o[r]=e,o[r+ne]=i,o[r+oe]=n,0===r&&t._state&&Y.async(S,t)}function S(t){var e=t._subscribers,i=t._state;if(Y.instrument&&ee(i===ne?"fulfilled":"rejected",t),0!==e.length){for(var n,o,r=t._result,s=0;sh;h++)s[h]=t[h];for(n=0;nn;n++)i[n-1]=t[n];return i}function L(t,e){return{then:function(i,n){return t.call(e,i,n)}}}function N(t,e,i,n){var o=R(i,n,e);return o===ge&&y(t,o.value),t}function V(t,e,i,n){return fe.all(e).then(function(e){var o=R(i,n,e);return o===ge&&y(t,o.value),t})}function F(t){return t&&"object"==typeof t?t.constructor===fe?!0:C(t):!1}function q(t,e,i){this._superConstructor(t,e,!1,i)}function O(t,e,i){this._superConstructor(t,e,!0,i)}function I(t,e,i){this._superConstructor(t,e,!1,i)}function A(){return function(){process.nextTick(z)}}function M(){var t=0,e=new Ne(z),i=document.createTextNode("");return e.observe(i,{characterData:!0}),function(){i.data=t=++t%2}}function H(){var t=new MessageChannel;return t.port1.onmessage=z,function(){t.port2.postMessage(0)}}function j(){return function(){setTimeout(z,1)}}function z(){for(var t=0;Te>t;t+=2){var e=Fe[t],i=Fe[t+1];e(i),Fe[t]=void 0,Fe[t+1]=void 0}Te=0}function D(t,e){Y.async(t,e)}function W(){Y.on.apply(Y,arguments)}function X(){Y.off.apply(Y,arguments)}var Q={mixin:function(t){return t.on=this.on,t.off=this.off,t.trigger=this.trigger,t._promiseCallbacks=void 0,t},on:function(i,n){var o,r=e(this);o=r[i],o||(o=r[i]=[]),-1===t(o,n)&&o.push(n)},off:function(i,n){var o,r,s=e(this);return n?(o=s[i],r=t(o,n),-1!==r&&o.splice(r,1),void 0):(s[i]=[],void 0)},trigger:function(t,i){var n,o,r=e(this);if(n=r[t])for(var s=0;s1)throw new Error("Second argument not supported");if("object"!=typeof t)throw new TypeError("Argument must be an object");return s.prototype=t,new s},te=[],ee=function(t,e,i){1===te.push({name:t,payload:{guid:e._guidKey+e._id,eventName:t,detail:e._result,childGuid:i&&e._guidKey+i._id,label:e._label,timeStamp:Z(),stack:new Error(e._label).stack}})&&setTimeout(function(){for(var t,e=0;en;n++)this._eachEntry(i[n],n)},U.prototype._eachEntry=function(t,e){var i=this._instanceConstructor;r(t)?t.constructor===i&&t._state!==ie?(t._onerror=null,this._settledAt(t._state,e,t._result)):this._willSettleAt(i.resolve(t),e):(this._remaining--,this._result[e]=this._makeResult(ne,e,t))},U.prototype._settledAt=function(t,e,i){var n=this.promise;n._state===ie&&(this._remaining--,this._abortOnReject&&t===oe?y(n,i):this._result[e]=this._makeResult(t,e,i)),0===this._remaining&&g(n,this._result)},U.prototype._makeResult=function(t,e,i){return i},U.prototype._willSettleAt=function(t,e){var i=this;m(t,void 0,function(t){i._settledAt(ne,e,t)},function(t){i._settledAt(oe,e,t)})};var ae=function(t,e){return new he(this,t,!0,e).promise},ce=function(t,e){function i(t){d(r,t)}function n(t){y(r,t)}var o=this,r=new o(h,e);if(!G(t))return y(r,new TypeError("You must pass an array to race.")),r;for(var s=t.length,a=0;r._state===ie&&s>a;a++)m(o.resolve(t[a]),void 0,i,n);return r},ue=function(t,e){var i=this;if(t&&"object"==typeof t&&t.constructor===i)return t;var n=new i(h,e);return d(n,t),n},pe=function(t,e){var i=this,n=new i(h,e);return y(n,t),n},le="rsvp_"+Z()+"-",de=0,fe=x;x.cast=ue,x.all=ae,x.race=ce,x.resolve=ue,x.reject=pe,x.prototype={constructor:x,_guidKey:le,_onerror:function(t){Y.trigger("error",t)},then:function(t,e,i){var n=this,o=n._state;if(o===ne&&!t||o===oe&&!e)return Y.instrument&&ee("chained",this,this),this;n._onerror=null;var r=new this.constructor(h,i),s=n._result;if(Y.instrument&&ee("chained",n,r),o){var a=arguments[o-1];Y.async(function(){P(o,r,a,s)})}else m(n,r,t,e);return r},"catch":function(t,e){return this.then(null,t,e)},"finally":function(t,e){var i=this.constructor;return this.then(function(e){return i.resolve(t()).then(function(){return e})},function(e){return i.resolve(t()).then(function(){throw e})},e)}};var ge=new _,ye=new _,me=function(t,e){var i=function(){for(var i,n=this,o=arguments.length,r=new Array(o+1),s=!1,a=0;o>a;++a){if(i=arguments[a],!s){if(s=F(i),s===ye){var c=new fe(h);return y(c,ye.value),c}s&&s!==!0&&(i=L(s,i))}r[a]=i}var u=new fe(h);return r[o]=function(t,i){t?y(u,t):void 0===e?d(u,i):e===!0?d(u,k(arguments)):G(e)?d(u,T(arguments,e)):d(u,i)},s?V(u,r,t,n):N(u,r,t,n)};return i.__proto__=t,i},Se=function(t,e){return fe.all(t,e)};q.prototype=$(he.prototype),q.prototype._superConstructor=he,q.prototype._makeResult=w,q.prototype._validationError=function(){return new Error("allSettled must be called with an array")};var Ee=function(t,e){return new q(fe,t,e).promise},ve=function(t,e){return fe.race(t,e)},Pe=O;O.prototype=$(he.prototype),O.prototype._superConstructor=he,O.prototype._init=function(){this._result={}},O.prototype._validateInput=function(t){return t&&"object"==typeof t},O.prototype._validationError=function(){return new Error("Promise.hash must be called with an object")},O.prototype._enumerate=function(){var t=this.promise,e=this._input,i=[];for(var n in e)t._state===ie&&e.hasOwnProperty(n)&&i.push({position:n,entry:e[n]});var o=i.length;this._remaining=o;for(var r,s=0;t._state===ie&&o>s;s++)r=i[s],this._eachEntry(r.entry,r.position)};var Be=function(t,e){return new Pe(fe,t,e).promise};I.prototype=$(Pe.prototype),I.prototype._superConstructor=he,I.prototype._makeResult=w,I.prototype._validationError=function(){return new Error("hashSettled must be called with an object")};var we,Ue=function(t,e){return new I(fe,t,e).promise},Je=function(t){throw setTimeout(function(){throw t}),t},be=function(t){var e={};return e.promise=new fe(function(t,i){e.resolve=t,e.reject=i},t),e},xe=function(t,e,i){return fe.all(t,i).then(function(t){if(!o(e))throw new TypeError("You must pass a function as map's second argument.");for(var n=t.length,r=new Array(n),s=0;n>s;s++)r[s]=e(t[s]);return fe.all(r,i)})},_e=function(t,e){return fe.resolve(t,e)},Ce=function(t,e){return fe.reject(t,e)},Re=function(t,e,i){return fe.all(t,i).then(function(t){if(!o(e))throw new TypeError("You must pass a function as filter's second argument.");for(var n=t.length,r=new Array(n),s=0;n>s;s++)r[s]=e(t[s]);return fe.all(r,i).then(function(e){for(var i=new Array(n),o=0,r=0;n>r;r++)e[r]&&(i[o]=t[r],o++);return i.length=o,i})})},Te=0,ke=function(t,e){Fe[Te]=t,Fe[Te+1]=e,Te+=2,2===Te&&we()},Le="undefined"!=typeof window?window:{},Ne=Le.MutationObserver||Le.WebKitMutationObserver,Ve="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,Fe=new Array(1e3);we="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?A():Ne?M():Ve?H():j(),Y.async=ke;if("undefined"!=typeof window&&"object"==typeof window.__PROMISE_INSTRUMENTATION__){var qe=window.__PROMISE_INSTRUMENTATION__;i("instrument",!0);for(var Oe in qe)qe.hasOwnProperty(Oe)&&W(Oe,qe[Oe])}var Ie={race:ve,Promise:fe,allSettled:Ee,hash:Be,hashSettled:Ue,denodeify:me,on:W,off:X,map:xe,filter:Re,resolve:_e,reject:Ce,all:Se,rethrow:Je,defer:be,EventTarget:Q,configure:i,async:D};"function"==typeof define&&define.amd?define(function(){return Ie}):"undefined"!=typeof module&&module.exports?module.exports=Ie:"undefined"!=typeof this&&(this.RSVP=Ie)}).call(this),"undefined"==typeof EPUBJS&&(("undefined"!=typeof window?window:this).EPUBJS={}),EPUBJS.VERSION="0.3.0",function(t){"use strict";var e=function(t){return new EPUBJS.Book(t)};"object"==typeof exports?(t.RSVP=require("rsvp"),module.exports=e):"function"==typeof define&&define.amd?define(e):t.ePub=e}(this),EPUBJS.core={},EPUBJS.core.request=function(t,e,i,n){function o(){if(this.readyState===this.DONE)if(200===this.status||this.responseXML){var t;t="xml"==e?this.responseXML?this.responseXML:(new DOMParser).parseFromString(this.response,"text/xml"):"json"==e?JSON.parse(this.response):"blob"==e?s?this.response:new Blob([this.response]):this.response,a.resolve(t)}else a.reject({status:this.status,message:this.response,stack:(new Error).stack})}var r,s=window.URL,h=s?"blob":"arraybuffer",a=new RSVP.defer,c=new XMLHttpRequest,u=XMLHttpRequest.prototype;"overrideMimeType"in u||Object.defineProperty(u,"overrideMimeType",{value:function(){}}),i&&(c.withCredentials=!0),c.open("GET",t,!0);for(r in n)c.setRequestHeader(r,n[r]);return c.onreadystatechange=o,"blob"==e&&(c.responseType=h),"json"==e&&c.setRequestHeader("Accept","application/json"),"xml"==e&&c.overrideMimeType("text/xml"),c.send(),a.promise},EPUBJS.core.uri=function(t){var e,i,n,o={protocol:"",host:"",path:"",origin:"",directory:"",base:"",filename:"",extension:"",fragment:"",href:t},r=t.indexOf("://"),s=t.indexOf("?"),h=t.indexOf("#");return-1!=h&&(o.fragment=t.slice(h+1),t=t.slice(0,h)),-1!=s&&(o.search=t.slice(s+1),t=t.slice(0,s),href=t),-1!=r?(o.protocol=t.slice(0,r),e=t.slice(r+3),n=e.indexOf("/"),-1===n?(o.host=o.path,o.path=""):(o.host=e.slice(0,n),o.path=e.slice(n)),o.origin=o.protocol+"://"+o.host,o.directory=EPUBJS.core.folder(o.path),o.base=o.origin+o.directory):(o.path=t,o.directory=EPUBJS.core.folder(t),o.base=o.directory),o.filename=t.replace(o.base,""),i=o.filename.lastIndexOf("."),-1!=i&&(o.extension=o.filename.slice(i+1)),o},EPUBJS.core.folder=function(t){var e=t.lastIndexOf("/");if(-1==e)var i="";return i=t.slice(0,e+1)},EPUBJS.core.queue=function(t){var e=[],i=t,n=function(t,i,n){return e.push({funcName:t,args:i,context:n}),e},o=function(){var t;e.length&&(t=e.shift(),i[t.funcName].apply(t.context||i,t.args))},r=function(){for(;e.length;)o()},s=function(){e=[]},h=function(){return e.length};return{enqueue:n,dequeue:o,flush:r,clear:s,length:h}},EPUBJS.core.isElement=function(t){return!(!t||1!=t.nodeType)},EPUBJS.core.uuid=function(){var t=(new Date).getTime(),e="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var i=(t+16*Math.random())%16|0;return t=Math.floor(t/16),("x"==e?i:7&i|8).toString(16)});return e},EPUBJS.core.values=function(t){for(var e=-1,i=Object.keys(t),n=i.length,o=Array(n);++eo;o++)if("undefined"!=typeof document.body.style[e[o]+i])return e[o]+i;return t},EPUBJS.core.defaults=function(t){for(var e=1,i=arguments.length;i>e;e++){var n=arguments[e];for(var o in n)void 0===t[o]&&(t[o]=n[o])}return t},EPUBJS.core.extend=function(t){var e=[].slice.call(arguments,1);return e.forEach(function(e){e&&Object.getOwnPropertyNames(e).forEach(function(i){Object.defineProperty(t,i,Object.getOwnPropertyDescriptor(e,i))})}),t},EPUBJS.core.insert=function(t,e,i){var n=EPUBJS.core.locationOf(t,e,i);return e.splice(n,0,t),n},EPUBJS.core.locationOf=function(t,e,i,n,o){var r,s=n||0,h=o||e.length,a=parseInt(s+(h-s)/2);return i||(i=function(t,e){return t>e?1:e>t?-1:(t=e)?0:void 0}),0>=h-s?a:(r=i(e[a],t),h-s===1?r>0?a:a+1:0===r?a:-1===r?EPUBJS.core.locationOf(t,e,i,a,h):EPUBJS.core.locationOf(t,e,i,s,a))},EPUBJS.core.indexOfSorted=function(t,e,i,n,o){var r,s=n||0,h=o||e.length,a=parseInt(s+(h-s)/2);return i||(i=function(t,e){return t>e?1:e>t?-1:(t=e)?0:void 0}),0>=h-s?-1:(r=i(e[a],t),h-s===1?0===r?a:-1:0===r?a:-1===r?EPUBJS.core.indexOfSorted(t,e,i,a,h):EPUBJS.core.indexOfSorted(t,e,i,s,a))},EPUBJS.core.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,EPUBJS.core.bounds=function(t){var e=window.getComputedStyle(t),i=["width","paddingRight","paddingLeft","marginRight","marginLeft","borderRightWidth","borderLeftWidth"],n=["height","paddingTop","paddingBottom","marginTop","marginBottom","borderTopWidth","borderBottomWidth"],o=0,r=0;return i.forEach(function(t){o+=parseFloat(e[t])||0}),n.forEach(function(t){r+=parseFloat(e[t])||0}),{height:r,width:o}},EPUBJS.core.borders=function(t){var e=window.getComputedStyle(t),i=["paddingRight","paddingLeft","marginRight","marginLeft","borderRightWidth","borderLeftWidth"],n=["paddingTop","paddingBottom","marginTop","marginBottom","borderTopWidth","borderBottomWidth"],o=0,r=0;return i.forEach(function(t){o+=parseFloat(e[t])||0}),n.forEach(function(t){r+=parseFloat(e[t])||0}),{height:r,width:o}},EPUBJS.core.windowBounds=function(){var t=window.innerWidth,e=window.innerHeight;return{top:0,left:0,right:t,bottom:e,width:t,height:e}},EPUBJS.core.cleanStringForXpath=function(t){var e=t.match(/[^'"]+|['"]/g);return e=e.map(function(t){return"'"===t?'"\'"':'"'===t?"'\"'":"'"+t+"'"}),"concat('',"+e.join(",")+")"},EPUBJS.core.indexOfTextNode=function(t){for(var e,i=t.parentNode,n=i.childNodes,o=-1,r=0;r=0;s--){var h=o.snapshotItem(s),a=h.getAttribute("id")||!1,c=h.querySelector("content"),u=c.getAttribute("src"),p=h.querySelector("navLabel"),l=p.textContent?p.textContent:"",d=u.split("#"),f=(d[0],e(h));n.unshift({id:a,href:u,label:l,subitems:f,parent:i?i.getAttribute("id"):null})}return n}var i=t.querySelector("navMap");return i?e(i):[]},EPUBJS.EpubCFI=function(t){return t?this.parse(t):void 0},EPUBJS.EpubCFI.prototype.generateChapterComponent=function(t,e,i){var n=parseInt(e),o=t+1,r="/"+o+"/";return r+=2*(n+1),i&&(r+="["+i+"]"),r},EPUBJS.EpubCFI.prototype.generatePathComponent=function(t){var e=[];return t.forEach(function(t){var i="";i+=2*(t.index+1),t.id&&(i+="["+t.id+"]"),e.push(i)}),e.join("/")},EPUBJS.EpubCFI.prototype.generateCfiFromElement=function(t,e){var i=this.pathTo(t),n=this.generatePathComponent(i);return n.length?"epubcfi("+e+"!"+n+"/1:0)":"epubcfi("+e+"!/4/)"},EPUBJS.EpubCFI.prototype.pathTo=function(t){for(var e,i=[];t&&null!==t.parentNode&&9!=t.parentNode.nodeType;)e=t.parentNode.children,i.unshift({id:t.id,tagName:t.tagName,index:e?Array.prototype.indexOf.call(e,t):0}),t=t.parentNode;return i},EPUBJS.EpubCFI.prototype.getChapterComponent=function(t){var e=t.split("!");return e[0]},EPUBJS.EpubCFI.prototype.getPathComponent=function(t){var e=t.split("!"),i=e[1]?e[1].split(":"):"";return i[0]},EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent=function(t){var e=t.split(":");return e[1]||""},EPUBJS.EpubCFI.prototype.parse=function(t){var e,i,n,o,r,s,h,a,c,u={},p=function(t){var e,i,n,o;return e="element",i=parseInt(t)/2-1,n=t.match(/\[(.*)\]/),n&&n[1]&&(o=n[1]),{type:e,index:i,id:o||!1}};return"string"!=typeof t?{spinePos:-1}:(u.str=t,0===t.indexOf("epubcfi(")&&")"===t[t.length-1]&&(t=t.slice(8,t.length-1)),i=this.getChapterComponent(t),n=this.getPathComponent(t)||"",o=this.getCharecterOffsetComponent(t),i?(e=i.split("/")[2]||"")?(u.spinePos=parseInt(e)/2-1||0,s=e.match(/\[(.*)\]/),u.spineId=s?s[1]:!1,-1!=n.indexOf(",")&&console.warn("CFI Ranges are not supported"),h=n.split("/"),a=h.pop(),u.steps=[],h.forEach(function(t){var e;t&&(e=p(t),u.steps.push(e))}),c=parseInt(a),isNaN(c)||(c%2===0?u.steps.push(p(a)):u.steps.push({type:"text",index:(c-1)/2})),r=o.match(/\[(.*)\]/),r&&r[1]?(u.characterOffset=parseInt(o.split("[")[0]),u.textLocationAssertion=r[1]):u.characterOffset=parseInt(o),u):{spinePos:-1}:{spinePos:-1})},EPUBJS.EpubCFI.prototype.addMarker=function(t,e,i){var n,o,r,s,h=e||document,a=i||this.createMarker(h);return"string"==typeof t&&(t=this.parse(t)),o=t.steps[t.steps.length-1],-1===t.spinePos?!1:(n=this.findParent(t,h))?(o&&"text"===o.type?(r=n.childNodes[o.index],t.characterOffset?(s=r.splitText(t.characterOffset),a.classList.add("EPUBJS-CFI-SPLIT"),n.insertBefore(a,s)):n.insertBefore(a,r)):n.insertBefore(a,n.firstChild),a):!1},EPUBJS.EpubCFI.prototype.createMarker=function(t){var e=t||document,i=e.createElement("span");return i.id="EPUBJS-CFI-MARKER:"+EPUBJS.core.uuid(),i.classList.add("EPUBJS-CFI-MARKER"),i},EPUBJS.EpubCFI.prototype.removeMarker=function(t,e){t.classList.contains("EPUBJS-CFI-SPLIT")?(nextSib=t.nextSibling,prevSib=t.previousSibling,nextSib&&prevSib&&3===nextSib.nodeType&&3===prevSib.nodeType&&(prevSib.textContent+=nextSib.textContent,t.parentNode.removeChild(nextSib)),t.parentNode.removeChild(t)):t.classList.contains("EPUBJS-CFI-MARKER")&&t.parentNode.removeChild(t)},EPUBJS.EpubCFI.prototype.findParent=function(t,e){var i,n,o,r=e||document,s=r.getElementsByTagName("html")[0],h=Array.prototype.slice.call(s.children);if("string"==typeof t&&(t=this.parse(t)),n=t.steps.slice(0),!n.length)return r.getElementsByTagName("body")[0];for(;n&&n.length>0;){if(i=n.shift(),"text"===i.type?(o=s.childNodes[i.index],s=o.parentNode||s):s=i.id?r.getElementById(i.id):h[i.index],"undefined"==typeof s)return console.error("No Element For",i,t.str),!1;h=Array.prototype.slice.call(s.children)}return s},EPUBJS.EpubCFI.prototype.compare=function(t,e){if("string"==typeof t&&(t=new EPUBJS.EpubCFI(t)),"string"==typeof e&&(e=new EPUBJS.EpubCFI(e)),t.spinePos>e.spinePos)return 1;if(t.spinePose.steps[i].index)return 1;if(t.steps[i].indexe.characterOffset?1:t.characterOffset=0?(r=o.length,t.characterOffset-1?(delete this.spineByHref[t.href],delete this.spineById[t.idref],this.spineItems.splice(e,1)):void 0},EPUBJS.Spine.prototype.each=function(){return this.spineItems.forEach.apply(this.spineItems,arguments)},EPUBJS.replace={},EPUBJS.replace.links=function(t,e){for(var i=t.document.querySelectorAll("a[href]"),n=function(t){var i=t.getAttribute("href"),n=new EPUBJS.core.uri(i);n.protocol?t.setAttribute("target","_blank"):0===i.indexOf("#")||(t.onclick=function(){return e.display(i),!1})},o=0;o-1&&(this.observer=this.observe(this.document.body)),this.imageLoadListeners(),this.mediaQueryListeners(),this.addEventListeners(),this.addSelectionListeners()},EPUBJS.View.prototype.removeListeners=function(){this.removeEventListeners(),this.removeSelectionListeners()},EPUBJS.View.prototype.resizeListenters=function(){clearTimeout(this.expanding),this.expanding=setTimeout(this.expand.bind(this),350)},EPUBJS.View.prototype.mediaQueryListeners=function(){for(var t=this.document.styleSheets,e=function(t){t.matches&&!this._expanding&&setTimeout(this.expand.bind(this),1)}.bind(this),i=0;i-1&&(id=t.substring(t.indexOf("#")+1),el=this.document.getElementById(id),el&&(i=el.getBoundingClientRect())),{left:window.scrollX+e.left+i.left,top:window.scrollY+e.top+i.top}):void 0},EPUBJS.View.prototype.addCss=function(t){return new RSVP.Promise(function(e){var i,n=!1;return this.document?(i=this.document.createElement("link"),i.type="text/css",i.rel="stylesheet",i.href=t,i.onload=i.onreadystatechange=function(){n||this.readyState&&"complete"!=this.readyState||(n=!0,setTimeout(function(){e(!0)},1))},this.document.head.appendChild(i),void 0):(e(!1),void 0)}.bind(this))},EPUBJS.View.prototype.addStylesheetRules=function(t){var e,i;if(this.document){e=this.document.createElement("style"),this.document.head.appendChild(e),i=e.sheet;for(var n=0,o=t.length;o>n;n++){var r=1,s=t[n],h=t[n][0],a="";"[object Array]"===Object.prototype.toString.call(s[1][0])&&(s=s[1],r=0);for(var c=s.length;c>r;r++){var u=s[r];a+=u[0]+":"+u[1]+(u[2]?" !important":"")+";\n"}i.insertRule(h+"{"+a+"}",i.cssRules.length)}}},EPUBJS.View.prototype.addScript=function(t){return new RSVP.Promise(function(e){var i,n=!1;return this.document?(i=this.document.createElement("script"),i.type="text/javascript",i.async=!0,i.src=t,i.onload=i.onreadystatechange=function(){n||this.readyState&&"complete"!=this.readyState||(n=!0,setTimeout(function(){e(!0)},1))},this.document.head.appendChild(i),void 0):(e(!1),void 0)}.bind(this))},EPUBJS.View.prototype.addEventListeners=function(){this.document&&this.listenedEvents.forEach(function(t){this.document.addEventListener(t,this.triggerEvent.bind(this),!1)},this)},EPUBJS.View.prototype.removeEventListeners=function(){this.document&&this.listenedEvents.forEach(function(t){this.document.removeEventListener(t,this.triggerEvent,!1)},this)},EPUBJS.View.prototype.triggerEvent=function(t){this.trigger(t.type,t)},EPUBJS.View.prototype.addSelectionListeners=function(){this.document&&this.document.addEventListener("selectionchange",this.onSelectionChange.bind(this),!1)},EPUBJS.View.prototype.removeSelectionListeners=function(){this.document&&this.document.removeEventListener("selectionchange",this.onSelectionChange,!1)},EPUBJS.View.prototype.onSelectionChange=function(){this.selectionEndTimeout&&clearTimeout(this.selectionEndTimeout),this.selectionEndTimeout=setTimeout(function(){this.selectedRange=this.window.getSelection(),this.trigger("selected",this.selectedRange)}.bind(this),500)},RSVP.EventTarget.mixin(EPUBJS.View.prototype),EPUBJS.Views=function(t){this.container=t,this._views=[],this.length=0,this.hidden=!1},EPUBJS.Views.prototype.first=function(){return this._views[0]},EPUBJS.Views.prototype.last=function(){return this._views[this._views.length-1]},EPUBJS.Views.prototype.each=function(){return this._views.forEach.apply(this._views,arguments)},EPUBJS.Views.prototype.indexOf=function(t){return this._views.indexOf(t)},EPUBJS.Views.prototype.slice=function(){return this._views.slice.apply(this._views,arguments)},EPUBJS.Views.prototype.get=function(t){return this._views[t]},EPUBJS.Views.prototype.append=function(t){return this._views.push(t),this.container.appendChild(t.element),this.length++,t},EPUBJS.Views.prototype.prepend=function(t){return this._views.unshift(t),this.container.insertBefore(t.element,this.container.firstChild),this.length++,t},EPUBJS.Views.prototype.insert=function(t,e){return this._views.splice(e,0,t),e-1&&this._views.splice(e,1),this.destroy(t),this.length--},EPUBJS.Views.prototype.destroy=function(t){t.off("resized"),t.displayed&&t.destroy(),this.container.removeChild(t.element),t=null},EPUBJS.Views.prototype.clear=function(){var t,e=this.length;if(this.length){for(var i=0;e>i;i++)t=this._views[i],this.destroy(t);this._views=[],this.length=0}},EPUBJS.Views.prototype.find=function(t){for(var e,i=this.length,n=0;i>n;n++)if(e=this._views[n],e.displayed&&e.section.index==t.index)return e},EPUBJS.Views.prototype.displayed=function(){for(var t,e=[],i=this.length,n=0;i>n;n++)t=this._views[n],t.displayed&&e.push(t);return e},EPUBJS.Views.prototype.show=function(){for(var t,e=this.length,i=0;e>i;i++)t=this._views[i],t.displayed&&t.show();this.hidden=!1},EPUBJS.Views.prototype.hide=function(){for(var t,e=this.length,i=0;e>i;i++)t=this._views[i],t.displayed&&t.hide();this.hidden=!0},EPUBJS.Layout=EPUBJS.Layout||{},EPUBJS.Layout.Reflowable=function(){},EPUBJS.Layout.Reflowable.prototype.calculate=function(t,e,i,n){var o,r,s,h=n||1,a=Math.floor(t),c=a%2===0?a:a-1,u=Math.floor(c/8),p=i>=0?i:u%2===0?u:u-1;o=h>1?Math.floor((c-p)/h):c,r=o*h,s=(o+p)*h,this.columnAxis=EPUBJS.core.prefixed("columnAxis"),this.columnGap=EPUBJS.core.prefixed("columnGap"),this.columnWidth=EPUBJS.core.prefixed("columnWidth"),this.columnFill=EPUBJS.core.prefixed("columnFill"),this.width=c,this.height=e,this.spread=r,this.delta=s,this.column=o,this.gap=p,this.divisor=h},EPUBJS.Layout.Reflowable.prototype.format=function(t){var e=t.document.documentElement,i=t.document.body;e.style.overflow="hidden",e.style.width=this.width+"px",i.style.height=this.height+"px",i.style[this.columnAxis]="horizontal",i.style[this.columnFill]="auto",i.style[this.columnGap]=this.gap+"px",i.style[this.columnWidth]=this.column+"px",t.iframe.style.marginRight=this.gap+"px"},EPUBJS.Layout.Reflowable.prototype.count=function(t){var e=t.root().scrollWidth,i=Math.ceil(e/this.spread);return{spreads:i,pages:i*this.divisor}},EPUBJS.Layout.Fixed=function(){},EPUBJS.Layout.Fixed.prototype.calculate=function(){},EPUBJS.Layout.Fixed.prototype.format=function(t){var e,i,n=t.document.documentElement,o=documentElement.querySelector("[name=viewport");o&&o.hasAttribute("content")&&(content=o.getAttribute("content"),contents=content.split(","),contents[0]&&(e=contents[0].replace("width=","")),contents[1]&&(i=contents[1].replace("height=",""))),t.resize(e,i),n.style.overflow="auto"},EPUBJS.Layout.Fixed.prototype.count=function(){return{spreads:1,pages:1}},EPUBJS.Layout.Scroll=function(){},EPUBJS.Layout.Scroll.prototype.calculate=function(t){this.spread=t,this.column=t,this.gap=0},EPUBJS.Layout.Scroll.prototype.format=function(t){var e=t.document.documentElement;e.style.width="auto",e.style.height="auto"},EPUBJS.Layout.Scroll.prototype.count=function(){return{spreads:1,pages:1}},EPUBJS.Rendition=function(t,e){this.settings=EPUBJS.core.extend(this.settings||{},{infinite:!0,hidden:!1,width:!1,height:null,layoutOveride:null,axis:"vertical"}),EPUBJS.core.extend(this.settings,e),this.viewSettings={},this.book=t,this.views=null,this.hooks={},this.hooks.display=new EPUBJS.Hook(this),this.hooks.content=new EPUBJS.Hook(this),this.hooks.layout=new EPUBJS.Hook(this),this.hooks.render=new EPUBJS.Hook(this),this.hooks.show=new EPUBJS.Hook(this),this.hooks.content.register(EPUBJS.replace.links.bind(this)),this.hooks.content.register(this.passViewEvents.bind(this)),this.epubcfi=new EPUBJS.EpubCFI,this.q=new EPUBJS.Queue(this),this.q.enqueue(this.book.opened),this.q.enqueue(this.parseLayoutProperties)},EPUBJS.Rendition.prototype.initialize=function(t){{var e,i=t||{},n=i.height,o=i.width;i.hidden||!1}return i.height&&EPUBJS.core.isNumber(i.height)&&(n=i.height+"px"),i.width&&EPUBJS.core.isNumber(i.width)&&(o=i.width+"px"),e=document.createElement("div"),e.id="epubjs-container:"+EPUBJS.core.uuid(),e.classList.add("epub-container"),e.style.fontSize="0",e.style.wordSpacing="0",e.style.lineHeight="0",e.style.verticalAlign="top","horizontal"===this.settings.axis&&(e.style.whiteSpace="nowrap"),o&&(e.style.width=o),n&&(e.style.height=n),e.style.overflow=this.settings.overflow,e},EPUBJS.Rendition.wrap=function(t){var e=document.createElement("div");return e.style.visibility="hidden",e.style.overflow="hidden",e.style.width="0",e.style.height="0",e.appendChild(t),e},EPUBJS.Rendition.prototype.attachTo=function(t){return this.container=this.initialize({width:this.settings.width,height:this.settings.height}),EPUBJS.core.isElement(t)?this.element=t:"string"==typeof t&&(this.element=document.getElementById(t)),this.element?(this.settings.hidden?(this.wrapper=this.wrap(this.container),this.element.appendChild(this.wrapper)):this.element.appendChild(this.container),this.views=new EPUBJS.Views(this.container),this.attachListeners(),this.stageSize(),this.applyLayoutMethod(),this.trigger("attached"),void 0):(console.error("Not an Element"),void 0)},EPUBJS.Rendition.prototype.attachListeners=function(){EPUBJS.core.isNumber(this.settings.width)&&EPUBJS.core.isNumber(this.settings.height)||window.addEventListener("resize",this.onResized.bind(this),!1)},EPUBJS.Rendition.prototype.bounds=function(){return this.container.getBoundingClientRect()},EPUBJS.Rendition.prototype.display=function(t){return this.q.enqueue(this._display,t)},EPUBJS.Rendition.prototype._display=function(t){var e,i,n,o,r,s=new RSVP.defer,h=s.promise,a=this.epubcfi.isCfiString(t);return(e=this.book.spine.get(t))?(r=this.views.find(e),r?(n=i.locationOf(t),h=this.moveTo(n).then(function(){return this.check()})):(this.views.hide(),i=new EPUBJS.View(e,this.viewSettings),h=this.fill(i).then(function(){return"string"==typeof t&&t.indexOf("#")>-1&&(o=t.substring(t.indexOf("#")+1)),a||o?(n=i.locationOf(t),this.moveTo(n)):"function"==typeof this.check?this.check():void 0}.bind(this)).then(function(){return this.hooks.display.trigger(i)}.bind(this)).then(function(){this.views.show()}.bind(this))),h.then(function(){this.trigger("displayed",e)}.bind(this)),h):(s.reject(new Error("No Section Found")),h)},EPUBJS.Rendition.prototype.moveTo=function(t){this.scrollBy(t.left,t.top)},EPUBJS.Rendition.prototype.render=function(t,e){return t.create(),t.onLayout=this.layout.format.bind(this.layout),this.resizeView(t),t.render(this.book.request).then(function(){return this.hooks.content.trigger(t,this)}.bind(this)).then(function(){return this.hooks.layout.trigger(t,this)}.bind(this)).then(function(){return t.display()}.bind(this)).then(function(){return this.hooks.render.trigger(t,this)}.bind(this)).then(function(){e!==!1&&this.views.hidden===!1&&this.q.enqueue(function(t){t.show()},t),this.trigger("rendered",t.section)}.bind(this)).catch(function(t){this.trigger("loaderror",t)}.bind(this))},EPUBJS.Rendition.prototype.afterDisplayed=function(t){this.trigger("added",t.section)},EPUBJS.Rendition.prototype.fill=function(t){return this.views.clear(),this.views.append(t),t.onDisplayed=this.afterDisplayed.bind(this),this.render(t)},EPUBJS.Rendition.prototype.resizeView=function(t){"pre-paginated"===this.globalLayoutProperties.layout?t.lock("both",this.stage.width,this.stage.height):t.lock("width",this.stage.width,this.stage.height)},EPUBJS.Rendition.prototype.stageSize=function(t,e){var i,n=t||this.settings.width,o=e||this.settings.height;return n===!1&&(i=this.element.getBoundingClientRect(),i.width&&(n=i.width,this.container.style.width=i.width+"px")),o===!1&&(i=i||this.element.getBoundingClientRect(),i.height&&(o=i.height,this.container.style.height=i.height+"px")),n&&!EPUBJS.core.isNumber(n)&&(i=this.container.getBoundingClientRect(),n=i.width),o&&!EPUBJS.core.isNumber(o)&&(i=i||this.container.getBoundingClientRect(),o=i.height),this.containerStyles=window.getComputedStyle(this.container),this.containerPadding={left:parseFloat(this.containerStyles["padding-left"])||0,right:parseFloat(this.containerStyles["padding-right"])||0,top:parseFloat(this.containerStyles["padding-top"])||0,bottom:parseFloat(this.containerStyles["padding-bottom"])||0},this.stage={width:n-this.containerPadding.left-this.containerPadding.right,height:o-this.containerPadding.top-this.containerPadding.bottom},this.stage},EPUBJS.Rendition.prototype.applyLayoutMethod=function(){this.layout=new EPUBJS.Layout.Scroll,this.updateLayout(),this.map=new EPUBJS.Map(this.layout)},EPUBJS.Rendition.prototype.updateLayout=function(){this.layout.calculate(this.stage.width,this.stage.height)},EPUBJS.Rendition.prototype.resize=function(t,e){this.stageSize(t,e),this.updateLayout(),this.views.each(this.resizeView.bind(this)),this.trigger("resized",{width:this.stage.width,height:this.stage.height})},EPUBJS.Rendition.prototype.onResized=function(){this.resize()},EPUBJS.Rendition.prototype.createView=function(t){return new EPUBJS.View(t,this.viewSettings)},EPUBJS.Rendition.prototype.next=function(){return this.q.enqueue(function(){var t,e;return this.views.length?(t=this.views.last().section.next(),t?(e=this.createView(t),this.fill(e)):void 0):void 0})},EPUBJS.Rendition.prototype.prev=function(){return this.q.enqueue(function(){var t,e;return this.views.length?(t=this.views.first().section.prev(),t?(e=this.createView(t),this.fill(e)):void 0):void 0})},EPUBJS.Rendition.prototype.parseLayoutProperties=function(t){var e=t||this.book.package.metadata,i=this.layoutOveride&&this.layoutOveride.layout||e.layout||"reflowable",n=this.layoutOveride&&this.layoutOveride.spread||e.spread||"auto",o=this.layoutOveride&&this.layoutOveride.orientation||e.orientation||"auto";return this.globalLayoutProperties={layout:i,spread:n,orientation:o},this.globalLayoutProperties},EPUBJS.Rendition.prototype.current=function(){var t=this.visible();return t.length?t[t.length-1]:null},EPUBJS.Rendition.prototype.isVisible=function(t,e,i,n){var o=t.position(),r=n||this.container.getBoundingClientRect();return"horizontal"===this.settings.axis&&o.right>r.left-e&&o.leftr.top-e&&o.topthis.settings.offsetDelta||this.scrollDeltaHorz>this.settings.offsetDelta)&&(this.q.enqueue(this.check),this.scrollDeltaVert=0,this.scrollDeltaHorz=0),this.scrollDeltaVert+=Math.abs(scrollTop-this.prevScrollTop),this.scrollDeltaHorz+=Math.abs(scrollLeft-this.prevScrollLeft),this.settings.height?(this.prevScrollTop=this.container.scrollTop,this.prevScrollLeft=this.container.scrollLeft):(this.prevScrollTop=window.scrollY,this.prevScrollLeft=window.scrollX),clearTimeout(this.scrollTimeout),this.scrollTimeout=setTimeout(function(){this.scrollDeltaVert=0,this.scrollDeltaHorz=0}.bind(this),150),this.scrolled=!1),this.tick.call(window,this.onScroll.bind(this))},EPUBJS.Continuous.prototype.resizeView=function(t){"horizontal"===this.settings.axis?t.lock("height",this.stage.width,this.stage.height):t.lock("width",this.stage.width,this.stage.height)},EPUBJS.Continuous.prototype.currentLocation=function(){{var t,e,i=this.visible();this.container.getBoundingClientRect()}return 1===i.length?this.map.page(i[0]):i.length>1?(t=this.map.page(i[0]),e=this.map.page(i[i.length-1]),{start:t.start,end:e.end}):void 0},EPUBJS.Paginate=function(t,e){EPUBJS.Continuous.apply(this,arguments),this.settings=EPUBJS.core.extend(this.settings||{},{width:600,height:400,axis:"horizontal",forceSingle:!1,minSpreadWidth:800,gap:"auto",overflow:"hidden",infinite:!1}),EPUBJS.core.extend(this.settings,e),this.isForcedSingle=this.settings.forceSingle,this.viewSettings={axis:this.settings.axis},this.start()},EPUBJS.Paginate.prototype=Object.create(EPUBJS.Continuous.prototype),EPUBJS.Paginate.prototype.constructor=EPUBJS.Paginate,EPUBJS.Paginate.prototype.determineSpreads=function(t){return this.isForcedSingle||!t||this.bounds().width1?(t=h.left-s[0].position().left,i=t+this.layout.column,e=h.left+this.layout.spread-s[s.length-1].position().left,n=e+this.layout.column,o=this.map.page(s[0],t,i),r=this.map.page(s[s.length-1],e,n),{start:o.start,end:r.end}):void 0},EPUBJS.Paginate.prototype.resize=function(t,e){this.q.clear(),this.stageSize(t,e),this.updateLayout(),this.location&&this.display(this.location.start),this.trigger("resized",{width:this.stage.width,height:this.stage.height})},EPUBJS.Paginate.prototype.onResized=function(){this.views.clear(),clearTimeout(this.resizeTimeout),this.resizeTimeout=setTimeout(function(){this.resize()}.bind(this),150)},EPUBJS.Paginate.prototype.adjustImages=function(t){return t.addStylesheetRules([["img",["max-width",this.layout.spread+"px"],["max-height",this.layout.height+"px"]]]),new RSVP.Promise(function(t){setTimeout(function(){t()},1)})},EPUBJS.Map=function(t){this.layout=t},EPUBJS.Map.prototype.section=function(t){var e=this.findRanges(t),i=this.rangeListToCfiList(t,e);return i},EPUBJS.Map.prototype.page=function(t,e,i){var n=t.document.body;return this.rangePairToCfiPair(t.section,{start:this.findStart(n,e,i),end:this.findEnd(n,e,i)})},EPUBJS.Map.prototype.walk=function(t,e){for(var i,n,o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode:function(t){return t.data.trim().length>0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}},!1);(i=o.nextNode())&&!(n=e(i)););return n},EPUBJS.Map.prototype.findRanges=function(t){for(var e,i,n=[],o=this.layout.count(t),r=this.layout.column,s=this.layout.gap,h=0;h=e&&i>=n?t:o>e?t:(s=t,r.push(t),void 0)}))return this.findTextStartRange(o,e,i);return this.findTextStartRange(s,e,i)},EPUBJS.Map.prototype.findEnd=function(t,e,i){for(var n,o,r=[t],s=t;r.length;)if(n=r.shift(),o=this.walk(n,function(t){var e,n,o,h;return t.nodeType==Node.TEXT_NODE?(h=document.createRange(),h.selectNodeContents(t),o=h.getBoundingClientRect()):o=t.getBoundingClientRect(),e=o.left,n=o.right,e>i&&s?s:n>i?t:(s=t,r.push(t),void 0)}))return this.findTextEndRange(o,e,i);return this.findTextEndRange(s,e,i)},EPUBJS.Map.prototype.findTextStartRange=function(t,e){for(var i,n,o,r=this.splitTextNodeIntoRanges(t),s=0;s=e)return n;i=n}return r[0]},EPUBJS.Map.prototype.findTextEndRange=function(t,e,i){for(var n,o,r,s=this.splitTextNodeIntoRanges(t),h=0;hi&&n)return n;if(r.right>i)return o;n=o}return s[s.length-1]},EPUBJS.Map.prototype.splitTextNodeIntoRanges=function(t,e){var i,n=[],o=t.textContent||"",r=o.trim(),s=t.ownerDocument,h=e||" ";if(pos=r.indexOf(h),-1===pos||t.nodeType!=Node.TEXT_NODE)return i=s.createRange(),i.selectNodeContents(t),[i];for(i=s.createRange(),i.setStart(t,0),i.setEnd(t,pos),n.push(i),i=!1;-1!=pos;)pos=r.indexOf(h,pos+1),pos>0&&(i&&(i.setEnd(t,pos),n.push(i)),i=s.createRange(),i.setStart(t,pos+1));return i&&(i.setEnd(t,r.length),n.push(i)),n},EPUBJS.Map.prototype.rangePairToCfiPair=function(t,e){var i=e.start,n=e.end;return i.collapse(!0),n.collapse(!0),startCfi=t.cfiFromRange(i),endCfi=t.cfiFromRange(n),{start:startCfi,end:endCfi}},EPUBJS.Map.prototype.rangeListToCfiList=function(t,e){for(var i,n=[],o=0;os&&(o+=s,h=s);s>h;)o=this.break,h+=this.break,h>=s?o=s-(h-this.break):(i.setEnd(e,h),cfi=t.cfiFromRange(i),this._locations.push(cfi),o=0,h+=1,i=n.createRange(),i.setStart(e,h))}.bind(this)),i&&(i.setEnd(prev,prev.length),cfi=t.cfiFromRange(i),this._locations.push(cfi),o=0)}.bind(this))},EPUBJS.Locations.prototype.sprint=function(t,e){for(var i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,null,!1);node=i.nextNode();)e(node)},EPUBJS.Locations.prototype.locationFromCfi=function(t){return 0===this._locations.length?-1:EPUBJS.core.locationOf(t,this._locations,this.epubcfi.compare)},EPUBJS.Locations.prototype.precentageFromCfi=function(t){var e=this.locationFromCfi(t);return this.precentageFromLocation(e)},EPUBJS.Locations.prototype.precentageFromLocation=function(t){return Math.ceil(t/this.total*1e3)/1e3},EPUBJS.Locations.prototype.cfiFromLocation=function(t){var e=-1;return"number"!=typeof t&&(t=parseInt(pg)),t>=0&&t // Load the opf // var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf"); - var book = ePub("books/alice/OPS/package.opf"); + var book = ePub("../books/alice/OPS/package.opf"); var rendition = book.renderTo("viewer", { method: "paginate", width: "100%", @@ -148,7 +148,7 @@ rendition.prev(); }, false); - document.addEventListener("keyup", function(e){ + var keyListener = function(e){ // Left Key if ((e.keyCode || e.which) == 37) { @@ -160,7 +160,10 @@ rendition.next(); } - }, false); + }; + + rendition.on("keyup", keyListener); + document.addEventListener("keyup", keyListener, false); diff --git a/gulpfile.js b/gulpfile.js index 9730f3a74..8a7f5c398 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -29,7 +29,8 @@ var files = [ 'src/rendition.js', 'src/continuous.js', 'src/paginate.js', - 'src/map.js' + 'src/map.js', + 'src/locations.js' ]; // Lint JS diff --git a/src/book.js b/src/book.js index 36a954fe4..cd0726c3a 100644 --- a/src/book.js +++ b/src/book.js @@ -1,4 +1,4 @@ -EPUBJS.Book = function(_url){ +EPUBJS.Book = function(_url, options){ // Promises this.opening = new RSVP.defer(); this.opened = this.opening.promise; @@ -6,8 +6,6 @@ EPUBJS.Book = function(_url){ this.url = undefined; - this.spine = new EPUBJS.Spine(this.request); - this.loading = { manifest: new RSVP.defer(), spine: new RSVP.defer(), @@ -34,6 +32,9 @@ EPUBJS.Book = function(_url){ this.request = this.requestMethod.bind(this); + this.spine = new EPUBJS.Spine(this.request); + this.locations = new EPUBJS.Locations(this.spine, this.request); + if(_url) { this.open(_url); } @@ -64,7 +65,7 @@ EPUBJS.Book.prototype.open = function(_url){ // Direct link to package, no container this.packageUrl = uri.href; this.containerUrl = ''; - + if(uri.origin) { this.url = uri.base; } else if(window){ @@ -82,9 +83,9 @@ EPUBJS.Book.prototype.open = function(_url){ this.url = ''; } - // Find the path to the Package from the container + // Find the path to the Package from the container else if (!uri.extension) { - + this.containerUrl = _url + containerPath; epubPackage = this.request(this.containerUrl). @@ -95,7 +96,7 @@ EPUBJS.Book.prototype.open = function(_url){ var packageUri = EPUBJS.core.uri(paths.packagePath); book.packageUrl = _url + paths.packagePath; book.encoding = paths.encoding; - + // Set Url relative to the content if(packageUri.origin) { book.url = packageUri.base; @@ -106,7 +107,7 @@ EPUBJS.Book.prototype.open = function(_url){ book.url = packageUri.directory; } - return book.request(book.packageUrl); + return book.request(book.packageUrl); }).catch(function(error) { // handle errors in either of the two requests console.error("Could not load book at: " + (this.packageUrl || this.containerPath)); @@ -156,7 +157,7 @@ EPUBJS.Book.prototype.unpack = function(packageXml){ book.toc = toc; book.loading.navigation.resolve(book.toc); }); - + // //-- Set Global Layout setting based on metadata // MOVE TO RENDER // book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata); @@ -171,7 +172,7 @@ EPUBJS.Book.prototype.section = function(target) { // Sugar to render a book EPUBJS.Book.prototype.renderTo = function(element, options) { - var renderer = (options && options.method) ? + var renderer = (options && options.method) ? options.method.charAt(0).toUpperCase() + options.method.substr(1) : "Rendition"; @@ -183,7 +184,7 @@ EPUBJS.Book.prototype.renderTo = function(element, options) { EPUBJS.Book.prototype.requestMethod = function(_url) { // Switch request methods if(this.archived) { - // TODO: handle archived + // TODO: handle archived } else { return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders); } @@ -197,6 +198,7 @@ EPUBJS.Book.prototype.setRequestCredentials = function(_credentials) { EPUBJS.Book.prototype.setRequestHeaders = function(_headers) { this.requestHeaders = _headers; }; + //-- Enable binding events to book RSVP.EventTarget.mixin(EPUBJS.Book.prototype); @@ -211,4 +213,4 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject // RSVP.on('fulfilled', listener); RSVP.on('rejected', function(event){ console.error(event.detail.message, event.detail.stack); -}); \ No newline at end of file +}); diff --git a/src/epubcfi.js b/src/epubcfi.js index ccb7db7b6..c290df17d 100644 --- a/src/epubcfi.js +++ b/src/epubcfi.js @@ -58,10 +58,10 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) { 'tagName' : node.tagName, 'index' : children ? Array.prototype.indexOf.call(children, node) : 0 }); - + node = node.parentNode; } - + return stack; }; @@ -100,21 +100,21 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { text, parseStep = function(part){ var type, index, has_brackets, id; - + type = "element"; index = parseInt(part) / 2 - 1; has_brackets = part.match(/\[(.*)\]/); if(has_brackets && has_brackets[1]){ id = has_brackets[1]; } - + return { "type" : type, 'index' : index, 'id' : id || false }; }; - + if(typeof cfiStr !== "string") { return {spinePos: -1}; } @@ -133,7 +133,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { if(!chapterComponent) { return {spinePos: -1}; } - + // Chapter segment is always the second one chapSegment = chapterComponent.split("/")[2] || ''; if(!chapSegment) return {spinePos:-1}; @@ -156,7 +156,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { path.forEach(function(part){ var step; - + if(part) { step = parseStep(part); cfi.steps.push(step); @@ -166,7 +166,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { //-- Check if END is a text node or element endInt = parseInt(end); if(!isNaN(endInt)) { - + if(endInt % 2 === 0) { // Even = is an element cfi.steps.push(parseStep(end)); } else { @@ -186,7 +186,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) { } else { cfi.characterOffset = parseInt(charecterOffsetComponent); } - + return cfi; }; @@ -197,7 +197,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { var lastStep; var text; var split; - + if(typeof cfi === 'string') { cfi = this.parse(cfi); } @@ -212,13 +212,13 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { // Find the CFI elements parent parent = this.findParent(cfi, doc); - + if(!parent) { // CFI didn't return an element // Maybe it isnt in the current chapter? return false; } - + if(lastStep && lastStep.type === "text") { text = parent.childNodes[lastStep.index]; if(cfi.characterOffset){ @@ -231,7 +231,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) { } else { parent.insertBefore(marker, parent.firstChild); } - + return marker; }; @@ -240,7 +240,7 @@ EPUBJS.EpubCFI.prototype.createMarker = function(_doc) { var element = doc.createElement('span'); element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid(); element.classList.add("EPUBJS-CFI-MARKER"); - + return element; }; @@ -278,7 +278,7 @@ EPUBJS.EpubCFI.prototype.findParent = function(cfi, _doc) { if(typeof cfi === 'string') { cfi = this.parse(cfi); } - + sections = cfi.steps.slice(0); // Clone steps array if(!sections.length) { return doc.getElementsByTagName('body')[0]; @@ -323,8 +323,8 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) { if(cfiOne.spinePos < cfiTwo.spinePos) { return -1; } - - + + // Compare Each Step in the First item for (var i = 0; i < cfiOne.steps.length; i++) { if(!cfiTwo.steps[i]) { @@ -338,7 +338,7 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) { } // Otherwise continue checking } - + // All steps in First present in Second if(cfiOne.steps.length < cfiTwo.steps.length) { return -1; @@ -365,7 +365,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) { var deferred = new RSVP.defer(); var epubcfi = new EPUBJS.EpubCFI(); var spineItem; - + if(typeof spinePos !== "undefined"){ spineItem = book.spine[spinePos]; loaded = book.loadXml(spineItem.url); @@ -376,7 +376,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) { deferred.resolve(cfi); }); } - + return deferred.promise; }; @@ -399,7 +399,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { var end, endElement, endSteps, endPath, endOffset, endIndex; start = range.startContainer; - + if(start.nodeType === 3) { // text node startElement = start.parentNode; //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); @@ -410,18 +410,18 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { } else { startSteps = this.pathTo(start); } - + startPath = this.generatePathComponent(startSteps); startOffset = range.startOffset; - + if(!range.collapsed) { end = range.endContainer; - + if(end.nodeType === 3) { // text node endElement = end.parentNode; - // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); + // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end)); - + endSteps = this.pathTo(endElement); } else { endSteps = this.pathTo(end); @@ -430,8 +430,15 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { endPath = this.generatePathComponent(endSteps); endOffset = range.endOffset; - return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + "/" + endIndex + ":" + endOffset + ")"; - + // Remove steps present in startPath + endPath = endPath.replace(startPath, ''); + + if (endPath.length) { + endPath = endPath + "/"; + } + + return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")"; + } else { return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")"; } @@ -442,7 +449,7 @@ EPUBJS.EpubCFI.prototype.generateXpathFromSteps = function(steps) { steps.forEach(function(step){ var position = step.index + 1; - + if(step.id){ xpath.push("*[position()=" + position + " and @id='" + step.id + "']"); } else if(step.type === "text") { @@ -463,19 +470,19 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) { var xpath; var startContainer; var textLength; - + if(typeof cfi === 'string') { cfi = this.parse(cfi); } - + // check spinePos if(cfi.spinePos === -1) { // Not a valid CFI return false; } - + xpath = this.generateXpathFromSteps(cfi.steps); - + // Get the terminal step lastStep = cfi.steps[cfi.steps.length-1]; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; @@ -493,7 +500,7 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) { } else { console.debug("offset greater than length:", cfi.characterOffset, textLength); range.setStart(startContainer, textLength - 1 ); - range.setEnd(startContainer, textLength ); + range.setEnd(startContainer, textLength ); } } else if(startContainer) { range.selectNode(startContainer); @@ -509,4 +516,4 @@ EPUBJS.EpubCFI.prototype.isCfiString = function(target) { } return false; -}; \ No newline at end of file +}; diff --git a/src/locations.js b/src/locations.js new file mode 100644 index 000000000..ad3198269 --- /dev/null +++ b/src/locations.js @@ -0,0 +1,211 @@ +EPUBJS.Locations = function(spine, request) { + this.spine = spine; + this.request = request; + + this.q = new EPUBJS.Queue(this); + this.epubcfi = new EPUBJS.EpubCFI(); + + this._locations = []; + this.total = 0; + + this.break = 150; + + this._current = 0; + +}; + +// Load all of sections in the book +EPUBJS.Locations.prototype.generate = function(chars) { + + if (chars) { + this.break = chars; + } + + this.q.pause(); + + this.spine.each(function(section) { + + this.q.enqueue(this.process, section); + + }.bind(this)); + + return this.q.run().then(function() { + this.total = this._locations.length-1; + + if (this._currentCfi) { + this.currentLocation = this._currentCfi; + } + + return this._locations; + // console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end)); + }.bind(this)); + +}; + +EPUBJS.Locations.prototype.process = function(section) { + + return section.load(this.request) + .then(function(contents) { + + var range; + var doc = contents.ownerDocument; + var counter = 0; + + this.sprint(contents, function(node) { + var len = node.length; + var dist; + var pos = 0; + + // Start range + if (counter == 0) { + range = doc.createRange(); + range.setStart(node, 0); + } + + dist = this.break - counter; + + // Node is smaller than a break + if(dist > len){ + counter += len; + pos = len; + } + + while (pos < len) { + counter = this.break; + pos += this.break; + + // Gone over + if(pos >= len){ + // Continue counter for next node + counter = len - (pos - this.break); + + // At End + } else { + // End the previous range + range.setEnd(node, pos); + cfi = section.cfiFromRange(range); + this._locations.push(cfi); + counter = 0; + + // Start new range + pos += 1; + range = doc.createRange(); + range.setStart(node, pos); + } + } + + + + }.bind(this)); + + // Close remaining + if (range) { + range.setEnd(prev, prev.length); + cfi = section.cfiFromRange(range); + this._locations.push(cfi) + counter = 0; + } + + }.bind(this)); + +}; + +EPUBJS.Locations.prototype.sprint = function(root, func) { + var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false); + + while ((node = treeWalker.nextNode())) { + func(node); + } + +}; + +EPUBJS.Locations.prototype.locationFromCfi = function(cfi){ + // Check if the location has not been set yet + if(this._locations.length === 0) { + return -1; + } + + return EPUBJS.core.locationOf(cfi, this._locations, this.epubcfi.compare); +}; + +EPUBJS.Locations.prototype.precentageFromCfi = function(cfi) { + // Find closest cfi + var loc = this.locationFromCfi(cfi); + // Get percentage in total + return this.precentageFromLocation(loc); +}; + +EPUBJS.Locations.prototype.precentageFromLocation = function(loc) { + return Math.ceil((loc / this.total ) * 1000) / 1000; +}; + +EPUBJS.Locations.prototype.cfiFromLocation = function(loc){ + var cfi = -1; + // check that pg is an int + if(typeof loc != "number"){ + loc = parseInt(pg); + } + + if(loc >= 0 && loc < this._locations.length) { + cfi = this._locations[loc]; + } + + return cfi; +}; + +EPUBJS.Locations.prototype.cfiFromPercentage = function(percent){ + var loc = Math.round(this.total * percent); + return this.cfiFromLocation(loc); +}; + +EPUBJS.Locations.prototype.load = function(locations){ + this._locations = JSON.parse(locations); + this.total = this._locations.length-1; + return this._locations; +}; + +EPUBJS.Locations.prototype.save = function(json){ + return JSON.stringify(this._locations); +}; + +EPUBJS.Locations.prototype.getCurrent = function(json){ + return this._current; +}; + +EPUBJS.Locations.prototype.setCurrent = function(curr){ + var loc; + + if(typeof curr == "string"){ + this._currentCfi = curr; + } else if (typeof curr == "number") { + this._current = curr; + } else { + return; + } + + if(this._locations.length === 0) { + return; + } + + if(typeof curr == "string"){ + loc = this.locationFromCfi(curr); + this._current = loc; + } else { + loc = curr; + } + console.log( this.precentageFromLocation(loc)) + this.trigger("changed", { + percentage: this.precentageFromLocation(loc) + }); +}; + +Object.defineProperty(EPUBJS.Locations.prototype, 'currentLocation', { + get: function () { + return this._current; + }, + set: function (curr) { + this.setCurrent(curr); + } +}); + +RSVP.EventTarget.mixin(EPUBJS.Locations.prototype); diff --git a/src/queue.js b/src/queue.js index 70435c470..2cd8a03ed 100644 --- a/src/queue.js +++ b/src/queue.js @@ -3,6 +3,7 @@ EPUBJS.Queue = function(_context){ this.context = _context; this.tick = EPUBJS.core.requestAnimationFrame; this.running = false; + this.paused = false; }; // Add an item to the queue @@ -44,7 +45,11 @@ EPUBJS.Queue.prototype.enqueue = function() { this._q.push(queued); // Wait to start queue flush - setTimeout(this.flush.bind(this), 0); + if (this.paused == false && !this.running) { + // setTimeout(this.flush.bind(this), 0); + // this.tick.call(window, this.run.bind(this)); + this.run(); + } return queued.promise; }; @@ -97,25 +102,46 @@ EPUBJS.Queue.prototype.dump = function(){ // Run all sequentially, at convince EPUBJS.Queue.prototype.run = function(){ - if(!this.running && this._q.length) { + + if(!this.running){ this.running = true; - this.dequeue().then(function(){ - this.running = false; - }.bind(this)); + this.defered = new RSVP.defer(); } - this.tick.call(window, this.run.bind(this)); + this.tick.call(window, function() { + + if(this._q.length) { + + this.dequeue() + .then(function(){ + this.run(); + }.bind(this)); + + } else { + this.defered.resolve(); + this.running = undefined; + } + + }.bind(this)); + + // Unpause + if(this.paused == true) { + this.paused = false; + } + + return this.defered.promise; }; // Flush all, as quickly as possible EPUBJS.Queue.prototype.flush = function(){ + if(this.running){ return this.running; } if(this._q.length) { - this.running = this.dequeue(). - then(function(){ + this.running = this.dequeue() + .then(function(){ this.running = undefined; return this.flush(); }.bind(this)); @@ -135,6 +161,10 @@ EPUBJS.Queue.prototype.length = function(){ return this._q.length; }; +EPUBJS.Queue.prototype.pause = function(){ + this.paused = true; +}; + // Create a new task from a callback EPUBJS.Task = function(task, args, context){ diff --git a/src/section.js b/src/section.js index b1a83f9f6..e8506d565 100644 --- a/src/section.js +++ b/src/section.js @@ -7,7 +7,7 @@ EPUBJS.Section = function(item){ this.url = item.url; this.next = item.next; this.prev = item.prev; - + this.epubcfi = new EPUBJS.EpubCFI(); this.cfiBase = item.cfiBase; @@ -44,7 +44,7 @@ EPUBJS.Section.prototype.load = function(_request){ loading.reject(error); }); } - + return loaded; }; @@ -64,7 +64,7 @@ EPUBJS.Section.prototype.replacements = function(_document){ } else { task.reject(new Error("No head to insert into")); } - + return task.promise; }; @@ -76,7 +76,7 @@ EPUBJS.Section.prototype.beforeSectionLoad = function(){ EPUBJS.Section.prototype.render = function(_request){ var rendering = new RSVP.defer(); var rendered = rendering.promise; - + this.load(_request).then(function(contents){ var serializer = new XMLSerializer(); var output = serializer.serializeToString(contents); @@ -125,4 +125,8 @@ EPUBJS.Section.prototype.reconcileLayoutSettings = function(global){ EPUBJS.Section.prototype.cfiFromRange = function(_range) { return this.epubcfi.generateCfiFromRange(_range, this.cfiBase); -}; \ No newline at end of file +}; + +EPUBJS.Section.prototype.cfiFromElement = function(el) { + return this.epubcfi.generateCfiFromElement(el, this.cfiBase); +}; diff --git a/src/spine.js b/src/spine.js index 3a01e4ae0..4ddd05562 100644 --- a/src/spine.js +++ b/src/spine.js @@ -109,3 +109,7 @@ EPUBJS.Spine.prototype.remove = function(section) { return this.spineItems.splice(index, 1); } }; + +EPUBJS.Spine.prototype.each = function() { + return this.spineItems.forEach.apply(this.spineItems, arguments); +};