diff --git a/files_opds/ajax/clear_bookshelf.php b/files_opds/ajax/clear_bookshelf.php
new file mode 100644
index 0000000..5273c0b
--- /dev/null
+++ b/files_opds/ajax/clear_bookshelf.php
@@ -0,0 +1,21 @@
+ array( "message" => $l->t("Bookshelf cleared"))));
diff --git a/files_opds/ajax/personal.php b/files_opds/ajax/personal.php
new file mode 100644
index 0000000..8ea0704
--- /dev/null
+++ b/files_opds/ajax/personal.php
@@ -0,0 +1,46 @@
+ array('message'=> $l->t('Directory does not exist!'))
+ )
+ );
+ } else {
+ Config::set('root_path', $rootPath);
+ \OCP\JSON::success(
+ array(
+ 'data' => array('message'=> $l->t('Settings updated successfully.'))
+ )
+ );
+ }
+ Config::set('enable', $opdsEnable);
+ Config::set('file_types', $fileTypes);
+ Config::set('id', Util::genUuid());
+ exit();
+}
+
+exit();
+
diff --git a/files_opds/appinfo/app.php b/files_opds/appinfo/app.php
new file mode 100644
index 0000000..a71521b
--- /dev/null
+++ b/files_opds/appinfo/app.php
@@ -0,0 +1,7 @@
+
+
+ files_opds
+ OPDS catalog
+ Personal OPDS catalog
+ AGPL
+ 0.1
+ Frank de Lange
+ 7.0
+ true
+
+
+
diff --git a/files_opds/index.php b/files_opds/index.php
new file mode 100644
index 0000000..c524ee3
--- /dev/null
+++ b/files_opds/index.php
@@ -0,0 +1,57 @@
+getType()) {
+ case 'file':
+ Util::serveFile($dir,$id);
+ break;
+ case 'dir':
+ Util::serveFeed($dir, $id);
+ break;
+ default:
+ Util::logWarn("I don't know how to handle files of type " . $dirInfo->getType());
+ break;
+}
diff --git a/files_opds/js/personal.js b/files_opds/js/personal.js
new file mode 100644
index 0000000..32c9b21
--- /dev/null
+++ b/files_opds/js/personal.js
@@ -0,0 +1,45 @@
+$(document).ready(function(){
+ // clear bookshelf
+ $('#opds-clear-bookshelf').on("click", function() {
+ $('#opds-really-clear-bookshelf,#opds-dont-clear-bookshelf').show();
+ });
+ $('#opds-dont-clear-bookshelf').on("click", function() {
+ $('#opds-really-clear-bookshelf,#opds-dont-clear-bookshelf').hide();
+ });
+ $('#opds-really-clear-bookshelf').on("click", function() {
+ $.post(OC.filePath('files_opds','ajax','clear_bookshelf.php'), {},
+ function(result){
+ if(result) {
+ OC.msg.finishedSaving('#opds-personal .clr', result);
+ $('#opds-book-count').hide();
+ }
+ });
+ $('#opds-really-clear-bookshelf,#opds-dont-clear-bookshelf').hide();
+ });
+
+ // save settings
+ var opdsSettings = {
+ save : function() {
+ var opdsEnable = document.getElementById('opds-enable').checked ? 'true' : 'false';
+ var data = {
+ opdsEnable : opdsEnable,
+ rootPath : $('#opds-root-path').val(),
+ fileTypes : $('#opds-file-types').val()
+ };
+ OC.msg.startSaving('#opds-personal .msg');
+ $.post(OC.filePath('files_opds', 'ajax', 'personal.php'), data, opdsSettings.afterSave);
+ },
+ afterSave : function(data){
+ OC.msg.finishedSaving('#opds-personal .msg', data);
+ }
+ };
+ $('#opds-root-path,#opds-file-types').blur(opdsSettings.save);
+ $('#opds-root-path,#opds-file-types').keypress(function( event ) {
+ if (event.which == 13) {
+ event.preventDefault();
+ opdsSettings.save();
+ }
+ });
+ $('#opds-enable').on("change", opdsSettings.save);
+});
+
diff --git a/files_opds/lib/bookshelf.php b/files_opds/lib/bookshelf.php
new file mode 100644
index 0000000..dc2bd94
--- /dev/null
+++ b/files_opds/lib/bookshelf.php
@@ -0,0 +1,65 @@
+getName();
+ $entry['mimetype'] = $i['mimetype'];
+ $entry['size'] = $i['size'];
+ $entry['type'] = $i['type'];
+ return $entry;
+ }
+
+ /**
+ * Format file info for OPDS feed
+ * @param \OCP\Files\FileInfo[] $fileInfos file infos
+ */
+ public static function formatFileInfos($fileInfos) {
+ $files = array();
+ /* if set, add only files with given extensions */
+ $fileTypes = array_filter(explode(',', strtolower(Config::get('file_types', ''))));
+ foreach ($fileInfos as $i) {
+ if((!empty($fileTypes)) && (!in_array(strtolower(substr(strrchr($i->getName(), "."), 1)), $fileTypes))) {
+ continue;
+ }
+ $files[] = self::formatFileInfo($i);
+ }
+
+ return $files;
+ }
+
+ /*
+ * @brief check if $child is a subdirectory of $parent
+ *
+ * @param string $parent a directory
+ * @param string $child a directory
+ * @return bool true if $child is a subdirectory of $parent
+ */
+ public static function isChild($parent, $child) {
+ return strpos($child, $parent . '/') === 0;
+ }
+}
diff --git a/files_opds/lib/util.php b/files_opds/lib/util.php
new file mode 100644
index 0000000..1c1cfb9
--- /dev/null
+++ b/files_opds/lib/util.php
@@ -0,0 +1,151 @@
+getName();
+ header ("HTTP/1.0 401 Unauthorized");
+ header ('WWW-Authenticate: Basic realm="' . $realm. '"');
+ exit();
+ }
+
+ $userName = $_SERVER['PHP_AUTH_USER'];
+
+ // Check the password in the ownCloud database
+ return self::checkPassword($userName, $_SERVER['PHP_AUTH_PW']);
+ }
+
+ /**
+ * @brief Checks the password of a user.
+ * @param string $userName ownCloud user name whose password will be checked.
+ * @param string $password ownCloud password.
+ * @return bool True if the password is correct, false otherwise.
+ *
+ */
+ private static function checkPassword($userName, $password) {
+
+ // Check password normally
+ if (\OCP\User::checkPassword($userName, $password) != false) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief Change HTTP response code.
+ *
+ * @param integer $statusCode The new HTTP status code.
+ */
+ public static function changeHttpStatus($statusCode) {
+
+ $message = '';
+ switch ($statusCode) {
+ case 400: $message = 'Bad Request'; break;
+ case 401: $message = 'Unauthorized'; break;
+ case 403: $message = 'Forbidden'; break;
+ case 404: $message = 'Not Found'; break;
+ case 500: $message = 'Internal Server Error'; break;
+ case 503: $message = 'Service Unavailable'; break;
+ }
+
+ // Set status code and status message in HTTP header
+ header('HTTP/1.0 ' . $statusCode . ' ' . $message);
+ }
+
+ /**
+ * @brief offer single file for download
+ *
+ * @param string $path full path to file
+ * @param int $id file id
+ */
+ public static function serveFile($path, $id) {
+ \OCP\User::checkLoggedIn();
+ \OC::$session->close();
+ Bookshelf::add($id);
+ $dirName = dirname($path);
+ $fileName = basename($path);
+ \OC_Files::get($dirName, array($fileName), $_SERVER['REQUEST_METHOD'] == 'HEAD');
+ }
+
+ /**
+ * @brief serve opds feed for given directory
+ *
+ * @param string $dir full path to directory
+ * @param int $id requested id
+ */
+ public static function serveFeed($dir, $id) {
+ if (isset($_SERVER['HTTP_ACCEPT']) && stristr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) {
+ header('Content-Type: application/atom+xml');
+ } else {
+ header('Content-Type: text/xml; charset=UTF-8');
+ }
+ $sortAttribute = 'name';
+ $sortDirection = false;
+ $defaults = new \OC_Defaults();
+ $tmpl = new \OCP\Template('files_opds', 'feed');
+ $tmpl->assign('files', Files::formatFileInfos(Files::getFiles($dir, $sortAttribute, $sortDirection)));
+ $tmpl->assign('bookshelf', Files::formatFileInfos(Bookshelf::get()));
+ $tmpl->assign('bookshelf-count', Bookshelf::count());
+ $tmpl->assign('feed_id', self::getFeedId());
+ $tmpl->assign('id', $id);
+ $tmpl->assign('dir', $dir);
+ $tmpl->assign('user', \OCP\User::getDisplayName());
+ $tmpl->assign('ocname', $defaults->getName());
+ $tmpl->printPage();
+ }
+
+ /**
+ * @brief generate v3 UUID based on display name and site url
+ *
+ * @return string uuid
+ */
+ public static function genUuid() {
+ $defaults = new \OC_Defaults();
+ $hash = md5(\OCP\User::getDisplayName() . $defaults->getBaseUrl());
+ $hash = substr($hash, 0, 8 ) .'-'.
+ substr($hash, 8, 4) .'-3'.
+ substr($hash, 13, 3) .'-9'.
+ substr($hash, 17, 3) .'-'.
+ substr($hash, 20);
+ return $hash;
+ }
+
+ /**
+ * @brief get feed id
+ *
+ * @return string feed id
+ */
+ public static function getFeedId() {
+ return Config::get('id', '');
+ }
+
+ /**
+ * @brief log warning
+ * @param string message to write to log
+ */
+ public static function logWarn($msg) {
+ \OCP\Util::writeLog('files_opds', $msg, \OCP\Util::WARN);
+ }
+}
diff --git a/files_opds/personal.php b/files_opds/personal.php
new file mode 100644
index 0000000..2aab169
--- /dev/null
+++ b/files_opds/personal.php
@@ -0,0 +1,24 @@
+assign('opdsEnable-checked', ($opdsEnable === 'true') ? 'checked="checked"' : '');
+$tmpl->assign('opdsEnable-value', ($opdsEnable === 'true') ? '1' : '0');
+$tmpl->assign('rootPath', Config::get('root_path', '/Library'));
+$tmpl->assign('fileTypes', Config::get('file_types', ''));
+$tmpl->assign('bookshelf-count', Bookshelf::count());
+
+return $tmpl->fetchPage();
+
diff --git a/files_opds/templates/feed.php b/files_opds/templates/feed.php
new file mode 100644
index 0000000..183f5e7
--- /dev/null
+++ b/files_opds/templates/feed.php
@@ -0,0 +1,124 @@
+';
+?>
+
+
+ id:
+ t("%s's library", array($_['user']))); ?>
+ t("%s OPDS Catalog", array($_['ocname']))); ?>
+
+
+
+
+
+
+
+
+
+ t("Browse catalog")); ?>
+ t("Browse the catalog in alphabetical order")); ?>
+
+ id:by_directory
+
+
+ t("%s's bookshelf", array($_['user']))); ?>
+ t("This bookshelf contains %s books", array($_['bookshelf-count']))); ?>
+
+ id:by_bookshelf
+
+
+
+
+
+
+
+
+ id:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id:
+
+
+
+
+
+
+
+
+ id:
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/files_opds/templates/personal.php b/files_opds/templates/personal.php
new file mode 100644
index 0000000..18ecb85
--- /dev/null
+++ b/files_opds/templates/personal.php
@@ -0,0 +1,39 @@
+
+
+
+
t('OPDS')); ?>
+
+ type="checkbox">
+
+
+
+
+ " value="" />
+
+
+
+ " value="" />
+
+
+
+
diff --git a/files_reader/appinfo/app.php b/files_reader/appinfo/app.php
new file mode 100644
index 0000000..174f8f2
--- /dev/null
+++ b/files_reader/appinfo/app.php
@@ -0,0 +1,3 @@
+
+
+ files_reader
+ Reader (ebook reader)
+ Online ePub file reader
+ 0.4.4
+ LGPL
+ Frank de Lange, (taken clues from Thomas Müller/files_pdfviewer, using slightly modified Futurepress/epub.js)
+ 7.0
+ false
+
+
+
diff --git a/files_reader/appinfo/version b/files_reader/appinfo/version
new file mode 100644
index 0000000..6f2743d
--- /dev/null
+++ b/files_reader/appinfo/version
@@ -0,0 +1 @@
+0.4.4
diff --git a/files_reader/css/font/fontello.eot b/files_reader/css/font/fontello.eot
new file mode 100644
index 0000000..f63ffa0
Binary files /dev/null and b/files_reader/css/font/fontello.eot differ
diff --git a/files_reader/css/font/fontello.svg b/files_reader/css/font/fontello.svg
new file mode 100644
index 0000000..0b9f2af
Binary files /dev/null and b/files_reader/css/font/fontello.svg differ
diff --git a/files_reader/css/font/fontello.ttf b/files_reader/css/font/fontello.ttf
new file mode 100644
index 0000000..e1220c5
Binary files /dev/null and b/files_reader/css/font/fontello.ttf differ
diff --git a/files_reader/css/font/fontello.woff b/files_reader/css/font/fontello.woff
new file mode 100644
index 0000000..084f0c5
Binary files /dev/null and b/files_reader/css/font/fontello.woff differ
diff --git a/files_reader/css/idevice.css b/files_reader/css/idevice.css
new file mode 100644
index 0000000..888c060
--- /dev/null
+++ b/files_reader/css/idevice.css
@@ -0,0 +1,33 @@
+/* For iPad portrait layouts only */
+@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: portrait) {
+ #viewer iframe {
+ width: 460px;
+ height: 740px;
+ }
+}
+ /*For iPad landscape layouts only */
+@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: landscape) {
+ #viewer iframe {
+ width: 460px;
+ height: 415px;
+ }
+}
+/* For iPhone portrait layouts only */
+@media only screen and (max-device-width: 480px) and (orientation: portrait) {
+ #viewer {
+ width: 256px;
+ height: 432px;
+ }
+ #viewer iframe {
+ width: 256px;
+ height: 432px;
+ }
+}
+/* For iPhone landscape layouts only */
+@media only screen and (max-device-width: 480px) and (orientation: landscape) {
+ #viewer iframe {
+ width: 256px;
+ height: 124px;
+ }
+}
+
diff --git a/files_reader/css/main.css b/files_reader/css/main.css
new file mode 100644
index 0000000..436966e
--- /dev/null
+++ b/files_reader/css/main.css
@@ -0,0 +1,782 @@
+@font-face {
+ font-family: 'fontello';
+ src: url('font/fontello.eot?60518104');
+ src: url('font/fontello.eot?60518104#iefix') format('embedded-opentype'),
+ url('font/fontello.woff?60518104') format('woff'),
+ url('font/fontello.ttf?60518104') format('truetype'),
+ url('font/fontello.svg?60518104#fontello') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+body {
+ background: #4e4e4e;
+ overflow: hidden;
+}
+
+#main {
+ /* height: 500px; */
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ right: 0;
+ /* left: 40px; */
+/* -webkit-transform: translate(40px, 0);
+ -moz-transform: translate(40px, 0); */
+
+ /* border-radius: 5px 0px 0px 5px; */
+ border-radius: 5px;
+ background: #fff;
+ overflow: hidden;
+ -webkit-transition: -webkit-transform .4s, width .2s;
+ -moz-transition: -webkit-transform .4s, width .2s;
+
+ -moz-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
+ -webkit-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
+ box-shadow: inset 0 0 50px rgba(0,0,0,.1);
+}
+
+
+#titlebar {
+ height: 8%;
+ min-height: 20px;
+ padding: 10px;
+ /* margin: 0 50px 0 50px; */
+ position: relative;
+ color: #4f4f4f;
+ font-weight: 100;
+ font-family: Georgia, "Times New Roman", Times, serif;
+ opacity: .5;
+ text-align: center;
+ -webkit-transition: opacity .5s;
+ -moz-transition: opacity .5s;
+ z-index: 10;
+}
+
+#titlebar:hover {
+ opacity: 1;
+}
+
+#titlebar a {
+ width: 18px;
+ height: 19px;
+ line-height: 20px;
+ overflow: hidden;
+ display: inline-block;
+ opacity: .5;
+ padding: 4px;
+ border-radius: 4px;
+}
+
+#titlebar a::before {
+ visibility: visible;
+}
+
+#titlebar a:hover {
+ opacity: .8;
+ border: 1px rgba(0,0,0,.2) solid;
+ padding: 3px;
+}
+
+#titlebar a:active {
+ opacity: 1;
+ color: rgba(0,0,0,.6);
+ /* margin: 1px -1px -1px 1px; */
+ -moz-box-shadow: inset 0 0 6px rgba(155,155,155,.8);
+ -webkit-box-shadow: inset 0 0 6px rgba(155,155,155,.8);
+ box-shadow: inset 0 0 6px rgba(155,155,155,.8);
+}
+
+#book-title {
+ font-weight: 600;
+}
+
+#title-seperator {
+ display: none;
+}
+
+#viewer {
+ width: 80%;
+ height: 80%;
+ /* margin-left: 10%; */
+ margin: 0 auto;
+ max-width: 1250px;
+ z-index: 2;
+ position: relative;
+ overflow: hidden;
+}
+
+#viewer iframe {
+ border: none;
+}
+
+#prev, #next {
+ position: absolute;
+ top: 10%;
+ height: 85%;
+ margin: 0;
+}
+
+.touch_nav {
+ width: 35%;
+}
+
+.arrow div {
+ display: table-cell;
+ vertical-align: middle;
+}
+
+
+#prev {
+ left: 0;
+ padding-left: 40px;
+}
+
+#next {
+ right: 0;
+ padding-right: 40px;
+ text-align: right;
+}
+
+.arrow {
+ /* position: relative;
+ top: 50%;
+ margin-top: -32px; */
+ font-size: 64px;
+ color: #E2E2E2;
+ font-family: arial, sans-serif;
+ font-weight: bold;
+ cursor: pointer;
+ display: table;
+ z-index: 3;
+}
+
+.arrow:hover {
+ color: #777;
+}
+
+.arrow:active,
+.arrow.active {
+ color: #000;
+}
+
+#sidebar {
+ background: #6b6b6b;
+ position: absolute;
+ /* left: -260px; */
+ /* -webkit-transform: translate(-260px, 0);
+ -moz-transform: translate(-260px, 0); */
+ top: 0;
+ min-width: 300px;
+ width: 25%;
+ height: 100%;
+ -webkit-transition: -webkit-transform .5s;
+ -moz-transition: -moz-transform .5s;
+
+ overflow: hidden;
+}
+
+#sidebar.open {
+ /* left: 0; */
+ /* -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0); */
+}
+
+#main.closed {
+ /* left: 300px; */
+ -webkit-transform: translate(300px, 0);
+ -moz-transform: translate(300px, 0);
+}
+
+#main.single {
+ width: 75%;
+}
+
+#main.single #viewer {
+ /* width: 60%;
+ margin-left: 20%; */
+}
+
+#panels {
+ background: #4e4e4e;
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ padding: 13px 0;
+ height: 14px;
+ -moz-box-shadow: 0px 1px 3px rgba(0,0,0,.6);
+ -webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.6);
+ box-shadow: 0px 1px 3px rgba(0,0,0,.6);
+}
+
+#opener {
+ /* padding: 10px 10px; */
+ float: left;
+}
+
+/* #opener #slider {
+ width: 25px;
+} */
+
+#metainfo {
+ display: inline-block;
+ text-align: center;
+ max-width: 80%;
+}
+
+#title-controls {
+ float: right;
+}
+
+#panels a {
+ visibility: hidden;
+ width: 18px;
+ height: 20px;
+ overflow: hidden;
+ display: inline-block;
+ color: #ccc;
+ margin-left: 6px;
+}
+
+#panels a::before {
+ visibility: visible;
+}
+
+#panels a:hover {
+ color: #AAA;
+}
+
+#panels a:active {
+ color: #AAA;
+ margin: 1px 0 -1px 6px;
+}
+
+#panels a.active,
+#panels a.active:hover {
+ color: #AAA;
+}
+
+#searchBox {
+ width: 165px;
+ float: left;
+ margin-left: 10px;
+ margin-top: -1px;
+ /*
+ border-radius: 5px;
+ background: #9b9b9b;
+ float: left;
+ margin-left: 5px;
+ margin-top: -5px;
+ padding: 3px 10px;
+ color: #000;
+ border: none;
+ outline: none; */
+
+}
+
+input::-webkit-input-placeholder {
+ color: #454545;
+}
+input:-moz-placeholder {
+ color: #454545;
+}
+
+#divider {
+ position: absolute;
+ width: 1px;
+ border-right: 1px #000 solid;
+ height: 80%;
+ z-index: 1;
+ left: 50%;
+ margin-left: -1px;
+ top: 10%;
+ opacity: .15;
+ box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
+ display: none;
+}
+
+#divider.show {
+ display: block;
+}
+
+#loader {
+ position: absolute;
+ z-index: 10;
+ left: 50%;
+ top: 50%;
+ margin: -33px 0 0 -33px;
+}
+
+#tocView,
+#bookmarksView {
+ overflow-x: hidden;
+ overflow-y: hidden;
+ min-width: 300px;
+ width: 25%;
+ height: 100%;
+ visibility: hidden;
+ -webkit-transition: visibility 0 ease .5s;
+ -moz-transition: visibility 0 ease .5s;
+}
+
+
+
+#sidebar.open #tocView,
+#sidebar.open #bookmarksView {
+ overflow-y: auto;
+ visibility: visible;
+ -webkit-transition: visibility 0 ease 0;
+ -moz-transition: visibility 0 ease 0;
+}
+
+#sidebar.open #tocView {
+ display: block;
+}
+
+#tocView > ul,
+#bookmarksView > ul {
+ margin-top: 15px;
+ margin-bottom: 50px;
+ padding-left: 20px;
+ display: block;
+}
+
+#tocView li,
+#bookmarksView li {
+ margin-bottom:10px;
+ width: 225px;
+ font-family: Georgia, "Times New Roman", Times, serif;
+ list-style: none;
+ text-transform: capitalize;
+}
+
+#tocView li:active,
+#tocView li.currentChapter
+{
+ list-style: none;
+}
+
+.list_item a {
+ color: #AAA;
+ text-decoration: none;
+}
+
+.list_item a.chapter {
+ font-size: 1em;
+}
+
+.list_item a.section {
+ font-size: .8em;
+}
+
+.list_item.currentChapter > a,
+.list_item a:hover {
+ color: #f1f1f1
+}
+
+/* #tocView li.openChapter > a, */
+.list_item a:hover {
+ color: #E2E2E2;
+}
+
+.list_item ul {
+ padding-left:10px;
+ margin-top: 8px;
+ display: none;
+}
+
+.list_item.currentChapter > ul,
+.list_item.openChapter > ul {
+ display: block;
+}
+
+#tocView.hidden {
+ display: none;
+}
+
+.toc_toggle {
+ display: inline-block;
+ width: 14px;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+.toc_toggle:before {
+ content: '▸';
+ color: #fff;
+ margin-right: -4px;
+}
+
+.currentChapter > .toc_toggle:before,
+.openChapter > .toc_toggle:before {
+ content: '▾';
+}
+
+.view {
+ width: 300px;
+ height: 100%;
+ display: none;
+ padding-top: 50px;
+ overflow-y: auto;
+}
+
+#searchResults {
+ margin-bottom: 50px;
+ padding-left: 20px;
+ display: block;
+}
+
+#searchResults li {
+ margin-bottom:10px;
+ width: 225px;
+ font-family: Georgia, "Times New Roman", Times, serif;
+ list-style: none;
+}
+
+#searchResults a {
+ color: #AAA;
+ text-decoration: none;
+}
+
+#searchResults p {
+ text-decoration: none;
+ font-size: 12px;
+ line-height: 16px;
+}
+
+#searchResults p .match {
+ background: #ccc;
+ color: #000;
+}
+
+#searchResults li > p {
+ color: #AAA;
+}
+
+#searchResults li a:hover {
+ color: #E2E2E2;
+}
+
+#searchView.shown {
+ display: block;
+ overflow-y: scroll;
+}
+
+#notes {
+ padding: 0 0 0 34px;
+}
+
+#notes li {
+ color: #eee;
+ font-size: 12px;
+ width: 240px;
+ border-top: 1px #fff solid;
+ padding-top: 6px;
+ margin-bottom: 6px;
+}
+
+#notes li a {
+ color: #fff;
+ display: inline-block;
+ margin-left: 6px;
+}
+
+#notes li a:hover {
+ text-decoration: underline;
+}
+
+#notes li img {
+ max-width: 240px;
+}
+
+#note-text {
+ display: block;
+ width: 260px;
+ height: 80px;
+ margin: 0 auto;
+ padding: 5px;
+ border-radius: 5px;
+}
+
+#note-text[disabled], #note-text[disabled="disabled"]{
+ opacity: .5;
+}
+
+#note-anchor {
+ margin-left: 218px;
+ margin-top: 5px;
+}
+
+#settingsPanel {
+ display:none;
+}
+
+#settingsPanel h3 {
+ color:#f1f1f1;
+ font-family:Georgia, "Times New Roman", Times, serif;
+ margin-bottom:10px;
+}
+
+#settingsPanel ul {
+ margin-top:60px;
+ list-style-type:none;
+}
+
+#settingsPanel li {
+ font-size:1em;
+ color:#f1f1f1;
+}
+
+#settingsPanel .xsmall { font-size:x-small; }
+#settingsPanel .small { font-size:small; }
+#settingsPanel .medium { font-size:medium; }
+#settingsPanel .large { font-size:large; }
+#settingsPanel .xlarge { font-size:x-large; }
+
+.highlight { background-color: yellow }
+
+.modal {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ width: 50%;
+ width: 630px;
+
+ height: auto;
+ z-index: 2000;
+ visibility: hidden;
+ margin-left: -320px;
+ margin-top: -160px;
+
+}
+
+.overlay {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ visibility: hidden;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ opacity: 0;
+ background: rgba(255,255,255,0.8);
+ -webkit-transition: all 0.3s;
+ -moz-transition: all 0.3s;
+ transition: all 0.3s;
+}
+
+.md-show {
+ visibility: visible;
+}
+
+.md-show ~ .overlay {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* Content styles */
+.md-content {
+ color: #fff;
+ background: #6b6b6b;
+ position: relative;
+ border-radius: 3px;
+ margin: 0 auto;
+ height: 320px;
+}
+
+.md-content h3 {
+ margin: 0;
+ padding: 6px;
+ text-align: center;
+ font-size: 22px;
+ font-weight: 300;
+ opacity: 0.8;
+ background: rgba(0,0,0,0.1);
+ border-radius: 3px 3px 0 0;
+}
+
+.md-content > div {
+ padding: 15px 40px 30px;
+ margin: 0;
+ font-weight: 300;
+ font-size: 14px;
+}
+
+.md-content > div p {
+ margin: 0;
+ padding: 10px 0;
+}
+
+.md-content > div ul {
+ margin: 0;
+ padding: 0 0 30px 20px;
+}
+
+.md-content > div ul li {
+ padding: 5px 0;
+}
+
+.md-content button {
+ display: block;
+ margin: 0 auto;
+ font-size: 0.8em;
+}
+
+/* Effect 1: Fade in and scale up */
+.md-effect-1 .md-content {
+ -webkit-transform: scale(0.7);
+ -moz-transform: scale(0.7);
+ -ms-transform: scale(0.7);
+ transform: scale(0.7);
+ opacity: 0;
+ -webkit-transition: all 0.3s;
+ -moz-transition: all 0.3s;
+ transition: all 0.3s;
+}
+
+.md-show.md-effect-1 .md-content {
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ -ms-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+}
+
+.md-content > .closer {
+ font-size: 18px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ font-size: 24px;
+ padding: 4px;
+}
+
+@media only screen and (max-width: 1040px) {
+ #viewer{
+ width: 50%;
+ margin-left: 25%;
+ }
+
+ #divider,
+ #divider.show {
+ display: none;
+ }
+}
+
+@media only screen and (max-width: 900px) {
+ #viewer{
+ width: 60%;
+ margin-left: 20%;
+ }
+
+ #prev {
+ padding-left: 20px;
+ }
+
+ #next {
+ padding-right: 20px;
+ }
+}
+
+@media only screen and (max-width: 550px) {
+ #viewer{
+ width: 80%;
+ margin-left: 10%;
+ }
+
+ #prev {
+ padding-left: 0;
+ }
+
+ #next {
+ padding-right: 0;
+ }
+
+ .arrow div {
+ text-indent: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+
+ #main {
+ -webkit-transform: translate(0, 0);
+ -moz-transform: translate(0, 0);
+ -webkit-transition: -webkit-transform .3s;
+ -moz-transition: -moz-transform .3s;
+ }
+
+ #main.closed {
+ -webkit-transform: translate(260px, 0);
+ -moz-transform: translate(260px, 0);
+ }
+
+ #titlebar {
+ /* font-size: 16px; */
+ /* margin: 0 50px 0 50px; */
+ }
+
+ #metainfo {
+ font-size: 10px;
+ }
+
+ #tocView {
+ width: 260px;
+ }
+
+ #tocView li {
+ font-size: 12px;
+ }
+
+ #tocView > ul{
+ padding-left: 10px;
+ webkit-padding-start:;
+ }
+}
+
+[class^="icon-"]:before, [class*=" icon-"]:before {
+ font-family: "fontello";
+ font-style: normal;
+ font-weight: normal;
+ speak: none;
+
+ display: inline-block;
+ text-decoration: inherit;
+ width: 1em;
+ margin-right: .2em;
+ text-align: center;
+ /* opacity: .8; */
+
+ /* For safety - reset parent styles, that can break glyph codes*/
+ font-variant: normal;
+ text-transform: none;
+
+ /* you can be more comfortable with increased icons size */
+ font-size: 112%;
+}
+
+
+.icon-search:before { content: '\e807'; } /* '' */
+.icon-resize-full-1:before { content: '\e804'; } /* '' */
+.icon-cancel-circled2:before { content: '\e80f'; } /* '' */
+.icon-link:before { content: '\e80d'; } /* '' */
+.icon-bookmark:before { content: '\e805'; } /* '' */
+.icon-bookmark-empty:before { content: '\e806'; } /* '' */
+.icon-download-cloud:before { content: '\e811'; } /* '' */
+.icon-edit:before { content: '\e814'; } /* '' */
+.icon-menu:before { content: '\e802'; } /* '' */
+.icon-cog:before { content: '\e813'; } /* '' */
+.icon-resize-full:before { content: '\e812'; } /* '' */
+.icon-cancel-circled:before { content: '\e80e'; } /* '' */
+.icon-up-dir:before { content: '\e80c'; } /* '' */
+.icon-right-dir:before { content: '\e80b'; } /* '' */
+.icon-angle-right:before { content: '\e809'; } /* '' */
+.icon-angle-down:before { content: '\e80a'; } /* '' */
+.icon-right:before { content: '\e815'; } /* '' */
+.icon-list-1:before { content: '\e803'; } /* '' */
+.icon-list-numbered:before { content: '\e801'; } /* '' */
+.icon-columns:before { content: '\e810'; } /* '' */
+.icon-list:before { content: '\e800'; } /* '' */
+.icon-resize-small:before { content: '\e808'; } /* '' */
diff --git a/files_reader/css/normalize.css b/files_reader/css/normalize.css
new file mode 100644
index 0000000..c3e014d
--- /dev/null
+++ b/files_reader/css/normalize.css
@@ -0,0 +1,505 @@
+/*! normalize.css v1.0.1 | MIT License | git.io/normalize */
+
+/* ==========================================================================
+ HTML5 display definitions
+ ========================================================================== */
+
+/*
+ * Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/*
+ * Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
+ */
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+/*
+ * Prevents modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/*
+ * Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3,
+ * and Safari 4.
+ * Known issue: no IE 6 support.
+ */
+
+[hidden] {
+ display: none;
+}
+
+/* ==========================================================================
+ Base
+ ========================================================================== */
+
+/*
+ * 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using
+ * `em` units.
+ * 2. Prevents iOS text size adjust after orientation change, without disabling
+ * user zoom.
+ */
+
+html {
+ font-size: 100%; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+ -ms-text-size-adjust: 100%; /* 2 */
+}
+
+/*
+ * Addresses `font-family` inconsistency between `textarea` and other form
+ * elements.
+ */
+
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+/*
+ * Addresses margins handled incorrectly in IE 6/7.
+ */
+
+body {
+ margin: 0;
+}
+
+/* ==========================================================================
+ Links
+ ========================================================================== */
+
+/*
+ * Addresses `outline` inconsistency between Chrome and other browsers.
+ */
+
+a:focus {
+ outline: thin dotted;
+}
+
+/*
+ * Improves readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* ==========================================================================
+ Typography
+ ========================================================================== */
+
+/*
+ * Addresses font sizes and margins set differently in IE 6/7.
+ * Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5,
+ * and Chrome.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.75em;
+ margin: 2.33em 0;
+}
+
+/*
+ * Addresses styling not present in IE 7/8/9, Safari 5, and Chrome.
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/*
+ * Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
+ */
+
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+/*
+ * Addresses styling not present in Safari 5 and Chrome.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/*
+ * Addresses styling not present in IE 6/7/8/9.
+ */
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/*
+ * Addresses margins set differently in IE 6/7.
+ */
+
+p,
+pre {
+ margin: 1em 0;
+}
+
+/*
+ * Corrects font family set oddly in IE 6, Safari 4/5, and Chrome.
+ */
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
+}
+
+/*
+ * Improves readability of pre-formatted text in all browsers.
+ */
+
+pre {
+ white-space: pre;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+/*
+ * Addresses CSS quotes not supported in IE 6/7.
+ */
+
+q {
+ quotes: none;
+}
+
+/*
+ * Addresses `quotes` property not supported in Safari 4.
+ */
+
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+/*
+ * Addresses inconsistent and variable font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/*
+ * Prevents `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* ==========================================================================
+ Lists
+ ========================================================================== */
+
+/*
+ * Addresses margins set differently in IE 6/7.
+ */
+
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+/*
+ * Addresses paddings set differently in IE 6/7.
+ */
+
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+
+/*
+ * Corrects list images handled incorrectly in IE 7.
+ */
+
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/* ==========================================================================
+ Embedded content
+ ========================================================================== */
+
+/*
+ * 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3.
+ * 2. Improves image quality when scaled in IE 7.
+ */
+
+img {
+ border: 0; /* 1 */
+ -ms-interpolation-mode: bicubic; /* 2 */
+}
+
+/*
+ * Corrects overflow displayed oddly in IE 9.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* ==========================================================================
+ Figures
+ ========================================================================== */
+
+/*
+ * Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
+ */
+
+figure {
+ margin: 0;
+}
+
+/* ==========================================================================
+ Forms
+ ========================================================================== */
+
+/*
+ * Corrects margin displayed oddly in IE 6/7.
+ */
+
+form {
+ margin: 0;
+}
+
+/*
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/*
+ * 1. Corrects color not being inherited in IE 6/7/8/9.
+ * 2. Corrects text not wrapping in Firefox 3.
+ * 3. Corrects alignment displayed oddly in IE 6/7.
+ */
+
+legend {
+ border: 0; /* 1 */
+ padding: 0;
+ white-space: normal; /* 2 */
+ *margin-left: -7px; /* 3 */
+}
+
+/*
+ * 1. Corrects font size not being inherited in all browsers.
+ * 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5,
+ * and Chrome.
+ * 3. Improves appearance and consistency in all browsers.
+ */
+
+button,
+input,
+select,
+textarea {
+ font-size: 100%; /* 1 */
+ margin: 0; /* 2 */
+ vertical-align: baseline; /* 3 */
+ *vertical-align: middle; /* 3 */
+}
+
+/*
+ * Addresses Firefox 3+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+button,
+input {
+ line-height: normal;
+}
+
+/*
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ * and `video` controls.
+ * 2. Corrects inability to style clickable `input` types in iOS.
+ * 3. Improves usability and consistency of cursor style between image-type
+ * `input` and others.
+ * 4. Removes inner spacing in IE 7 without affecting normal text inputs.
+ * Known issue: inner spacing remains in IE 6.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+ cursor: pointer; /* 3 */
+ *overflow: visible; /* 4 */
+}
+
+/*
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+input[disabled] {
+ cursor: default;
+}
+
+/*
+ * 1. Addresses box sizing set to content-box in IE 8/9.
+ * 2. Removes excess padding in IE 8/9.
+ * 3. Removes excess padding in IE 7.
+ * Known issue: excess padding remains in IE 6.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+ *height: 13px; /* 3 */
+ *width: 13px; /* 3 */
+}
+
+/*
+ * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
+ * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
+ * (include `-moz` to future-proof).
+ */
+/*
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+*/
+
+/*
+ * Removes inner padding and search cancel button in Safari 5 and Chrome
+ * on OS X.
+ */
+
+/* input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+} */
+
+/*
+ * Removes inner padding and border in Firefox 3+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/*
+ * 1. Removes default vertical scrollbar in IE 6/7/8/9.
+ * 2. Improves readability and alignment in all browsers.
+ */
+
+textarea {
+ overflow: auto; /* 1 */
+ vertical-align: top; /* 2 */
+}
+
+/* ==========================================================================
+ Tables
+ ========================================================================== */
+
+/*
+ * Remove most spacing between table cells.
+ */
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/files_reader/css/popup.css b/files_reader/css/popup.css
new file mode 100644
index 0000000..c41aac7
--- /dev/null
+++ b/files_reader/css/popup.css
@@ -0,0 +1,96 @@
+/* http://davidwalsh.name/css-tooltips */
+/* base CSS element */
+.popup {
+ background: #eee;
+ border: 1px solid #ccc;
+ padding: 10px;
+ border-radius: 8px;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+ position: fixed;
+ max-width: 300px;
+ font-size: 12px;
+
+ display: none;
+ margin-left: 2px;
+
+ margin-top: 30px;
+}
+
+.popup.above {
+ margin-top: -10px;
+}
+
+.popup.left {
+ margin-left: -20px;
+}
+
+.popup.right {
+ margin-left: 40px;
+}
+
+.pop_content {
+ max-height: 225px;
+ overflow-y: auto;
+}
+
+.pop_content > p {
+ margin-top: 0;
+}
+
+/* below */
+.popup:before {
+ position: absolute;
+ display: inline-block;
+ border-bottom: 10px solid #eee;
+ border-right: 10px solid transparent;
+ border-left: 10px solid transparent;
+ border-bottom-color: rgba(0, 0, 0, 0.2);
+ left: 50%;
+ top: -10px;
+ margin-left: -6px;
+ content: '';
+}
+
+.popup:after {
+ position: absolute;
+ display: inline-block;
+ border-bottom: 9px solid #eee;
+ border-right: 9px solid transparent;
+ border-left: 9px solid transparent;
+ left: 50%;
+ top: -9px;
+ margin-left: -5px;
+ content: '';
+}
+
+/* above */
+.popup.above:before {
+ border-bottom: none;
+ border-top: 10px solid #eee;
+ border-top-color: rgba(0, 0, 0, 0.2);
+ top: 100%;
+}
+
+.popup.above:after {
+ border-bottom: none;
+ border-top: 9px solid #eee;
+ top: 100%;
+}
+
+.popup.left:before,
+.popup.left:after
+{
+ left: 20px;
+}
+
+.popup.right:before,
+.popup.right:after
+{
+ left: auto;
+ right: 20px;
+}
+
+
+.popup.show, .popup.on {
+ display: block;
+}
\ No newline at end of file
diff --git a/files_reader/css/tooltip.css b/files_reader/css/tooltip.css
new file mode 100644
index 0000000..cd538ab
--- /dev/null
+++ b/files_reader/css/tooltip.css
@@ -0,0 +1,31 @@
+.tooltip {
+ position: relative;
+ top: 0;
+ left: 0;
+}
+
+*.tooltip:hover span {
+ opacity: 1;
+ visibility: visible;
+}
+
+*.tooltip span {
+ z-index: 10;
+ padding: 1em;
+ bottom: 2em;
+ right: -10em;
+ width: 50%;
+ background-color: #222222;
+ color: #FFFFFF;
+ height: auto;
+ border-radius: 0.5em;
+ opacity: 0;
+ position:absolute;
+ visibility: hidden;
+ word-wrap: break-word;
+ -webkit-transition: all 0.5s;
+ -moz-transition: all 0.5s;
+ -ms-transition: all 0.5s;
+ -o-transition: all 0.5s;
+ transition: all 0.5s;
+}
diff --git a/files_reader/img/book.png b/files_reader/img/book.png
new file mode 100644
index 0000000..a7b8079
Binary files /dev/null and b/files_reader/img/book.png differ
diff --git a/files_reader/img/loading.gif b/files_reader/img/loading.gif
new file mode 100644
index 0000000..f8f3dff
Binary files /dev/null and b/files_reader/img/loading.gif differ
diff --git a/files_reader/js/epub.js b/files_reader/js/epub.js
new file mode 100644
index 0000000..2a563ae
--- /dev/null
+++ b/files_reader/js/epub.js
@@ -0,0 +1,7406 @@
+(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.indexi;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);
+(function(global) {
+var define, requireModule, require, requirejs;
+
+(function() {
+ var registry = {}, seen = {};
+
+ define = function(name, deps, callback) {
+ registry[name] = { deps: deps, callback: callback };
+ };
+
+ requirejs = require = requireModule = function(name) {
+ requirejs._eak_seen = registry;
+
+ if (seen[name]) { return seen[name]; }
+ seen[name] = {};
+
+ if (!registry[name]) {
+ throw new Error("Could not find module " + name);
+ }
+
+ var mod = registry[name],
+ deps = mod.deps,
+ callback = mod.callback,
+ reified = [],
+ exports;
+
+ for (var i=0, l=deps.length; i 1;
+ };
+
+ RSVP.filter(promises, filterFn).then(function(result){
+ // result is [ 2, 3 ]
+ });
+ ```
+
+ If any of the `promises` given to `RSVP.filter` are rejected, the first promise
+ that is rejected will be given as an argument to the returned promises's
+ rejection handler. For example:
+
+ ```javascript
+ var promise1 = RSVP.resolve(1);
+ var promise2 = RSVP.reject(new Error("2"));
+ var promise3 = RSVP.reject(new Error("3"));
+ var promises = [ promise1, promise2, promise3 ];
+
+ var filterFn = function(item){
+ return item > 1;
+ };
+
+ RSVP.filter(promises, filterFn).then(function(array){
+ // Code here never runs because there are rejected promises!
+ }, function(reason) {
+ // reason.message === "2"
+ });
+ ```
+
+ `RSVP.filter` will also wait for any promises returned from `filterFn`.
+ For instance, you may want to fetch a list of users then return a subset
+ of those users based on some asynchronous operation:
+
+ ```javascript
+
+ var alice = { name: 'alice' };
+ var bob = { name: 'bob' };
+ var users = [ alice, bob ];
+
+ var promises = users.map(function(user){
+ return RSVP.resolve(user);
+ });
+
+ var filterFn = function(user){
+ // Here, Alice has permissions to create a blog post, but Bob does not.
+ return getPrivilegesForUser(user).then(function(privs){
+ return privs.can_create_blog_post === true;
+ });
+ };
+ RSVP.filter(promises, filterFn).then(function(users){
+ // true, because the server told us only Alice can create a blog post.
+ users.length === 1;
+ // false, because Alice is the only user present in `users`
+ users[0] === bob;
+ });
+ ```
+
+ @method filter
+ @for RSVP
+ @param {Array} promises
+ @param {Function} filterFn - function to be called on each resolved value to
+ filter the final results.
+ @param {String} label optional string describing the promise. Useful for
+ tooling.
+ @return {Promise}
+ */
+ function filter(promises, filterFn, label) {
+ if (!isArray(promises)) {
+ throw new TypeError('You must pass an array to filter.');
+ }
+
+ if (!isFunction(filterFn)){
+ throw new TypeError("You must pass a function to filter's second argument.");
+ }
+
+ return all(promises, label).then(function(values){
+ return map(promises, filterFn, label).then(function(filterResults){
+ var i,
+ valuesLen = values.length,
+ filtered = [];
+
+ for (i = 0; i < valuesLen; i++){
+ if(filterResults[i]) filtered.push(values[i]);
+ }
+ return filtered;
+ });
+ });
+ }
+
+ __exports__["default"] = filter;
+ });
+define("rsvp/hash",
+ ["./promise","./utils","exports"],
+ function(__dependency1__, __dependency2__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+ var isNonThenable = __dependency2__.isNonThenable;
+ var keysOf = __dependency2__.keysOf;
+
+ /**
+ `RSVP.hash` is similar to `RSVP.all`, but takes an object instead of an array
+ for its `promises` argument.
+
+ Returns a promise that is fulfilled when all the given promises have been
+ fulfilled, or rejected if any of them become rejected. The returned promise
+ is fulfilled with a hash that has the same key names as the `promises` object
+ argument. If any of the values in the object are not promises, they will
+ simply be copied over to the fulfilled object.
+
+ Example:
+
+ ```javascript
+ var promises = {
+ myPromise: RSVP.resolve(1),
+ yourPromise: RSVP.resolve(2),
+ theirPromise: RSVP.resolve(3),
+ notAPromise: 4
+ };
+
+ RSVP.hash(promises).then(function(hash){
+ // hash here is an object that looks like:
+ // {
+ // myPromise: 1,
+ // yourPromise: 2,
+ // theirPromise: 3,
+ // notAPromise: 4
+ // }
+ });
+ ````
+
+ If any of the `promises` given to `RSVP.hash` are rejected, the first promise
+ that is rejected will be given as as the first argument, or as the reason to
+ the rejection handler. For example:
+
+ ```javascript
+ var promises = {
+ myPromise: RSVP.resolve(1),
+ rejectedPromise: RSVP.reject(new Error("rejectedPromise")),
+ anotherRejectedPromise: RSVP.reject(new Error("anotherRejectedPromise")),
+ };
+
+ RSVP.hash(promises).then(function(hash){
+ // Code here never runs because there are rejected promises!
+ }, function(reason) {
+ // reason.message === "rejectedPromise"
+ });
+ ```
+
+ An important note: `RSVP.hash` is intended for plain JavaScript objects that
+ are just a set of keys and values. `RSVP.hash` will NOT preserve prototype
+ chains.
+
+ Example:
+
+ ```javascript
+ function MyConstructor(){
+ this.example = RSVP.resolve("Example");
+ }
+
+ MyConstructor.prototype = {
+ protoProperty: RSVP.resolve("Proto Property")
+ };
+
+ var myObject = new MyConstructor();
+
+ RSVP.hash(myObject).then(function(hash){
+ // protoProperty will not be present, instead you will just have an
+ // object that looks like:
+ // {
+ // example: "Example"
+ // }
+ //
+ // hash.hasOwnProperty('protoProperty'); // false
+ // 'undefined' === typeof hash.protoProperty
+ });
+ ```
+
+ @method hash
+ @for RSVP
+ @param {Object} promises
+ @param {String} label - optional string that describes the promise.
+ Useful for tooling.
+ @return {Promise} promise that is fulfilled when all properties of `promises`
+ have been fulfilled, or rejected if any of them become rejected.
+ */
+ __exports__["default"] = function hash(object, label) {
+ return new Promise(function(resolve, reject){
+ var results = {};
+ var keys = keysOf(object);
+ var remaining = keys.length;
+ var entry, property;
+
+ if (remaining === 0) {
+ resolve(results);
+ return;
+ }
+
+ function fulfilledTo(property) {
+ return function(value) {
+ results[property] = value;
+ if (--remaining === 0) {
+ resolve(results);
+ }
+ };
+ }
+
+ function onRejection(reason) {
+ remaining = 0;
+ reject(reason);
+ }
+
+ for (var i = 0; i < keys.length; i++) {
+ property = keys[i];
+ entry = object[property];
+
+ if (isNonThenable(entry)) {
+ results[property] = entry;
+ if (--remaining === 0) {
+ resolve(results);
+ }
+ } else {
+ Promise.cast(entry).then(fulfilledTo(property), onRejection);
+ }
+ }
+ });
+ };
+ });
+define("rsvp/instrument",
+ ["./config","./utils","exports"],
+ function(__dependency1__, __dependency2__, __exports__) {
+ "use strict";
+ var config = __dependency1__.config;
+ var now = __dependency2__.now;
+
+ __exports__["default"] = function instrument(eventName, promise, child) {
+ // instrumentation should not disrupt normal usage.
+ try {
+ config.trigger(eventName, {
+ guid: promise._guidKey + promise._id,
+ eventName: eventName,
+ detail: promise._detail,
+ childGuid: child && promise._guidKey + child._id,
+ label: promise._label,
+ timeStamp: now(),
+ stack: new Error(promise._label).stack
+ });
+ } catch(error) {
+ setTimeout(function(){
+ throw error;
+ }, 0);
+ }
+ };
+ });
+define("rsvp/map",
+ ["./promise","./all","./utils","exports"],
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+ var all = __dependency2__["default"];
+ var isArray = __dependency3__.isArray;
+ var isFunction = __dependency3__.isFunction;
+
+ /**
+
+ `RSVP.map` is similar to JavaScript's native `map` method, except that it
+ waits for all promises to become fulfilled before running the `mapFn` on
+ each item in given to `promises`. `RSVP.map` returns a promise that will
+ become fulfilled with the result of running `mapFn` on the values the promises
+ become fulfilled with.
+
+ For example:
+
+ ```javascript
+
+ var promise1 = RSVP.resolve(1);
+ var promise2 = RSVP.resolve(2);
+ var promise3 = RSVP.resolve(3);
+ var promises = [ promise1, promise2, promise3 ];
+
+ var mapFn = function(item){
+ return item + 1;
+ };
+
+ RSVP.map(promises, mapFn).then(function(result){
+ // result is [ 2, 3, 4 ]
+ });
+ ```
+
+ If any of the `promises` given to `RSVP.map` are rejected, the first promise
+ that is rejected will be given as an argument to the returned promises's
+ rejection handler. For example:
+
+ ```javascript
+ var promise1 = RSVP.resolve(1);
+ var promise2 = RSVP.reject(new Error("2"));
+ var promise3 = RSVP.reject(new Error("3"));
+ var promises = [ promise1, promise2, promise3 ];
+
+ var mapFn = function(item){
+ return item + 1;
+ };
+
+ RSVP.map(promises, mapFn).then(function(array){
+ // Code here never runs because there are rejected promises!
+ }, function(reason) {
+ // reason.message === "2"
+ });
+ ```
+
+ `RSVP.map` will also wait if a promise is returned from `mapFn`. For example,
+ say you want to get all comments from a set of blog posts, but you need
+ the blog posts first becuase they contain a url to those comments.
+
+ ```javscript
+
+ var mapFn = function(blogPost){
+ // getComments does some ajax and returns an RSVP.Promise that is fulfilled
+ // with some comments data
+ return getComments(blogPost.comments_url);
+ };
+
+ // getBlogPosts does some ajax and returns an RSVP.Promise that is fulfilled
+ // with some blog post data
+ RSVP.map(getBlogPosts(), mapFn).then(function(comments){
+ // comments is the result of asking the server for the comments
+ // of all blog posts returned from getBlogPosts()
+ });
+ ```
+
+ @method map
+ @for RSVP
+ @param {Array} promises
+ @param {Function} mapFn function to be called on each fulfilled promise.
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise} promise that is fulfilled with the result of calling
+ `mapFn` on each fulfilled promise or value when they become fulfilled.
+ The promise will be rejected if any of the given `promises` become rejected.
+ */
+ __exports__["default"] = function map(promises, mapFn, label) {
+
+ if (!isArray(promises)) {
+ throw new TypeError('You must pass an array to map.');
+ }
+
+ if (!isFunction(mapFn)){
+ throw new TypeError("You must pass a function to map's second argument.");
+ }
+
+ return all(promises, label).then(function(results){
+ var resultLen = results.length,
+ mappedResults = [],
+ i;
+
+ for (i = 0; i < resultLen; i++){
+ mappedResults.push(mapFn(results[i]));
+ }
+
+ return all(mappedResults, label);
+ });
+ };
+ });
+define("rsvp/node",
+ ["./promise","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+
+ var slice = Array.prototype.slice;
+
+ function makeNodeCallbackFor(resolve, reject) {
+ return function (error, value) {
+ if (error) {
+ reject(error);
+ } else if (arguments.length > 2) {
+ resolve(slice.call(arguments, 1));
+ } else {
+ resolve(value);
+ }
+ };
+ }
+
+ /**
+ `RSVP.denodeify` takes a "node-style" function and returns a function that
+ will return an `RSVP.Promise`. You can use `denodeify` in Node.js or the
+ browser when you'd prefer to use promises over using callbacks. For example,
+ `denodeify` transforms the following:
+
+ ```javascript
+ var fs = require('fs');
+
+ fs.readFile('myfile.txt', function(err, data){
+ if (err) return handleError(err);
+ handleData(data);
+ });
+ ```
+
+ into:
+
+ ```javascript
+ var fs = require('fs');
+
+ var readFile = RSVP.denodeify(fs.readFile);
+
+ readFile('myfile.txt').then(handleData, handleError);
+ ```
+
+ Using `denodeify` makes it easier to compose asynchronous operations instead
+ of using callbacks. For example, instead of:
+
+ ```javascript
+ var fs = require('fs');
+ var log = require('some-async-logger');
+
+ fs.readFile('myfile.txt', function(err, data){
+ if (err) return handleError(err);
+ fs.writeFile('myfile2.txt', data, function(err){
+ if (err) throw err;
+ log('success', function(err) {
+ if (err) throw err;
+ });
+ });
+ });
+ ```
+
+ You can chain the operations together using `then` from the returned promise:
+
+ ```javascript
+ var fs = require('fs');
+ var denodeify = RSVP.denodeify;
+ var readFile = denodeify(fs.readFile);
+ var writeFile = denodeify(fs.writeFile);
+ var log = denodeify(require('some-async-logger'));
+
+ readFile('myfile.txt').then(function(data){
+ return writeFile('myfile2.txt', data);
+ }).then(function(){
+ return log('SUCCESS');
+ }).then(function(){
+ // success handler
+ }, function(reason){
+ // rejection handler
+ });
+ ```
+
+ @method denodeify
+ @for RSVP
+ @param {Function} nodeFunc a "node-style" function that takes a callback as
+ its last argument. The callback expects an error to be passed as its first
+ argument (if an error occurred, otherwise null), and the value from the
+ operation as its second argument ("function(err, value){ }").
+ @param {Any} binding optional argument for binding the "this" value when
+ calling the `nodeFunc` function.
+ @return {Function} a function that wraps `nodeFunc` to return an
+ `RSVP.Promise`
+ */
+ __exports__["default"] = function denodeify(nodeFunc, binding) {
+ return function() {
+ var nodeArgs = slice.call(arguments), resolve, reject;
+ var thisArg = this || binding;
+
+ return new Promise(function(resolve, reject) {
+ Promise.all(nodeArgs).then(function(nodeArgs) {
+ try {
+ nodeArgs.push(makeNodeCallbackFor(resolve, reject));
+ nodeFunc.apply(thisArg, nodeArgs);
+ } catch(e) {
+ reject(e);
+ }
+ });
+ });
+ };
+ };
+ });
+define("rsvp/promise",
+ ["./config","./events","./instrument","./utils","./promise/cast","./promise/all","./promise/race","./promise/resolve","./promise/reject","exports"],
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
+ "use strict";
+ var config = __dependency1__.config;
+ var EventTarget = __dependency2__["default"];
+ var instrument = __dependency3__["default"];
+ var objectOrFunction = __dependency4__.objectOrFunction;
+ var isFunction = __dependency4__.isFunction;
+ var now = __dependency4__.now;
+ var cast = __dependency5__["default"];
+ var all = __dependency6__["default"];
+ var race = __dependency7__["default"];
+ var Resolve = __dependency8__["default"];
+ var Reject = __dependency9__["default"];
+
+ var guidKey = 'rsvp_' + now() + '-';
+ var counter = 0;
+
+ function noop() {}
+
+ __exports__["default"] = Promise;
+
+
+ /**
+
+ Promise objects represent the eventual result of an asynchronous operation. The
+ primary way of interacting with a promise is through its `then` method, which
+ registers callbacks to receive either a promise’s eventual value or the reason
+ why the promise cannot be fulfilled.
+
+ Terminology
+ -----------
+
+ - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
+ - `thenable` is an object or function that defines a `then` method.
+ - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
+ - `exception` is a value that is thrown using the throw statement.
+ - `reason` is a value that indicates why a promise was rejected.
+ - `settled` the final resting state of a promise, fulfilled or rejected.
+
+ A promise can be in one of three states: pending, fulfilled, or rejected.
+
+
+ Basic Usage:
+ ------------
+
+ ```js
+ var promise = new Promise(function(resolve, reject) {
+ // on success
+ resolve(value);
+
+ // on failure
+ reject(reason);
+ });
+
+ promise.then(function(value) {
+ // on fulfillment
+ }, function(reason) {
+ // on rejection
+ });
+ ```
+
+ Advanced Usage:
+ ---------------
+
+ Promises shine when abstracting away asynchronous interactions such as
+ `XMLHttpRequest`s.
+
+ ```js
+ function getJSON(url) {
+ return new Promise(function(resolve, reject){
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', url);
+ xhr.onreadystatechange = handler;
+ xhr.responseType = 'json';
+ xhr.setRequestHeader('Accept', 'application/json');
+ xhr.send();
+
+ function handler() {
+ if (this.readyState === this.DONE) {
+ if (this.status === 200) {
+ resolve(this.response);
+ } else {
+ reject(new Error("getJSON: `" + url + "` failed with status: [" + this.status + "]");
+ }
+ }
+ };
+ });
+ }
+
+ getJSON('/posts.json').then(function(json) {
+ // on fulfillment
+ }, function(reason) {
+ // on rejection
+ });
+ ```
+
+ Unlike callbacks, promises are great composable primitives.
+
+ ```js
+ Promise.all([
+ getJSON('/posts'),
+ getJSON('/comments')
+ ]).then(function(values){
+ values[0] // => postsJSON
+ values[1] // => commentsJSON
+
+ return values;
+ });
+ ```
+
+ @class Promise
+ @param {function}
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @constructor
+ */
+ function Promise(resolver, label) {
+ if (!isFunction(resolver)) {
+ throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
+ }
+
+ if (!(this instanceof Promise)) {
+ throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
+ }
+
+ this._id = counter++;
+ this._label = label;
+ this._subscribers = [];
+
+ if (config.instrument) {
+ instrument('created', this);
+ }
+
+ if (noop !== resolver) {
+ invokeResolver(resolver, this);
+ }
+ }
+
+ function invokeResolver(resolver, promise) {
+ function resolvePromise(value) {
+ resolve(promise, value);
+ }
+
+ function rejectPromise(reason) {
+ reject(promise, reason);
+ }
+
+ try {
+ resolver(resolvePromise, rejectPromise);
+ } catch(e) {
+ rejectPromise(e);
+ }
+ }
+
+ Promise.cast = cast;
+ Promise.all = all;
+ Promise.race = race;
+ Promise.resolve = Resolve;
+ Promise.reject = Reject;
+
+ var PENDING = void 0;
+ var SEALED = 0;
+ var FULFILLED = 1;
+ var REJECTED = 2;
+
+ function subscribe(parent, child, onFulfillment, onRejection) {
+ var subscribers = parent._subscribers;
+ var length = subscribers.length;
+
+ subscribers[length] = child;
+ subscribers[length + FULFILLED] = onFulfillment;
+ subscribers[length + REJECTED] = onRejection;
+ }
+
+ function publish(promise, settled) {
+ var child, callback, subscribers = promise._subscribers, detail = promise._detail;
+
+ if (config.instrument) {
+ instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
+ }
+
+ for (var i = 0; i < subscribers.length; i += 3) {
+ child = subscribers[i];
+ callback = subscribers[i + settled];
+
+ invokeCallback(settled, child, callback, detail);
+ }
+
+ promise._subscribers = null;
+ }
+
+ Promise.prototype = {
+ /**
+ @property constructor
+ */
+ constructor: Promise,
+
+ _id: undefined,
+ _guidKey: guidKey,
+ _label: undefined,
+
+ _state: undefined,
+ _detail: undefined,
+ _subscribers: undefined,
+
+ _onerror: function (reason) {
+ config.trigger('error', reason);
+ },
+
+ /**
+
+ A promise represents the eventual result of an asynchronous operation. The
+ primary way of interacting with a promise is through its `then` method, which
+ registers callbacks to receive either a promise's eventual value or the reason
+ why the promise cannot be fulfilled.
+
+ ```js
+ findUser().then(function(user){
+ // user is available
+ }, function(reason){
+ // user is unavailable, and you are given the reason why
+ });
+ ```
+
+ Chaining
+ --------
+
+ The return value of `then` is itself a promise. This second, "downstream"
+ promise is resolved with the return value of the first promise's fulfillment
+ or rejection handler, or rejected if the handler throws an exception.
+
+ ```js
+ findUser().then(function (user) {
+ return user.name;
+ }, function (reason) {
+ return "default name";
+ }).then(function (userName) {
+ // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
+ // will be `"default name"`
+ });
+
+ findUser().then(function (user) {
+ throw "Found user, but still unhappy";
+ }, function (reason) {
+ throw "`findUser` rejected and we're unhappy";
+ }).then(function (value) {
+ // never reached
+ }, function (reason) {
+ // if `findUser` fulfilled, `reason` will be "Found user, but still unhappy".
+ // If `findUser` rejected, `reason` will be "`findUser` rejected and we're unhappy".
+ });
+ ```
+ If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
+
+ ```js
+ findUser().then(function (user) {
+ throw new PedagogicalException("Upstream error");
+ }).then(function (value) {
+ // never reached
+ }).then(function (value) {
+ // never reached
+ }, function (reason) {
+ // The `PedgagocialException` is propagated all the way down to here
+ });
+ ```
+
+ Assimilation
+ ------------
+
+ Sometimes the value you want to propagate to a downstream promise can only be
+ retrieved asynchronously. This can be achieved by returning a promise in the
+ fulfillment or rejection handler. The downstream promise will then be pending
+ until the returned promise is settled. This is called *assimilation*.
+
+ ```js
+ findUser().then(function (user) {
+ return findCommentsByAuthor(user);
+ }).then(function (comments) {
+ // The user's comments are now available
+ });
+ ```
+
+ If the assimliated promise rejects, then the downstream promise will also reject.
+
+ ```js
+ findUser().then(function (user) {
+ return findCommentsByAuthor(user);
+ }).then(function (comments) {
+ // If `findCommentsByAuthor` fulfills, we'll have the value here
+ }, function (reason) {
+ // If `findCommentsByAuthor` rejects, we'll have the reason here
+ });
+ ```
+
+ Simple Example
+ --------------
+
+ Synchronous Example
+
+ ```javascript
+ var result;
+
+ try {
+ result = findResult();
+ // success
+ } catch(reason) {
+ // failure
+ }
+ ```
+
+ Errback Example
+
+ ```js
+ findResult(function(result, err){
+ if (err) {
+ // failure
+ } else {
+ // success
+ }
+ });
+ ```
+
+ Promise Example;
+
+ ```javacsript
+ findResult().then(function(result){
+
+ }, function(reason){
+
+ });
+ ```
+
+ Advanced Example
+ --------------
+
+ Synchronous Example
+
+ ```javascript
+ var author, books;
+
+ try {
+ author = findAuthor();
+ books = findBooksByAuthor(author);
+ // success
+ } catch(reason) {
+ // failure
+ }
+ ```
+
+ Errback Example
+
+ ```js
+
+ function foundBooks(books) {
+
+ }
+
+ function failure(reason) {
+
+ }
+
+ findAuthor(function(author, err){
+ if (err) {
+ failure(err);
+ // failure
+ } else {
+ try {
+ findBoooksByAuthor(author, function(books, err) {
+ if (err) {
+ failure(err);
+ } else {
+ try {
+ foundBooks(books);
+ } catch(reason) {
+ failure(reason);
+ }
+ }
+ });
+ } catch(error) {
+ failure(err);
+ }
+ // success
+ }
+ });
+ ```
+
+ Promise Example;
+
+ ```javacsript
+ findAuthor().
+ then(findBooksByAuthor).
+ then(function(books){
+ // found books
+ }).catch(function(reason){
+ // something went wrong;
+ });
+ ```
+
+ @method then
+ @param {Function} onFulfillment
+ @param {Function} onRejection
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise}
+ */
+ then: function(onFulfillment, onRejection, label) {
+ var promise = this;
+ this._onerror = null;
+
+ var thenPromise = new this.constructor(noop, label);
+
+ if (this._state) {
+ var callbacks = arguments;
+ config.async(function invokePromiseCallback() {
+ invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
+ });
+ } else {
+ subscribe(this, thenPromise, onFulfillment, onRejection);
+ }
+
+ if (config.instrument) {
+ instrument('chained', promise, thenPromise);
+ }
+
+ return thenPromise;
+ },
+
+ /**
+ `catch` is simply sugar for `then(null, onRejection)` which makes it the same
+ as the catch block, of a try/catch statement.
+
+ ```js
+ function findAuthor(){
+ throw new Error("couldn't find that author");
+ }
+
+ // synchronous
+ try {
+ findAuthor();
+ } catch(reason) {
+
+ }
+
+ // async with promises
+ findAuthor().catch(function(reason){
+ // something went wrong;
+ });
+ ```
+
+ @method catch
+ @param {Function} onRejection
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise}
+ */
+ 'catch': function(onRejection, label) {
+ return this.then(null, onRejection, label);
+ },
+
+ /**
+ `finally` will be invoked regardless of the promise's fate just as native
+ try/catch/finally behaves
+
+ ```js
+ findAuthor() {
+ if (Math.random() > 0.5) {
+ throw new Error();
+ }
+ return new Author();
+ }
+
+ try {
+ return findAuthor(); // succeed or fail
+ } catch(error) {
+ return findOtherAuther();
+ } finally {
+ // always runs
+ // doesn't effect the return value
+ }
+
+ findAuthor().finally(function(){
+ // author was either found, or not
+ });
+ ```
+
+ @method finally
+ @param {Function} callback
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise}
+ */
+ 'finally': function(callback, label) {
+ var constructor = this.constructor;
+
+ return this.then(function(value) {
+ return constructor.cast(callback()).then(function(){
+ return value;
+ });
+ }, function(reason) {
+ return constructor.cast(callback()).then(function(){
+ throw reason;
+ });
+ }, label);
+ }
+ };
+
+ function invokeCallback(settled, promise, callback, detail) {
+ var hasCallback = isFunction(callback),
+ value, error, succeeded, failed;
+
+ if (hasCallback) {
+ try {
+ value = callback(detail);
+ succeeded = true;
+ } catch(e) {
+ failed = true;
+ error = e;
+ }
+ } else {
+ value = detail;
+ succeeded = true;
+ }
+
+ if (handleThenable(promise, value)) {
+ return;
+ } else if (hasCallback && succeeded) {
+ resolve(promise, value);
+ } else if (failed) {
+ reject(promise, error);
+ } else if (settled === FULFILLED) {
+ resolve(promise, value);
+ } else if (settled === REJECTED) {
+ reject(promise, value);
+ }
+ }
+
+ function handleThenable(promise, value) {
+ var then = null,
+ resolved;
+
+ try {
+ if (promise === value) {
+ throw new TypeError("A promises callback cannot return that same promise.");
+ }
+
+ if (objectOrFunction(value)) {
+ then = value.then;
+
+ if (isFunction(then)) {
+ then.call(value, function(val) {
+ if (resolved) { return true; }
+ resolved = true;
+
+ if (value !== val) {
+ resolve(promise, val);
+ } else {
+ fulfill(promise, val);
+ }
+ }, function(val) {
+ if (resolved) { return true; }
+ resolved = true;
+
+ reject(promise, val);
+ }, 'derived from: ' + (promise._label || ' unknown promise'));
+
+ return true;
+ }
+ }
+ } catch (error) {
+ if (resolved) { return true; }
+ reject(promise, error);
+ return true;
+ }
+
+ return false;
+ }
+
+ function resolve(promise, value) {
+ if (promise === value) {
+ fulfill(promise, value);
+ } else if (!handleThenable(promise, value)) {
+ fulfill(promise, value);
+ }
+ }
+
+ function fulfill(promise, value) {
+ if (promise._state !== PENDING) { return; }
+ promise._state = SEALED;
+ promise._detail = value;
+
+ config.async(publishFulfillment, promise);
+ }
+
+ function reject(promise, reason) {
+ if (promise._state !== PENDING) { return; }
+ promise._state = SEALED;
+ promise._detail = reason;
+
+ config.async(publishRejection, promise);
+ }
+
+ function publishFulfillment(promise) {
+ publish(promise, promise._state = FULFILLED);
+ }
+
+ function publishRejection(promise) {
+ if (promise._onerror) {
+ promise._onerror(promise._detail);
+ }
+
+ publish(promise, promise._state = REJECTED);
+ }
+ });
+define("rsvp/promise/all",
+ ["../utils","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ var isArray = __dependency1__.isArray;
+ var isNonThenable = __dependency1__.isNonThenable;
+
+ /**
+
+ `RSVP.Promise.all` returns a new promise which is fulfilled with an array of
+ fulfillment values for the passed promises, or rejects with the reason of the
+ first passed promise that rejects. It casts all elements of the passed iterable
+ to promises as it runs this algorithm.
+
+ Example:
+
+ ```javascript
+ var promise1 = RSVP.resolve(1);
+ var promise2 = RSVP.resolve(2);
+ var promise3 = RSVP.resolve(3);
+ var promises = [ promise1, promise2, promise3 ];
+
+ RSVP.Promise.all(promises).then(function(array){
+ // The array here would be [ 1, 2, 3 ];
+ });
+ ```
+
+ If any of the `promises` given to `RSVP.all` are rejected, the first promise
+ that is rejected will be given as an argument to the returned promises's
+ rejection handler. For example:
+
+ Example:
+
+ ```javascript
+ var promise1 = RSVP.resolve(1);
+ var promise2 = RSVP.reject(new Error("2"));
+ var promise3 = RSVP.reject(new Error("3"));
+ var promises = [ promise1, promise2, promise3 ];
+
+ RSVP.Promise.all(promises).then(function(array){
+ // Code here never runs because there are rejected promises!
+ }, function(error) {
+ // error.message === "2"
+ });
+ ```
+
+ @method all
+ @for RSVP.Promise
+ @param {Array} promises
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise} promise that is fulfilled when all `promises` have been
+ fulfilled, or rejected if any of them become rejected.
+ */
+ __exports__["default"] = function all(entries, label) {
+
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ return new Constructor(function(resolve, reject) {
+ if (!isArray(entries)) {
+ throw new TypeError('You must pass an array to all.');
+ }
+
+ var remaining = entries.length;
+ var results = new Array(remaining);
+ var entry, pending = true;
+
+ if (remaining === 0) {
+ resolve(results);
+ return;
+ }
+
+ function fulfillmentAt(index) {
+ return function(value) {
+ results[index] = value;
+ if (--remaining === 0) {
+ resolve(results);
+ }
+ };
+ }
+
+ function onRejection(reason) {
+ remaining = 0;
+ reject(reason);
+ }
+
+ for (var index = 0; index < entries.length; index++) {
+ entry = entries[index];
+ if (isNonThenable(entry)) {
+ results[index] = entry;
+ if (--remaining === 0) {
+ resolve(results);
+ }
+ } else {
+ Constructor.cast(entry).then(fulfillmentAt(index), onRejection);
+ }
+ }
+ }, label);
+ };
+ });
+define("rsvp/promise/cast",
+ ["exports"],
+ function(__exports__) {
+ "use strict";
+ /**
+
+ `RSVP.Promise.cast` cast coerces its argument to a promise, or returns the
+ argument if it is already a promise which shares a constructor with the caster;
+
+ Example:
+
+ ```javascript
+ var promise = RSVP.Promise.resolve(1);
+ var casted = RSVP.Promise.cast(promise);
+
+ console.log(promise === casted); // true
+ ```
+
+ In the case of a promise whose constructor does not match, it is assimilated.
+ The resulting promise will fulfill or reject based on the outcome of the
+ promise being casted.
+
+ In the case of a non-promise, a promise which will fulfill with that value is
+ returned.
+
+ Example:
+
+ ```javascript
+ var value = 1; // could be a number, boolean, string, undefined...
+ var casted = RSVP.Promise.cast(value);
+
+ console.log(value === casted); // false
+ console.log(casted instanceof RSVP.Promise) // true
+
+ casted.then(function(val) {
+ val === value // => true
+ });
+ ```
+
+ `RSVP.Promise.cast` is similar to `RSVP.Promise.resolve`, but `RSVP.Promise.cast` differs in the
+ following ways:
+
+ * `RSVP.Promise.cast` serves as a memory-efficient way of getting a promise, when you
+ have something that could either be a promise or a value. RSVP.resolve
+ will have the same effect but will create a new promise wrapper if the
+ argument is a promise.
+ * `RSVP.Promise.cast` is a way of casting incoming thenables or promise subclasses to
+ promises of the exact class specified, so that the resulting object's `then` is
+ ensured to have the behavior of the constructor you are calling cast on (i.e., RSVP.Promise).
+
+ @method cast
+ @for RSVP.Promise
+ @param {Object} object to be casted
+ @param {String} label optional string for labeling the promise.
+ Useful for tooling.
+ @return {Promise} promise
+ */
+
+ __exports__["default"] = function cast(object, label) {
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ if (object && typeof object === 'object' && object.constructor === Constructor) {
+ return object;
+ }
+
+ return new Constructor(function(resolve) {
+ resolve(object);
+ }, label);
+ };
+ });
+define("rsvp/promise/race",
+ ["../utils","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ /* global toString */
+
+ var isArray = __dependency1__.isArray;
+ var isFunction = __dependency1__.isFunction;
+ var isNonThenable = __dependency1__.isNonThenable;
+
+ /**
+ `RSVP.Promise.race` returns a new promise which is settled in the same way as the
+ first passed promise to settle.
+
+ Example:
+
+ ```javascript
+ var promise1 = new RSVP.Promise(function(resolve, reject){
+ setTimeout(function(){
+ resolve("promise 1");
+ }, 200);
+ });
+
+ var promise2 = new RSVP.Promise(function(resolve, reject){
+ setTimeout(function(){
+ resolve("promise 2");
+ }, 100);
+ });
+
+ RSVP.Promise.race([promise1, promise2]).then(function(result){
+ // result === "promise 2" because it was resolved before promise1
+ // was resolved.
+ });
+ ```
+
+ `RSVP.Promise.race` is deterministic in that only the state of the first
+ completed promise matters. For example, even if other promises given to the
+ `promises` array argument are resolved, but the first completed promise has
+ become rejected before the other promises became fulfilled, the returned
+ promise will become rejected:
+
+ ```javascript
+ var promise1 = new RSVP.Promise(function(resolve, reject){
+ setTimeout(function(){
+ resolve("promise 1");
+ }, 200);
+ });
+
+ var promise2 = new RSVP.Promise(function(resolve, reject){
+ setTimeout(function(){
+ reject(new Error("promise 2"));
+ }, 100);
+ });
+
+ RSVP.Promise.race([promise1, promise2]).then(function(result){
+ // Code here never runs because there are rejected promises!
+ }, function(reason){
+ // reason.message === "promise2" because promise 2 became rejected before
+ // promise 1 became fulfilled
+ });
+ ```
+
+ @method race
+ @for RSVP.Promise
+ @param {Array} promises array of promises to observe
+ @param {String} label optional string for describing the promise returned.
+ Useful for tooling.
+ @return {Promise} a promise which settles in the same way as the first passed
+ promise to settle.
+ */
+ __exports__["default"] = function race(entries, label) {
+ /*jshint validthis:true */
+ var Constructor = this, entry;
+
+ return new Constructor(function(resolve, reject) {
+ if (!isArray(entries)) {
+ throw new TypeError('You must pass an array to race.');
+ }
+
+ var pending = true;
+
+ function onFulfillment(value) { if (pending) { pending = false; resolve(value); } }
+ function onRejection(reason) { if (pending) { pending = false; reject(reason); } }
+
+ for (var i = 0; i < entries.length; i++) {
+ entry = entries[i];
+ if (isNonThenable(entry)) {
+ pending = false;
+ resolve(entry);
+ return;
+ } else {
+ Constructor.cast(entry).then(onFulfillment, onRejection);
+ }
+ }
+ }, label);
+ };
+ });
+define("rsvp/promise/reject",
+ ["exports"],
+ function(__exports__) {
+ "use strict";
+ /**
+ `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
+ It is essentially shorthand for the following:
+
+ ```javascript
+ var promise = new RSVP.Promise(function(resolve, reject){
+ reject(new Error('WHOOPS'));
+ });
+
+ promise.then(function(value){
+ // Code here doesn't run because the promise is rejected!
+ }, function(reason){
+ // reason.message === 'WHOOPS'
+ });
+ ```
+
+ Instead of writing the above, your code now simply becomes the following:
+
+ ```javascript
+ var promise = RSVP.Promise.reject(new Error('WHOOPS'));
+
+ promise.then(function(value){
+ // Code here doesn't run because the promise is rejected!
+ }, function(reason){
+ // reason.message === 'WHOOPS'
+ });
+ ```
+
+ @method reject
+ @for RSVP.Promise
+ @param {Any} reason value that the returned promise will be rejected with.
+ @param {String} label optional string for identifying the returned promise.
+ Useful for tooling.
+ @return {Promise} a promise rejected with the given `reason`.
+ */
+ __exports__["default"] = function reject(reason, label) {
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ return new Constructor(function (resolve, reject) {
+ reject(reason);
+ }, label);
+ };
+ });
+define("rsvp/promise/resolve",
+ ["exports"],
+ function(__exports__) {
+ "use strict";
+ /**
+ `RSVP.Promise.resolve` returns a promise that will become fulfilled with the passed
+ `value`. It is essentially shorthand for the following:
+
+ ```javascript
+ var promise = new RSVP.Promise(function(resolve, reject){
+ resolve(1);
+ });
+
+ promise.then(function(value){
+ // value === 1
+ });
+ ```
+
+ Instead of writing the above, your code now simply becomes the following:
+
+ ```javascript
+ var promise = RSVP.Promise.resolve(1);
+
+ promise.then(function(value){
+ // value === 1
+ });
+ ```
+
+ @method resolve
+ @for RSVP.Promise
+ @param {Any} value value that the returned promise will be resolved with
+ @param {String} label optional string for identifying the returned promise.
+ Useful for tooling.
+ @return {Promise} a promise that will become fulfilled with the given
+ `value`
+ */
+ __exports__["default"] = function resolve(value, label) {
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ return new Constructor(function(resolve, reject) {
+ resolve(value);
+ }, label);
+ };
+ });
+define("rsvp/race",
+ ["./promise","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+
+ __exports__["default"] = function race(array, label) {
+ return Promise.race(array, label);
+ };
+ });
+define("rsvp/reject",
+ ["./promise","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+
+ __exports__["default"] = function reject(reason, label) {
+ return Promise.reject(reason, label);
+ };
+ });
+define("rsvp/resolve",
+ ["./promise","exports"],
+ function(__dependency1__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+
+ __exports__["default"] = function resolve(value, label) {
+ return Promise.resolve(value, label);
+ };
+ });
+define("rsvp/rethrow",
+ ["exports"],
+ function(__exports__) {
+ "use strict";
+ /**
+ `RSVP.rethrow` will rethrow an error on the next turn of the JavaScript event
+ loop in order to aid debugging.
+
+ Promises A+ specifies that any exceptions that occur with a promise must be
+ caught by the promises implementation and bubbled to the last handler. For
+ this reason, it is recommended that you always specify a second rejection
+ handler function to `then`. However, `RSVP.rethrow` will throw the exception
+ outside of the promise, so it bubbles up to your console if in the browser,
+ or domain/cause uncaught exception in Node. `rethrow` will throw the error
+ again so the error can be handled by the promise.
+
+ ```javascript
+ function throws(){
+ throw new Error('Whoops!');
+ }
+
+ var promise = new RSVP.Promise(function(resolve, reject){
+ throws();
+ });
+
+ promise.catch(RSVP.rethrow).then(function(){
+ // Code here doesn't run because the promise became rejected due to an
+ // error!
+ }, function (err){
+ // handle the error here
+ });
+ ```
+
+ The 'Whoops' error will be thrown on the next turn of the event loop
+ and you can watch for it in your console. You can also handle it using a
+ rejection handler given to `.then` or `.catch` on the returned promise.
+
+ @method rethrow
+ @for RSVP
+ @param {Error} reason reason the promise became rejected.
+ @throws Error
+ */
+ __exports__["default"] = function rethrow(reason) {
+ setTimeout(function() {
+ throw reason;
+ });
+ throw reason;
+ };
+ });
+define("rsvp/utils",
+ ["exports"],
+ function(__exports__) {
+ "use strict";
+ function objectOrFunction(x) {
+ return typeof x === "function" || (typeof x === "object" && x !== null);
+ }
+
+ __exports__.objectOrFunction = objectOrFunction;function isFunction(x) {
+ return typeof x === "function";
+ }
+
+ __exports__.isFunction = isFunction;function isNonThenable(x) {
+ return !objectOrFunction(x);
+ }
+
+ __exports__.isNonThenable = isNonThenable;function isArray(x) {
+ return Object.prototype.toString.call(x) === "[object Array]";
+ }
+
+ __exports__.isArray = isArray;// Date.now is not available in browsers < IE9
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
+ var now = Date.now || function() { return new Date().getTime(); };
+ __exports__.now = now;
+ var keysOf = Object.keys || function(object) {
+ var result = [];
+
+ for (var prop in object) {
+ result.push(prop);
+ }
+
+ return result;
+ };
+ __exports__.keysOf = keysOf;
+ });
+define("rsvp",
+ ["./rsvp/promise","./rsvp/events","./rsvp/node","./rsvp/all","./rsvp/all_settled","./rsvp/race","./rsvp/hash","./rsvp/rethrow","./rsvp/defer","./rsvp/config","./rsvp/map","./rsvp/resolve","./rsvp/reject","./rsvp/asap","./rsvp/filter","exports"],
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) {
+ "use strict";
+ var Promise = __dependency1__["default"];
+ var EventTarget = __dependency2__["default"];
+ var denodeify = __dependency3__["default"];
+ var all = __dependency4__["default"];
+ var allSettled = __dependency5__["default"];
+ var race = __dependency6__["default"];
+ var hash = __dependency7__["default"];
+ var rethrow = __dependency8__["default"];
+ var defer = __dependency9__["default"];
+ var config = __dependency10__.config;
+ var configure = __dependency10__.configure;
+ var map = __dependency11__["default"];
+ var resolve = __dependency12__["default"];
+ var reject = __dependency13__["default"];
+ var asap = __dependency14__["default"];
+ var filter = __dependency15__["default"];
+
+ config.async = asap; // default async is asap;
+
+ function async(callback, arg) {
+ config.async(callback, arg);
+ }
+
+ function on() {
+ config.on.apply(config, arguments);
+ }
+
+ function off() {
+ config.off.apply(config, arguments);
+ }
+
+ // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
+ if (typeof window !== 'undefined' && typeof window.__PROMISE_INSTRUMENTATION__ === 'object') {
+ var callbacks = window.__PROMISE_INSTRUMENTATION__;
+ configure('instrument', true);
+ for (var eventName in callbacks) {
+ if (callbacks.hasOwnProperty(eventName)) {
+ on(eventName, callbacks[eventName]);
+ }
+ }
+ }
+
+ __exports__.Promise = Promise;
+ __exports__.EventTarget = EventTarget;
+ __exports__.all = all;
+ __exports__.allSettled = allSettled;
+ __exports__.race = race;
+ __exports__.hash = hash;
+ __exports__.rethrow = rethrow;
+ __exports__.defer = defer;
+ __exports__.denodeify = denodeify;
+ __exports__.configure = configure;
+ __exports__.on = on;
+ __exports__.off = off;
+ __exports__.resolve = resolve;
+ __exports__.reject = reject;
+ __exports__.async = async;
+ __exports__.map = map;
+ __exports__.filter = filter;
+ });
+global.RSVP = requireModule('rsvp');
+}(window));
+'use strict';
+
+var EPUBJS = EPUBJS || {};
+EPUBJS.VERSION = "0.2.2";
+
+EPUBJS.plugins = EPUBJS.plugins || {};
+
+EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";
+
+EPUBJS.Render = {};
+
+(function(root) {
+
+ var previousEpub = root.ePub || {};
+
+ var ePub = root.ePub = function() {
+ var bookPath, options;
+
+ //-- var book = ePub("path/to/book.epub", { restore: true })
+ if(typeof(arguments[0]) != 'undefined' &&
+ typeof arguments[0] === 'string') {
+
+ bookPath = arguments[0];
+
+ if( arguments[1] && typeof arguments[1] === 'object' ) {
+ options = arguments[1];
+ options.bookPath = bookPath;
+ } else {
+ options = { 'bookPath' : bookPath };
+ }
+
+ }
+
+ /*
+ * var book = ePub({ bookPath: "path/to/book.epub", restore: true });
+ *
+ * - OR -
+ *
+ * var book = ePub({ restore: true });
+ * book.open("path/to/book.epub");
+ */
+
+ if( arguments[0] && typeof arguments[0] === 'object' ) {
+ options = arguments[0];
+ }
+
+
+ return new EPUBJS.Book(options);
+ };
+
+ _.extend(ePub, {
+ noConflict : function() {
+ root.ePub = previousEpub;
+ return this;
+ }
+ });
+
+ //exports to multiple environments
+ if (typeof define === 'function' && define.amd)
+ //AMD
+ define(function(){ return ePub; });
+ else if (typeof module != "undefined" && module.exports)
+ //Node
+ module.exports = ePub;
+
+})(window);
+
+EPUBJS.Book = function(options){
+
+ var book = this;
+
+ this.settings = _.defaults(options || {}, {
+ bookPath : null,
+ bookKey : null,
+ packageUrl : null,
+ storage: false, //-- true (auto) or false (none) | override: 'ram', 'websqldatabase', 'indexeddb', 'filesystem'
+ fromStorage : false,
+ saved : false,
+ online : true,
+ contained : false,
+ width : null,
+ height: null,
+ layoutOveride : null, // Default: { spread: 'reflowable', layout: 'auto', orientation: 'auto'}
+ orientation : null,
+ minSpreadWidth: 800, //-- overridden by spread: none (never) / both (always)
+ gap: "auto", //-- "auto" or int
+ version: 1,
+ restore: false,
+ reload : false,
+ goto : false,
+ styles : {},
+ headTags : {},
+ withCredentials: false,
+ render_method: "Iframe"
+ });
+
+ this.settings.EPUBJSVERSION = EPUBJS.VERSION;
+
+ this.spinePos = 0;
+ this.stored = false;
+
+ //-- All Book events for listening
+ /*
+ book:ready
+ book:stored
+ book:online
+ book:offline
+ book:pageChanged
+ book:loadFailed
+ book:loadChapterFailed
+ */
+
+ //-- Adds Hook methods to the Book prototype
+ // Hooks will all return before triggering the callback.
+ // EPUBJS.Hooks.mixin(this);
+ //-- Get pre-registered hooks for events
+ // this.getHooks("beforeChapterDisplay");
+
+ this.online = this.settings.online || navigator.onLine;
+ this.networkListeners();
+
+ this.store = false; //-- False if not using storage;
+
+ //-- Determine storage method
+ //-- Override options: none | ram | websqldatabase | indexeddb | filesystem
+
+ if(this.settings.storage !== false){
+ this.storage = new fileStorage.storage(this.settings.storage);
+ }
+
+ this.ready = {
+ manifest: new RSVP.defer(),
+ spine: new RSVP.defer(),
+ metadata: new RSVP.defer(),
+ cover: new RSVP.defer(),
+ toc: new RSVP.defer(),
+ pageList: new RSVP.defer()
+ };
+
+ this.readyPromises = [
+ this.ready.manifest.promise,
+ this.ready.spine.promise,
+ this.ready.metadata.promise,
+ this.ready.cover.promise,
+ this.ready.toc.promise
+ ];
+
+ this.pageList = [];
+ this.pagination = new EPUBJS.Pagination();
+ this.pageListReady = this.ready.pageList.promise;
+
+ this.ready.all = RSVP.all(this.readyPromises);
+
+ this.ready.all.then(this._ready.bind(this));
+
+ // Queue for methods used before rendering
+ this.isRendered = false;
+ this._q = EPUBJS.core.queue(this);
+ // Queue for rendering
+ this._rendering = false;
+ this._displayQ = EPUBJS.core.queue(this);
+ // Queue for going to another location
+ this._moving = false;
+ this._gotoQ = EPUBJS.core.queue(this);
+
+ /**
+ * Creates a new renderer.
+ * The renderer will handle displaying the content using the method provided in the settings
+ */
+ this.renderer = new EPUBJS.Renderer(this.settings.render_method);
+ //-- Set the width at which to switch from spreads to single pages
+ this.renderer.setMinSpreadWidth(this.settings.minSpreadWidth);
+ this.renderer.setGap(this.settings.gap);
+ //-- Pass through the renderer events
+ this.listenToRenderer(this.renderer);
+
+ this.defer_opened = new RSVP.defer();
+ this.opened = this.defer_opened.promise;
+ // BookUrl is optional, but if present start loading process
+ if(typeof this.settings.bookPath === 'string') {
+ this.open(this.settings.bookPath, this.settings.reload);
+ }
+
+ window.addEventListener("beforeunload", this.unload.bind(this), false);
+
+ //-- Listen for these promises:
+ //-- book.opened.then()
+ //-- book.rendered.then()
+};
+
+//-- Check bookUrl and start parsing book Assets or load them from storage
+EPUBJS.Book.prototype.open = function(bookPath, forceReload){
+ var book = this,
+ epubpackage,
+ opened = new RSVP.defer();
+
+ this.settings.bookPath = bookPath;
+
+ //-- Get a absolute URL from the book path
+ this.bookUrl = this.urlFrom(bookPath);
+
+ if(this.settings.contained || this.isContained(bookPath)){
+
+ this.settings.contained = this.contained = true;
+
+ this.bookUrl = '';
+
+ epubpackage = this.unarchive(bookPath).
+ then(function(){
+ return book.loadPackage();
+ });
+
+ } else {
+ epubpackage = this.loadPackage();
+ }
+
+ if(this.settings.restore && !forceReload && localStorage){
+ //-- Will load previous package json, or re-unpack if error
+ epubpackage.then(function(packageXml) {
+ var identifier = book.packageIdentifier(packageXml);
+ var restored = book.restore(identifier);
+
+ if(!restored) {
+ book.unpack(packageXml);
+ }
+ opened.resolve();
+ book.defer_opened.resolve();
+ });
+
+ }else{
+
+ //-- Get package information from epub opf
+ epubpackage.then(function(packageXml) {
+ book.unpack(packageXml);
+ opened.resolve();
+ book.defer_opened.resolve();
+ });
+ }
+
+ //-- If there is network connection, store the books contents
+ if(this.online && this.settings.storage && !this.settings.contained){
+ if(!this.settings.stored) opened.then(book.storeOffline());
+ }
+
+ this._registerReplacements(this.renderer);
+
+ return opened.promise;
+
+};
+
+EPUBJS.Book.prototype.loadPackage = function(_containerPath){
+ var book = this,
+ parse = new EPUBJS.Parser(),
+ containerPath = _containerPath || "META-INF/container.xml",
+ containerXml,
+ packageXml;
+
+ if(!this.settings.packageUrl) { //-- provide the packageUrl to skip this step
+ packageXml = book.loadXml(book.bookUrl + containerPath).
+ then(function(containerXml){
+ return parse.container(containerXml); // Container has path to content
+ }).
+ then(function(paths){
+ book.settings.contentsPath = book.bookUrl + paths.basePath;
+ book.settings.packageUrl = book.bookUrl + paths.packagePath;
+ book.settings.encoding = paths.encoding;
+ return book.loadXml(book.settings.packageUrl); // Containes manifest, spine and metadata
+ });
+ } else {
+ packageXml = book.loadXml(book.settings.packageUrl);
+ }
+
+ packageXml.catch(function(error) {
+ // handle errors in either of the two requests
+ console.error("Could not load book at: "+ containerPath);
+ book.trigger("book:loadFailed", containerPath);
+ });
+ return packageXml;
+};
+
+EPUBJS.Book.prototype.packageIdentifier = function(packageXml){
+ var book = this,
+ parse = new EPUBJS.Parser();
+
+ return parse.identifier(packageXml);
+};
+
+EPUBJS.Book.prototype.unpack = function(packageXml){
+ var book = this,
+ parse = new EPUBJS.Parser();
+
+ book.contents = parse.packageContents(packageXml, book.settings.contentsPath); // Extract info from contents
+
+ book.manifest = book.contents.manifest;
+ book.spine = book.contents.spine;
+ book.spineIndexByURL = book.contents.spineIndexByURL;
+ book.metadata = book.contents.metadata;
+ if(!book.settings.bookKey) {
+ book.settings.bookKey = book.generateBookKey(book.metadata.identifier);
+ }
+
+ //-- Set Globbal Layout setting based on metadata
+ book.globalLayoutProperties = book.parseLayoutProperties(book.metadata);
+
+ book.cover = book.contents.cover = book.settings.contentsPath + book.contents.coverPath;
+
+ book.spineNodeIndex = book.contents.spineNodeIndex;
+
+ book.ready.manifest.resolve(book.contents.manifest);
+ book.ready.spine.resolve(book.contents.spine);
+ book.ready.metadata.resolve(book.contents.metadata);
+ book.ready.cover.resolve(book.contents.cover);
+
+
+ //-- Load the TOC, optional; either the EPUB3 XHTML Navigation file or the EPUB2 NCX file
+ if(book.contents.navPath) {
+ book.settings.navUrl = book.settings.contentsPath + book.contents.navPath;
+
+ book.loadXml(book.settings.navUrl).
+ then(function(navHtml){
+ return parse.nav(navHtml, book.spineIndexByURL, book.spine); // Grab Table of Contents
+ }).then(function(toc){
+ book.toc = book.contents.toc = toc;
+ book.ready.toc.resolve(book.contents.toc);
+ }, function(error) {
+ book.ready.toc.resolve(false);
+ });
+
+ // Load the optional pageList
+ book.loadXml(book.settings.navUrl).
+ then(function(navHtml){
+ return parse.pageList(navHtml, book.spineIndexByURL, book.spine);
+ }).then(function(pageList){
+ var epubcfi = new EPUBJS.EpubCFI();
+ var wait = 0; // need to generate a cfi
+
+ // No pageList found
+ if(pageList.length === 0) {
+ return;
+ }
+
+ book.pageList = book.contents.pageList = pageList;
+
+ // Replace HREFs with CFI
+ book.pageList.forEach(function(pg){
+ if(!pg.cfi) {
+ wait += 1;
+ epubcfi.generateCfiFromHref(pg.href, book).then(function(cfi){
+ pg.cfi = cfi;
+ pg.packageUrl = book.settings.packageUrl;
+
+ wait -= 1;
+ if(wait === 0) {
+ book.pagination.process(book.pageList);
+ book.ready.pageList.resolve(book.pageList);
+ }
+ });
+ }
+ });
+
+ if(!wait) {
+ book.pagination.process(book.pageList);
+ book.ready.pageList.resolve(book.pageList);
+ }
+
+ }, function(error) {
+ book.ready.pageList.resolve([]);
+ });
+ } else if(book.contents.tocPath) {
+ book.settings.tocUrl = book.settings.contentsPath + book.contents.tocPath;
+
+ book.loadXml(book.settings.tocUrl).
+ then(function(tocXml){
+ return parse.toc(tocXml, book.spineIndexByURL, book.spine); // Grab Table of Contents
+ }).then(function(toc){
+ book.toc = book.contents.toc = toc;
+ book.ready.toc.resolve(book.contents.toc);
+ }, function(error) {
+ book.ready.toc.resolve(false);
+ });
+
+ } else {
+ book.ready.toc.resolve(false);
+ }
+
+};
+
+EPUBJS.Book.prototype.createHiddenRender = function(renderer, _width, _height) {
+ var box = this.element.getBoundingClientRect();
+ var width = _width || this.settings.width || box.width;
+ var height = _height || this.settings.height || box.height;
+ var hiddenContainer;
+ var hiddenEl;
+ renderer.setMinSpreadWidth(this.settings.minSpreadWidth);
+ renderer.setGap(this.settings.gap);
+
+ this._registerReplacements(renderer);
+ if(this.settings.forceSingle) {
+ renderer.forceSingle(true);
+ }
+
+ hiddenContainer = document.createElement("div");
+ hiddenContainer.style.visibility = "hidden";
+ hiddenContainer.style.overflow = "hidden";
+ hiddenContainer.style.width = "0";
+ hiddenContainer.style.height = "0";
+ this.element.appendChild(hiddenContainer);
+
+ hiddenEl = document.createElement("div");
+ hiddenEl.style.visibility = "hidden";
+ hiddenEl.style.overflow = "hidden";
+ hiddenEl.style.width = width + "px";//"0";
+ hiddenEl.style.height = height +"px"; //"0";
+ hiddenContainer.appendChild(hiddenEl);
+
+ renderer.initialize(hiddenEl);
+ return hiddenContainer;
+};
+
+// Generates the pageList array by loading every chapter and paging through them
+EPUBJS.Book.prototype.generatePageList = function(width, height){
+ var pageList = [];
+ var pager = new EPUBJS.Renderer(this.settings.render_method, false); //hidden
+ var hiddenContainer = this.createHiddenRender(pager, width, height);
+ var deferred = new RSVP.defer();
+ var spinePos = -1;
+ var spineLength = this.spine.length;
+ var totalPages = 0;
+ var currentPage = 0;
+ var nextChapter = function(deferred){
+ var chapter;
+ var next = spinePos + 1;
+ var done = deferred || new RSVP.defer();
+ var loaded;
+ if(next >= spineLength) {
+ done.resolve();
+ } else {
+ spinePos = next;
+ chapter = new EPUBJS.Chapter(this.spine[spinePos], this.store);
+ pager.displayChapter(chapter, this.globalLayoutProperties).then(function(chap){
+ pager.pageMap.forEach(function(item){
+ currentPage += 1;
+ pageList.push({
+ "cfi" : item.start,
+ "page" : currentPage
+ });
+
+ });
+
+ if(pager.pageMap.length % 2 > 0 &&
+ pager.spreads) {
+ currentPage += 1; // Handle Spreads
+ pageList.push({
+ "cfi" : pager.pageMap[pager.pageMap.length - 1].end,
+ "page" : currentPage
+ });
+ }
+
+ // Load up the next chapter
+ setTimeout(function(){
+ nextChapter(done);
+ }, 1);
+ });
+ }
+ return done.promise;
+ }.bind(this);
+
+ var finished = nextChapter().then(function(){
+ pager.remove();
+ this.element.removeChild(hiddenContainer);
+ deferred.resolve(pageList);
+ }.bind(this));
+
+ return deferred.promise;
+};
+
+// Render out entire book and generate the pagination
+// Width and Height are optional and will default to the current dimensions
+EPUBJS.Book.prototype.generatePagination = function(width, height) {
+ var book = this;
+ var defered = new RSVP.defer();
+
+ this.ready.spine.promise.then(function(){
+ book.generatePageList(width, height).then(function(pageList){
+ book.pageList = book.contents.pageList = pageList;
+ book.pagination.process(pageList);
+ book.ready.pageList.resolve(book.pageList);
+ defered.resolve(book.pageList);
+ });
+ });
+
+ return defered.promise;
+};
+
+// Process the pagination from a JSON array containing the pagelist
+EPUBJS.Book.prototype.loadPagination = function(pagelistJSON) {
+ var pageList = JSON.parse(pagelistJSON);
+
+ if(pageList && pageList.length) {
+ this.pageList = pageList;
+ this.pagination.process(this.pageList);
+ this.ready.pageList.resolve(this.pageList);
+ }
+ return this.pageList;
+};
+
+EPUBJS.Book.prototype.getPageList = function() {
+ return this.ready.pageList.promise;
+};
+
+EPUBJS.Book.prototype.getMetadata = function() {
+ return this.ready.metadata.promise;
+};
+
+EPUBJS.Book.prototype.getToc = function() {
+ return this.ready.toc.promise;
+};
+
+/* Private Helpers */
+
+//-- Listeners for browser events
+EPUBJS.Book.prototype.networkListeners = function(){
+ var book = this;
+
+ window.addEventListener("offline", function(e) {
+ book.online = false;
+ book.trigger("book:offline");
+ }, false);
+
+ window.addEventListener("online", function(e) {
+ book.online = true;
+ book.trigger("book:online");
+ }, false);
+
+};
+
+// Listen to all events the renderer triggers and pass them as book events
+EPUBJS.Book.prototype.listenToRenderer = function(renderer){
+ var book = this;
+ renderer.Events.forEach(function(eventName){
+ renderer.on(eventName, function(e){
+ book.trigger(eventName, e);
+ });
+ });
+
+ renderer.on("renderer:visibleRangeChanged", function(range) {
+ var startPage, endPage, percent;
+ var pageRange = [];
+
+ if(this.pageList.length > 0) {
+ startPage = this.pagination.pageFromCfi(range.start);
+ percent = this.pagination.percentageFromPage(startPage);
+ pageRange.push(startPage);
+
+ if(range.end) {
+ endPage = this.pagination.pageFromCfi(range.end);
+ //if(startPage != endPage) {
+ pageRange.push(endPage);
+ //}
+ }
+ this.trigger("book:pageChanged", {
+ "anchorPage": startPage,
+ "percentage": percent,
+ "pageRange" : pageRange
+ });
+
+ // TODO: Add event for first and last page.
+ // (though last is going to be hard, since it could be several reflowed pages long)
+ }
+ }.bind(this));
+
+ renderer.on("render:loaded", this.loadChange.bind(this));
+};
+
+// Listens for load events from the Renderer and checks against the current chapter
+// Prevents the Render from loading a different chapter when back button is pressed
+EPUBJS.Book.prototype.loadChange = function(url){
+ var uri = EPUBJS.core.uri(url);
+ var chapter;
+
+ if(this.currentChapter) {
+ chapter = EPUBJS.core.uri(this.currentChapter.absolute);
+ }
+
+ if(!this._rendering && this.currentChapter && uri.path != chapter.path){
+ console.warn("Miss Match", uri.path, this.currentChapter.absolute);
+ this.goto(uri.filename);
+ }
+};
+
+EPUBJS.Book.prototype.unlistenToRenderer = function(renderer){
+ renderer.Events.forEach(function(eventName){
+ renderer.off(eventName);
+ } );
+};
+
+//-- Choose between a request from store or a request from network
+EPUBJS.Book.prototype.loadXml = function(url){
+ if(this.settings.fromStorage) {
+ return this.storage.getXml(url, this.settings.encoding);
+ } else if(this.settings.contained) {
+ return this.zip.getXml(url, this.settings.encoding);
+ }else{
+ return EPUBJS.core.request(url, 'xml', this.settings.withCredentials);
+ }
+};
+
+//-- Turns a url into a absolute url
+EPUBJS.Book.prototype.urlFrom = function(bookPath){
+ var uri = EPUBJS.core.uri(bookPath),
+ absolute = uri.protocol,
+ fromRoot = uri.path[0] == "/",
+ location = window.location,
+ //-- Get URL orgin, try for native or combine
+ origin = location.origin || location.protocol + "//" + location.host,
+ baseTag = document.getElementsByTagName('base'),
+ base;
+
+
+ //-- Check is Base tag is set
+
+ if(baseTag.length) {
+ base = baseTag[0].href;
+ }
+
+ //-- 1. Check if url is absolute
+ if(uri.protocol){
+ return uri.origin + uri.path;
+ }
+
+ //-- 2. Check if url starts with /, add base url
+ if(!absolute && fromRoot){
+ return (base || origin) + uri.path;
+ }
+
+ //-- 3. Or find full path to url and add that
+ if(!absolute && !fromRoot){
+ return EPUBJS.core.resolveUrl(base || location.pathname, uri.path);
+ }
+
+};
+
+
+EPUBJS.Book.prototype.unarchive = function(bookPath){
+ var book = this,
+ unarchived;
+
+ //-- Must use storage
+ // if(this.settings.storage == false ){
+ // this.settings.storage = true;
+ // this.storage = new fileStorage.storage();
+ // }
+
+ this.zip = new EPUBJS.Unarchiver();
+ this.store = this.zip; // Use zip storaged in ram
+ return this.zip.openZip(bookPath);
+};
+
+//-- Checks if url has a .epub or .zip extension
+EPUBJS.Book.prototype.isContained = function(bookUrl){
+ var uri = EPUBJS.core.uri(bookUrl);
+
+ if(uri.extension && (uri.extension == "epub" || uri.extension == "zip")){
+ return true;
+ }
+
+ return false;
+};
+
+//-- Checks if the book can be retrieved from localStorage
+EPUBJS.Book.prototype.isSaved = function(bookKey) {
+ var storedSettings;
+
+ if(!localStorage) {
+ return false;
+ }
+
+ storedSettings = localStorage.getItem(bookKey);
+
+ if( !localStorage ||
+ storedSettings === null) {
+ return false;
+ } else {
+ return true;
+ }
+};
+
+// Generates the Book Key using the identifer in the manifest or other string provided
+EPUBJS.Book.prototype.generateBookKey = function(identifier){
+ return "epubjs:" + EPUBJS.VERSION + ":" + window.location.host + ":" + identifier;
+};
+
+EPUBJS.Book.prototype.saveContents = function(){
+ if(!localStorage) {
+ return false;
+ }
+ localStorage.setItem(this.settings.bookKey, JSON.stringify(this.contents));
+};
+
+EPUBJS.Book.prototype.removeSavedContents = function() {
+ if(!localStorage) {
+ return false;
+ }
+ localStorage.removeItem(this.settings.bookKey);
+};
+
+
+
+//-- Takes a string or a element
+EPUBJS.Book.prototype.renderTo = function(elem){
+ var book = this,
+ rendered;
+
+ if(_.isElement(elem)) {
+ this.element = elem;
+ } else if (typeof elem == "string") {
+ this.element = EPUBJS.core.getEl(elem);
+ } else {
+ console.error("Not an Element");
+ return;
+ }
+
+ rendered = this.opened.
+ then(function(){
+ // book.render = new EPUBJS.Renderer[this.settings.renderer](book);
+ book.renderer.initialize(book.element, book.settings.width, book.settings.height);
+ book._rendered();
+ return book.startDisplay();
+ });
+
+ // rendered.then(null, function(error) { console.error(error); });
+
+ return rendered;
+};
+
+EPUBJS.Book.prototype.startDisplay = function(){
+ var display;
+
+ if(this.settings.goto) {
+ display = this.goto(this.settings.goto);
+ }else if(this.settings.previousLocationCfi) {
+ display = this.gotoCfi(this.settings.previousLocationCfi);
+ }else{
+ display = this.displayChapter(this.spinePos);
+ }
+
+ return display;
+};
+
+EPUBJS.Book.prototype.restore = function(identifier){
+
+ var book = this,
+ fetch = ['manifest', 'spine', 'metadata', 'cover', 'toc', 'spineNodeIndex', 'spineIndexByURL', 'globalLayoutProperties'],
+ reject = false,
+ bookKey = this.generateBookKey(identifier),
+ fromStore = localStorage.getItem(bookKey),
+ len = fetch.length,
+ i;
+
+ if(this.settings.clearSaved) reject = true;
+
+ if(!reject && fromStore != 'undefined' && fromStore !== null){
+ book.contents = JSON.parse(fromStore);
+
+ for(i = 0; i < len; i++) {
+ var item = fetch[i];
+
+ if(!book.contents[item]) {
+ reject = true;
+ break;
+ }
+ book[item] = book.contents[item];
+ }
+ }
+
+ if(reject || !fromStore || !this.contents || !this.settings.contentsPath){
+ return false;
+ }else{
+ this.settings.bookKey = bookKey;
+ this.ready.manifest.resolve(this.manifest);
+ this.ready.spine.resolve(this.spine);
+ this.ready.metadata.resolve(this.metadata);
+ this.ready.cover.resolve(this.cover);
+ this.ready.toc.resolve(this.toc);
+ return true;
+ }
+
+};
+
+EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
+ var book = this,
+ render,
+ cfi,
+ pos,
+ store,
+ defer = deferred || new RSVP.defer();
+
+ var chapter;
+
+ if(!this.isRendered) {
+ this._q.enqueue("displayChapter", arguments);
+ // Reject for now. TODO: pass promise to queue
+ defer.reject({
+ message : "Rendering",
+ stack : new Error().stack
+ });
+ return defer.promise;
+ }
+
+
+ if(this._rendering || this._rendering) {
+ // Pass along the current defer
+ this._displayQ.enqueue("displayChapter", [chap, end, defer]);
+ return defer.promise;
+ }
+
+ if(_.isNumber(chap)){
+ pos = chap;
+ }else{
+ cfi = new EPUBJS.EpubCFI(chap);
+ pos = cfi.spinePos;
+ }
+
+ if(pos < 0 || pos >= this.spine.length){
+ console.warn("Not A Valid Location");
+ pos = 0;
+ end = false;
+ cfi = false;
+ }
+
+ //-- Create a new chapter
+ chapter = new EPUBJS.Chapter(this.spine[pos], this.store);
+
+ this._rendering = true;
+
+ render = book.renderer.displayChapter(chapter, this.globalLayoutProperties);
+ if(cfi) {
+ book.renderer.gotoCfi(cfi);
+ } else if(end) {
+ book.renderer.lastPage();
+ }
+ //-- Success, Clear render queue
+ render.then(function(rendered){
+ // var inwait;
+ //-- Set the book's spine position
+ book.spinePos = pos;
+
+ defer.resolve(book.renderer);
+
+ if(!book.settings.fromStorage &&
+ !book.settings.contained) {
+ book.preloadNextChapter();
+ }
+
+ book.currentChapter = chapter;
+ book._rendering = false;
+ book._displayQ.dequeue();
+ if(book._displayQ.length() === 0) {
+ book._gotoQ.dequeue();
+ }
+
+ }, function(error) {
+ // handle errors in either of the two requests
+ console.error("Could not load Chapter: "+ chapter.absolute);
+ book.trigger("book:chapterLoadFailed", chapter.absolute);
+ book._rendering = false;
+ defer.reject(error);
+ });
+
+ return defer.promise;
+};
+
+EPUBJS.Book.prototype.nextPage = function(){
+ var next;
+
+ if(!this.isRendered) return this._q.enqueue("nextPage", arguments);
+
+ next = this.renderer.nextPage();
+
+ if(!next){
+ return this.nextChapter();
+ }
+};
+
+EPUBJS.Book.prototype.prevPage = function() {
+ var prev;
+
+ if(!this.isRendered) return this._q.enqueue("prevPage", arguments);
+
+ prev = this.renderer.prevPage();
+
+ if(!prev){
+ return this.prevChapter();
+ }
+};
+
+EPUBJS.Book.prototype.nextChapter = function() {
+ var next;
+ if (this.spinePos < this.spine.length - 1) {
+ next = this.spinePos + 1;
+ // Skip non linear chapters
+ while (this.spine[next] && this.spine[next].linear && this.spine[next].linear == 'no') {
+ next++;
+ }
+ if (next < this.spine.length) {
+ return this.displayChapter(next);
+ } else {
+ this.trigger("book:atEnd");
+ }
+
+ } else {
+ this.trigger("book:atEnd");
+ }
+};
+
+EPUBJS.Book.prototype.prevChapter = function() {
+ var prev;
+ if (this.spinePos > 0) {
+ prev = this.spinePos - 1;
+ while (this.spine[prev] && this.spine[prev].linear && this.spine[prev].linear == 'no') {
+ prev--;
+ }
+ if (prev >= 0) {
+ return this.displayChapter(prev, true);
+ } else {
+ this.trigger("book:atStart");
+ }
+
+ } else {
+ this.trigger("book:atStart");
+ }
+};
+
+EPUBJS.Book.prototype.getCurrentLocationCfi = function() {
+ if(!this.isRendered) return false;
+ return this.renderer.currentLocationCfi;
+};
+
+EPUBJS.Book.prototype.goto = function(target){
+
+ if(target.indexOf("epubcfi(") === 0) {
+ return this.gotoCfi(target);
+ } else if(target.indexOf("%") === target.length-1) {
+ return this.gotoPercentage(parseInt(target.substring(0, target.length-1))/100);
+ } else if(typeof target === "number" || isNaN(target) === false){
+ return this.gotoPage(target);
+ } else {
+ return this.gotoHref(target);
+ }
+
+};
+
+EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
+ var cfi,
+ spinePos,
+ spineItem,
+ rendered,
+ deferred = defer || new RSVP.defer();
+
+ if(!this.isRendered) {
+ console.warn("Not yet Rendered");
+ this.settings.previousLocationCfi = cfiString;
+ return false;
+ }
+
+ // Currently going to a chapter
+ if(this._moving || this._rendering) {
+ console.warn("Renderer is moving");
+ this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]);
+ return false;
+ }
+
+ cfi = new EPUBJS.EpubCFI(cfiString);
+ spinePos = cfi.spinePos;
+
+ if(spinePos == -1) {
+ return false;
+ }
+
+ spineItem = this.spine[spinePos];
+ promise = deferred.promise;
+ this._moving = true;
+ //-- If same chapter only stay on current chapter
+ if(this.currentChapter && this.spinePos === spinePos){
+ this.renderer.gotoCfi(cfi);
+ this._moving = false;
+ deferred.resolve(this.renderer.currentLocationCfi);
+ } else {
+
+ if(!spineItem || spinePos == -1) {
+ spinePos = 0;
+ spineItem = this.spine[spinePos];
+ }
+
+ this.currentChapter = new EPUBJS.Chapter(spineItem, this.store);
+
+ if(this.currentChapter) {
+ this.spinePos = spinePos;
+ render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties);
+
+ this.renderer.gotoCfi(cfi);
+ render.then(function(rendered){
+ this._moving = false;
+ deferred.resolve(rendered.currentLocationCfi);
+ }.bind(this));
+ }
+ }
+
+ promise.then(function(){
+ this._gotoQ.dequeue();
+ }.bind(this));
+
+ return promise;
+};
+
+EPUBJS.Book.prototype.gotoHref = function(url, defer){
+ var split, chapter, section, relativeURL, spinePos;
+ var deferred = defer || new RSVP.defer();
+
+ if(!this.isRendered) {
+ this.settings.goto = url;
+ return false;
+ }
+
+ // Currently going to a chapter
+ if(this._moving || this._rendering) {
+ this._gotoQ.enqueue("gotoHref", [url, deferred]);
+ return false;
+ }
+
+ split = url.split("#");
+ chapter = split[0];
+ section = split[1] || false;
+ // absoluteURL = (chapter.search("://") === -1) ? (this.settings.contentsPath + chapter) : chapter;
+ relativeURL = chapter.replace(this.settings.contentsPath, '');
+ spinePos = this.spineIndexByURL[relativeURL];
+
+ //-- If link fragment only stay on current chapter
+ if(!chapter){
+ spinePos = this.currentChapter ? this.currentChapter.spinePos : 0;
+ }
+
+ //-- Check that URL is present in the index, or stop
+ if(typeof(spinePos) != "number") return false;
+
+ if(!this.currentChapter || spinePos != this.currentChapter.spinePos){
+ //-- Load new chapter if different than current
+ return this.displayChapter(spinePos).then(function(){
+ if(section){
+ this.renderer.section(section);
+ }
+ deferred.resolve(this.renderer.currentLocationCfi);
+ }.bind(this));
+ }else{
+ //-- Goto section
+ if(section) {
+ this.renderer.section(section);
+ } else {
+ // Or jump to the start
+ this.renderer.firstPage();
+ }
+ deferred.resolve(this.renderer.currentLocationCfi);
+ }
+
+ deferred.promise.then(function(){
+ this._gotoQ.dequeue();
+ }.bind(this));
+
+ return deferred.promise;
+};
+
+EPUBJS.Book.prototype.gotoPage = function(pg){
+ var cfi = this.pagination.cfiFromPage(pg);
+ return this.gotoCfi(cfi);
+};
+
+EPUBJS.Book.prototype.gotoPercentage = function(percent){
+ var pg = this.pagination.pageFromPercentage(percent);
+ return this.gotoPage(pg);
+};
+
+EPUBJS.Book.prototype.preloadNextChapter = function() {
+ var next;
+ var chap = this.spinePos + 1;
+
+ if(chap >= this.spine.length){
+ return false;
+ }
+
+ next = new EPUBJS.Chapter(this.spine[chap]);
+ if(next) {
+ EPUBJS.core.request(next.absolute);
+ }
+};
+
+
+EPUBJS.Book.prototype.storeOffline = function() {
+ var book = this,
+ assets = _.values(this.manifest);
+
+ //-- Creates a queue of all items to load
+ return EPUBJS.storage.batch(assets).
+ then(function(){
+ book.settings.stored = true;
+ book.trigger("book:stored");
+ });
+};
+
+EPUBJS.Book.prototype.availableOffline = function() {
+ return this.settings.stored > 0 ? true : false;
+};
+
+/*
+EPUBJS.Book.prototype.fromStorage = function(stored) {
+
+ if(this.contained) return;
+
+ if(!stored){
+ this.online = true;
+ this.tell("book:online");
+ }else{
+ if(!this.availableOffline){
+ //-- If book hasn't been cached yet, store offline
+ this.storeOffline(function(){
+ this.online = false;
+ this.tell("book:offline");
+ }.bind(this));
+
+ }else{
+ this.online = false;
+ this.tell("book:offline");
+ }
+ }
+
+}
+*/
+
+EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) {
+ var noreflow = ["color", "background", "background-color"];
+
+ if(!this.isRendered) return this._q.enqueue("setStyle", arguments);
+
+ this.settings.styles[style] = val;
+
+ this.renderer.setStyle(style, val, prefixed);
+
+ if(noreflow.indexOf(style) === -1) {
+ // clearTimeout(this.reformatTimeout);
+ // this.reformatTimeout = setTimeout(function(){
+ this.renderer.reformat();
+ // }.bind(this), 10);
+ }
+};
+
+EPUBJS.Book.prototype.removeStyle = function(style) {
+ if(!this.isRendered) return this._q.enqueue("removeStyle", arguments);
+ this.renderer.removeStyle(style);
+ this.renderer.reformat();
+ delete this.settings.styles[style];
+};
+
+EPUBJS.Book.prototype.addHeadTag = function(tag, attrs) {
+ if(!this.isRendered) return this._q.enqueue("addHeadTag", arguments);
+ this.settings.headTags[tag] = attrs;
+};
+
+EPUBJS.Book.prototype.useSpreads = function(use) {
+ console.warn("useSpreads is deprecated, use forceSingle or set a layoutOveride instead");
+ if(use === false) {
+ this.forceSingle(true);
+ } else {
+ this.forceSingle(false);
+ }
+};
+
+EPUBJS.Book.prototype.forceSingle = function(_use) {
+ var force = typeof _use === "undefined" ? true : _use;
+
+ this.renderer.forceSingle(force);
+ this.settings.forceSingle = force;
+ if(this.isRendered) {
+ this.renderer.reformat();
+ }
+};
+
+EPUBJS.Book.prototype.setMinSpreadWidth = function(width) {
+ this.settings.minSpreadWidth = width;
+ if(this.isRendered) {
+ this.renderer.setMinSpreadWidth(this.settings.minSpreadWidth);
+ this.renderer.reformat();
+ }
+};
+
+EPUBJS.Book.prototype.setGap = function(gap) {
+ this.settings.gap = gap;
+ if(this.isRendered) {
+ this.renderer.setGap(this.settings.gap);
+ this.renderer.reformat();
+ }
+};
+
+EPUBJS.Book.prototype.chapter = function(path) {
+ var spinePos = this.spineIndexByURL[path];
+ var spineItem;
+ var chapter;
+
+ if(spinePos){
+ spineItem = this.spine[spinePos];
+ chapter = new EPUBJS.Chapter(spineItem, this.store);
+ chapter.load();
+ }
+ return chapter;
+};
+
+EPUBJS.Book.prototype.unload = function(){
+
+ if(this.settings.restore && localStorage) {
+ this.saveContents();
+ }
+
+ this.unlistenToRenderer(this.renderer);
+
+ this.trigger("book:unload");
+};
+
+EPUBJS.Book.prototype.destroy = function() {
+
+ window.removeEventListener("beforeunload", this.unload);
+
+ if(this.currentChapter) this.currentChapter.unload();
+
+ this.unload();
+
+ if(this.render) this.render.remove();
+
+};
+
+EPUBJS.Book.prototype._ready = function() {
+
+ this.trigger("book:ready");
+
+};
+
+EPUBJS.Book.prototype._rendered = function(err) {
+ var book = this;
+
+ this.isRendered = true;
+ this.trigger("book:rendered");
+
+ this._q.flush();
+};
+
+
+EPUBJS.Book.prototype.applyStyles = function(renderer, callback){
+ // if(!this.isRendered) return this._q.enqueue("applyStyles", arguments);
+ renderer.applyStyles(this.settings.styles);
+ callback();
+};
+
+EPUBJS.Book.prototype.applyHeadTags = function(renderer, callback){
+ // if(!this.isRendered) return this._q.enqueue("applyHeadTags", arguments);
+ renderer.applyHeadTags(this.settings.headTags);
+ callback();
+};
+
+EPUBJS.Book.prototype._registerReplacements = function(renderer){
+ renderer.registerHook("beforeChapterDisplay", this.applyStyles.bind(this, renderer), true);
+ renderer.registerHook("beforeChapterDisplay", this.applyHeadTags.bind(this, renderer), true);
+ renderer.registerHook("beforeChapterDisplay", EPUBJS.replace.hrefs.bind(this), true);
+
+ if(this._needsAssetReplacement()) {
+
+ renderer.registerHook("beforeChapterDisplay", [
+ EPUBJS.replace.head,
+ EPUBJS.replace.resources,
+ EPUBJS.replace.svg
+ ], true);
+
+ }
+
+};
+
+EPUBJS.Book.prototype._needsAssetReplacement = function(){
+ if(this.settings.fromStorage) {
+
+ //-- Filesystem api links are relative, so no need to replace them
+ if(this.storage.getStorageType() == "filesystem") {
+ return false;
+ }
+
+ return true;
+
+ } else if(this.settings.contained) {
+
+ return true;
+
+ } else {
+
+ return false;
+
+ }
+};
+
+
+//-- http://www.idpf.org/epub/fxl/
+EPUBJS.Book.prototype.parseLayoutProperties = function(metadata){
+ var layout = (this.layoutOveride && this.layoutOveride.layout) || metadata.layout || "reflowable";
+ var spread = (this.layoutOveride && this.layoutOveride.spread) || metadata.spread || "auto";
+ var orientation = (this.layoutOveride && this.layoutOveride.orientation) || metadata.orientation || "auto";
+ return {
+ layout : layout,
+ spread : spread,
+ orientation : orientation
+ };
+};
+
+//-- Enable binding events to book
+RSVP.EventTarget.mixin(EPUBJS.Book.prototype);
+
+//-- Handle RSVP Errors
+RSVP.on('error', function(event) {
+ //console.error(event, event.detail);
+});
+
+RSVP.configure('instrument', true); //-- true | will logging out all RSVP rejections
+// RSVP.on('created', listener);
+// RSVP.on('chained', listener);
+// RSVP.on('fulfilled', listener);
+RSVP.on('rejected', function(event){
+ console.error(event.detail.message, event.detail.stack);
+});
+
+EPUBJS.Chapter = function(spineObject, store){
+ this.href = spineObject.href;
+ this.absolute = spineObject.url;
+ this.id = spineObject.id;
+ this.spinePos = spineObject.index;
+ this.cfiBase = spineObject.cfiBase;
+ this.properties = spineObject.properties;
+ this.manifestProperties = spineObject.manifestProperties;
+ this.linear = spineObject.linear;
+ this.pages = 1;
+ this.store = store;
+ this.epubcfi = new EPUBJS.EpubCFI();
+ this.deferred = new RSVP.defer();
+ this.loaded = this.deferred.promise;
+};
+
+
+EPUBJS.Chapter.prototype.load = function(_store){
+ var store = _store || this.store;
+ var promise;
+ // if(this.store && (!this.book.online || this.book.contained))
+ if(store){
+ promise = store.get(this.href);
+ }else{
+ promise = EPUBJS.core.request(this.absolute, 'xml');
+ }
+
+ promise.then(function(xml){
+ this.setDocument(xml);
+ this.deferred.resolve(this);
+ }.bind(this));
+
+ return promise;
+};
+
+EPUBJS.Chapter.prototype.render = function(_store){
+
+ return this.load().then(function(doc){
+
+ var serializer = new XMLSerializer();
+ var contents;
+ var head = doc.head;
+ var base = doc.createElement("base");
+
+ base.setAttribute("href", window.location.origin + this.absolute);
+ head.insertBefore(base, head.firstChild);
+ contents = serializer.serializeToString(doc);
+
+ return contents;
+
+ }.bind(this));
+};
+
+EPUBJS.Chapter.prototype.url = function(_store){
+ var deferred = new RSVP.defer();
+ var store = _store || this.store;
+ var loaded;
+ var chapter = this;
+ var url;
+
+ if(store){
+ if(!this.tempUrl) {
+ store.getUrl(this.absolute).then(function(url){
+ chapter.tempUrl = url;
+ deferred.resolve(url);
+ });
+ } else {
+ url = this.tempUrl;
+ deferred.resolve(url);
+ }
+ }else{
+ url = this.absolute;
+ deferred.resolve(url);
+ }
+ /*
+ loaded = EPUBJS.core.request(url, 'xml', false);
+ loaded.then(function(contents){
+ chapter.contents = contents;
+ deferred.resolve(chapter.absolute);
+ }, function(error){
+ deferred.reject(error);
+ });
+ */
+
+ return deferred.promise;
+};
+
+EPUBJS.Chapter.prototype.setPages = function(num){
+ this.pages = num;
+};
+
+EPUBJS.Chapter.prototype.getPages = function(num){
+ return this.pages;
+};
+
+EPUBJS.Chapter.prototype.getID = function(){
+ return this.ID;
+};
+
+EPUBJS.Chapter.prototype.unload = function(store){
+ this.document = null;
+ if(this.tempUrl && store) {
+ store.revokeUrl(this.tempUrl);
+ this.tempUrl = false;
+ }
+};
+
+EPUBJS.Chapter.prototype.setDocument = function(_document){
+ var uri = _document.namespaceURI;
+ var doctype = _document.doctype;
+
+ // Creates an empty document
+ this.document = _document.implementation.createDocument(
+ uri,
+ null,
+ null
+ );
+ this.contents = this.document.importNode(
+ _document.documentElement, //node to import
+ true //clone its descendants
+ );
+
+ this.document.appendChild(this.contents);
+
+ // Fix to apply wgxpath to new document in IE
+ if(!this.document.evaluate && document.evaluate) {
+ this.document.evaluate = document.evaluate;
+ }
+
+ // this.deferred.resolve(this.contents);
+};
+
+EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
+ var range;
+ var startXpath, endXpath;
+ var startContainer, endContainer;
+ var cleanTextContent, cleanEndTextContent;
+
+ // Check for Contents
+ if(!this.document) return;
+ startXpath = EPUBJS.core.getElementXPath(_range.startContainer);
+ // console.log(startContainer)
+ endXpath = EPUBJS.core.getElementXPath(_range.endContainer);
+
+ startContainer = this.document.evaluate(startXpath, this.document, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+
+ if(!_range.collapsed) {
+ endContainer = this.document.evaluate(endXpath, this.document, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+ }
+
+ range = this.document.createRange();
+ // Find Exact Range in original document
+ if(startContainer) {
+ try {
+ range.setStart(startContainer, _range.startOffset);
+ if(!_range.collapsed && endContainer) {
+ range.setEnd(endContainer, _range.endOffset);
+ }
+ } catch (e) {
+ console.log("missed");
+ startContainer = false;
+ }
+
+ }
+
+ // Fuzzy Match
+ if(!startContainer) {
+ console.log("not found, try fuzzy match");
+ cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent);
+ startXpath = "//text()[contains(.," + cleanStartTextContent + ")]";
+
+ startContainer = this.document.evaluate(startXpath, this.document, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+
+ if(startContainer){
+ // console.log("Found with Fuzzy");
+ range.setStart(startContainer, _range.startOffset);
+
+ if(!_range.collapsed) {
+ cleanEndTextContent = EPUBJS.core.cleanStringForXpath(_range.endContainer.textContent);
+ endXpath = "//text()[contains(.," + cleanEndTextContent + ")]";
+ endContainer = this.document.evaluate(endXpath, this.document, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+ if(endContainer) {
+ range.setEnd(endContainer, _range.endOffset);
+ }
+ }
+
+ }
+ }
+
+ // Generate the Cfi
+ return this.epubcfi.generateCfiFromRange(range, this.cfiBase);
+};
+
+EPUBJS.Chapter.prototype.find = function(_query){
+ var chapter = this;
+ var matches = [];
+ var query = _query.toLowerCase();
+ //var xpath = this.document.evaluate(".//text()[contains(translate(., '"+query.toUpperCase()+"', '"+query+"'),'"+query+"')]", this.document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ var find = function(node){
+ // Search String
+ var text = node.textContent.toLowerCase();
+ var range = chapter.document.createRange();
+ var cfi;
+ var pos;
+ var last = -1;
+ var excerpt;
+ var limit = 150;
+
+ while (pos != -1) {
+ pos = text.indexOf(query, last + 1);
+
+ if(pos != -1) {
+ // If Found, Create Range
+ range = chapter.document.createRange();
+ range.setStart(node, pos);
+ range.setEnd(node, pos + query.length);
+
+ //Generate CFI
+ cfi = chapter.cfiFromRange(range);
+
+ // Generate Excerpt
+ if(node.textContent.length < limit) {
+ excerpt = node.textContent;
+ } else {
+ excerpt = node.textContent.substring(pos-limit/2,pos+limit/2);
+ excerpt = "..." + excerpt + "...";
+ }
+
+ //Add CFI to list
+ matches.push({
+ cfi: cfi,
+ excerpt: excerpt
+ });
+ }
+
+ last = pos;
+ }
+
+ };
+
+ // Grab text nodes
+
+ /*
+ for ( var i=0 ; i < xpath.snapshotLength; i++ ) {
+ find(xpath.snapshotItem(i));
+ }
+ */
+
+ this.textSprint(this.document, function(node){
+ find(node);
+ });
+
+
+ // Return List of CFIs
+ return matches;
+};
+
+
+EPUBJS.Chapter.prototype.textSprint = function(root, func) {
+ var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
+ acceptNode: function (node) {
+ if (node.data && ! /^\s*$/.test(node.data) ) {
+ return NodeFilter.FILTER_ACCEPT;
+ } else {
+ return NodeFilter.FILTER_REJECT;
+ }
+ }
+ }, false);
+ var node;
+ while ((node = treeWalker.nextNode())) {
+ func(node);
+ }
+
+};
+var EPUBJS = EPUBJS || {};
+EPUBJS.core = {};
+
+//-- Get a element for an id
+EPUBJS.core.getEl = function(elem) {
+ return document.getElementById(elem);
+};
+
+//-- Get all elements for a class
+EPUBJS.core.getEls = function(classes) {
+ return document.getElementsByClassName(classes);
+};
+
+EPUBJS.core.request = function(url, type, withCredentials) {
+ var supportsURL = window.URL;
+ var BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer";
+
+ var deferred = new RSVP.defer();
+
+ var xhr = new XMLHttpRequest();
+
+ //-- Check from PDF.js:
+ // https://github.com/mozilla/pdf.js/blob/master/web/compatibility.js
+ var xhrPrototype = XMLHttpRequest.prototype;
+
+ if (!('overrideMimeType' in xhrPrototype)) {
+ // IE10 might have response, but not overrideMimeType
+ Object.defineProperty(xhrPrototype, 'overrideMimeType', {
+ value: function xmlHttpRequestOverrideMimeType(mimeType) {}
+ });
+ }
+ if(withCredentials) {
+ xhr.withCredentials = true;
+ }
+ xhr.open("GET", url, true);
+ xhr.onreadystatechange = handler;
+
+ if(type == 'blob'){
+ xhr.responseType = BLOB_RESPONSE;
+ }
+
+ if(type == "json") {
+ xhr.setRequestHeader("Accept", "application/json");
+ }
+
+ if(type == 'xml') {
+ xhr.overrideMimeType('text/xml');
+ }
+
+ xhr.send();
+
+ function handler() {
+ if (this.readyState === this.DONE) {
+ if (this.status === 200 || this.responseXML ) { //-- Firefox is reporting 0 for blob urls
+ var r;
+
+ if(type == 'xml'){
+ r = this.responseXML;
+ }else
+ if(type == 'json'){
+ r = JSON.parse(this.response);
+ }else
+ if(type == 'blob'){
+
+ if(supportsURL) {
+ r = this.response;
+ } else {
+ //-- Safari doesn't support responseType blob, so create a blob from arraybuffer
+ r = new Blob([this.response]);
+ }
+
+ }else{
+ r = this.response;
+ }
+
+ deferred.resolve(r);
+ } else {
+ deferred.reject({
+ message : this.response,
+ stack : new Error().stack
+ });
+ }
+ }
+ }
+
+ return deferred.promise;
+};
+
+EPUBJS.core.toArray = function(obj) {
+ var arr = [];
+
+ for (var member in obj) {
+ var newitm;
+ if ( obj.hasOwnProperty(member) ) {
+ newitm = obj[member];
+ newitm.ident = member;
+ arr.push(newitm);
+ }
+ }
+
+ return arr;
+};
+
+//-- Parse the different parts of a url, returning a object
+EPUBJS.core.uri = function(url){
+ var uri = {
+ protocol : '',
+ host : '',
+ path : '',
+ origin : '',
+ directory : '',
+ base : '',
+ filename : '',
+ extension : '',
+ fragment : '',
+ href : url
+ },
+ doubleSlash = url.indexOf('://'),
+ search = url.indexOf('?'),
+ fragment = url.indexOf("#"),
+ withoutProtocol,
+ dot,
+ firstSlash;
+
+ if(fragment != -1) {
+ uri.fragment = url.slice(fragment + 1);
+ url = url.slice(0, fragment);
+ }
+
+ if(search != -1) {
+ uri.search = url.slice(search + 1);
+ url = url.slice(0, search);
+ href = url;
+ }
+
+ if(doubleSlash != -1) {
+ uri.protocol = url.slice(0, doubleSlash);
+ withoutProtocol = url.slice(doubleSlash+3);
+ firstSlash = withoutProtocol.indexOf('/');
+
+ if(firstSlash === -1) {
+ uri.host = uri.path;
+ uri.path = "";
+ } else {
+ uri.host = withoutProtocol.slice(0, firstSlash);
+ uri.path = withoutProtocol.slice(firstSlash);
+ }
+
+
+ uri.origin = uri.protocol + "://" + uri.host;
+
+ uri.directory = EPUBJS.core.folder(uri.path);
+
+ uri.base = uri.origin + uri.directory;
+ // return origin;
+ } else {
+ uri.path = url;
+ uri.directory = EPUBJS.core.folder(url);
+ uri.base = uri.directory;
+ }
+
+ //-- Filename
+ uri.filename = url.replace(uri.base, '');
+ dot = uri.filename.lastIndexOf('.');
+ if(dot != -1) {
+ uri.extension = uri.filename.slice(dot+1);
+ }
+ return uri;
+};
+
+//-- Parse out the folder, will return everything before the last slash
+
+EPUBJS.core.folder = function(url){
+
+ var lastSlash = url.lastIndexOf('/');
+
+ if(lastSlash == -1) var folder = '';
+
+ folder = url.slice(0, lastSlash + 1);
+
+ return folder;
+
+};
+
+//-- https://github.com/ebidel/filer.js/blob/master/src/filer.js#L128
+EPUBJS.core.dataURLToBlob = function(dataURL) {
+ var BASE64_MARKER = ';base64,',
+ parts, contentType, raw, rawLength, uInt8Array;
+
+ if (dataURL.indexOf(BASE64_MARKER) == -1) {
+ parts = dataURL.split(',');
+ contentType = parts[0].split(':')[1];
+ raw = parts[1];
+
+ return new Blob([raw], {type: contentType});
+ }
+
+ parts = dataURL.split(BASE64_MARKER);
+ contentType = parts[0].split(':')[1];
+ raw = window.atob(parts[1]);
+ rawLength = raw.length;
+
+ uInt8Array = new Uint8Array(rawLength);
+
+ for (var i = 0; i < rawLength; ++i) {
+ uInt8Array[i] = raw.charCodeAt(i);
+ }
+
+ return new Blob([uInt8Array], {type: contentType});
+};
+
+//-- Load scripts async: http://stackoverflow.com/questions/7718935/load-scripts-asynchronously
+EPUBJS.core.addScript = function(src, callback, target) {
+ var s, r;
+ r = false;
+ s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.async = false;
+ s.src = src;
+ s.onload = s.onreadystatechange = function() {
+ if ( !r && (!this.readyState || this.readyState == 'complete') ) {
+ r = true;
+ if(callback) callback();
+ }
+ };
+ target = target || document.body;
+ target.appendChild(s);
+};
+
+EPUBJS.core.addScripts = function(srcArr, callback, target) {
+ var total = srcArr.length,
+ curr = 0,
+ cb = function(){
+ curr++;
+ if(total == curr){
+ if(callback) callback();
+ }else{
+ EPUBJS.core.addScript(srcArr[curr], cb, target);
+ }
+ };
+
+ EPUBJS.core.addScript(srcArr[curr], cb, target);
+};
+
+EPUBJS.core.addCss = function(src, callback, target) {
+ var s, r;
+ r = false;
+ s = document.createElement('link');
+ s.type = 'text/css';
+ s.rel = "stylesheet";
+ s.href = src;
+ s.onload = s.onreadystatechange = function() {
+ if ( !r && (!this.readyState || this.readyState == 'complete') ) {
+ r = true;
+ if(callback) callback();
+ }
+ };
+ target = target || document.body;
+ target.appendChild(s);
+};
+
+EPUBJS.core.prefixed = function(unprefixed) {
+ var vendors = ["Webkit", "Moz", "O", "ms" ],
+ prefixes = ['-Webkit-', '-moz-', '-o-', '-ms-'],
+ upper = unprefixed[0].toUpperCase() + unprefixed.slice(1),
+ length = vendors.length;
+
+ if (typeof(document.body.style[unprefixed]) != 'undefined') {
+ return unprefixed;
+ }
+
+ for ( var i=0; i < length; i++ ) {
+ if (typeof(document.body.style[vendors[i] + upper]) != 'undefined') {
+ return vendors[i] + upper;
+ }
+ }
+
+ return unprefixed;
+};
+
+EPUBJS.core.resolveUrl = function(base, path) {
+ var url,
+ segments = [],
+ uri = EPUBJS.core.uri(path),
+ folders = base.split("/"),
+ paths;
+
+ if(uri.host) {
+ return path;
+ }
+
+ folders.pop();
+
+ paths = path.split("/");
+ paths.forEach(function(p){
+ if(p === ".."){
+ folders.pop();
+ }else{
+ segments.push(p);
+ }
+ });
+
+ url = folders.concat(segments);
+
+ return url.join("/");
+};
+
+// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
+EPUBJS.core.uuid = function() {
+ var d = new Date().getTime();
+ var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = (d + Math.random()*16)%16 | 0;
+ d = Math.floor(d/16);
+ return (c=='x' ? r : (r&0x7|0x8)).toString(16);
+ });
+ return uuid;
+};
+
+// Fast quicksort insert for sorted array -- based on:
+// http://stackoverflow.com/questions/1344500/efficient-way-to-insert-a-number-into-a-sorted-array-of-numbers
+EPUBJS.core.insert = function(item, array, compareFunction) {
+ var location = EPUBJS.core.locationOf(item, array, compareFunction);
+ array.splice(location, 0, item);
+
+ return location;
+};
+
+EPUBJS.core.locationOf = function(item, array, compareFunction, _start, _end) {
+ var start = _start || 0;
+ var end = _end || array.length;
+ var pivot = parseInt(start + (end - start) / 2);
+ var compared;
+ if(!compareFunction){
+ compareFunction = function(a, b) {
+ if(a > b) return 1;
+ if(a < b) return -1;
+ if(a = b) return 0;
+ };
+ }
+ if(end-start <= 0) {
+ return pivot;
+ }
+
+ compared = compareFunction(array[pivot], item);
+ if(end-start === 1) {
+ return compared > 0 ? pivot : pivot + 1;
+ }
+
+ if(compared === 0) {
+ return pivot;
+ }
+ if(compared === -1) {
+ return EPUBJS.core.locationOf(item, array, compareFunction, pivot, end);
+ } else{
+ return EPUBJS.core.locationOf(item, array, compareFunction, start, pivot);
+ }
+};
+
+EPUBJS.core.indexOfSorted = function(item, array, compareFunction, _start, _end) {
+ var start = _start || 0;
+ var end = _end || array.length;
+ var pivot = parseInt(start + (end - start) / 2);
+ var compared;
+ if(!compareFunction){
+ compareFunction = function(a, b) {
+ if(a > b) return 1;
+ if(a < b) return -1;
+ if(a = b) return 0;
+ };
+ }
+ if(end-start <= 0) {
+ return -1; // Not found
+ }
+
+ compared = compareFunction(array[pivot], item);
+ if(end-start === 1) {
+ return compared === 0 ? pivot : -1;
+ }
+ if(compared === 0) {
+ return pivot; // Found
+ }
+ if(compared === -1) {
+ return EPUBJS.core.indexOfSorted(item, array, compareFunction, pivot, end);
+ } else{
+ return EPUBJS.core.indexOfSorted(item, array, compareFunction, start, pivot);
+ }
+};
+
+
+EPUBJS.core.queue = function(_scope){
+ var _q = [];
+ var scope = _scope;
+ // Add an item to the queue
+ var enqueue = function(funcName, args, context) {
+ _q.push({
+ "funcName" : funcName,
+ "args" : args,
+ "context" : context
+ });
+ return _q;
+ };
+ // Run one item
+ var dequeue = function(){
+ var inwait;
+ if(_q.length) {
+ inwait = _q.shift();
+ // Defer to any current tasks
+ // setTimeout(function(){
+ scope[inwait.funcName].apply(inwait.context || scope, inwait.args);
+ // }, 0);
+ }
+ };
+
+ // Run All
+ var flush = function(){
+ while(_q.length) {
+ dequeue();
+ }
+ };
+ // Clear all items in wait
+ var clear = function(){
+ _q = [];
+ };
+
+ var length = function(){
+ return _q.length;
+ };
+
+ return {
+ "enqueue" : enqueue,
+ "dequeue" : dequeue,
+ "flush" : flush,
+ "clear" : clear,
+ "length" : length
+ };
+};
+
+// From: https://code.google.com/p/fbug/source/browse/branches/firebug1.10/content/firebug/lib/xpath.js
+/**
+ * Gets an XPath for an element which describes its hierarchical location.
+ */
+EPUBJS.core.getElementXPath = function(element) {
+ if (element && element.id) {
+ return '//*[@id="' + element.id + '"]';
+ } else {
+ return EPUBJS.core.getElementTreeXPath(element);
+ }
+};
+
+EPUBJS.core.getElementTreeXPath = function(element) {
+ var paths = [];
+ var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml");
+ var index, nodeName, tagName, pathIndex;
+
+ if(element.nodeType === Node.TEXT_NODE){
+ // index = Array.prototype.indexOf.call(element.parentNode.childNodes, element) + 1;
+ index = EPUBJS.core.indexOfTextNode(element) + 1;
+
+ paths.push("text()["+index+"]");
+ element = element.parentNode;
+ }
+
+ // Use nodeName (instead of localName) so namespace prefix is included (if any).
+ for (; element && element.nodeType == 1; element = element.parentNode)
+ {
+ index = 0;
+ for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
+ {
+ // Ignore document type declaration.
+ if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE) {
+ continue;
+ }
+ if (sibling.nodeName == element.nodeName) {
+ ++index;
+ }
+ }
+ nodeName = element.nodeName.toLowerCase();
+ tagName = (isXhtml ? "xhtml:" + nodeName : nodeName);
+ pathIndex = (index ? "[" + (index+1) + "]" : "");
+ paths.splice(0, 0, tagName + pathIndex);
+ }
+
+ return paths.length ? "./" + paths.join("/") : null;
+};
+
+EPUBJS.core.nsResolver = function(prefix) {
+ var ns = {
+ 'xhtml' : 'http://www.w3.org/1999/xhtml',
+ 'epub': 'http://www.idpf.org/2007/ops'
+ };
+ return ns[prefix] || null;
+};
+
+//https://stackoverflow.com/questions/13482352/xquery-looking-for-text-with-single-quote/13483496#13483496
+EPUBJS.core.cleanStringForXpath = function(str) {
+ var parts = str.match(/[^'"]+|['"]/g);
+ parts = parts.map(function(part){
+ if (part === "'") {
+ return '\"\'\"'; // output "'"
+ }
+
+ if (part === '"') {
+ return "\'\"\'"; // output '"'
+ }
+ return "\'" + part + "\'";
+ });
+ return "concat(\'\'," + parts.join(",") + ")";
+};
+
+EPUBJS.core.indexOfTextNode = function(textNode){
+ var parent = textNode.parentNode;
+ var children = parent.childNodes;
+ var sib;
+ var index = -1;
+ for (var i = 0; i < children.length; i++) {
+ sib = children[i];
+ if(sib.nodeType === Node.TEXT_NODE){
+ index++;
+ }
+ if(sib == textNode) break;
+ }
+
+ return index;
+};
+EPUBJS.EpubCFI = function(cfiStr){
+ if(cfiStr) return this.parse(cfiStr);
+};
+
+EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
+ var pos = parseInt(_pos),
+ spineNodeIndex = _spineNodeIndex + 1,
+ cfi = '/'+spineNodeIndex+'/';
+
+ cfi += (pos + 1) * 2;
+
+ if(id) cfi += "[" + id + "]";
+
+ //cfi += "!";
+
+ return cfi;
+};
+
+EPUBJS.EpubCFI.prototype.generatePathComponent = function(steps) {
+ var parts = [];
+
+ steps.forEach(function(part){
+ var segment = '';
+ segment += (part.index + 1) * 2;
+
+ if(part.id) {
+ segment += "[" + part.id + "]";
+ }
+
+ parts.push(segment);
+ });
+
+ return parts.join('/');
+};
+
+EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
+ var steps = this.pathTo(element);
+ var path = this.generatePathComponent(steps);
+ if(!path.length) {
+ // Start of Chapter
+ return "epubcfi(" + chapter + "!/4/)";
+ } else {
+ // First Text Node
+ return "epubcfi(" + chapter + "!" + path + "/1:0)";
+ }
+};
+
+EPUBJS.EpubCFI.prototype.pathTo = function(node) {
+ var stack = [],
+ children;
+
+ while(node && node.parentNode !== null && node.parentNode.nodeType != 9) {
+ children = node.parentNode.children;
+
+ stack.unshift({
+ 'id' : node.id,
+ // 'classList' : node.classList,
+ 'tagName' : node.tagName,
+ 'index' : children ? Array.prototype.indexOf.call(children, node) : 0
+ });
+
+ node = node.parentNode;
+ }
+
+ return stack;
+};
+
+EPUBJS.EpubCFI.prototype.getChapterComponent = function(cfiStr) {
+
+ var splitStr = cfiStr.split("!");
+
+ return splitStr[0];
+};
+
+EPUBJS.EpubCFI.prototype.getPathComponent = function(cfiStr) {
+
+ var splitStr = cfiStr.split("!");
+ var pathComponent = splitStr[1] ? splitStr[1].split(":") : '';
+
+ return pathComponent[0];
+};
+
+EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent = function(cfiStr) {
+ var splitStr = cfiStr.split(":");
+ return splitStr[1] || '';
+};
+
+
+EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
+ var cfi = {},
+ chapSegment,
+ chapterComponent,
+ pathComponent,
+ charecterOffsetComponent,
+ assertion,
+ chapId,
+ path,
+ end,
+ endInt,
+ 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};
+ }
+
+ cfi.str = cfiStr;
+
+ if(cfiStr.indexOf("epubcfi(") === 0 && cfiStr[cfiStr.length-1] === ")") {
+ // Remove intial epubcfi( and ending )
+ cfiStr = cfiStr.slice(8, cfiStr.length-1);
+ }
+
+ chapterComponent = this.getChapterComponent(cfiStr);
+ pathComponent = this.getPathComponent(cfiStr) || '';
+ charecterOffsetComponent = this.getCharecterOffsetComponent(cfiStr);
+ // Make sure this is a valid cfi or return
+ if(!chapterComponent) {
+ return {spinePos: -1};
+ }
+
+ // Chapter segment is always the second one
+ chapSegment = chapterComponent.split("/")[2] || '';
+ if(!chapSegment) return {spinePos:-1};
+
+ cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
+
+ chapId = chapSegment.match(/\[(.*)\]/);
+
+ cfi.spineId = chapId ? chapId[1] : false;
+
+ if(pathComponent.indexOf(',') != -1) {
+ // Handle ranges -- not supported yet
+ console.warn("CFI Ranges are not supported");
+ }
+
+ path = pathComponent.split('/');
+ end = path.pop();
+
+ cfi.steps = [];
+
+ path.forEach(function(part){
+ var step;
+
+ if(part) {
+ step = parseStep(part);
+ cfi.steps.push(step);
+ }
+ });
+
+ //-- 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 {
+ cfi.steps.push({
+ "type" : "text",
+ 'index' : (endInt - 1 ) / 2
+ });
+ }
+
+ }
+
+ assertion = charecterOffsetComponent.match(/\[(.*)\]/);
+ if(assertion && assertion[1]){
+ cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
+ // We arent handling these assertions yet
+ cfi.textLocationAssertion = assertion[1];
+ } else {
+ cfi.characterOffset = parseInt(charecterOffsetComponent);
+ }
+
+ return cfi;
+};
+
+EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
+ var doc = _doc || document;
+ var marker = _marker || this.createMarker(doc);
+ var parent;
+ var lastStep;
+ var text;
+ var split;
+
+ if(typeof cfi === 'string') {
+ cfi = this.parse(cfi);
+ }
+ // Get the terminal step
+ lastStep = cfi.steps[cfi.steps.length-1];
+
+ // check spinePos
+ if(cfi.spinePos === -1) {
+ // Not a valid CFI
+ return false;
+ }
+
+ // 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){
+ split = text.splitText(cfi.characterOffset);
+ marker.classList.add("EPUBJS-CFI-SPLIT");
+ parent.insertBefore(marker, split);
+ } else {
+ parent.insertBefore(marker, text);
+ }
+ } else {
+ parent.insertBefore(marker, parent.firstChild);
+ }
+
+ return marker;
+};
+
+EPUBJS.EpubCFI.prototype.createMarker = function(_doc) {
+ var doc = _doc || document;
+ var element = doc.createElement('span');
+ element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
+ element.classList.add("EPUBJS-CFI-MARKER");
+
+ return element;
+};
+
+EPUBJS.EpubCFI.prototype.removeMarker = function(marker, _doc) {
+ var doc = _doc || document;
+ // var id = marker.id;
+
+ // Cleanup textnodes if they were split
+ if(marker.classList.contains("EPUBJS-CFI-SPLIT")){
+ nextSib = marker.nextSibling;
+ prevSib = marker.previousSibling;
+ if(nextSib &&
+ prevSib &&
+ nextSib.nodeType === 3 &&
+ prevSib.nodeType === 3){
+
+ prevSib.textContent += nextSib.textContent;
+ marker.parentNode.removeChild(nextSib);
+ }
+ marker.parentNode.removeChild(marker);
+ } else if(marker.classList.contains("EPUBJS-CFI-MARKER")) {
+ // Remove only elements added as markers
+ marker.parentNode.removeChild(marker);
+ }
+
+};
+
+EPUBJS.EpubCFI.prototype.findParent = function(cfi, _doc) {
+ var doc = _doc || document,
+ element = doc.getElementsByTagName('html')[0],
+ children = Array.prototype.slice.call(element.children),
+ num, index, part, sections,
+ text, textBegin, textEnd;
+
+ if(typeof cfi === 'string') {
+ cfi = this.parse(cfi);
+ }
+
+ sections = cfi.steps.slice(0); // Clone steps array
+ if(!sections.length) {
+ return doc.getElementsByTagName('body')[0];
+ }
+
+ while(sections && sections.length > 0) {
+ part = sections.shift();
+ // Find textNodes Parent
+ if(part.type === "text") {
+ text = element.childNodes[part.index];
+ element = text.parentNode || element;
+ // Find element by id if present
+ } else if(part.id){
+ element = doc.getElementById(part.id);
+ // Find element in parent
+ }else{
+ element = children[part.index];
+ }
+ // Element can't be found
+ if(typeof element === "undefined") {
+ console.error("No Element For", part, cfi.str);
+ return false;
+ }
+ // Get current element children and continue through steps
+ children = Array.prototype.slice.call(element.children);
+ }
+
+ return element;
+};
+
+EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
+ if(typeof cfiOne === 'string') {
+ cfiOne = new EPUBJS.EpubCFI(cfiOne);
+ }
+ if(typeof cfiTwo === 'string') {
+ cfiTwo = new EPUBJS.EpubCFI(cfiTwo);
+ }
+ // Compare Spine Positions
+ if(cfiOne.spinePos > cfiTwo.spinePos) {
+ return 1;
+ }
+ 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]) {
+ return 1;
+ }
+ if(cfiOne.steps[i].index > cfiTwo.steps[i].index) {
+ return 1;
+ }
+ if(cfiOne.steps[i].index < cfiTwo.steps[i].index) {
+ return -1;
+ }
+ // Otherwise continue checking
+ }
+
+ // All steps in First present in Second
+ if(cfiOne.steps.length < cfiTwo.steps.length) {
+ return -1;
+ }
+
+ // Compare the charecter offset of the text node
+ if(cfiOne.characterOffset > cfiTwo.characterOffset) {
+ return 1;
+ }
+ if(cfiOne.characterOffset < cfiTwo.characterOffset) {
+ return -1;
+ }
+
+ // CFI's are equal
+ return 0;
+};
+
+EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
+ var uri = EPUBJS.core.uri(href);
+ var path = uri.path;
+ var fragment = uri.fragment;
+ var spinePos = book.spineIndexByURL[path];
+ var loaded;
+ 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);
+ loaded.then(function(doc){
+ var element = doc.getElementById(fragment);
+ var cfi;
+ cfi = epubcfi.generateCfiFromElement(element, spineItem.cfiBase);
+ deferred.resolve(cfi);
+ });
+ }
+
+ return deferred.promise;
+};
+
+EPUBJS.EpubCFI.prototype.generateCfiFromTextNode = function(anchor, offset, base) {
+ var parent = anchor.parentNode;
+ var steps = this.pathTo(parent);
+ var path = this.generatePathComponent(steps);
+ var index = 1 + (2 * Array.prototype.indexOf.call(parent.childNodes, anchor));
+ return "epubcfi(" + base + "!" + path + "/"+index+":"+(offset || 0)+")";
+};
+
+EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
+ var anchor = range.anchorNode;
+ var offset = range.anchorOffset;
+ return this.generateCfiFromTextNode(anchor, offset, base);
+};
+
+EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
+ var start, startElement, startSteps, startPath, startOffset, startIndex;
+ 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));
+ startIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(start));
+ startSteps = this.pathTo(startElement);
+ } else if(range.collapsed) {
+ return this.generateCfiFromElement(start, base); // single element
+ } 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 * EPUBJS.core.indexOfTextNode(end));
+
+ endSteps = this.pathTo(endElement);
+ } else {
+ endSteps = this.pathTo(end);
+ }
+
+ endPath = this.generatePathComponent(endSteps);
+ endOffset = range.endOffset;
+
+ return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + "/" + endIndex + ":" + endOffset + ")";
+
+ } else {
+ return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")";
+ }
+};
+
+EPUBJS.EpubCFI.prototype.generateXpathFromSteps = function(steps) {
+ var xpath = [".", "*"];
+
+ 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") {
+ xpath.push("text()[" + position + "]");
+ } else {
+ xpath.push("*[" + position + "]");
+ }
+ });
+
+ return xpath.join("/");
+};
+
+
+EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
+ var doc = _doc || document;
+ var range = doc.createRange();
+ var lastStep;
+ 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;
+
+ if(!startContainer) {
+ return null;
+ }
+
+ if(startContainer && cfi.characterOffset >= 0) {
+ textLength = startContainer.length;
+
+ if(cfi.characterOffset < textLength) {
+ range.setStart(startContainer, cfi.characterOffset);
+ range.setEnd(startContainer, textLength );
+ } else {
+ console.debug("offset greater than length:", cfi.characterOffset, textLength);
+ range.setStart(startContainer, textLength - 1 );
+ range.setEnd(startContainer, textLength );
+ }
+ } else if(startContainer) {
+ range.selectNode(startContainer);
+ }
+ // doc.defaultView.getSelection().addRange(range);
+ return range;
+};
+
+EPUBJS.Events = function(obj, el){
+
+ this.events = {};
+
+ if(!el){
+ this.el = document.createElement('div');
+ }else{
+ this.el = el;
+ }
+
+ obj.createEvent = this.createEvent;
+ obj.tell = this.tell;
+ obj.listen = this.listen;
+ obj.deafen = this.deafen;
+ obj.listenUntil = this.listenUntil;
+
+ return this;
+};
+
+EPUBJS.Events.prototype.createEvent = function(evt){
+ var e = new CustomEvent(evt);
+ this.events[evt] = e;
+ return e;
+};
+
+EPUBJS.Events.prototype.tell = function(evt, msg){
+ var e;
+
+ if(!this.events[evt]){
+ console.warn("No event:", evt, "defined yet, creating.");
+ e = this.createEvent(evt);
+ }else{
+ e = this.events[evt];
+ }
+
+ if(msg) e.msg = msg;
+ this.el.dispatchEvent(e);
+
+};
+
+EPUBJS.Events.prototype.listen = function(evt, func, bindto){
+ if(!this.events[evt]){
+ console.warn("No event:", evt, "defined yet, creating.");
+ this.createEvent(evt);
+ return;
+ }
+
+ if(bindto){
+ this.el.addEventListener(evt, func.bind(bindto), false);
+ }else{
+ this.el.addEventListener(evt, func, false);
+ }
+
+};
+
+EPUBJS.Events.prototype.deafen = function(evt, func){
+ this.el.removeEventListener(evt, func, false);
+};
+
+EPUBJS.Events.prototype.listenUntil = function(OnEvt, OffEvt, func, bindto){
+ this.listen(OnEvt, func, bindto);
+
+ function unlisten(){
+ this.deafen(OnEvt, func);
+ this.deafen(OffEvt, unlisten);
+ }
+
+ this.listen(OffEvt, unlisten, this);
+};
+EPUBJS.hooks = {};
+EPUBJS.Hooks = (function(){
+ function hooks(){}
+
+ //-- Get pre-registered hooks
+ hooks.prototype.getHooks = function(){
+ var plugs;
+ this.hooks = {};
+ Array.prototype.slice.call(arguments).forEach(function(arg){
+ this.hooks[arg] = [];
+ }, this);
+
+ for (var plugType in this.hooks) {
+ plugs = _.values(EPUBJS.hooks[plugType]);
+
+ plugs.forEach(function(hook){
+ this.registerHook(plugType, hook);
+ }, this);
+ }
+ };
+
+ //-- Hooks allow for injecting async functions that must all complete before continuing
+ // Functions must have a callback as their first argument.
+ hooks.prototype.registerHook = function(type, toAdd, toFront){
+
+ if(typeof(this.hooks[type]) != "undefined"){
+
+ if(typeof(toAdd) === "function"){
+ if(toFront) {
+ this.hooks[type].unshift(toAdd);
+ }else{
+ this.hooks[type].push(toAdd);
+ }
+ }else if(Array.isArray(toAdd)){
+ toAdd.forEach(function(hook){
+ if(toFront) {
+ this.hooks[type].unshift(hook);
+ }else{
+ this.hooks[type].push(hook);
+ }
+ }, this);
+ }
+ }else{
+ //-- Allows for undefined hooks, but maybe this should error?
+ this.hooks[type] = [func];
+ }
+ };
+
+ hooks.prototype.triggerHooks = function(type, callback, passed){
+ var hooks, count;
+
+ if(typeof(this.hooks[type]) == "undefined") return false;
+
+ hooks = this.hooks[type];
+
+ count = hooks.length;
+ if(count === 0 && callback) {
+ callback();
+ }
+
+ function countdown(){
+ count--;
+ if(count <= 0 && callback) callback();
+ }
+
+ hooks.forEach(function(hook){
+ hook(countdown, passed);
+ });
+ };
+
+ return {
+ register: function(name) {
+ if(EPUBJS.hooks[name] === undefined) { EPUBJS.hooks[name] = {}; }
+ if(typeof EPUBJS.hooks[name] !== 'object') { throw "Already registered: "+name; }
+ return EPUBJS.hooks[name];
+ },
+ mixin: function(object) {
+ for (var prop in hooks.prototype) {
+ object[prop] = hooks.prototype[prop];
+ }
+ }
+ };
+})();
+
+
+EPUBJS.Layout = EPUBJS.Layout || {};
+
+EPUBJS.Layout.Reflowable = function(){
+ this.documentElement = null;
+ this.spreadWidth = null;
+};
+
+EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _height, _gap){
+ // Get the prefixed CSS commands
+ var columnAxis = EPUBJS.core.prefixed('columnAxis');
+ var columnGap = EPUBJS.core.prefixed('columnGap');
+ var columnWidth = EPUBJS.core.prefixed('columnWidth');
+ var columnFill = EPUBJS.core.prefixed('columnFill');
+
+ //-- Check the width and create even width columns
+ var width = Math.floor(_width);
+ // var width = (fullWidth % 2 === 0) ? fullWidth : fullWidth - 0; // Not needed for single
+ var section = Math.floor(width / 8);
+ var gap = (_gap >= 0) ? _gap : ((section % 2 === 0) ? section : section - 1);
+ this.documentElement = documentElement;
+ //-- Single Page
+ this.spreadWidth = (width + gap);
+
+
+ documentElement.style.overflow = "hidden";
+
+ // Must be set to the new calculated width or the columns will be off
+ documentElement.style.width = width + "px";
+
+ //-- Adjust height
+ documentElement.style.height = _height + "px";
+
+ //-- Add columns
+ documentElement.style[columnAxis] = "horizontal";
+ documentElement.style[columnFill] = "auto";
+ documentElement.style[columnWidth] = width+"px";
+ documentElement.style[columnGap] = gap+"px";
+ this.colWidth = width;
+ this.gap = gap;
+
+ return {
+ pageWidth : this.spreadWidth,
+ pageHeight : _height
+ };
+};
+
+EPUBJS.Layout.Reflowable.prototype.calculatePages = function() {
+ var totalWidth, displayedPages;
+ this.documentElement.style.width = "auto"; //-- reset width for calculations
+ totalWidth = this.documentElement.scrollWidth;
+ displayedPages = Math.ceil(totalWidth / this.spreadWidth);
+
+ return {
+ displayedPages : displayedPages,
+ pageCount : displayedPages
+ };
+};
+
+EPUBJS.Layout.ReflowableSpreads = function(){
+ this.documentElement = null;
+ this.spreadWidth = null;
+};
+
+EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _width, _height, _gap){
+ var columnAxis = EPUBJS.core.prefixed('columnAxis');
+ var columnGap = EPUBJS.core.prefixed('columnGap');
+ var columnWidth = EPUBJS.core.prefixed('columnWidth');
+ var columnFill = EPUBJS.core.prefixed('columnFill');
+
+ var divisor = 2,
+ cutoff = 800;
+
+ //-- Check the width and create even width columns
+ var fullWidth = Math.floor(_width);
+ var width = (fullWidth % 2 === 0) ? fullWidth : fullWidth - 1;
+
+ var section = Math.floor(width / 8);
+ var gap = (_gap >= 0) ? _gap : ((section % 2 === 0) ? section : section - 1);
+
+ //-- Double Page
+ var colWidth = Math.floor((width - gap) / divisor);
+
+ this.documentElement = documentElement;
+ this.spreadWidth = (colWidth + gap) * divisor;
+
+
+ documentElement.style.overflow = "hidden";
+
+ // Must be set to the new calculated width or the columns will be off
+ documentElement.style.width = width + "px";
+
+ //-- Adjust height
+ documentElement.style.height = _height + "px";
+
+ //-- Add columns
+ documentElement.style[columnAxis] = "horizontal";
+ documentElement.style[columnFill] = "auto";
+ documentElement.style[columnGap] = gap+"px";
+ documentElement.style[columnWidth] = colWidth+"px";
+
+ this.colWidth = colWidth;
+ this.gap = gap;
+ return {
+ pageWidth : this.spreadWidth,
+ pageHeight : _height
+ };
+};
+
+EPUBJS.Layout.ReflowableSpreads.prototype.calculatePages = function() {
+ var totalWidth = this.documentElement.scrollWidth;
+ var displayedPages = Math.ceil(totalWidth / this.spreadWidth);
+
+ //-- Add a page to the width of the document to account an for odd number of pages
+ this.documentElement.style.width = ((displayedPages * this.spreadWidth) - this.gap) + "px";
+
+ return {
+ displayedPages : displayedPages,
+ pageCount : displayedPages * 2
+ };
+};
+
+EPUBJS.Layout.Fixed = function(){
+ this.documentElement = null;
+};
+
+EPUBJS.Layout.Fixed = function(documentElement, _width, _height, _gap){
+ var columnWidth = EPUBJS.core.prefixed('columnWidth');
+ var viewport = documentElement.querySelector("[name=viewport");
+ var content;
+ var contents;
+ var width, height;
+
+ this.documentElement = documentElement;
+ /**
+ * check for the viewport size
+ *
+ */
+ if(viewport && viewport.hasAttribute("content")) {
+ content = viewport.getAttribute("content");
+ contents = content.split(',');
+ if(contents[0]){
+ width = contents[0].replace("width=", '');
+ }
+ if(contents[1]){
+ height = contents[1].replace("height=", '');
+ }
+ }
+
+ //-- Adjust width and height
+ documentElement.style.width = width + "px" || "auto";
+ documentElement.style.height = height + "px" || "auto";
+
+ //-- Remove columns
+ documentElement.style[columnWidth] = "auto";
+
+ //-- Scroll
+ documentElement.style.overflow = "auto";
+
+ this.colWidth = width;
+ this.gap = 0;
+
+ return {
+ pageWidth : width,
+ pageHeight : height
+ };
+
+};
+
+EPUBJS.Layout.Fixed.prototype.calculatePages = function(){
+ return {
+ displayedPages : 1,
+ pageCount : 1
+ };
+};
+
+EPUBJS.Pagination = function(pageList) {
+ this.pages = [];
+ this.locations = [];
+ this.epubcfi = new EPUBJS.EpubCFI();
+ if(pageList && pageList.length) {
+ this.process(pageList);
+ }
+};
+
+EPUBJS.Pagination.prototype.process = function(pageList){
+ pageList.forEach(function(item){
+ this.pages.push(item.page);
+ this.locations.push(item.cfi);
+ }, this);
+
+ this.pageList = pageList;
+ this.firstPage = parseInt(this.pages[0]);
+ this.lastPage = parseInt(this.pages[this.pages.length-1]);
+ this.totalPages = this.lastPage - this.firstPage;
+};
+
+EPUBJS.Pagination.prototype.pageFromCfi = function(cfi){
+ var pg = -1;
+
+ // Check if the pageList has not been set yet
+ if(this.locations.length === 0) {
+ return -1;
+ }
+
+ // TODO: check if CFI is valid?
+
+ // check if the cfi is in the location list
+ // var index = this.locations.indexOf(cfi);
+ var index = EPUBJS.core.indexOfSorted(cfi, this.locations, this.epubcfi.compare);
+ if(index != -1 && index < (this.pages.length-1) ) {
+ pg = this.pages[index];
+ } else {
+ // Otherwise add it to the list of locations
+ // Insert it in the correct position in the locations page
+ //index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
+ index = EPUBJS.core.locationOf(cfi, this.locations, this.epubcfi.compare);
+ // Get the page at the location just before the new one, or return the first
+ pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
+ if(pg !== undefined) {
+ // Add the new page in so that the locations and page array match up
+ //this.pages.splice(index, 0, pg);
+ } else {
+ pg = -1;
+ }
+
+ }
+ return pg;
+};
+
+EPUBJS.Pagination.prototype.cfiFromPage = function(pg){
+ var cfi = -1;
+ // check that pg is an int
+ if(typeof pg != "number"){
+ pg = parseInt(pg);
+ }
+
+ // check if the cfi is in the page list
+ // Pages could be unsorted.
+ var index = this.pages.indexOf(pg);
+ if(index != -1) {
+ cfi = this.locations[index];
+ }
+ // TODO: handle pages not in the list
+ return cfi;
+};
+
+EPUBJS.Pagination.prototype.pageFromPercentage = function(percent){
+ var pg = Math.round(this.totalPages * percent);
+ return pg;
+};
+
+// Returns a value between 0 - 1 corresponding to the location of a page
+EPUBJS.Pagination.prototype.percentageFromPage = function(pg){
+ var percentage = (pg - this.firstPage) / this.totalPages;
+ return Math.round(percentage * 1000) / 1000;
+};
+
+// Returns a value between 0 - 1 corresponding to the location of a cfi
+EPUBJS.Pagination.prototype.percentageFromCfi = function(cfi){
+ var pg = this.pageFromCfi(cfi);
+ var percentage = this.percentageFromPage(pg);
+ return percentage;
+};
+EPUBJS.Parser = function(baseUrl){
+ this.baseUrl = baseUrl || '';
+};
+
+EPUBJS.Parser.prototype.container = function(containerXml){
+ //--
+ var rootfile, fullpath, folder, encoding;
+
+ if(!containerXml) {
+ console.error("Container File Not Found");
+ return;
+ }
+
+ rootfile = containerXml.querySelector("rootfile");
+
+ if(!rootfile) {
+ console.error("No RootFile Found");
+ return;
+ }
+
+ fullpath = rootfile.getAttribute('full-path');
+ folder = EPUBJS.core.uri(fullpath).directory;
+ encoding = containerXml.xmlEncoding;
+
+ //-- Now that we have the path we can parse the contents
+ return {
+ 'packagePath' : fullpath,
+ 'basePath' : folder,
+ 'encoding' : encoding
+ };
+};
+
+EPUBJS.Parser.prototype.identifier = function(packageXml){
+ var metadataNode;
+
+ if(!packageXml) {
+ console.error("Package File Not Found");
+ return;
+ }
+
+ metadataNode = packageXml.querySelector("metadata");
+
+ if(!metadataNode) {
+ console.error("No Metadata Found");
+ return;
+ }
+
+ return this.getElementText(metadataNode, "identifier");
+};
+
+EPUBJS.Parser.prototype.packageContents = function(packageXml, baseUrl){
+ var parse = this;
+ var metadataNode, manifestNode, spineNode;
+ var manifest, navPath, tocPath, coverPath;
+ var spineNodeIndex;
+ var spine;
+ var spineIndexByURL;
+
+ if(baseUrl) this.baseUrl = baseUrl;
+
+ if(!packageXml) {
+ console.error("Package File Not Found");
+ return;
+ }
+
+ metadataNode = packageXml.querySelector("metadata");
+ if(!metadataNode) {
+ console.error("No Metadata Found");
+ return;
+ }
+
+ manifestNode = packageXml.querySelector("manifest");
+ if(!manifestNode) {
+ console.error("No Manifest Found");
+ return;
+ }
+
+ spineNode = packageXml.querySelector("spine");
+ if(!spineNode) {
+ console.error("No Spine Found");
+ return;
+ }
+
+ manifest = parse.manifest(manifestNode);
+ navPath = parse.findNavPath(manifestNode);
+ tocPath = parse.findTocPath(manifestNode);
+ coverPath = parse.findCoverPath(manifestNode);
+
+ spineNodeIndex = Array.prototype.indexOf.call(spineNode.parentNode.childNodes, spineNode);
+
+ spine = parse.spine(spineNode, manifest);
+
+ spineIndexByURL = {};
+ spine.forEach(function(item){
+ spineIndexByURL[item.href] = item.index;
+ });
+
+ return {
+ 'metadata' : parse.metadata(metadataNode),
+ 'spine' : spine,
+ 'manifest' : manifest,
+ 'navPath' : navPath,
+ 'tocPath' : tocPath,
+ 'coverPath': coverPath,
+ 'spineNodeIndex' : spineNodeIndex,
+ 'spineIndexByURL' : spineIndexByURL
+ };
+};
+
+//-- Find TOC NAV: media-type="application/xhtml+xml" href="toc.ncx"
+EPUBJS.Parser.prototype.findNavPath = function(manifestNode){
+ var node = manifestNode.querySelector("item[properties^='nav']");
+ return node ? node.getAttribute('href') : false;
+};
+
+//-- Find TOC NCX: media-type="application/x-dtbncx+xml" href="toc.ncx"
+EPUBJS.Parser.prototype.findTocPath = function(manifestNode){
+ var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
+ return node ? node.getAttribute('href') : false;
+};
+
+//-- Find Cover:
+EPUBJS.Parser.prototype.findCoverPath = function(manifestNode){
+ var node = manifestNode.querySelector("item[properties='cover-image']");
+ return node ? node.getAttribute('href') : false;
+};
+
+//-- Expanded to match Readium web components
+EPUBJS.Parser.prototype.metadata = function(xml){
+ var metadata = {},
+ p = this;
+
+ metadata.bookTitle = p.getElementText(xml, 'title');
+ metadata.creator = p.getElementText(xml, 'creator');
+ metadata.description = p.getElementText(xml, 'description');
+
+ metadata.pubdate = p.getElementText(xml, 'date');
+
+ metadata.publisher = p.getElementText(xml, 'publisher');
+
+ metadata.identifier = p.getElementText(xml, "identifier");
+ metadata.language = p.getElementText(xml, "language");
+ metadata.rights = p.getElementText(xml, "rights");
+
+ metadata.modified_date = p.querySelectorText(xml, "meta[property='dcterms:modified']");
+ metadata.layout = p.querySelectorText(xml, "meta[property='rendition:layout']");
+ metadata.orientation = p.querySelectorText(xml, "meta[property='rendition:orientation']");
+ metadata.spread = p.querySelectorText(xml, "meta[property='rendition:spread']");
+ // metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
+
+ return metadata;
+};
+
+EPUBJS.Parser.prototype.getElementText = function(xml, tag){
+ var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
+ el;
+
+ if(!found || found.length === 0) return '';
+
+ el = found[0];
+
+ if(el.childNodes.length){
+ return el.childNodes[0].nodeValue;
+ }
+
+ return '';
+
+};
+
+EPUBJS.Parser.prototype.querySelectorText = function(xml, q){
+ var el = xml.querySelector(q);
+
+ if(el && el.childNodes.length){
+ return el.childNodes[0].nodeValue;
+ }
+
+ return '';
+};
+
+EPUBJS.Parser.prototype.manifest = function(manifestXml){
+ var baseUrl = this.baseUrl,
+ manifest = {};
+
+ //-- Turn items into an array
+ var selected = manifestXml.querySelectorAll("item"),
+ items = Array.prototype.slice.call(selected);
+
+ //-- Create an object with the id as key
+ items.forEach(function(item){
+ var id = item.getAttribute('id'),
+ href = item.getAttribute('href') || '',
+ type = item.getAttribute('media-type') || '',
+ properties = item.getAttribute('properties') || '';
+
+ manifest[id] = {
+ 'href' : href,
+ 'url' : baseUrl + href, //-- Absolute URL for loading with a web worker
+ 'type' : type,
+ 'properties' : properties
+ };
+
+ });
+
+ return manifest;
+
+};
+
+EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
+ var spine = [];
+
+ var selected = spineXml.getElementsByTagName("itemref"),
+ items = Array.prototype.slice.call(selected);
+
+ var spineNodeIndex = Array.prototype.indexOf.call(spineXml.parentNode.childNodes, spineXml);
+
+ var epubcfi = new EPUBJS.EpubCFI();
+
+ //-- Add to array to mantain ordering and cross reference with manifest
+ items.forEach(function(item, index){
+ var Id = item.getAttribute('idref');
+ var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
+ var props = item.getAttribute('properties') || '';
+ var propArray = props.length ? props.split(' ') : [];
+ var manifestProps = manifest[Id].properties;
+ var manifestPropArray = manifestProps.length ? manifestProps.split(' ') : [];
+ var vert = {
+ 'id' : Id,
+ 'linear' : item.getAttribute('linear') || '',
+ 'properties' : propArray,
+ 'manifestProperties' : manifestPropArray,
+ 'href' : manifest[Id].href,
+ 'url' : manifest[Id].url,
+ 'index' : index,
+ 'cfiBase' : cfiBase,
+ 'cfi' : "epub(" + cfiBase + ")"
+ };
+ spine.push(vert);
+ });
+
+ return spine;
+};
+
+EPUBJS.Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
+ var navEl = navHtml.querySelector('nav[*|type="toc"]'), //-- [*|type="toc"] * Doesn't seem to work
+ idCounter = 0;
+
+ if(!navEl) return [];
+
+ // Implements `> ol > li`
+ function findListItems(parent){
+ var items = [];
+
+ Array.prototype.slice.call(parent.childNodes).forEach(function(node){
+ if('ol' == node.tagName){
+ Array.prototype.slice.call(node.childNodes).forEach(function(item){
+ if('li' == item.tagName){
+ items.push(item);
+ }
+ });
+ }
+ });
+
+ return items;
+
+ }
+
+ // Implements `> a, > span`
+ function findAnchorOrSpan(parent){
+ var item = null;
+
+ Array.prototype.slice.call(parent.childNodes).forEach(function(node){
+ if('a' == node.tagName || 'span' == node.tagName){
+ item = node;
+ }
+ });
+
+ return item;
+ }
+
+ function getTOC(parent){
+ var list = [],
+ nodes = findListItems(parent),
+ items = Array.prototype.slice.call(nodes),
+ length = items.length,
+ node;
+
+ if(length === 0) return false;
+
+ items.forEach(function(item){
+ var id = item.getAttribute('id') || false,
+ content = findAnchorOrSpan(item),
+ href = content.getAttribute('href') || '',
+ text = content.textContent || "",
+ split = href.split("#"),
+ baseUrl = split[0],
+ subitems = getTOC(item),
+ spinePos = spineIndexByURL[baseUrl],
+ spineItem = bookSpine[spinePos],
+ cfi = spineItem ? spineItem.cfi : '';
+
+ if(!id) {
+ if(spinePos) {
+ spineItem = bookSpine[spinePos];
+ id = spineItem.id;
+ cfi = spineItem.cfi;
+ } else {
+ id = 'epubjs-autogen-toc-id-' + (idCounter++);
+ }
+ }
+
+ item.setAttribute('id', id); // Ensure all elements have an id
+ list.push({
+ "id": id,
+ "href": href,
+ "label": text,
+ "subitems" : subitems,
+ "parent" : parent ? parent.getAttribute('id') : null,
+ "cfi" : cfi
+ });
+
+ });
+
+ return list;
+ }
+
+ return getTOC(navEl);
+};
+
+EPUBJS.Parser.prototype.toc = function(tocXml, spineIndexByURL, bookSpine){
+ var navMap = tocXml.querySelector("navMap");
+ if(!navMap) return [];
+
+ function getTOC(parent){
+ var list = [],
+ snapshot = tocXml.evaluate("*[local-name()='navPoint']", parent, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null),
+ length = snapshot.snapshotLength;
+
+ if(length === 0) return [];
+
+ for ( var i=length-1 ; i >= 0; i-- ) {
+ var item = snapshot.snapshotItem(i);
+
+ var id = item.getAttribute('id') || false,
+ content = item.querySelector("content"),
+ src = content.getAttribute('src'),
+ navLabel = item.querySelector("navLabel"),
+ text = navLabel.textContent ? navLabel.textContent : "",
+ split = src.split("#"),
+ baseUrl = split[0],
+ spinePos = spineIndexByURL[baseUrl],
+ spineItem = bookSpine[spinePos],
+ subitems = getTOC(item),
+ cfi = spineItem ? spineItem.cfi : '';
+
+ if(!id) {
+ if(spinePos) {
+ spineItem = bookSpine[spinePos];
+ id = spineItem.id;
+ cfi = spineItem.cfi;
+ } else {
+ id = 'epubjs-autogen-toc-id-' + (idCounter++);
+ }
+ }
+
+ list.unshift({
+ "id": id,
+ "href": src,
+ "label": text,
+ "spinePos": spinePos,
+ "subitems" : subitems,
+ "parent" : parent ? parent.getAttribute('id') : null,
+ "cfi" : cfi
+ });
+
+ }
+
+ return list;
+ }
+
+ return getTOC(navMap);
+};
+
+EPUBJS.Parser.prototype.pageList = function(navHtml, spineIndexByURL, bookSpine){
+ var navEl = navHtml.querySelector('nav[*|type="page-list"]'),
+ idCounter = 0;
+
+ if(!navEl) return [];
+
+ // Implements `> ol > li`
+ function findListItems(parent){
+ var items = [];
+
+ Array.prototype.slice.call(parent.childNodes).forEach(function(node){
+ if('ol' == node.tagName){
+ Array.prototype.slice.call(node.childNodes).forEach(function(item){
+ if('li' == item.tagName){
+ items.push(item);
+ }
+ });
+ }
+ });
+
+ return items;
+
+ }
+
+ // Implements `> a, > span`
+ function findAnchorOrSpan(parent){
+ var item = null;
+
+ Array.prototype.slice.call(parent.childNodes).forEach(function(node){
+ if('a' == node.tagName || 'span' == node.tagName){
+ item = node;
+ }
+ });
+
+ return item;
+ }
+
+ function getPages(parent){
+ var list = [],
+ nodes = findListItems(parent),
+ items = Array.prototype.slice.call(nodes),
+ length = items.length,
+ node;
+
+ if(length === 0) return false;
+
+ items.forEach(function(item){
+ var id = item.getAttribute('id') || false,
+ content = findAnchorOrSpan(item),
+ href = content.getAttribute('href') || '',
+ text = content.textContent || "",
+ page = parseInt(text),
+ isCfi = href.indexOf("epubcfi"),
+ split,
+ packageUrl,
+ cfi;
+
+ if(isCfi != -1) {
+ split = href.split("#");
+ packageUrl = split[0];
+ cfi = split.length > 1 ? split[1] : false;
+ list.push({
+ "cfi" : cfi,
+ "href" : href,
+ "packageUrl" : packageUrl,
+ "page" : page
+ });
+ } else {
+ list.push({
+ "href" : href,
+ "page" : page
+ });
+ }
+
+ });
+
+ return list;
+ }
+
+ return getPages(navEl);
+};
+
+EPUBJS.Render.Iframe = function() {
+ this.iframe = null;
+ this.document = null;
+ this.window = null;
+ this.docEl = null;
+ this.bodyEl = null;
+
+ this.leftPos = 0;
+ this.pageWidth = 0;
+};
+
+//-- Build up any html needed
+EPUBJS.Render.Iframe.prototype.create = function(){
+ this.iframe = document.createElement('iframe');
+ this.iframe.id = "epubjs-iframe:" + EPUBJS.core.uuid();
+ this.iframe.scrolling = "no";
+ this.iframe.seamless = "seamless";
+ // Back up if seamless isn't supported
+ this.iframe.style.border = "none";
+
+ this.iframe.addEventListener("load", this.loaded.bind(this), false);
+ return this.iframe;
+};
+
+/**
+* Sets the source of the iframe with the given URL string
+* Takes: URL string
+* Returns: promise with document element
+*/
+EPUBJS.Render.Iframe.prototype.load = function(chapter){
+ var render = this,
+ deferred = new RSVP.defer();
+
+ chapter.url().then(function(url){
+ // Reset the scroll position
+ render.leftPos = 0;
+
+ if(this.window) {
+ this.unload();
+ }
+
+ this.iframe.onload = function(e) {
+ render.document = render.iframe.contentDocument;
+ render.docEl = render.document.documentElement;
+ render.headEl = render.document.head;
+ render.bodyEl = render.document.body;
+ render.window = render.iframe.contentWindow;
+
+ render.window.addEventListener("resize", render.resized.bind(render), false);
+
+ //-- Clear Margins
+ if(render.bodyEl) {
+ render.bodyEl.style.margin = "0";
+ }
+
+ deferred.resolve(render.docEl);
+ };
+
+ this.iframe.onerror = function(e) {
+ //console.error("Error Loading Contents", e);
+ deferred.reject({
+ message : "Error Loading Contents: " + e,
+ stack : new Error().stack
+ });
+ };
+
+ this.iframe.contentWindow.location.replace(url);
+
+ }.bind(this));
+
+ return deferred.promise;
+};
+
+
+EPUBJS.Render.Iframe.prototype.loaded = function(v){
+ var url = this.iframe.contentWindow.location.href;
+ if(url != "about:blank"){
+ this.trigger("render:loaded", url);
+ }
+};
+
+// Resize the iframe to the given width and height
+EPUBJS.Render.Iframe.prototype.resize = function(width, height){
+ var iframeBox;
+
+ if(!this.iframe) return;
+
+ this.iframe.height = height;
+
+ if(!isNaN(width) && width % 2 !== 0){
+ width += 1; //-- Prevent cutting off edges of text in columns
+ }
+
+ this.iframe.width = width;
+ // Get the fractional height and width of the iframe
+ // Default to orginal if bounding rect is 0
+ this.width = this.iframe.getBoundingClientRect().width || width;
+ this.height = this.iframe.getBoundingClientRect().height || height;
+};
+
+
+EPUBJS.Render.Iframe.prototype.resized = function(e){
+ // Get the fractional height and width of the iframe
+ this.width = this.iframe.getBoundingClientRect().width;
+ this.height = this.iframe.getBoundingClientRect().height;
+};
+
+EPUBJS.Render.Iframe.prototype.totalWidth = function(){
+ return this.docEl.scrollWidth;
+};
+
+EPUBJS.Render.Iframe.prototype.totalHeight = function(){
+ return this.docEl.scrollHeight;
+};
+
+EPUBJS.Render.Iframe.prototype.setPageDimensions = function(pageWidth, pageHeight){
+ this.pageWidth = pageWidth;
+ this.pageHeight = pageHeight;
+ //-- Add a page to the width of the document to account an for odd number of pages
+ // this.docEl.style.width = this.docEl.scrollWidth + pageWidth + "px";
+};
+
+EPUBJS.Render.Iframe.prototype.setLeft = function(leftPos){
+ // this.bodyEl.style.marginLeft = -leftPos + "px";
+ // this.docEl.style.marginLeft = -leftPos + "px";
+ // this.docEl.style[EPUBJS.Render.Iframe.transform] = 'translate('+ (-leftPos) + 'px, 0)';
+ this.document.defaultView.scrollTo(leftPos, 0);
+};
+
+EPUBJS.Render.Iframe.prototype.setStyle = function(style, val, prefixed){
+ if(prefixed) {
+ style = EPUBJS.core.prefixed(style);
+ }
+
+ if(this.bodyEl) this.bodyEl.style[style] = val;
+};
+
+EPUBJS.Render.Iframe.prototype.removeStyle = function(style){
+
+ if(this.bodyEl) this.bodyEl.style[style] = '';
+
+};
+
+EPUBJS.Render.Iframe.prototype.addHeadTag = function(tag, attrs, _doc) {
+ var doc = _doc || this.document;
+ var tagEl = doc.createElement(tag);
+ var headEl = doc.head;
+
+ for(var attr in attrs) {
+ tagEl.setAttribute(attr, attrs[attr]);
+ }
+
+ if(headEl) headEl.insertBefore(tagEl, headEl.firstChild);
+};
+
+EPUBJS.Render.Iframe.prototype.page = function(pg){
+ this.leftPos = this.pageWidth * (pg-1); //-- pages start at 1
+ this.setLeft(this.leftPos);
+};
+
+//-- Show the page containing an Element
+EPUBJS.Render.Iframe.prototype.getPageNumberByElement = function(el){
+ var left, pg;
+ if(!el) return;
+
+ left = this.leftPos + el.getBoundingClientRect().left; //-- Calculate left offset compaired to scrolled position
+
+ pg = Math.floor(left / this.pageWidth) + 1; //-- pages start at 1
+
+ return pg;
+};
+
+//-- Show the page containing an Element
+EPUBJS.Render.Iframe.prototype.getPageNumberByRect = function(boundingClientRect){
+ var left, pg;
+
+ left = this.leftPos + boundingClientRect.left; //-- Calculate left offset compaired to scrolled position
+ pg = Math.floor(left / this.pageWidth) + 1; //-- pages start at 1
+
+ return pg;
+};
+
+// Return the root element of the content
+EPUBJS.Render.Iframe.prototype.getBaseElement = function(){
+ return this.bodyEl;
+};
+
+// Checks if an element is on the screen
+EPUBJS.Render.Iframe.prototype.isElementVisible = function(el){
+ var rect;
+ var left;
+
+ if(el && typeof el.getBoundingClientRect === 'function'){
+ rect = el.getBoundingClientRect();
+ left = rect.left; //+ rect.width;
+ if( rect.width !== 0 &&
+ rect.height !== 0 && // Element not visible
+ left >= 0 &&
+ left < this.pageWidth ) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+
+EPUBJS.Render.Iframe.prototype.scroll = function(bool){
+ if(bool) {
+ this.iframe.scrolling = "yes";
+ } else {
+ this.iframe.scrolling = "no";
+ }
+};
+
+// Cleanup event listeners
+EPUBJS.Render.Iframe.prototype.unload = function(){
+ this.window.removeEventListener("resize", this.resized);
+};
+
+//-- Enable binding events to Render
+RSVP.EventTarget.mixin(EPUBJS.Render.Iframe.prototype);
+EPUBJS.Renderer = function(renderMethod, hidden) {
+ // Dom events to listen for
+ this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click"];
+ this.upEvent = "mouseup";
+ this.downEvent = "mousedown";
+ if('ontouchstart' in document.documentElement) {
+ this.listenedEvents.push("touchstart", "touchend");
+ this.upEvent = "touchend";
+ this.downEvent = "touchstart";
+ }
+ /**
+ * Setup a render method.
+ * Options are: Iframe
+ */
+ if(renderMethod && typeof(EPUBJS.Render[renderMethod]) != "undefined"){
+ this.render = new EPUBJS.Render[renderMethod]();
+ } else {
+ console.error("Not a Valid Rendering Method");
+ }
+
+ // Listen for load events
+ this.render.on("render:loaded", this.loaded.bind(this));
+
+ // Cached for replacement urls from storage
+ this.caches = {};
+
+ // Blank Cfi for Parsing
+ this.epubcfi = new EPUBJS.EpubCFI();
+
+ this.spreads = true;
+ this.isForcedSingle = false;
+ this.resized = _.debounce(this.onResized.bind(this), 100);
+
+ this.layoutSettings = {};
+
+ this.hidden = hidden || false;
+ //-- Adds Hook methods to the Book prototype
+ // Hooks will all return before triggering the callback.
+ EPUBJS.Hooks.mixin(this);
+ //-- Get pre-registered hooks for events
+ this.getHooks("beforeChapterDisplay");
+
+ //-- Queue up page changes if page map isn't ready
+ this._q = EPUBJS.core.queue(this);
+
+ this._moving = false;
+
+};
+
+//-- Renderer events for listening
+EPUBJS.Renderer.prototype.Events = [
+ "renderer:keydown",
+ "renderer:keyup",
+ "renderer:keypressed",
+ "renderer:mouseup",
+ "renderer:mousedown",
+ "renderer:click",
+ "renderer:touchstart",
+ "renderer:touchend",
+ "renderer:selected",
+ "renderer:chapterUnloaded",
+ "renderer:chapterDisplayed",
+ "renderer:locationChanged",
+ "renderer:visibleLocationChanged",
+ "renderer:resized",
+ "renderer:spreads"
+];
+
+/**
+* Creates an element to render to.
+* Resizes to passed width and height or to the elements size
+*/
+EPUBJS.Renderer.prototype.initialize = function(element, width, height){
+ this.container = element;
+ this.element = this.render.create();
+
+ this.initWidth = width;
+ this.initHeight = height;
+
+ this.width = width || this.container.clientWidth;
+ this.height = height || this.container.clientHeight;
+
+ this.container.appendChild(this.element);
+
+ if(width && height){
+ this.render.resize(this.width, this.height);
+ } else {
+ this.render.resize('100%', '100%');
+ }
+
+ document.addEventListener("orientationchange", this.onResized);
+};
+
+/**
+* Display a chapter
+* Takes: chapter object, global layout settings
+* Returns: Promise with passed Renderer after pages has loaded
+*/
+EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
+ var store = false;
+ if(this._moving) {
+ console.error("Rendering In Progress");
+ return;
+ }
+ this._moving = true;
+ // Get the url string from the chapter (may be from storage)
+ return chapter.url().
+ then(function(url) {
+
+ // Unload the previous chapter listener
+ if(this.currentChapter) {
+ this.currentChapter.unload(); // Remove stored blobs
+
+ if(this.render.window){
+ this.render.window.removeEventListener("resize", this.resized);
+ }
+
+ this.removeEventListeners();
+ this.removeSelectionListeners();
+ this.trigger("renderer:chapterUnloaded");
+ this.contents = null;
+ this.doc = null;
+ this.pageMap = null;
+ }
+
+ this.currentChapter = chapter;
+ this.chapterPos = 1;
+ this.currentChapterCfiBase = chapter.cfiBase;
+
+ this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties);
+ return this.load(chapter);
+
+ }.bind(this));
+
+};
+
+/**
+* Loads a url (string) and renders it,
+* attaching event listeners and triggering hooks.
+* Returns: Promise with the rendered contents.
+*/
+
+EPUBJS.Renderer.prototype.load = function(url){
+ var deferred = new RSVP.defer();
+ var loaded;
+
+ // Switch to the required layout method for the settings
+ this.layoutMethod = this.determineLayout(this.layoutSettings);
+ this.layout = new EPUBJS.Layout[this.layoutMethod]();
+
+ this.visible(false);
+
+ render = this.render.load(url);
+
+ render.then(function(contents) {
+ var formated;
+ this.currentChapter.setDocument(this.render.document);
+ this.contents = contents;
+ this.doc = this.render.document;
+
+ // Format the contents using the current layout method
+ this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap);
+ this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
+
+ // window.addEventListener("orientationchange", this.onResized.bind(this), false);
+ if(!this.initWidth && !this.initHeight){
+ this.render.window.addEventListener("resize", this.resized, false);
+ }
+
+ this.addEventListeners();
+ this.addSelectionListeners();
+
+ //-- Trigger registered hooks before displaying
+ this.beforeDisplay(function(){
+ var pages = this.layout.calculatePages();
+ var msg = this.currentChapter;
+ var queued = this._q.length();
+ this._moving = false;
+
+ this.updatePages(pages);
+
+ this.visibleRangeCfi = this.getVisibleRangeCfi();
+ this.currentLocationCfi = this.visibleRangeCfi.start;
+
+ if(queued === 0) {
+ this.trigger("renderer:locationChanged", this.currentLocationCfi);
+ this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
+ }
+
+ msg.cfi = this.currentLocationCfi; //TODO: why is this cfi passed to chapterDisplayed
+ this.trigger("renderer:chapterDisplayed", msg);
+
+ this.visible(true);
+
+ deferred.resolve(this); //-- why does this return the renderer?
+ }.bind(this));
+
+ }.bind(this));
+
+ return deferred.promise;
+};
+
+EPUBJS.Renderer.prototype.loaded = function(url){
+ this.trigger("render:loaded", url);
+ // var uri = EPUBJS.core.uri(url);
+ // var relative = uri.path.replace(book.bookUrl, '');
+ // console.log(url, uri, relative);
+};
+
+/**
+* Reconciles the current chapters layout properies with
+* the global layout properities.
+* Takes: global layout settings object, chapter properties string
+* Returns: Object with layout properties
+*/
+EPUBJS.Renderer.prototype.reconcileLayoutSettings = function(global, chapter){
+ var settings = {};
+
+ //-- Get the global defaults
+ for (var attr in global) {
+ if (global.hasOwnProperty(attr)){
+ settings[attr] = global[attr];
+ }
+ }
+ //-- Get the chapter's display type
+ chapter.forEach(function(prop){
+ var rendition = prop.replace("rendition:", '');
+ var split = rendition.indexOf("-");
+ var property, value;
+
+ if(split != -1){
+ property = rendition.slice(0, split);
+ value = rendition.slice(split+1);
+
+ settings[property] = value;
+ }
+ });
+ return settings;
+};
+
+/**
+* Uses the settings to determine which Layout Method is needed
+* Triggers events based on the method choosen
+* Takes: Layout settings object
+* Returns: String of appropriate for EPUBJS.Layout function
+*/
+EPUBJS.Renderer.prototype.determineLayout = function(settings){
+ // Default is layout: reflowable & spread: auto
+ var spreads = this.determineSpreads(this.minSpreadWidth);
+ var layoutMethod = spreads ? "ReflowableSpreads" : "Reflowable";
+ var scroll = false;
+
+ if(settings.layout === "pre-paginated") {
+ layoutMethod = "Fixed";
+ scroll = true;
+ spreads = false;
+ }
+
+ if(settings.layout === "reflowable" && settings.spread === "none") {
+ layoutMethod = "Reflowable";
+ scroll = false;
+ spreads = false;
+ }
+
+ if(settings.layout === "reflowable" && settings.spread === "both") {
+ layoutMethod = "ReflowableSpreads";
+ scroll = false;
+ spreads = true;
+ }
+
+ this.spreads = spreads;
+ this.render.scroll(scroll);
+ this.trigger("renderer:spreads", spreads);
+ return layoutMethod;
+};
+
+// Shortcut to trigger the hook before displaying the chapter
+EPUBJS.Renderer.prototype.beforeDisplay = function(callback, renderer){
+ this.triggerHooks("beforeChapterDisplay", callback, this);
+};
+
+// Update the renderer with the information passed by the layout
+EPUBJS.Renderer.prototype.updatePages = function(layout){
+ this.pageMap = this.mapPage();
+ // this.displayedPages = layout.displayedPages;
+
+ if (this.spreads) {
+ this.displayedPages = Math.ceil(this.pageMap.length / 2);
+ } else {
+ this.displayedPages = this.pageMap.length;
+ }
+
+ // this.currentChapter.pages = layout.pageCount;
+ this.currentChapter.pages = this.pageMap.length;
+
+ this._q.flush();
+};
+
+// Apply the layout again and jump back to the previous cfi position
+EPUBJS.Renderer.prototype.reformat = function(){
+ var renderer = this;
+ var formated, pages;
+ if(!this.contents) return;
+
+ spreads = this.determineSpreads(this.minSpreadWidth);
+
+ // Only re-layout if the spreads have switched
+ if(spreads != this.spreads){
+ this.spreads = spreads;
+ this.layoutMethod = this.determineLayout(this.layoutSettings);
+ this.layout = new EPUBJS.Layout[this.layoutMethod]();
+ }
+
+ // Reset pages
+ this.chapterPos = 1;
+ this.render.page(1);
+
+ // Give the css styles time to update
+ // clearTimeout(this.timeoutTillCfi);
+ // this.timeoutTillCfi = setTimeout(function(){
+
+ renderer.formated = renderer.layout.format(renderer.contents, renderer.render.width, renderer.render.height, renderer.gap);
+ renderer.render.setPageDimensions(renderer.formated.pageWidth, renderer.formated.pageHeight);
+
+ pages = renderer.layout.calculatePages();
+ renderer.updatePages(pages);
+
+ //-- Go to current page after formating
+ if(renderer.currentLocationCfi){
+ renderer.gotoCfi(renderer.currentLocationCfi);
+ }
+ // renderer.timeoutTillCfi = null;
+
+};
+
+// Hide and show the render's container .
+EPUBJS.Renderer.prototype.visible = function(bool){
+ if(typeof(bool) === "undefined") {
+ return this.element.style.visibility;
+ }
+
+ if(bool === true && !this.hidden){
+ this.element.style.visibility = "visible";
+ }else if(bool === false){
+ this.element.style.visibility = "hidden";
+ }
+};
+
+// Remove the render element and clean up listeners
+EPUBJS.Renderer.prototype.remove = function() {
+ if(this.render.window) {
+ this.render.unload();
+ this.render.window.removeEventListener("resize", this.resized);
+ this.removeEventListeners();
+ this.removeSelectionListeners();
+ }
+
+ this.container.removeChild(this.element);
+};
+
+//-- STYLES
+
+EPUBJS.Renderer.prototype.applyStyles = function(styles) {
+ for (var style in styles) {
+ this.render.setStyle(style, styles[style]);
+ }
+};
+
+EPUBJS.Renderer.prototype.setStyle = function(style, val, prefixed){
+ this.render.setStyle(style, val, prefixed);
+};
+
+EPUBJS.Renderer.prototype.removeStyle = function(style){
+ this.render.removeStyle(style);
+};
+
+//-- HEAD TAGS
+EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
+ for ( var headTag in headTags ) {
+ this.render.addHeadTag(headTag, headTags[headTag]);
+ }
+};
+
+//-- NAVIGATION
+
+EPUBJS.Renderer.prototype.page = function(pg){
+ if(!this.pageMap) {
+ console.warn("pageMap not set, queuing");
+ this._q.enqueue("page", arguments);
+ return true;
+ }
+
+ if(pg >= 1 && pg <= this.displayedPages){
+ this.chapterPos = pg;
+
+ this.render.page(pg);
+ this.visibleRangeCfi = this.getVisibleRangeCfi();
+ this.currentLocationCfi = this.visibleRangeCfi.start;
+ this.trigger("renderer:locationChanged", this.currentLocationCfi);
+ this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
+
+ return true;
+ }
+ //-- Return false if page is greater than the total
+ return false;
+};
+
+// Short cut to find next page's cfi starting at the last visible element
+/*
+EPUBJS.Renderer.prototype.nextPage = function(){
+ var pg = this.chapterPos + 1;
+ if(pg <= this.displayedPages){
+ this.chapterPos = pg;
+
+ this.render.page(pg);
+
+ this.currentLocationCfi = this.getPageCfi(this.visibileEl);
+ this.trigger("renderer:locationChanged", this.currentLocationCfi);
+
+ return true;
+ }
+ //-- Return false if page is greater than the total
+ return false;
+};
+*/
+EPUBJS.Renderer.prototype.nextPage = function(){
+ return this.page(this.chapterPos + 1);
+};
+
+EPUBJS.Renderer.prototype.prevPage = function(){
+ return this.page(this.chapterPos - 1);
+};
+
+//-- Show the page containing an Element
+EPUBJS.Renderer.prototype.pageByElement = function(el){
+ var pg;
+ if(!el) return;
+
+ pg = this.render.getPageNumberByElement(el);
+ this.page(pg);
+};
+
+// Jump to the last page of the chapter
+EPUBJS.Renderer.prototype.lastPage = function(){
+ if(this._moving) {
+ return this._q.enqueue("lastPage", arguments);
+ }
+
+ this.page(this.displayedPages);
+};
+
+// Jump to the first page of the chapter
+EPUBJS.Renderer.prototype.firstPage = function(){
+ this.page(1);
+};
+
+//-- Find a section by fragement id
+EPUBJS.Renderer.prototype.section = function(fragment){
+ var el = this.doc.getElementById(fragment),
+ left, pg;
+
+ if(el){
+ this.pageByElement(el);
+ }
+
+};
+
+EPUBJS.Renderer.prototype.firstElementisTextNode = function(node) {
+ var children = node.childNodes;
+ var leng = children.length;
+
+ if(leng &&
+ children[0] && // First Child
+ children[0].nodeType === 3 && // This is a textNodes
+ children[0].textContent.trim().length) { // With non whitespace or return charecters
+ return true;
+ }
+ return false;
+};
+
+// Walk the node tree from a start element to next visible element
+EPUBJS.Renderer.prototype.walk = function(node, x, y) {
+ var r, children, leng,
+ startNode = node,
+ prevNode,
+ stack = [startNode];
+
+ var STOP = 10000, ITER=0;
+
+ while(!r && stack.length) {
+ node = stack.shift();
+ if( this.containsPoint(node, x, y) && this.firstElementisTextNode(node)) {
+ r = node;
+ }
+
+ if(!r && node && node.childElementCount > 0){
+ children = node.children;
+ if (children && children.length) {
+ leng = children.length ? children.length : 0;
+ } else {
+ return r;
+ }
+ for (var i = leng-1; i >= 0; i--) {
+ if(children[i] != prevNode) stack.unshift(children[i]);
+ }
+ }
+
+ if(!r && stack.length === 0 && startNode && startNode.parentNode !== null){
+ stack.push(startNode.parentNode);
+ prevNode = startNode;
+ startNode = startNode.parentNode;
+ }
+
+
+ ITER++;
+ if(ITER > STOP) {
+ console.error("ENDLESS LOOP");
+ break;
+ }
+
+ }
+
+ return r;
+};
+
+// Checks if an element is on the screen
+EPUBJS.Renderer.prototype.containsPoint = function(el, x, y){
+ var rect;
+ var left;
+ if(el && typeof el.getBoundingClientRect === 'function'){
+ rect = el.getBoundingClientRect();
+ // console.log(el, rect, x, y);
+
+ if( rect.width !== 0 &&
+ rect.height !== 0 && // Element not visible
+ rect.left >= x &&
+ x <= rect.left + rect.width) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+EPUBJS.Renderer.prototype.textSprint = function(root, func) {
+ var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
+ acceptNode: function (node) {
+ if ( ! /^\s*$/.test(node.data) ) {
+ return NodeFilter.FILTER_ACCEPT;
+ } else {
+ return NodeFilter.FILTER_REJECT;
+ }
+ }
+ }, false);
+ var node;
+ while ((node = treeWalker.nextNode())) {
+ func(node);
+ }
+
+};
+
+EPUBJS.Renderer.prototype.sprint = function(root, func) {
+ var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);
+ var node;
+ while ((node = treeWalker.nextNode())) {
+ func(node);
+ }
+
+};
+
+EPUBJS.Renderer.prototype.mapPage = function(){
+ var renderer = this;
+ var map = [];
+ var root = this.render.getBaseElement();
+ var page = 1;
+ var width = this.layout.colWidth + this.layout.gap;
+ var offset = this.formated.pageWidth * (this.chapterPos-1);
+ var limit = (width * page) - offset;// (width * page) - offset;
+ var elLimit = 0;
+ var prevRange;
+ var cfi;
+ var check = function(node) {
+ var elPos;
+ var elRange;
+ var children = Array.prototype.slice.call(node.childNodes);
+ if (node.nodeType == Node.ELEMENT_NODE) {
+ // elPos = node.getBoundingClientRect();
+ elRange = document.createRange();
+ elRange.selectNodeContents(node);
+ elPos = elRange.getBoundingClientRect();
+
+ if(!elPos || (elPos.width === 0 && elPos.height === 0)) {
+ return;
+ }
+
+ //-- Element starts new Col
+ if(elPos.left > elLimit) {
+ children.forEach(function(node){
+ if(node.nodeType == Node.TEXT_NODE &&
+ node.textContent.trim().length) {
+ checkText(node);
+ }
+ });
+ }
+
+ //-- Element Spans new Col
+ if(elPos.right > elLimit) {
+ children.forEach(function(node){
+ if(node.nodeType == Node.TEXT_NODE &&
+ node.textContent.trim().length) {
+ checkText(node);
+ }
+ });
+ }
+ }
+
+ };
+ var checkText = function(node){
+ var ranges = renderer.splitTextNodeIntoWordsRanges(node);
+ ranges.forEach(function(range){
+ var pos = range.getBoundingClientRect();
+
+ if(!pos || (pos.width === 0 && pos.height === 0)) {
+ return;
+ }
+ if(pos.left + pos.width < limit) {
+ if(!map[page-1]){
+ range.collapse(true);
+ cfi = renderer.currentChapter.cfiFromRange(range);
+ // map[page-1].start = cfi;
+ map.push({ start: cfi, end: null });
+ }
+ } else {
+ if(prevRange){
+ prevRange.collapse(true);
+ cfi = renderer.currentChapter.cfiFromRange(prevRange);
+ map[map.length-1].end = cfi;
+ }
+
+ range.collapse(true);
+ cfi = renderer.currentChapter.cfiFromRange(range);
+ map.push({
+ start: cfi,
+ end: null
+ });
+
+ page += 1;
+ limit = (width * page) - offset;
+ elLimit = limit;
+ }
+
+ prevRange = range;
+ });
+
+
+ };
+
+ this.sprint(root, check);
+ // this.textSprint(root, checkText);
+
+ if(prevRange){
+ prevRange.collapse(true);
+
+ cfi = renderer.currentChapter.cfiFromRange(prevRange);
+ map[map.length-1].end = cfi;
+ }
+
+ // Handle empty map
+ if(!map.length) {
+ range = this.doc.createRange();
+ range.selectNodeContents(root);
+ range.collapse(true);
+
+ cfi = renderer.currentChapter.cfiFromRange(range);
+
+ map.push({ start: cfi, end: cfi });
+
+ }
+
+ // clean up
+ prevRange = null;
+ ranges = null;
+ range = null;
+ root = null;
+
+ return map;
+};
+
+
+EPUBJS.Renderer.prototype.splitTextNodeIntoWordsRanges = function(node){
+ var ranges = [];
+ var text = node.textContent.trim();
+ var range;
+ var rect;
+ var list;
+ pos = text.indexOf(" ");
+
+ if(pos === -1) {
+ range = this.doc.createRange();
+ range.selectNodeContents(node);
+ return [range];
+ }
+
+ range = this.doc.createRange();
+ range.setStart(node, 0);
+ range.setEnd(node, pos);
+ ranges.push(range);
+ range = false;
+
+ while ( pos != -1 ) {
+
+ pos = text.indexOf(" ", pos + 1);
+ if(pos > 0) {
+
+ if(range) {
+ range.setEnd(node, pos);
+ ranges.push(range);
+ }
+
+ range = this.doc.createRange();
+ range.setStart(node, pos+1);
+ }
+ }
+
+ if(range) {
+ range.setEnd(node, text.length);
+ ranges.push(range);
+ }
+
+ return ranges;
+};
+
+EPUBJS.Renderer.prototype.rangePosition = function(range){
+ var rect;
+ var list;
+
+ list = range.getClientRects();
+
+ if(list.length) {
+ rect = list[0];
+ return rect;
+ }
+
+ return null;
+};
+
+/*
+// Get the cfi of the current page
+EPUBJS.Renderer.prototype.getPageCfi = function(prevEl){
+ var range = this.doc.createRange();
+ var position;
+ // TODO : this might need to take margin / padding into account?
+ var x = 1;//this.formated.pageWidth/2;
+ var y = 1;//;this.formated.pageHeight/2;
+
+ range = this.getRange(x, y);
+
+ // var test = this.doc.defaultView.getSelection();
+ // var r = this.doc.createRange();
+ // test.removeAllRanges();
+ // r.setStart(range.startContainer, range.startOffset);
+ // r.setEnd(range.startContainer, range.startOffset + 1);
+ // test.addRange(r);
+
+ return this.currentChapter.cfiFromRange(range);
+};
+*/
+
+// Get the cfi of the current page
+EPUBJS.Renderer.prototype.getPageCfi = function(){
+ var pg;
+ if (this.spreads) {
+ pg = this.chapterPos*2;
+ startRange = this.pageMap[pg-2];
+ } else {
+ pg = this.chapterPos;
+ startRange = this.pageMap[pg-1];
+ }
+ return this.pageMap[(this.chapterPos * 2) -1].start;
+};
+
+EPUBJS.Renderer.prototype.getRange = function(x, y, forceElement){
+ var range = this.doc.createRange();
+ var position;
+ forceElement = true; // temp override
+ if(typeof document.caretPositionFromPoint !== "undefined" && !forceElement){
+ position = this.doc.caretPositionFromPoint(x, y);
+ range.setStart(position.offsetNode, position.offset);
+ } else if(typeof document.caretRangeFromPoint !== "undefined" && !forceElement){
+ range = this.doc.caretRangeFromPoint(x, y);
+ } else {
+ this.visibileEl = this.findElementAfter(x, y);
+ range.setStart(this.visibileEl, 1);
+ }
+
+ // var test = this.doc.defaultView.getSelection();
+ // var r = this.doc.createRange();
+ // test.removeAllRanges();
+ // r.setStart(range.startContainer, range.startOffset);
+ // r.setEnd(range.startContainer, range.startOffset + 1);
+ // test.addRange(r);
+ return range;
+};
+
+/*
+EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(prevEl){
+ var startX = 0;
+ var startY = 0;
+ var endX = this.width-1;
+ var endY = this.height-1;
+ var startRange = this.getRange(startX, startY);
+ var endRange = this.getRange(endX, endY); //fix if carret not avail
+ var startCfi = this.currentChapter.cfiFromRange(startRange);
+ var endCfi;
+ if(endRange) {
+ endCfi = this.currentChapter.cfiFromRange(endRange);
+ }
+
+ return {
+ start: startCfi,
+ end: endCfi || false
+ };
+};
+*/
+
+EPUBJS.Renderer.prototype.pagesInCurrentChapter = function() {
+ var pgs;
+ var length;
+
+ if(!this.pageMap) {
+ console.warn("page map not loaded");
+ return false;
+ }
+
+ length = this.pageMap.length;
+
+ if(this.spreads){
+ pgs = Math.ceil(length / 2);
+ } else {
+ pgs = length;
+ }
+
+ return pgs;
+};
+
+EPUBJS.Renderer.prototype.currentRenderedPage = function(){
+ var pg;
+
+ if(!this.pageMap) {
+ console.warn("page map not loaded");
+ return false;
+ }
+
+ if (this.spreads && this.layout.pageCount > 1) {
+ pg = this.chapterPos*2;
+ } else {
+ pg = this.chapterPos;
+ }
+
+ return pg;
+};
+
+EPUBJS.Renderer.prototype.getRenderedPagesLeft = function(){
+ var pg;
+ var lastPage;
+ var pagesLeft;
+
+ if(!this.pageMap) {
+ console.warn("page map not loaded");
+ return false;
+ }
+
+ lastPage = this.pageMap.length;
+
+ if (this.spreads) {
+ pg = this.chapterPos*2;
+ } else {
+ pg = this.chapterPos;
+ }
+
+ pagesLeft = lastPage - pg;
+ return pagesLeft;
+
+};
+
+EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(){
+ var pg;
+ var startRange, endRange;
+
+ if(!this.pageMap) {
+ console.warn("page map not loaded");
+ return false;
+ }
+
+ if (this.spreads) {
+ pg = this.chapterPos*2;
+ startRange = this.pageMap[pg-2];
+ endRange = startRange;
+
+ if(this.layout.pageCount > 1) {
+ endRange = this.pageMap[pg-1];
+ }
+ } else {
+ pg = this.chapterPos;
+ startRange = this.pageMap[pg-1];
+ endRange = startRange;
+ }
+
+ if(!startRange) {
+ console.warn("page range miss:", pg, this.pageMap);
+ startRange = this.pageMap[this.pageMap.length-1];
+ endRange = startRange;
+ }
+
+ return {
+ start: startRange.start,
+ end: endRange.end
+ };
+};
+
+// Goto a cfi position in the current chapter
+EPUBJS.Renderer.prototype.gotoCfi = function(cfi){
+ var pg;
+ var marker;
+ var range;
+
+ if(this._moving){
+ return this._q.enqueue("gotoCfi", arguments);
+ }
+
+ if(_.isString(cfi)){
+ cfi = this.epubcfi.parse(cfi);
+ }
+
+ if(typeof document.evaluate === 'undefined') {
+ marker = this.epubcfi.addMarker(cfi, this.doc);
+ if(marker) {
+ pg = this.render.getPageNumberByElement(marker);
+ // Must Clean up Marker before going to page
+ this.epubcfi.removeMarker(marker, this.doc);
+ this.page(pg);
+ }
+ } else {
+ range = this.epubcfi.generateRangeFromCfi(cfi, this.doc);
+ if(range) {
+ pg = this.render.getPageNumberByRect(range.getBoundingClientRect());
+ this.page(pg);
+
+ // Reset the current location cfi to requested cfi
+ this.currentLocationCfi = cfi.str;
+ }
+ }
+};
+
+// Walk nodes until a visible element is found
+EPUBJS.Renderer.prototype.findFirstVisible = function(startEl){
+ var el = startEl || this.render.getBaseElement();
+ var found;
+ found = this.walk(el);
+
+ if(found) {
+ return found;
+ }else{
+ return startEl;
+ }
+
+};
+// TODO: remove me - unsused
+EPUBJS.Renderer.prototype.findElementAfter = function(x, y, startEl){
+ var el = startEl || this.render.getBaseElement();
+ var found;
+ found = this.walk(el, x, y);
+ if(found) {
+ return found;
+ }else{
+ return el;
+ }
+
+};
+
+/*
+EPUBJS.Renderer.prototype.route = function(hash, callback){
+ var location = window.location.hash.replace('#/', '');
+ if(this.useHash && location.length && location != this.prevLocation){
+ this.show(location, callback);
+ this.prevLocation = location;
+ return true;
+ }
+ return false;
+}
+
+EPUBJS.Renderer.prototype.hideHashChanges = function(){
+ this.useHash = false;
+}
+
+*/
+
+EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
+ var spreads;
+
+ this.width = width;
+ this.height = height;
+
+ if(setSize !== false) {
+ this.render.resize(this.width, this.height);
+ }
+
+
+
+ if(this.contents){
+ this.reformat();
+ }
+
+ this.trigger("renderer:resized", {
+ width: this.width,
+ height: this.height
+ });
+};
+
+//-- Listeners for events in the frame
+
+EPUBJS.Renderer.prototype.onResized = function(e) {
+ var width = this.container.clientWidth;
+ var height = this.container.clientHeight;
+
+ this.resize(width, height, false);
+};
+
+EPUBJS.Renderer.prototype.addEventListeners = function(){
+ if(!this.render.document) {
+ return;
+ }
+ this.listenedEvents.forEach(function(eventName){
+ this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
+ }, this);
+
+};
+
+EPUBJS.Renderer.prototype.removeEventListeners = function(){
+ if(!this.render.document) {
+ return;
+ }
+ this.listenedEvents.forEach(function(eventName){
+ this.render.document.removeEventListener(eventName, this.triggerEvent, false);
+ }, this);
+
+};
+
+// Pass browser events
+EPUBJS.Renderer.prototype.triggerEvent = function(e){
+ this.trigger("renderer:"+e.type, e);
+};
+
+EPUBJS.Renderer.prototype.addSelectionListeners = function(){
+ this.render.document.addEventListener("selectionchange", this.onSelectionChange.bind(this), false);
+};
+
+EPUBJS.Renderer.prototype.removeSelectionListeners = function(){
+ if(!this.render.document) {
+ return;
+ }
+ this.doc.removeEventListener("selectionchange", this.onSelectionChange, false);
+};
+
+EPUBJS.Renderer.prototype.onSelectionChange = function(e){
+ if (this.selectionEndTimeout) {
+ clearTimeout(this.selectionEndTimeout);
+ }
+ this.selectionEndTimeout = setTimeout(function() {
+ this.selectedRange = this.render.window.getSelection();
+ this.trigger("renderer:selected", this.selectedRange);
+ }.bind(this), 500);
+};
+
+
+//-- Spreads
+
+EPUBJS.Renderer.prototype.setMinSpreadWidth = function(width){
+ this.minSpreadWidth = width;
+ this.spreads = this.determineSpreads(width);
+};
+
+EPUBJS.Renderer.prototype.determineSpreads = function(cutoff){
+ if(this.isForcedSingle || !cutoff || this.width < cutoff) {
+ return false; //-- Single Page
+ }else{
+ return true; //-- Double Page
+ }
+};
+
+EPUBJS.Renderer.prototype.forceSingle = function(bool){
+ if(bool) {
+ this.isForcedSingle = true;
+ // this.spreads = false;
+ } else {
+ this.isForcedSingle = false;
+ // this.spreads = this.determineSpreads(this.minSpreadWidth);
+ }
+};
+
+EPUBJS.Renderer.prototype.setGap = function(gap){
+ this.gap = gap; //-- False == auto gap
+};
+
+//-- Content Replacements
+
+EPUBJS.Renderer.prototype.replace = function(query, func, finished, progress){
+ var items = this.contents.querySelectorAll(query),
+ resources = Array.prototype.slice.call(items),
+ count = resources.length;
+
+
+ if(count === 0) {
+ finished(false);
+ return;
+ }
+ resources.forEach(function(item){
+ var called = false;
+ var after = function(result, full){
+ if(called === false) {
+ count--;
+ if(progress) progress(result, full, count);
+ if(count <= 0 && finished) finished(true);
+ called = true;
+ }
+ };
+
+ func(item, after);
+
+ }.bind(this));
+
+};
+
+EPUBJS.Renderer.prototype.replaceWithStored = function(query, attr, func, callback) {
+ var _oldUrls,
+ _newUrls = {},
+ _store = this.currentChapter.store,
+ _cache = this.caches[query],
+ _uri = EPUBJS.core.uri(this.currentChapter.absolute),
+ _chapterBase = _uri.base,
+ _attr = attr,
+ _wait = 2000,
+ progress = function(url, full, count) {
+ _newUrls[full] = url;
+ },
+ finished = function(notempty) {
+ if(callback) callback();
+
+ _.each(_oldUrls, function(url){
+ _store.revokeUrl(url);
+ });
+
+ _cache = _newUrls;
+ };
+
+ if(!_store) return;
+
+ if(!_cache) _cache = {};
+ _oldUrls = _.clone(_cache);
+
+ this.replace(query, function(link, done){
+ var src = link.getAttribute(_attr),
+ full = EPUBJS.core.resolveUrl(_chapterBase, src);
+
+ var replaceUrl = function(url) {
+ var timeout;
+ link.onload = function(){
+ clearTimeout(timeout);
+ done(url, full);
+ };
+
+ link.onerror = function(e){
+ clearTimeout(timeout);
+ done(url, full);
+ console.error(e);
+ };
+
+ if(query == "image") {
+ //-- SVG needs this to trigger a load event
+ link.setAttribute("externalResourcesRequired", "true");
+ }
+
+ if(query == "link[href]" && link.getAttribute("rel") !== "stylesheet") {
+ //-- Only Stylesheet links seem to have a load events, just continue others
+ done(url, full);
+ }
+
+ link.setAttribute(_attr, url);
+
+ //-- If elements never fire Load Event, should continue anyways
+ timeout = setTimeout(function(){
+ done(url, full);
+ }, _wait);
+
+ };
+
+ if(full in _oldUrls){
+ replaceUrl(_oldUrls[full]);
+ _newUrls[full] = _oldUrls[full];
+ delete _oldUrls[full];
+ }else{
+ func(_store, full, replaceUrl, link);
+ }
+
+ }, finished, progress);
+};
+
+//-- Enable binding events to Renderer
+RSVP.EventTarget.mixin(EPUBJS.Renderer.prototype);
+
+var EPUBJS = EPUBJS || {};
+EPUBJS.replace = {};
+
+//-- Replaces the relative links within the book to use our internal page changer
+EPUBJS.replace.hrefs = function(callback, renderer){
+ var book = this;
+ var replacments = function(link, done){
+ var href = link.getAttribute("href"),
+ isRelative = href.search("://"),
+ directory,
+ relative;
+
+ if(isRelative != -1){
+
+ link.setAttribute("target", "_blank");
+
+ }else{
+
+ directory = EPUBJS.core.uri(renderer.render.window.location.href).directory;
+ relative = EPUBJS.core.resolveUrl(directory, href);
+
+ link.onclick = function(){
+ book.goto(relative);
+ return false;
+ };
+
+ }
+ done();
+
+ };
+
+ renderer.replace("a[href]", replacments, callback);
+
+};
+
+EPUBJS.replace.head = function(callback, renderer) {
+
+ renderer.replaceWithStored("link[href]", "href", EPUBJS.replace.links, callback);
+
+};
+
+
+//-- Replaces assets src's to point to stored version if browser is offline
+EPUBJS.replace.resources = function(callback, renderer){
+ //srcs = this.doc.querySelectorAll('[src]');
+ renderer.replaceWithStored("[src]", "src", EPUBJS.replace.srcs, callback);
+
+};
+
+EPUBJS.replace.svg = function(callback, renderer) {
+
+ renderer.replaceWithStored("image", "xlink:href", function(_store, full, done){
+ _store.getUrl(full).then(done);
+ }, callback);
+
+};
+
+EPUBJS.replace.srcs = function(_store, full, done){
+
+ _store.getUrl(full).then(done);
+
+};
+
+//-- Replaces links in head, such as stylesheets - link[href]
+EPUBJS.replace.links = function(_store, full, done, link){
+ //-- Handle replacing urls in CSS
+ if(link.getAttribute("rel") === "stylesheet") {
+ EPUBJS.replace.stylesheets(_store, full).then(function(url, full){
+ // done
+ setTimeout(function(){
+ done(url, full);
+ }, 5); //-- Allow for css to apply before displaying chapter
+ });
+ }else{
+ _store.getUrl(full).then(done);
+ }
+};
+
+EPUBJS.replace.stylesheets = function(_store, full) {
+ var deferred = new RSVP.defer();
+
+ if(!_store) return;
+
+ _store.getText(full).then(function(text){
+ var url;
+
+ EPUBJS.replace.cssUrls(_store, full, text).then(function(newText){
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+
+ var blob = new Blob([newText], { "type" : "text\/css" }),
+ url = _URL.createObjectURL(blob);
+
+ deferred.resolve(url);
+
+ }, function(e) {
+ console.error(e);
+ });
+
+ });
+
+ return deferred.promise;
+};
+
+EPUBJS.replace.cssUrls = function(_store, base, text){
+ var deferred = new RSVP.defer(),
+ promises = [],
+ matches = text.match(/url\(\'?\"?([^\'|^\"^\)]*)\'?\"?\)/g);
+
+ if(!_store) return;
+
+ if(!matches){
+ deferred.resolve(text);
+ return deferred.promise;
+ }
+
+ matches.forEach(function(str){
+ var full = EPUBJS.core.resolveUrl(base, str.replace(/url\(|[|\)|\'|\"]/g, ''));
+ var replaced = _store.getUrl(full).then(function(url){
+ text = text.replace(str, 'url("'+url+'")');
+ });
+
+ promises.push(replaced);
+ });
+
+ RSVP.all(promises).then(function(){
+ deferred.resolve(text);
+ });
+
+ return deferred.promise;
+};
+
+EPUBJS.Unarchiver = function(url){
+
+ this.libPath = EPUBJS.filePath;
+ this.zipUrl = url;
+ this.loadLib();
+ this.urlCache = {};
+
+ this.zipFs = new zip.fs.FS();
+
+ return this.promise;
+
+};
+
+//-- Load the zip lib and set the workerScriptsPath
+EPUBJS.Unarchiver.prototype.loadLib = function(callback){
+ if(typeof(zip) == "undefined") console.error("Zip lib not loaded");
+
+ /*
+ //-- load script
+ EPUBJS.core.loadScript(this.libPath+"zip.js", function(){
+ //-- Tell zip where it is located
+ zip.workerScriptsPath = this.libPath;
+ callback();
+ }.bind(this));
+ */
+ // console.log(this.libPath)
+ zip.workerScriptsPath = this.libPath;
+};
+
+EPUBJS.Unarchiver.prototype.openZip = function(zipUrl, callback){
+ var deferred = new RSVP.defer();
+ var zipFs = this.zipFs;
+ zipFs.importHttpContent(zipUrl, false, function() {
+ deferred.resolve(zipFs);
+ }, this.failed);
+
+ return deferred.promise;
+};
+
+EPUBJS.Unarchiver.prototype.getXml = function(url, encoding){
+
+ return this.getText(url, encoding).
+ then(function(text){
+ var parser = new DOMParser();
+ return parser.parseFromString(text, "application/xml");
+ });
+
+};
+
+EPUBJS.Unarchiver.prototype.getUrl = function(url, mime){
+ var unarchiver = this;
+ var deferred = new RSVP.defer();
+ var decodededUrl = window.decodeURIComponent(url);
+ var entry = this.zipFs.find(decodededUrl);
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+
+ if(!entry) {
+ deferred.reject({
+ message : "File not found in the epub: " + url,
+ stack : new Error().stack
+ });
+ return deferred.promise;
+ }
+
+ if(url in this.urlCache) {
+ deferred.resolve(this.urlCache[url]);
+ return deferred.promise;
+ }
+
+ entry.getBlob(mime || zip.getMimeType(entry.name), function(blob){
+ var tempUrl = _URL.createObjectURL(blob);
+ deferred.resolve(tempUrl);
+ unarchiver.urlCache[url] = tempUrl;
+ });
+
+ return deferred.promise;
+};
+
+EPUBJS.Unarchiver.prototype.getText = function(url, encoding){
+ var unarchiver = this;
+ var deferred = new RSVP.defer();
+ var decodededUrl = window.decodeURIComponent(url);
+ var entry = this.zipFs.find(decodededUrl);
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+
+ if(!entry) {
+ console.warn("File not found in the contained epub:", url);
+ return deferred.promise;
+ }
+
+ entry.getText(function(text){
+ deferred.resolve(text);
+ }, null, null, encoding || 'UTF-8');
+
+ return deferred.promise;
+};
+
+EPUBJS.Unarchiver.prototype.revokeUrl = function(url){
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ var fromCache = unarchiver.urlCache[url];
+ if(fromCache) _URL.revokeObjectURL(fromCache);
+};
+
+EPUBJS.Unarchiver.prototype.failed = function(error){
+ console.error(error);
+};
+
+EPUBJS.Unarchiver.prototype.afterSaved = function(error){
+ this.callback();
+};
+
+EPUBJS.Unarchiver.prototype.toStorage = function(entries){
+ var timeout = 0,
+ delay = 20,
+ that = this,
+ count = entries.length;
+
+ function callback(){
+ count--;
+ if(count === 0) that.afterSaved();
+ }
+
+ entries.forEach(function(entry){
+
+ setTimeout(function(entry){
+ that.saveEntryFileToStorage(entry, callback);
+ }, timeout, entry);
+
+ timeout += delay;
+ });
+
+ console.log("time", timeout);
+
+ //entries.forEach(this.saveEntryFileToStorage.bind(this));
+};
+
+EPUBJS.Unarchiver.prototype.saveEntryFileToStorage = function(entry, callback){
+ var that = this;
+ entry.getData(new zip.BlobWriter(), function(blob) {
+ EPUBJS.storage.save(entry.filename, blob, callback);
+ });
+};
+
+//# sourceMappingURL=epub.js.map
\ No newline at end of file
diff --git a/files_reader/js/epub.min.js b/files_reader/js/epub.min.js
new file mode 100644
index 0000000..b8a972a
--- /dev/null
+++ b/files_reader/js/epub.min.js
@@ -0,0 +1,4 @@
+(function(){var a=this,b=a._,c={},d=Array.prototype,e=Object.prototype,f=Function.prototype,g=d.push,h=d.slice,i=d.concat,j=e.toString,k=e.hasOwnProperty,l=d.forEach,m=d.map,n=d.reduce,o=d.reduceRight,p=d.filter,q=d.every,r=d.some,s=d.indexOf,t=d.lastIndexOf,u=Array.isArray,v=Object.keys,w=f.bind,x=function(a){return a instanceof x?a:this instanceof x?void(this._wrapped=a):new x(a)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=x),exports._=x):a._=x,x.VERSION="1.4.4";var y=x.each=x.forEach=function(a,b,d){if(null!=a)if(l&&a.forEach===l)a.forEach(b,d);else if(a.length===+a.length){for(var e=0,f=a.length;f>e;e++)if(b.call(d,a[e],e,a)===c)return}else for(var g in a)if(x.has(a,g)&&b.call(d,a[g],g,a)===c)return};x.map=x.collect=function(a,b,c){var d=[];return null==a?d:m&&a.map===m?a.map(b,c):(y(a,function(a,e,f){d[d.length]=b.call(c,a,e,f)}),d)};var z="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(a,b,c,d){var e=arguments.length>2;if(null==a&&(a=[]),n&&a.reduce===n)return d&&(b=x.bind(b,d)),e?a.reduce(b,c):a.reduce(b);if(y(a,function(a,f,g){e?c=b.call(d,c,a,f,g):(c=a,e=!0)}),!e)throw new TypeError(z);return c},x.reduceRight=x.foldr=function(a,b,c,d){var e=arguments.length>2;if(null==a&&(a=[]),o&&a.reduceRight===o)return d&&(b=x.bind(b,d)),e?a.reduceRight(b,c):a.reduceRight(b);var f=a.length;if(f!==+f){var g=x.keys(a);f=g.length}if(y(a,function(h,i,j){i=g?g[--f]:--f,e?c=b.call(d,c,a[i],i,j):(c=a[i],e=!0)}),!e)throw new TypeError(z);return c},x.find=x.detect=function(a,b,c){var d;return A(a,function(a,e,f){return b.call(c,a,e,f)?(d=a,!0):void 0}),d},x.filter=x.select=function(a,b,c){var d=[];return null==a?d:p&&a.filter===p?a.filter(b,c):(y(a,function(a,e,f){b.call(c,a,e,f)&&(d[d.length]=a)}),d)},x.reject=function(a,b,c){return x.filter(a,function(a,d,e){return!b.call(c,a,d,e)},c)},x.every=x.all=function(a,b,d){b||(b=x.identity);var e=!0;return null==a?e:q&&a.every===q?a.every(b,d):(y(a,function(a,f,g){return(e=e&&b.call(d,a,f,g))?void 0:c}),!!e)};var A=x.some=x.any=function(a,b,d){b||(b=x.identity);var e=!1;return null==a?e:r&&a.some===r?a.some(b,d):(y(a,function(a,f,g){return e||(e=b.call(d,a,f,g))?c:void 0}),!!e)};x.contains=x.include=function(a,b){return null==a?!1:s&&a.indexOf===s?-1!=a.indexOf(b):A(a,function(a){return a===b})},x.invoke=function(a,b){var c=h.call(arguments,2),d=x.isFunction(b);return x.map(a,function(a){return(d?b:a[b]).apply(a,c)})},x.pluck=function(a,b){return x.map(a,function(a){return a[b]})},x.where=function(a,b,c){return x.isEmpty(b)?c?null:[]:x[c?"find":"filter"](a,function(a){for(var c in b)if(b[c]!==a[c])return!1;return!0})},x.findWhere=function(a,b){return x.where(a,b,!0)},x.max=function(a,b,c){if(!b&&x.isArray(a)&&a[0]===+a[0]&&65535>a.length)return Math.max.apply(Math,a);if(!b&&x.isEmpty(a))return-1/0;var d={computed:-1/0,value:-1/0};return y(a,function(a,e,f){var g=b?b.call(c,a,e,f):a;g>=d.computed&&(d={value:a,computed:g})}),d.value},x.min=function(a,b,c){if(!b&&x.isArray(a)&&a[0]===+a[0]&&65535>a.length)return Math.min.apply(Math,a);if(!b&&x.isEmpty(a))return 1/0;var d={computed:1/0,value:1/0};return y(a,function(a,e,f){var g=b?b.call(c,a,e,f):a;d.computed>g&&(d={value:a,computed:g})}),d.value},x.shuffle=function(a){var b,c=0,d=[];return y(a,function(a){b=x.random(c++),d[c-1]=d[b],d[b]=a}),d};var B=function(a){return x.isFunction(a)?a:function(b){return b[a]}};x.sortBy=function(a,b,c){var d=B(b);return x.pluck(x.map(a,function(a,b,e){return{value:a,index:b,criteria:d.call(c,a,b,e)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;if(c!==d){if(c>d||void 0===c)return 1;if(d>c||void 0===d)return-1}return a.indexf;){var h=f+g>>>1;e>c.call(d,a[h])?f=h+1:g=h}return f},x.toArray=function(a){return a?x.isArray(a)?h.call(a):a.length===+a.length?x.map(a,x.identity):x.values(a):[]},x.size=function(a){return null==a?0:a.length===+a.length?a.length:x.keys(a).length},x.first=x.head=x.take=function(a,b,c){return null==a?void 0:null==b||c?a[0]:h.call(a,0,b)},x.initial=function(a,b,c){return h.call(a,0,a.length-(null==b||c?1:b))},x.last=function(a,b,c){return null==a?void 0:null==b||c?a[a.length-1]:h.call(a,Math.max(a.length-b,0))},x.rest=x.tail=x.drop=function(a,b,c){return h.call(a,null==b||c?1:b)},x.compact=function(a){return x.filter(a,x.identity)};var D=function(a,b,c){return y(a,function(a){x.isArray(a)?b?g.apply(c,a):D(a,b,c):c.push(a)}),c};x.flatten=function(a,b){return D(a,b,[])},x.without=function(a){return x.difference(a,h.call(arguments,1))},x.uniq=x.unique=function(a,b,c,d){x.isFunction(b)&&(d=c,c=b,b=!1);var e=c?x.map(a,c,d):a,f=[],g=[];return y(e,function(c,d){(b?d&&g[g.length-1]===c:x.contains(g,c))||(g.push(c),f.push(a[d]))}),f},x.union=function(){return x.uniq(i.apply(d,arguments))},x.intersection=function(a){var b=h.call(arguments,1);return x.filter(x.uniq(a),function(a){return x.every(b,function(b){return x.indexOf(b,a)>=0})})},x.difference=function(a){var b=i.apply(d,h.call(arguments,1));return x.filter(a,function(a){return!x.contains(b,a)})},x.zip=function(){for(var a=h.call(arguments),b=x.max(x.pluck(a,"length")),c=Array(b),d=0;b>d;d++)c[d]=x.pluck(a,""+d);return c},x.object=function(a,b){if(null==a)return{};for(var c={},d=0,e=a.length;e>d;d++)b?c[a[d]]=b[d]:c[a[d][0]]=a[d][1];return c},x.indexOf=function(a,b,c){if(null==a)return-1;var d=0,e=a.length;if(c){if("number"!=typeof c)return d=x.sortedIndex(a,b),a[d]===b?d:-1;d=0>c?Math.max(0,e+c):c}if(s&&a.indexOf===s)return a.indexOf(b,c);for(;e>d;d++)if(a[d]===b)return d;return-1},x.lastIndexOf=function(a,b,c){if(null==a)return-1;var d=null!=c;if(t&&a.lastIndexOf===t)return d?a.lastIndexOf(b,c):a.lastIndexOf(b);for(var e=d?c:a.length;e--;)if(a[e]===b)return e;return-1},x.range=function(a,b,c){1>=arguments.length&&(b=a||0,a=0),c=arguments[2]||1;for(var d=Math.max(Math.ceil((b-a)/c),0),e=0,f=Array(d);d>e;)f[e++]=a,a+=c;return f},x.bind=function(a,b){if(a.bind===w&&w)return w.apply(a,h.call(arguments,1));var c=h.call(arguments,2);return function(){return a.apply(b,c.concat(h.call(arguments)))}},x.partial=function(a){var b=h.call(arguments,1);return function(){return a.apply(this,b.concat(h.call(arguments)))}},x.bindAll=function(a){var b=h.call(arguments,1);return 0===b.length&&(b=x.functions(a)),y(b,function(b){a[b]=x.bind(a[b],a)}),a},x.memoize=function(a,b){var c={};return b||(b=x.identity),function(){var d=b.apply(this,arguments);return x.has(c,d)?c[d]:c[d]=a.apply(this,arguments)}},x.delay=function(a,b){var c=h.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)},x.defer=function(a){return x.delay.apply(x,[a,1].concat(h.call(arguments,1)))},x.throttle=function(a,b){var c,d,e,f,g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)};return function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},x.debounce=function(a,b,c){var d,e;return function(){var f=this,g=arguments,h=function(){d=null,c||(e=a.apply(f,g))},i=c&&!d;return clearTimeout(d),d=setTimeout(h,b),i&&(e=a.apply(f,g)),e}},x.once=function(a){var b,c=!1;return function(){return c?b:(c=!0,b=a.apply(this,arguments),a=null,b)}},x.wrap=function(a,b){return function(){var c=[a];return g.apply(c,arguments),b.apply(this,c)}},x.compose=function(){var a=arguments;return function(){for(var b=arguments,c=a.length-1;c>=0;c--)b=[a[c].apply(this,b)];return b[0]}},x.after=function(a,b){return 0>=a?b():function(){return 1>--a?b.apply(this,arguments):void 0}},x.keys=v||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[];for(var c in a)x.has(a,c)&&(b[b.length]=c);return b},x.values=function(a){var b=[];for(var c in a)x.has(a,c)&&b.push(a[c]);return b},x.pairs=function(a){var b=[];for(var c in a)x.has(a,c)&&b.push([c,a[c]]);return b},x.invert=function(a){var b={};for(var c in a)x.has(a,c)&&(b[a[c]]=c);return b},x.functions=x.methods=function(a){var b=[];for(var c in a)x.isFunction(a[c])&&b.push(c);return b.sort()},x.extend=function(a){return y(h.call(arguments,1),function(b){if(b)for(var c in b)a[c]=b[c]}),a},x.pick=function(a){var b={},c=i.apply(d,h.call(arguments,1));return y(c,function(c){c in a&&(b[c]=a[c])}),b},x.omit=function(a){var b={},c=i.apply(d,h.call(arguments,1));for(var e in a)x.contains(c,e)||(b[e]=a[e]);return b},x.defaults=function(a){return y(h.call(arguments,1),function(b){if(b)for(var c in b)null==a[c]&&(a[c]=b[c])}),a},x.clone=function(a){return x.isObject(a)?x.isArray(a)?a.slice():x.extend({},a):a},x.tap=function(a,b){return b(a),a};var E=function(a,b,c,d){if(a===b)return 0!==a||1/a==1/b;if(null==a||null==b)return a===b;a instanceof x&&(a=a._wrapped),b instanceof x&&(b=b._wrapped);var e=j.call(a);if(e!=j.call(b))return!1;switch(e){case"[object String]":return a==b+"";case"[object Number]":return a!=+a?b!=+b:0==a?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if("object"!=typeof a||"object"!=typeof b)return!1;for(var f=c.length;f--;)if(c[f]==a)return d[f]==b;c.push(a),d.push(b);var g=0,h=!0;if("[object Array]"==e){if(g=a.length,h=g==b.length)for(;g--&&(h=E(a[g],b[g],c,d)););}else{var i=a.constructor,k=b.constructor;if(i!==k&&!(x.isFunction(i)&&i instanceof i&&x.isFunction(k)&&k instanceof k))return!1;for(var l in a)if(x.has(a,l)&&(g++,!(h=x.has(b,l)&&E(a[l],b[l],c,d))))break;if(h){for(l in b)if(x.has(b,l)&&!g--)break;h=!g}}return c.pop(),d.pop(),h};x.isEqual=function(a,b){return E(a,b,[],[])},x.isEmpty=function(a){if(null==a)return!0;if(x.isArray(a)||x.isString(a))return 0===a.length;for(var b in a)if(x.has(a,b))return!1;return!0},x.isElement=function(a){return!(!a||1!==a.nodeType)},x.isArray=u||function(a){return"[object Array]"==j.call(a)},x.isObject=function(a){return a===Object(a)},y(["Arguments","Function","String","Number","Date","RegExp"],function(a){x["is"+a]=function(b){return j.call(b)=="[object "+a+"]"}}),x.isArguments(arguments)||(x.isArguments=function(a){return!(!a||!x.has(a,"callee"))}),"function"!=typeof/./&&(x.isFunction=function(a){return"function"==typeof a}),x.isFinite=function(a){return isFinite(a)&&!isNaN(parseFloat(a))},x.isNaN=function(a){return x.isNumber(a)&&a!=+a},x.isBoolean=function(a){return a===!0||a===!1||"[object Boolean]"==j.call(a)},x.isNull=function(a){return null===a},x.isUndefined=function(a){return void 0===a},x.has=function(a,b){return k.call(a,b)},x.noConflict=function(){return a._=b,this},x.identity=function(a){return a},x.times=function(a,b,c){for(var d=Array(a),e=0;a>e;e++)d[e]=b.call(c,e);return d},x.random=function(a,b){return null==b&&(b=a,a=0),a+Math.floor(Math.random()*(b-a+1))};var F={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};F.unescape=x.invert(F.escape);var G={escape:RegExp("["+x.keys(F.escape).join("")+"]","g"),unescape:RegExp("("+x.keys(F.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(a){x[a]=function(b){return null==b?"":(""+b).replace(G[a],function(b){return F[a][b]})}}),x.result=function(a,b){if(null==a)return null;var c=a[b];return x.isFunction(c)?c.call(a):c},x.mixin=function(a){y(x.functions(a),function(b){var c=x[b]=a[b];x.prototype[b]=function(){var a=[this._wrapped];return g.apply(a,arguments),L.call(this,c.apply(x,a))}})};var H=0;x.uniqueId=function(a){var b=++H+"";return a?a+b:b},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var I=/(.)^/,J={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},K=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(a,b,c){var d;c=x.defaults({},c,x.templateSettings);var e=RegExp([(c.escape||I).source,(c.interpolate||I).source,(c.evaluate||I).source].join("|")+"|$","g"),f=0,g="__p+='";a.replace(e,function(b,c,d,e,h){return g+=a.slice(f,h).replace(K,function(a){return"\\"+J[a]}),c&&(g+="'+\n((__t=("+c+"))==null?'':_.escape(__t))+\n'"),d&&(g+="'+\n((__t=("+d+"))==null?'':__t)+\n'"),e&&(g+="';\n"+e+"\n__p+='"),f=h+b.length,b}),g+="';\n",c.variable||(g="with(obj||{}){\n"+g+"}\n"),g="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+g+"return __p;\n";try{d=Function(c.variable||"obj","_",g)}catch(h){throw h.source=g,h}if(b)return d(b,x);var i=function(a){return d.call(this,a,x)};return i.source="function("+(c.variable||"obj")+"){\n"+g+"}",i},x.chain=function(a){return x(a).chain()};var L=function(a){return this._chain?x(a).chain():a};x.mixin(x),y(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=d[a];x.prototype[a]=function(){var c=this._wrapped;return b.apply(c,arguments),"shift"!=a&&"splice"!=a||0!==c.length||delete c[0],L.call(this,c)}}),y(["concat","join","slice"],function(a){var b=d[a];x.prototype[a]=function(){return L.call(this,b.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),function(a){var b,c,d,e;!function(){var a={},f={};b=function(b,c,d){a[b]={deps:c,callback:d}},e=d=c=function(b){function d(a){if("."!==a.charAt(0))return a;for(var c=a.split("/"),d=b.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(e._eak_seen=a,f[b])return f[b];if(f[b]={},!a[b])throw new Error("Could not find module "+b);for(var g,h=a[b],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:c(d(i[l])));var n=j.apply(this,k);return f[b]=g||n}}(),b("rsvp/all",["./promise","exports"],function(a,b){"use strict";var c=a["default"];b["default"]=function(a,b){return c.all(a,b)}}),b("rsvp/all_settled",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(a){return{state:"fulfilled",value:a}}function e(a){return{state:"rejected",reason:a}}var f=a["default"],g=b.isArray,h=b.isNonThenable;c["default"]=function(a,b){return new f(function(b){function c(a){return function(b){j(a,d(b))}}function i(a){return function(b){j(a,e(b))}}function j(a,c){m[a]=c,0===--l&&b(m)}if(!g(a))throw new TypeError("You must pass an array to allSettled.");var k,l=a.length;if(0===l)return void b([]);for(var m=new Array(l),n=0;nc;c++)if(a[c]===b)return c;return-1},c=function(a){var b=a._promiseCallbacks;return b||(b=a._promiseCallbacks={}),b};a["default"]={mixin:function(a){return a.on=this.on,a.off=this.off,a.trigger=this.trigger,a._promiseCallbacks=void 0,a},on:function(a,d){var e,f=c(this);e=f[a],e||(e=f[a]=[]),-1===b(e,d)&&e.push(d)},off:function(a,d){var e,f,g=c(this);return d?(e=g[a],f=b(e,d),void(-1!==f&&e.splice(f,1))):void(g[a]=[])},trigger:function(a,b){var d,e,f=c(this);if(d=f[a])for(var g=0;gb;b++)a[b]&&e.push(d[b]);return e})})}var f=a["default"],g=b["default"],h=c.isFunction,i=c.isArray;d["default"]=e}),b("rsvp/hash",["./promise","./utils","exports"],function(a,b,c){"use strict";var d=a["default"],e=b.isNonThenable,f=b.keysOf;c["default"]=function(a){return new d(function(b,c){function g(a){return function(c){k[a]=c,0===--m&&b(k)}}function h(a){m=0,c(a)}var i,j,k={},l=f(a),m=l.length;if(0===m)return void b(k);for(var n=0;nd;d++)g.push(b(a[d]));return e(g,c)})}}),b("rsvp/node",["./promise","exports"],function(a,b){"use strict";function c(a,b){return function(c,d){c?b(c):a(arguments.length>2?e.call(arguments,1):d)}}var d=a["default"],e=Array.prototype.slice;b["default"]=function(a,b){return function(){var f=e.call(arguments),g=this||b;return new d(function(b,e){d.all(f).then(function(d){try{d.push(c(b,e)),a.apply(g,d)}catch(f){e(f)}})})}}}),b("rsvp/promise",["./config","./events","./instrument","./utils","./promise/cast","./promise/all","./promise/race","./promise/resolve","./promise/reject","exports"],function(a,b,c,d,e,f,g,h,i,j){"use strict";function k(){}function l(a,b){if(!z(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof l))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._id=H++,this._label=b,this._subscribers=[],w.instrument&&x("created",this),k!==a&&m(a,this)}function m(a,b){function c(a){r(b,a)}function d(a){t(b,a)}try{a(c,d)}catch(e){d(e)}}function n(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+K]=c,e[f+L]=d}function o(a,b){var c,d,e=a._subscribers,f=a._detail;w.instrument&&x(b===K?"fulfilled":"rejected",a);for(var g=0;g=h?f.resolve():(g=e,b=new EPUBJS.Chapter(this.spine[g],this.store),d.displayChapter(b,this.globalLayoutProperties).then(function(){d.pageMap.forEach(function(a){i+=1,c.push({cfi:a.start,page:i})}),d.pageMap.length%2>0&&d.spreads&&(i+=1,c.push({cfi:d.pageMap[d.pageMap.length-1].end,page:i})),setTimeout(function(){j(f)},1)})),f.promise}.bind(this);j().then(function(){d.remove(),this.element.removeChild(e),f.resolve(c)}.bind(this))}return f.promise},EPUBJS.Book.prototype.generatePagination=function(a,b){var c=this,d=new RSVP.defer;return this.ready.spine.promise.then(function(){c.generatePageList(a,b).then(function(a){c.pageList=c.contents.pageList=a,c.pagination.process(a),c.ready.pageList.resolve(c.pageList),d.resolve(c.pageList)})}),d.promise},EPUBJS.Book.prototype.loadPagination=function(a){var b=JSON.parse(a);return b&&b.length&&(this.pageList=b,this.pagination.process(this.pageList),this.ready.pageList.resolve(this.pageList)),this.pageList},EPUBJS.Book.prototype.getPageList=function(){return this.ready.pageList.promise},EPUBJS.Book.prototype.getMetadata=function(){return this.ready.metadata.promise},EPUBJS.Book.prototype.getToc=function(){return this.ready.toc.promise
+},EPUBJS.Book.prototype.networkListeners=function(){var a=this;window.addEventListener("offline",function(){a.online=!1,a.trigger("book:offline")},!1),window.addEventListener("online",function(){a.online=!0,a.trigger("book:online")},!1)},EPUBJS.Book.prototype.listenToRenderer=function(a){var b=this;a.Events.forEach(function(c){a.on(c,function(a){b.trigger(c,a)})}),a.on("renderer:visibleRangeChanged",function(a){var b,c,d,e=[];this.pageList.length>0&&(b=this.pagination.pageFromCfi(a.start),d=this.pagination.percentageFromPage(b),e.push(b),a.end&&(c=this.pagination.pageFromCfi(a.end),e.push(c)),this.trigger("book:pageChanged",{anchorPage:b,percentage:d,pageRange:e}))}.bind(this)),a.on("render:loaded",this.loadChange.bind(this))},EPUBJS.Book.prototype.loadChange=function(a){var b,c=EPUBJS.core.uri(a);this.currentChapter&&(b=EPUBJS.core.uri(this.currentChapter.absolute)),!this._rendering&&this.currentChapter&&c.path!=b.path&&(console.warn("Miss Match",c.path,this.currentChapter.absolute),this.goto(c.filename))},EPUBJS.Book.prototype.unlistenToRenderer=function(a){a.Events.forEach(function(b){a.off(b)})},EPUBJS.Book.prototype.loadXml=function(a){return this.settings.fromStorage?this.storage.getXml(a,this.settings.encoding):this.settings.contained?this.zip.getXml(a,this.settings.encoding):EPUBJS.core.request(a,"xml",this.settings.withCredentials)},EPUBJS.Book.prototype.urlFrom=function(a){var b,c=EPUBJS.core.uri(a),d=c.protocol,e="/"==c.path[0],f=window.location,g=f.origin||f.protocol+"//"+f.host,h=document.getElementsByTagName("base");return h.length&&(b=h[0].href),c.protocol?c.origin+c.path:!d&&e?(b||g)+c.path:d||e?void 0:EPUBJS.core.resolveUrl(b||f.pathname,c.path)},EPUBJS.Book.prototype.unarchive=function(a){return this.zip=new EPUBJS.Unarchiver,this.store=this.zip,this.zip.openZip(a)},EPUBJS.Book.prototype.isContained=function(a){var b=EPUBJS.core.uri(a);return!b.extension||"epub"!=b.extension&&"zip"!=b.extension?!1:!0},EPUBJS.Book.prototype.isSaved=function(a){var b;return localStorage?(b=localStorage.getItem(a),localStorage&&null!==b?!0:!1):!1},EPUBJS.Book.prototype.generateBookKey=function(a){return"epubjs:"+EPUBJS.VERSION+":"+window.location.host+":"+a},EPUBJS.Book.prototype.saveContents=function(){return localStorage?void localStorage.setItem(this.settings.bookKey,JSON.stringify(this.contents)):!1},EPUBJS.Book.prototype.removeSavedContents=function(){return localStorage?void localStorage.removeItem(this.settings.bookKey):!1},EPUBJS.Book.prototype.renderTo=function(a){var b,c=this;if(_.isElement(a))this.element=a;else{if("string"!=typeof a)return void console.error("Not an Element");this.element=EPUBJS.core.getEl(a)}return b=this.opened.then(function(){return c.renderer.initialize(c.element,c.settings.width,c.settings.height),c._rendered(),c.startDisplay()})},EPUBJS.Book.prototype.startDisplay=function(){var a;return a=this.settings.goto?this.goto(this.settings.goto):this.settings.previousLocationCfi?this.gotoCfi(this.settings.previousLocationCfi):this.displayChapter(this.spinePos)},EPUBJS.Book.prototype.restore=function(a){var b,c=this,d=["manifest","spine","metadata","cover","toc","spineNodeIndex","spineIndexByURL","globalLayoutProperties"],e=!1,f=this.generateBookKey(a),g=localStorage.getItem(f),h=d.length;if(this.settings.clearSaved&&(e=!0),!e&&"undefined"!=g&&null!==g)for(c.contents=JSON.parse(g),b=0;h>b;b++){var i=d[b];if(!c.contents[i]){e=!0;break}c[i]=c.contents[i]}return!e&&g&&this.contents&&this.settings.contentsPath?(this.settings.bookKey=f,this.ready.manifest.resolve(this.manifest),this.ready.spine.resolve(this.spine),this.ready.metadata.resolve(this.metadata),this.ready.cover.resolve(this.cover),this.ready.toc.resolve(this.toc),!0):!1},EPUBJS.Book.prototype.displayChapter=function(a,b,c){var d,e,f,g,h=this,i=c||new RSVP.defer;return this.isRendered?this._rendering||this._rendering?(this._displayQ.enqueue("displayChapter",[a,b,i]),i.promise):(_.isNumber(a)?f=a:(e=new EPUBJS.EpubCFI(a),f=e.spinePos),(0>f||f>=this.spine.length)&&(console.warn("Not A Valid Location"),f=0,b=!1,e=!1),g=new EPUBJS.Chapter(this.spine[f],this.store),this._rendering=!0,d=h.renderer.displayChapter(g,this.globalLayoutProperties),e?h.renderer.gotoCfi(e):b&&h.renderer.lastPage(),d.then(function(){h.spinePos=f,i.resolve(h.renderer),h.settings.fromStorage||h.settings.contained||h.preloadNextChapter(),h.currentChapter=g,h._rendering=!1,h._displayQ.dequeue(),0===h._displayQ.length()&&h._gotoQ.dequeue()},function(a){console.error("Could not load Chapter: "+g.absolute),h.trigger("book:chapterLoadFailed",g.absolute),h._rendering=!1,i.reject(a)}),i.promise):(this._q.enqueue("displayChapter",arguments),i.reject({message:"Rendering",stack:(new Error).stack}),i.promise)},EPUBJS.Book.prototype.nextPage=function(){var a;return this.isRendered?(a=this.renderer.nextPage(),a?void 0:this.nextChapter()):this._q.enqueue("nextPage",arguments)},EPUBJS.Book.prototype.prevPage=function(){var a;return this.isRendered?(a=this.renderer.prevPage(),a?void 0:this.prevChapter()):this._q.enqueue("prevPage",arguments)},EPUBJS.Book.prototype.nextChapter=function(){var a;if(this.spinePos0){for(a=this.spinePos-1;this.spine[a]&&this.spine[a].linear&&"no"==this.spine[a].linear;)a--;if(a>=0)return this.displayChapter(a,!0);this.trigger("book:atStart")}else this.trigger("book:atStart")},EPUBJS.Book.prototype.getCurrentLocationCfi=function(){return this.isRendered?this.renderer.currentLocationCfi:!1},EPUBJS.Book.prototype.goto=function(a){return 0===a.indexOf("epubcfi(")?this.gotoCfi(a):a.indexOf("%")===a.length-1?this.gotoPercentage(parseInt(a.substring(0,a.length-1))/100):"number"==typeof a||isNaN(a)===!1?this.gotoPage(a):this.gotoHref(a)},EPUBJS.Book.prototype.gotoCfi=function(a,b){var c,d,e,f=b||new RSVP.defer;return this.isRendered?this._moving||this._rendering?(console.warn("Renderer is moving"),this._gotoQ.enqueue("gotoCfi",[a,f]),!1):(c=new EPUBJS.EpubCFI(a),d=c.spinePos,-1==d?!1:(e=this.spine[d],promise=f.promise,this._moving=!0,this.currentChapter&&this.spinePos===d?(this.renderer.gotoCfi(c),this._moving=!1,f.resolve(this.renderer.currentLocationCfi)):(e&&-1!=d||(d=0,e=this.spine[d]),this.currentChapter=new EPUBJS.Chapter(e,this.store),this.currentChapter&&(this.spinePos=d,render=this.renderer.displayChapter(this.currentChapter,this.globalLayoutProperties),this.renderer.gotoCfi(c),render.then(function(a){this._moving=!1,f.resolve(a.currentLocationCfi)}.bind(this)))),promise.then(function(){this._gotoQ.dequeue()}.bind(this)),promise)):(console.warn("Not yet Rendered"),this.settings.previousLocationCfi=a,!1)},EPUBJS.Book.prototype.gotoHref=function(a,b){var c,d,e,f,g,h=b||new RSVP.defer;return this.isRendered?this._moving||this._rendering?(this._gotoQ.enqueue("gotoHref",[a,h]),!1):(c=a.split("#"),d=c[0],e=c[1]||!1,f=d.replace(this.settings.contentsPath,""),g=this.spineIndexByURL[f],d||(g=this.currentChapter?this.currentChapter.spinePos:0),"number"!=typeof g?!1:this.currentChapter&&g==this.currentChapter.spinePos?(e?this.renderer.section(e):this.renderer.firstPage(),h.resolve(this.renderer.currentLocationCfi),h.promise.then(function(){this._gotoQ.dequeue()}.bind(this)),h.promise):this.displayChapter(g).then(function(){e&&this.renderer.section(e),h.resolve(this.renderer.currentLocationCfi)}.bind(this))):(this.settings.goto=a,!1)},EPUBJS.Book.prototype.gotoPage=function(a){var b=this.pagination.cfiFromPage(a);return this.gotoCfi(b)},EPUBJS.Book.prototype.gotoPercentage=function(a){var b=this.pagination.pageFromPercentage(a);return this.gotoPage(b)},EPUBJS.Book.prototype.preloadNextChapter=function(){var a,b=this.spinePos+1;return b>=this.spine.length?!1:(a=new EPUBJS.Chapter(this.spine[b]),void(a&&EPUBJS.core.request(a.absolute)))},EPUBJS.Book.prototype.storeOffline=function(){var a=this,b=_.values(this.manifest);return EPUBJS.storage.batch(b).then(function(){a.settings.stored=!0,a.trigger("book:stored")})},EPUBJS.Book.prototype.availableOffline=function(){return this.settings.stored>0?!0:!1},EPUBJS.Book.prototype.setStyle=function(a,b,c){var d=["color","background","background-color"];return this.isRendered?(this.settings.styles[a]=b,this.renderer.setStyle(a,b,c),void(-1===d.indexOf(a)&&this.renderer.reformat())):this._q.enqueue("setStyle",arguments)},EPUBJS.Book.prototype.removeStyle=function(a){return this.isRendered?(this.renderer.removeStyle(a),this.renderer.reformat(),void delete this.settings.styles[a]):this._q.enqueue("removeStyle",arguments)},EPUBJS.Book.prototype.addHeadTag=function(a,b){return this.isRendered?void(this.settings.headTags[a]=b):this._q.enqueue("addHeadTag",arguments)},EPUBJS.Book.prototype.useSpreads=function(a){console.warn("useSpreads is deprecated, use forceSingle or set a layoutOveride instead"),this.forceSingle(a===!1?!0:!1)},EPUBJS.Book.prototype.forceSingle=function(a){var b="undefined"==typeof a?!0:a;this.renderer.forceSingle(b),this.settings.forceSingle=b,this.isRendered&&this.renderer.reformat()},EPUBJS.Book.prototype.setMinSpreadWidth=function(a){this.settings.minSpreadWidth=a,this.isRendered&&(this.renderer.setMinSpreadWidth(this.settings.minSpreadWidth),this.renderer.reformat())},EPUBJS.Book.prototype.setGap=function(a){this.settings.gap=a,this.isRendered&&(this.renderer.setGap(this.settings.gap),this.renderer.reformat())},EPUBJS.Book.prototype.chapter=function(a){var b,c,d=this.spineIndexByURL[a];return d&&(b=this.spine[d],c=new EPUBJS.Chapter(b,this.store),c.load()),c},EPUBJS.Book.prototype.unload=function(){this.settings.restore&&localStorage&&this.saveContents(),this.unlistenToRenderer(this.renderer),this.trigger("book:unload")},EPUBJS.Book.prototype.destroy=function(){window.removeEventListener("beforeunload",this.unload),this.currentChapter&&this.currentChapter.unload(),this.unload(),this.render&&this.render.remove()},EPUBJS.Book.prototype._ready=function(){this.trigger("book:ready")},EPUBJS.Book.prototype._rendered=function(){this.isRendered=!0,this.trigger("book:rendered"),this._q.flush()},EPUBJS.Book.prototype.applyStyles=function(a,b){a.applyStyles(this.settings.styles),b()},EPUBJS.Book.prototype.applyHeadTags=function(a,b){a.applyHeadTags(this.settings.headTags),b()},EPUBJS.Book.prototype._registerReplacements=function(a){a.registerHook("beforeChapterDisplay",this.applyStyles.bind(this,a),!0),a.registerHook("beforeChapterDisplay",this.applyHeadTags.bind(this,a),!0),a.registerHook("beforeChapterDisplay",EPUBJS.replace.hrefs.bind(this),!0),this._needsAssetReplacement()&&a.registerHook("beforeChapterDisplay",[EPUBJS.replace.head,EPUBJS.replace.resources,EPUBJS.replace.svg],!0)},EPUBJS.Book.prototype._needsAssetReplacement=function(){return this.settings.fromStorage?"filesystem"==this.storage.getStorageType()?!1:!0:this.settings.contained?!0:!1},EPUBJS.Book.prototype.parseLayoutProperties=function(a){var b=this.layoutOveride&&this.layoutOveride.layout||a.layout||"reflowable",c=this.layoutOveride&&this.layoutOveride.spread||a.spread||"auto",d=this.layoutOveride&&this.layoutOveride.orientation||a.orientation||"auto";return{layout:b,spread:c,orientation:d}},RSVP.EventTarget.mixin(EPUBJS.Book.prototype),RSVP.on("error",function(){}),RSVP.configure("instrument",!0),RSVP.on("rejected",function(a){console.error(a.detail.message,a.detail.stack)}),EPUBJS.Chapter=function(a,b){this.href=a.href,this.absolute=a.url,this.id=a.id,this.spinePos=a.index,this.cfiBase=a.cfiBase,this.properties=a.properties,this.manifestProperties=a.manifestProperties,this.linear=a.linear,this.pages=1,this.store=b,this.epubcfi=new EPUBJS.EpubCFI,this.deferred=new RSVP.defer,this.loaded=this.deferred.promise},EPUBJS.Chapter.prototype.load=function(a){var b,c=a||this.store;return b=c?c.get(this.href):EPUBJS.core.request(this.absolute,"xml"),b.then(function(a){this.setDocument(a),this.deferred.resolve(this)}.bind(this)),b},EPUBJS.Chapter.prototype.render=function(){return this.load().then(function(a){var b,c=new XMLSerializer,d=a.head,e=a.createElement("base");return e.setAttribute("href",window.location.origin+this.absolute),d.insertBefore(e,d.firstChild),b=c.serializeToString(a)}.bind(this))},EPUBJS.Chapter.prototype.url=function(a){var b,c=new RSVP.defer,d=a||this.store,e=this;return d?this.tempUrl?(b=this.tempUrl,c.resolve(b)):d.getUrl(this.absolute).then(function(a){e.tempUrl=a,c.resolve(a)}):(b=this.absolute,c.resolve(b)),c.promise},EPUBJS.Chapter.prototype.setPages=function(a){this.pages=a},EPUBJS.Chapter.prototype.getPages=function(){return this.pages},EPUBJS.Chapter.prototype.getID=function(){return this.ID},EPUBJS.Chapter.prototype.unload=function(a){this.document=null,this.tempUrl&&a&&(a.revokeUrl(this.tempUrl),this.tempUrl=!1)},EPUBJS.Chapter.prototype.setDocument=function(a){{var b=a.namespaceURI;a.doctype}this.document=a.implementation.createDocument(b,null,null),this.contents=this.document.importNode(a.documentElement,!0),this.document.appendChild(this.contents),!this.document.evaluate&&document.evaluate&&(this.document.evaluate=document.evaluate)},EPUBJS.Chapter.prototype.cfiFromRange=function(a){var b,c,d,e,f,g;if(this.document){if(c=EPUBJS.core.getElementXPath(a.startContainer),d=EPUBJS.core.getElementXPath(a.endContainer),e=this.document.evaluate(c,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue,a.collapsed||(f=this.document.evaluate(d,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue),b=this.document.createRange(),e)try{b.setStart(e,a.startOffset),!a.collapsed&&f&&b.setEnd(f,a.endOffset)}catch(h){console.log("missed"),e=!1}return e||(console.log("not found, try fuzzy match"),cleanStartTextContent=EPUBJS.core.cleanStringForXpath(a.startContainer.textContent),c="//text()[contains(.,"+cleanStartTextContent+")]",e=this.document.evaluate(c,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue,e&&(b.setStart(e,a.startOffset),a.collapsed||(g=EPUBJS.core.cleanStringForXpath(a.endContainer.textContent),d="//text()[contains(.,"+g+")]",f=this.document.evaluate(d,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue,f&&b.setEnd(f,a.endOffset)))),this.epubcfi.generateCfiFromRange(b,this.cfiBase)}},EPUBJS.Chapter.prototype.find=function(a){var b=this,c=[],d=a.toLowerCase(),e=function(a){for(var e,f,g,h=a.textContent.toLowerCase(),i=b.document.createRange(),j=-1,k=150;-1!=f;)f=h.indexOf(d,j+1),-1!=f&&(i=b.document.createRange(),i.setStart(a,f),i.setEnd(a,f+d.length),e=b.cfiFromRange(i),a.textContent.lengthh;++h)f[h]=d.charCodeAt(h);return new Blob([f],{type:c})},EPUBJS.core.addScript=function(a,b,c){var d,e;e=!1,d=document.createElement("script"),d.type="text/javascript",d.async=!1,d.src=a,d.onload=d.onreadystatechange=function(){e||this.readyState&&"complete"!=this.readyState||(e=!0,b&&b())},c=c||document.body,c.appendChild(d)},EPUBJS.core.addScripts=function(a,b,c){var d=a.length,e=0,f=function(){e++,d==e?b&&b():EPUBJS.core.addScript(a[e],f,c)};EPUBJS.core.addScript(a[e],f,c)},EPUBJS.core.addCss=function(a,b,c){var d,e;e=!1,d=document.createElement("link"),d.type="text/css",d.rel="stylesheet",d.href=a,d.onload=d.onreadystatechange=function(){e||this.readyState&&"complete"!=this.readyState||(e=!0,b&&b())},c=c||document.body,c.appendChild(d)},EPUBJS.core.prefixed=function(a){var b=["Webkit","Moz","O","ms"],c=a[0].toUpperCase()+a.slice(1),d=b.length;if("undefined"!=typeof document.body.style[a])return a;for(var e=0;d>e;e++)if("undefined"!=typeof document.body.style[b[e]+c])return b[e]+c;return a},EPUBJS.core.resolveUrl=function(a,b){var c,d,e=[],f=EPUBJS.core.uri(b),g=a.split("/");return f.host?b:(g.pop(),d=b.split("/"),d.forEach(function(a){".."===a?g.pop():e.push(a)}),c=g.concat(e),c.join("/"))},EPUBJS.core.uuid=function(){var a=(new Date).getTime(),b="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(b){var c=(a+16*Math.random())%16|0;return a=Math.floor(a/16),("x"==b?c:7&c|8).toString(16)});return b},EPUBJS.core.insert=function(a,b,c){var d=EPUBJS.core.locationOf(a,b,c);return b.splice(d,0,a),d},EPUBJS.core.locationOf=function(a,b,c,d,e){var f,g=d||0,h=e||b.length,i=parseInt(g+(h-g)/2);return c||(c=function(a,b){return a>b?1:b>a?-1:(a=b)?0:void 0}),0>=h-g?i:(f=c(b[i],a),h-g===1?f>0?i:i+1:0===f?i:-1===f?EPUBJS.core.locationOf(a,b,c,i,h):EPUBJS.core.locationOf(a,b,c,g,i))},EPUBJS.core.indexOfSorted=function(a,b,c,d,e){var f,g=d||0,h=e||b.length,i=parseInt(g+(h-g)/2);return c||(c=function(a,b){return a>b?1:b>a?-1:(a=b)?0:void 0}),0>=h-g?-1:(f=c(b[i],a),h-g===1?0===f?i:-1:0===f?i:-1===f?EPUBJS.core.indexOfSorted(a,b,c,i,h):EPUBJS.core.indexOfSorted(a,b,c,g,i))},EPUBJS.core.queue=function(a){var b=[],c=a,d=function(a,c,d){return b.push({funcName:a,args:c,context:d}),b},e=function(){var a;b.length&&(a=b.shift(),c[a.funcName].apply(a.context||c,a.args))},f=function(){for(;b.length;)e()},g=function(){b=[]},h=function(){return b.length};return{enqueue:d,dequeue:e,flush:f,clear:g,length:h}},EPUBJS.core.getElementXPath=function(a){return a&&a.id?'//*[@id="'+a.id+'"]':EPUBJS.core.getElementTreeXPath(a)},EPUBJS.core.getElementTreeXPath=function(a){var b,c,d,e,f=[],g="http://www.w3.org/1999/xhtml"===a.ownerDocument.documentElement.getAttribute("xmlns");for(a.nodeType===Node.TEXT_NODE&&(b=EPUBJS.core.indexOfTextNode(a)+1,f.push("text()["+b+"]"),a=a.parentNode);a&&1==a.nodeType;a=a.parentNode){b=0;for(var h=a.previousSibling;h;h=h.previousSibling)h.nodeType!=Node.DOCUMENT_TYPE_NODE&&h.nodeName==a.nodeName&&++b;c=a.nodeName.toLowerCase(),d=g?"xhtml:"+c:c,e=b?"["+(b+1)+"]":"",f.splice(0,0,d+e)}return f.length?"./"+f.join("/"):null},EPUBJS.core.nsResolver=function(a){var b={xhtml:"http://www.w3.org/1999/xhtml",epub:"http://www.idpf.org/2007/ops"};return b[a]||null},EPUBJS.core.cleanStringForXpath=function(a){var b=a.match(/[^'"]+|['"]/g);return b=b.map(function(a){return"'"===a?'"\'"':'"'===a?"'\"'":"'"+a+"'"}),"concat('',"+b.join(",")+")"},EPUBJS.core.indexOfTextNode=function(a){for(var b,c=a.parentNode,d=c.childNodes,e=-1,f=0;f0;){if(c=d.shift(),"text"===c.type?(e=g.childNodes[c.index],g=e.parentNode||g):g=c.id?f.getElementById(c.id):h[c.index],"undefined"==typeof g)return console.error("No Element For",c,a.str),!1;h=Array.prototype.slice.call(g.children)}return g},EPUBJS.EpubCFI.prototype.compare=function(a,b){if("string"==typeof a&&(a=new EPUBJS.EpubCFI(a)),"string"==typeof b&&(b=new EPUBJS.EpubCFI(b)),a.spinePos>b.spinePos)return 1;if(a.spinePosb.steps[c].index)return 1;if(a.steps[c].indexb.characterOffset?1:a.characterOffset=0?(f=e.length,a.characterOffset=f&&b&&b()}var e,f;return"undefined"==typeof this.hooks[a]?!1:(e=this.hooks[a],f=e.length,0===f&&b&&b(),void e.forEach(function(a){a(d,c)}))},{register:function(a){if(void 0===EPUBJS.hooks[a]&&(EPUBJS.hooks[a]={}),"object"!=typeof EPUBJS.hooks[a])throw"Already registered: "+a;return EPUBJS.hooks[a]},mixin:function(b){for(var c in a.prototype)b[c]=a.prototype[c]}}}(),EPUBJS.Layout=EPUBJS.Layout||{},EPUBJS.Layout.Reflowable=function(){this.documentElement=null,this.spreadWidth=null},EPUBJS.Layout.Reflowable.prototype.format=function(a,b,c,d){var e=EPUBJS.core.prefixed("columnAxis"),f=EPUBJS.core.prefixed("columnGap"),g=EPUBJS.core.prefixed("columnWidth"),h=EPUBJS.core.prefixed("columnFill"),i=Math.floor(b),j=Math.floor(i/8),k=d>=0?d:j%2===0?j:j-1;return this.documentElement=a,this.spreadWidth=i+k,a.style.overflow="hidden",a.style.width=i+"px",a.style.height=c+"px",a.style[e]="horizontal",a.style[h]="auto",a.style[g]=i+"px",a.style[f]=k+"px",this.colWidth=i,this.gap=k,{pageWidth:this.spreadWidth,pageHeight:c}},EPUBJS.Layout.Reflowable.prototype.calculatePages=function(){var a,b;return this.documentElement.style.width="auto",a=this.documentElement.scrollWidth,b=Math.ceil(a/this.spreadWidth),{displayedPages:b,pageCount:b}},EPUBJS.Layout.ReflowableSpreads=function(){this.documentElement=null,this.spreadWidth=null},EPUBJS.Layout.ReflowableSpreads.prototype.format=function(a,b,c,d){var e=EPUBJS.core.prefixed("columnAxis"),f=EPUBJS.core.prefixed("columnGap"),g=EPUBJS.core.prefixed("columnWidth"),h=EPUBJS.core.prefixed("columnFill"),i=2,j=Math.floor(b),k=j%2===0?j:j-1,l=Math.floor(k/8),m=d>=0?d:l%2===0?l:l-1,n=Math.floor((k-m)/i);return this.documentElement=a,this.spreadWidth=(n+m)*i,a.style.overflow="hidden",a.style.width=k+"px",a.style.height=c+"px",a.style[e]="horizontal",a.style[h]="auto",a.style[f]=m+"px",a.style[g]=n+"px",this.colWidth=n,this.gap=m,{pageWidth:this.spreadWidth,pageHeight:c}},EPUBJS.Layout.ReflowableSpreads.prototype.calculatePages=function(){var a=this.documentElement.scrollWidth,b=Math.ceil(a/this.spreadWidth);return this.documentElement.style.width=b*this.spreadWidth-this.gap+"px",{displayedPages:b,pageCount:2*b}},EPUBJS.Layout.Fixed=function(){this.documentElement=null},EPUBJS.Layout.Fixed=function(a){var b,c,d,e,f=EPUBJS.core.prefixed("columnWidth"),g=a.querySelector("[name=viewport");return this.documentElement=a,g&&g.hasAttribute("content")&&(b=g.getAttribute("content"),c=b.split(","),c[0]&&(d=c[0].replace("width=","")),c[1]&&(e=c[1].replace("height=",""))),a.style.width=d+"px"||"auto",a.style.height=e+"px"||"auto",a.style[f]="auto",a.style.overflow="auto",this.colWidth=d,this.gap=0,{pageWidth:d,pageHeight:e}},EPUBJS.Layout.Fixed.prototype.calculatePages=function(){return{displayedPages:1,pageCount:1}},EPUBJS.Pagination=function(a){this.pages=[],this.locations=[],this.epubcfi=new EPUBJS.EpubCFI,a&&a.length&&this.process(a)},EPUBJS.Pagination.prototype.process=function(a){a.forEach(function(a){this.pages.push(a.page),this.locations.push(a.cfi)},this),this.pageList=a,this.firstPage=parseInt(this.pages[0]),this.lastPage=parseInt(this.pages[this.pages.length-1]),this.totalPages=this.lastPage-this.firstPage},EPUBJS.Pagination.prototype.pageFromCfi=function(a){var b=-1;if(0===this.locations.length)return-1;var c=EPUBJS.core.indexOfSorted(a,this.locations,this.epubcfi.compare);return-1!=c&&c=0?this.pages[c-1]:this.pages[0],void 0!==b||(b=-1)),b
+},EPUBJS.Pagination.prototype.cfiFromPage=function(a){var b=-1;"number"!=typeof a&&(a=parseInt(a));var c=this.pages.indexOf(a);return-1!=c&&(b=this.locations[c]),b},EPUBJS.Pagination.prototype.pageFromPercentage=function(a){var b=Math.round(this.totalPages*a);return b},EPUBJS.Pagination.prototype.percentageFromPage=function(a){var b=(a-this.firstPage)/this.totalPages;return Math.round(1e3*b)/1e3},EPUBJS.Pagination.prototype.percentageFromCfi=function(a){var b=this.pageFromCfi(a),c=this.percentageFromPage(b);return c},EPUBJS.Parser=function(a){this.baseUrl=a||""},EPUBJS.Parser.prototype.container=function(a){var b,c,d,e;return a?(b=a.querySelector("rootfile"))?(c=b.getAttribute("full-path"),d=EPUBJS.core.uri(c).directory,e=a.xmlEncoding,{packagePath:c,basePath:d,encoding:e}):void console.error("No RootFile Found"):void console.error("Container File Not Found")},EPUBJS.Parser.prototype.identifier=function(a){var b;return a?(b=a.querySelector("metadata"),b?this.getElementText(b,"identifier"):void console.error("No Metadata Found")):void console.error("Package File Not Found")},EPUBJS.Parser.prototype.packageContents=function(a,b){var c,d,e,f,g,h,i,j,k,l,m=this;return b&&(this.baseUrl=b),a?(c=a.querySelector("metadata"))?(d=a.querySelector("manifest"))?(e=a.querySelector("spine"))?(f=m.manifest(d),g=m.findNavPath(d),h=m.findTocPath(d),i=m.findCoverPath(d),j=Array.prototype.indexOf.call(e.parentNode.childNodes,e),k=m.spine(e,f),l={},k.forEach(function(a){l[a.href]=a.index}),{metadata:m.metadata(c),spine:k,manifest:f,navPath:g,tocPath:h,coverPath:i,spineNodeIndex:j,spineIndexByURL:l}):void console.error("No Spine Found"):void console.error("No Manifest Found"):void console.error("No Metadata Found"):void console.error("Package File Not Found")},EPUBJS.Parser.prototype.findNavPath=function(a){var b=a.querySelector("item[properties^='nav']");return b?b.getAttribute("href"):!1},EPUBJS.Parser.prototype.findTocPath=function(a){var b=a.querySelector("item[media-type='application/x-dtbncx+xml']");return b?b.getAttribute("href"):!1},EPUBJS.Parser.prototype.findCoverPath=function(a){var b=a.querySelector("item[properties='cover-image']");return b?b.getAttribute("href"):!1},EPUBJS.Parser.prototype.metadata=function(a){var b={},c=this;return b.bookTitle=c.getElementText(a,"title"),b.creator=c.getElementText(a,"creator"),b.description=c.getElementText(a,"description"),b.pubdate=c.getElementText(a,"date"),b.publisher=c.getElementText(a,"publisher"),b.identifier=c.getElementText(a,"identifier"),b.language=c.getElementText(a,"language"),b.rights=c.getElementText(a,"rights"),b.modified_date=c.querySelectorText(a,"meta[property='dcterms:modified']"),b.layout=c.querySelectorText(a,"meta[property='rendition:layout']"),b.orientation=c.querySelectorText(a,"meta[property='rendition:orientation']"),b.spread=c.querySelectorText(a,"meta[property='rendition:spread']"),b},EPUBJS.Parser.prototype.getElementText=function(a,b){var c,d=a.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/",b);return d&&0!==d.length?(c=d[0],c.childNodes.length?c.childNodes[0].nodeValue:""):""},EPUBJS.Parser.prototype.querySelectorText=function(a,b){var c=a.querySelector(b);return c&&c.childNodes.length?c.childNodes[0].nodeValue:""},EPUBJS.Parser.prototype.manifest=function(a){var b=this.baseUrl,c={},d=a.querySelectorAll("item"),e=Array.prototype.slice.call(d);return e.forEach(function(a){var d=a.getAttribute("id"),e=a.getAttribute("href")||"",f=a.getAttribute("media-type")||"",g=a.getAttribute("properties")||"";c[d]={href:e,url:b+e,type:f,properties:g}}),c},EPUBJS.Parser.prototype.spine=function(a,b){var c=[],d=a.getElementsByTagName("itemref"),e=Array.prototype.slice.call(d),f=Array.prototype.indexOf.call(a.parentNode.childNodes,a),g=new EPUBJS.EpubCFI;return e.forEach(function(a,d){var e=a.getAttribute("idref"),h=g.generateChapterComponent(f,d,e),i=a.getAttribute("properties")||"",j=i.length?i.split(" "):[],k=b[e].properties,l=k.length?k.split(" "):[],m={id:e,linear:a.getAttribute("linear")||"",properties:j,manifestProperties:l,href:b[e].href,url:b[e].url,index:d,cfiBase:h,cfi:"epub("+h+")"};c.push(m)}),c},EPUBJS.Parser.prototype.nav=function(a,b,c){function d(a){var b=[];return Array.prototype.slice.call(a.childNodes).forEach(function(a){"ol"==a.tagName&&Array.prototype.slice.call(a.childNodes).forEach(function(a){"li"==a.tagName&&b.push(a)})}),b}function e(a){var b=null;return Array.prototype.slice.call(a.childNodes).forEach(function(a){("a"==a.tagName||"span"==a.tagName)&&(b=a)}),b}function f(a){var g=[],i=d(a),j=Array.prototype.slice.call(i),k=j.length;return 0===k?!1:(j.forEach(function(d){var i=d.getAttribute("id")||!1,j=e(d),k=j.getAttribute("href")||"",l=j.textContent||"",m=k.split("#"),n=m[0],o=f(d),p=b[n],q=c[p],r=q?q.cfi:"";i||(p?(q=c[p],i=q.id,r=q.cfi):i="epubjs-autogen-toc-id-"+h++),d.setAttribute("id",i),g.push({id:i,href:k,label:l,subitems:o,parent:a?a.getAttribute("id"):null,cfi:r})}),g)}var g=a.querySelector('nav[*|type="toc"]'),h=0;return g?f(g):[]},EPUBJS.Parser.prototype.toc=function(a,b,c){function d(e){var f=[],g=a.evaluate("*[local-name()='navPoint']",e,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),h=g.snapshotLength;if(0===h)return[];for(var i=h-1;i>=0;i--){var j=g.snapshotItem(i),k=j.getAttribute("id")||!1,l=j.querySelector("content"),m=l.getAttribute("src"),n=j.querySelector("navLabel"),o=n.textContent?n.textContent:"",p=m.split("#"),q=p[0],r=b[q],s=c[r],t=d(j),u=s?s.cfi:"";k||(r?(s=c[r],k=s.id,u=s.cfi):k="epubjs-autogen-toc-id-"+idCounter++),f.unshift({id:k,href:m,label:o,spinePos:r,subitems:t,parent:e?e.getAttribute("id"):null,cfi:u})}return f}var e=a.querySelector("navMap");return e?d(e):[]},EPUBJS.Parser.prototype.pageList=function(a){function b(a){var b=[];return Array.prototype.slice.call(a.childNodes).forEach(function(a){"ol"==a.tagName&&Array.prototype.slice.call(a.childNodes).forEach(function(a){"li"==a.tagName&&b.push(a)})}),b}function c(a){var b=null;return Array.prototype.slice.call(a.childNodes).forEach(function(a){("a"==a.tagName||"span"==a.tagName)&&(b=a)}),b}function d(a){var d=[],e=b(a),f=Array.prototype.slice.call(e),g=f.length;return 0===g?!1:(f.forEach(function(a){var b,e,f,g=(a.getAttribute("id")||!1,c(a)),h=g.getAttribute("href")||"",i=g.textContent||"",j=parseInt(i),k=h.indexOf("epubcfi");-1!=k?(b=h.split("#"),e=b[0],f=b.length>1?b[1]:!1,d.push({cfi:f,href:h,packageUrl:e,page:j})):d.push({href:h,page:j})}),d)}var e=a.querySelector('nav[*|type="page-list"]');return e?d(e):[]},EPUBJS.Render.Iframe=function(){this.iframe=null,this.document=null,this.window=null,this.docEl=null,this.bodyEl=null,this.leftPos=0,this.pageWidth=0},EPUBJS.Render.Iframe.prototype.create=function(){return this.iframe=document.createElement("iframe"),this.iframe.id="epubjs-iframe:"+EPUBJS.core.uuid(),this.iframe.scrolling="no",this.iframe.seamless="seamless",this.iframe.style.border="none",this.iframe.addEventListener("load",this.loaded.bind(this),!1),this.iframe},EPUBJS.Render.Iframe.prototype.load=function(a){var b=this,c=new RSVP.defer;return a.url().then(function(a){b.leftPos=0,this.window&&this.unload(),this.iframe.onload=function(){b.document=b.iframe.contentDocument,b.docEl=b.document.documentElement,b.headEl=b.document.head,b.bodyEl=b.document.body,b.window=b.iframe.contentWindow,b.window.addEventListener("resize",b.resized.bind(b),!1),b.bodyEl&&(b.bodyEl.style.margin="0"),c.resolve(b.docEl)},this.iframe.onerror=function(a){c.reject({message:"Error Loading Contents: "+a,stack:(new Error).stack})},this.iframe.contentWindow.location.replace(a)}.bind(this)),c.promise},EPUBJS.Render.Iframe.prototype.loaded=function(){var a=this.iframe.contentWindow.location.href;"about:blank"!=a&&this.trigger("render:loaded",a)},EPUBJS.Render.Iframe.prototype.resize=function(a,b){this.iframe&&(this.iframe.height=b,isNaN(a)||a%2===0||(a+=1),this.iframe.width=a,this.width=this.iframe.getBoundingClientRect().width||a,this.height=this.iframe.getBoundingClientRect().height||b)},EPUBJS.Render.Iframe.prototype.resized=function(){this.width=this.iframe.getBoundingClientRect().width,this.height=this.iframe.getBoundingClientRect().height},EPUBJS.Render.Iframe.prototype.totalWidth=function(){return this.docEl.scrollWidth},EPUBJS.Render.Iframe.prototype.totalHeight=function(){return this.docEl.scrollHeight},EPUBJS.Render.Iframe.prototype.setPageDimensions=function(a,b){this.pageWidth=a,this.pageHeight=b},EPUBJS.Render.Iframe.prototype.setLeft=function(a){this.document.defaultView.scrollTo(a,0)},EPUBJS.Render.Iframe.prototype.setStyle=function(a,b,c){c&&(a=EPUBJS.core.prefixed(a)),this.bodyEl&&(this.bodyEl.style[a]=b)},EPUBJS.Render.Iframe.prototype.removeStyle=function(a){this.bodyEl&&(this.bodyEl.style[a]="")},EPUBJS.Render.Iframe.prototype.addHeadTag=function(a,b,c){var d=c||this.document,e=d.createElement(a),f=d.head;for(var g in b)e.setAttribute(g,b[g]);f&&f.insertBefore(e,f.firstChild)},EPUBJS.Render.Iframe.prototype.page=function(a){this.leftPos=this.pageWidth*(a-1),this.setLeft(this.leftPos)},EPUBJS.Render.Iframe.prototype.getPageNumberByElement=function(a){var b,c;if(a)return b=this.leftPos+a.getBoundingClientRect().left,c=Math.floor(b/this.pageWidth)+1},EPUBJS.Render.Iframe.prototype.getPageNumberByRect=function(a){var b,c;return b=this.leftPos+a.left,c=Math.floor(b/this.pageWidth)+1},EPUBJS.Render.Iframe.prototype.getBaseElement=function(){return this.bodyEl},EPUBJS.Render.Iframe.prototype.isElementVisible=function(a){var b,c;return a&&"function"==typeof a.getBoundingClientRect&&(b=a.getBoundingClientRect(),c=b.left,0!==b.width&&0!==b.height&&c>=0&&c=1&&a<=this.displayedPages?(this.chapterPos=a,this.render.page(a),this.visibleRangeCfi=this.getVisibleRangeCfi(),this.currentLocationCfi=this.visibleRangeCfi.start,this.trigger("renderer:locationChanged",this.currentLocationCfi),this.trigger("renderer:visibleRangeChanged",this.visibleRangeCfi),!0):!1:(console.warn("pageMap not set, queuing"),this._q.enqueue("page",arguments),!0)},EPUBJS.Renderer.prototype.nextPage=function(){return this.page(this.chapterPos+1)},EPUBJS.Renderer.prototype.prevPage=function(){return this.page(this.chapterPos-1)},EPUBJS.Renderer.prototype.pageByElement=function(a){var b;a&&(b=this.render.getPageNumberByElement(a),this.page(b))},EPUBJS.Renderer.prototype.lastPage=function(){return this._moving?this._q.enqueue("lastPage",arguments):void this.page(this.displayedPages)},EPUBJS.Renderer.prototype.firstPage=function(){this.page(1)},EPUBJS.Renderer.prototype.section=function(a){var b=this.doc.getElementById(a);b&&this.pageByElement(b)},EPUBJS.Renderer.prototype.firstElementisTextNode=function(a){var b=a.childNodes,c=b.length;return c&&b[0]&&3===b[0].nodeType&&b[0].textContent.trim().length?!0:!1},EPUBJS.Renderer.prototype.walk=function(a,b,c){for(var d,e,f,g,h=a,i=[h],j=1e4,k=0;!d&&i.length;){if(a=i.shift(),this.containsPoint(a,b,c)&&this.firstElementisTextNode(a)&&(d=a),!d&&a&&a.childElementCount>0){if(e=a.children,!e||!e.length)return d;f=e.length?e.length:0;for(var l=f-1;l>=0;l--)e[l]!=g&&i.unshift(e[l])}if(!d&&0===i.length&&h&&null!==h.parentNode&&(i.push(h.parentNode),g=h,h=h.parentNode),k++,k>j){console.error("ENDLESS LOOP");break}}return d},EPUBJS.Renderer.prototype.containsPoint=function(a,b){var c;return a&&"function"==typeof a.getBoundingClientRect&&(c=a.getBoundingClientRect(),0!==c.width&&0!==c.height&&c.left>=b&&b<=c.left+c.width)?!0:!1},EPUBJS.Renderer.prototype.textSprint=function(a,b){for(var c,d=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,{acceptNode:function(a){return/^\s*$/.test(a.data)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}},!1);c=d.nextNode();)b(c)},EPUBJS.Renderer.prototype.sprint=function(a,b){for(var c,d=document.createTreeWalker(a,NodeFilter.SHOW_ELEMENT,null,!1);c=d.nextNode();)b(c)},EPUBJS.Renderer.prototype.mapPage=function(){var a,b,c=this,d=[],e=this.render.getBaseElement(),f=1,g=this.layout.colWidth+this.layout.gap,h=this.formated.pageWidth*(this.chapterPos-1),i=g*f-h,j=0,k=function(a){var b,c,d=Array.prototype.slice.call(a.childNodes);if(a.nodeType==Node.ELEMENT_NODE){if(c=document.createRange(),c.selectNodeContents(a),b=c.getBoundingClientRect(),!b||0===b.width&&0===b.height)return;b.left>j&&d.forEach(function(a){a.nodeType==Node.TEXT_NODE&&a.textContent.trim().length&&l(a)}),b.right>j&&d.forEach(function(a){a.nodeType==Node.TEXT_NODE&&a.textContent.trim().length&&l(a)})}},l=function(e){var k=c.splitTextNodeIntoWordsRanges(e);k.forEach(function(e){var k=e.getBoundingClientRect();!k||0===k.width&&0===k.height||(k.left+k.width0&&(b&&(b.setEnd(a,pos),c.push(b)),b=this.doc.createRange(),b.setStart(a,pos+1));return b&&(b.setEnd(a,d.length),c.push(b)),c},EPUBJS.Renderer.prototype.rangePosition=function(a){var b,c;return c=a.getClientRects(),c.length?b=c[0]:null},EPUBJS.Renderer.prototype.getPageCfi=function(){var a;return this.spreads?(a=2*this.chapterPos,startRange=this.pageMap[a-2]):(a=this.chapterPos,startRange=this.pageMap[a-1]),this.pageMap[2*this.chapterPos-1].start},EPUBJS.Renderer.prototype.getRange=function(a,b,c){var d,e=this.doc.createRange();return c=!0,"undefined"==typeof document.caretPositionFromPoint||c?"undefined"==typeof document.caretRangeFromPoint||c?(this.visibileEl=this.findElementAfter(a,b),e.setStart(this.visibileEl,1)):e=this.doc.caretRangeFromPoint(a,b):(d=this.doc.caretPositionFromPoint(a,b),e.setStart(d.offsetNode,d.offset)),e},EPUBJS.Renderer.prototype.pagesInCurrentChapter=function(){var a,b;return this.pageMap?(b=this.pageMap.length,a=this.spreads?Math.ceil(b/2):b):(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.currentRenderedPage=function(){var a;return this.pageMap?a=this.spreads&&this.layout.pageCount>1?2*this.chapterPos:this.chapterPos:(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.getRenderedPagesLeft=function(){var a,b,c;return this.pageMap?(b=this.pageMap.length,a=this.spreads?2*this.chapterPos:this.chapterPos,c=b-a):(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.getVisibleRangeCfi=function(){var a,b,c;return this.pageMap?(this.spreads?(a=2*this.chapterPos,b=this.pageMap[a-2],c=b,this.layout.pageCount>1&&(c=this.pageMap[a-1])):(a=this.chapterPos,b=this.pageMap[a-1],c=b),b||(console.warn("page range miss:",a,this.pageMap),b=this.pageMap[this.pageMap.length-1],c=b),{start:b.start,end:c.end}):(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.gotoCfi=function(a){var b,c,d;return this._moving?this._q.enqueue("gotoCfi",arguments):(_.isString(a)&&(a=this.epubcfi.parse(a)),void("undefined"==typeof document.evaluate?(c=this.epubcfi.addMarker(a,this.doc),c&&(b=this.render.getPageNumberByElement(c),this.epubcfi.removeMarker(c,this.doc),this.page(b))):(d=this.epubcfi.generateRangeFromCfi(a,this.doc),d&&(b=this.render.getPageNumberByRect(d.getBoundingClientRect()),this.page(b),this.currentLocationCfi=a.str))))},EPUBJS.Renderer.prototype.findFirstVisible=function(a){var b,c=a||this.render.getBaseElement();return b=this.walk(c),b?b:a},EPUBJS.Renderer.prototype.findElementAfter=function(a,b,c){var d,e=c||this.render.getBaseElement();return d=this.walk(e,a,b),d?d:e},EPUBJS.Renderer.prototype.resize=function(a,b,c){this.width=a,this.height=b,c!==!1&&this.render.resize(this.width,this.height),this.contents&&this.reformat(),this.trigger("renderer:resized",{width:this.width,height:this.height})},EPUBJS.Renderer.prototype.onResized=function(){var a=this.container.clientWidth,b=this.container.clientHeight;this.resize(a,b,!1)},EPUBJS.Renderer.prototype.addEventListeners=function(){this.render.document&&this.listenedEvents.forEach(function(a){this.render.document.addEventListener(a,this.triggerEvent.bind(this),!1)},this)},EPUBJS.Renderer.prototype.removeEventListeners=function(){this.render.document&&this.listenedEvents.forEach(function(a){this.render.document.removeEventListener(a,this.triggerEvent,!1)},this)},EPUBJS.Renderer.prototype.triggerEvent=function(a){this.trigger("renderer:"+a.type,a)},EPUBJS.Renderer.prototype.addSelectionListeners=function(){this.render.document.addEventListener("selectionchange",this.onSelectionChange.bind(this),!1)},EPUBJS.Renderer.prototype.removeSelectionListeners=function(){this.render.document&&this.doc.removeEventListener("selectionchange",this.onSelectionChange,!1)},EPUBJS.Renderer.prototype.onSelectionChange=function(){this.selectionEndTimeout&&clearTimeout(this.selectionEndTimeout),this.selectionEndTimeout=setTimeout(function(){this.selectedRange=this.render.window.getSelection(),this.trigger("renderer:selected",this.selectedRange)}.bind(this),500)},EPUBJS.Renderer.prototype.setMinSpreadWidth=function(a){this.minSpreadWidth=a,this.spreads=this.determineSpreads(a)},EPUBJS.Renderer.prototype.determineSpreads=function(a){return this.isForcedSingle||!a||this.width=g&&c&&c(!0),e=!0)};b(a,f)}.bind(this))},EPUBJS.Renderer.prototype.replaceWithStored=function(a,b,c,d){var e,f={},g=this.currentChapter.store,h=this.caches[a],i=EPUBJS.core.uri(this.currentChapter.absolute),j=i.base,k=b,l=2e3,m=function(a,b){f[b]=a},n=function(){d&&d(),_.each(e,function(a){g.revokeUrl(a)}),h=f};g&&(h||(h={}),e=_.clone(h),this.replace(a,function(b,d){var h=b.getAttribute(k),i=EPUBJS.core.resolveUrl(j,h),m=function(c){var e;b.onload=function(){clearTimeout(e),d(c,i)},b.onerror=function(a){clearTimeout(e),d(c,i),console.error(a)},"image"==a&&b.setAttribute("externalResourcesRequired","true"),"link[href]"==a&&"stylesheet"!==b.getAttribute("rel")&&d(c,i),b.setAttribute(k,c),e=setTimeout(function(){d(c,i)},l)};i in e?(m(e[i]),f[i]=e[i],delete e[i]):c(g,i,m,b)},n,m))},RSVP.EventTarget.mixin(EPUBJS.Renderer.prototype);var EPUBJS=EPUBJS||{};EPUBJS.replace={},EPUBJS.replace.hrefs=function(a,b){var c=this,d=function(a,d){var e,f,g=a.getAttribute("href"),h=g.search("://");-1!=h?a.setAttribute("target","_blank"):(e=EPUBJS.core.uri(b.render.window.location.href).directory,f=EPUBJS.core.resolveUrl(e,g),a.onclick=function(){return c.goto(f),!1}),d()};b.replace("a[href]",d,a)},EPUBJS.replace.head=function(a,b){b.replaceWithStored("link[href]","href",EPUBJS.replace.links,a)},EPUBJS.replace.resources=function(a,b){b.replaceWithStored("[src]","src",EPUBJS.replace.srcs,a)},EPUBJS.replace.svg=function(a,b){b.replaceWithStored("image","xlink:href",function(a,b,c){a.getUrl(b).then(c)},a)},EPUBJS.replace.srcs=function(a,b,c){a.getUrl(b).then(c)},EPUBJS.replace.links=function(a,b,c,d){"stylesheet"===d.getAttribute("rel")?EPUBJS.replace.stylesheets(a,b).then(function(a,b){setTimeout(function(){c(a,b)},5)}):a.getUrl(b).then(c)},EPUBJS.replace.stylesheets=function(a,b){var c=new RSVP.defer;if(a)return a.getText(b).then(function(d){EPUBJS.replace.cssUrls(a,b,d).then(function(a){var b=window.URL||window.webkitURL||window.mozURL,d=new Blob([a],{type:"text/css"}),e=b.createObjectURL(d);c.resolve(e)},function(a){console.error(a)})}),c.promise},EPUBJS.replace.cssUrls=function(a,b,c){var d=new RSVP.defer,e=[],f=c.match(/url\(\'?\"?([^\'|^\"^\)]*)\'?\"?\)/g);if(a)return f?(f.forEach(function(d){var f=EPUBJS.core.resolveUrl(b,d.replace(/url\(|[|\)|\'|\"]/g,"")),g=a.getUrl(f).then(function(a){c=c.replace(d,'url("'+a+'")')});e.push(g)}),RSVP.all(e).then(function(){d.resolve(c)}),d.promise):(d.resolve(c),d.promise)},EPUBJS.Unarchiver=function(a){return this.libPath=EPUBJS.filePath,this.zipUrl=a,this.loadLib(),this.urlCache={},this.zipFs=new zip.fs.FS,this.promise},EPUBJS.Unarchiver.prototype.loadLib=function(){"undefined"==typeof zip&&console.error("Zip lib not loaded"),zip.workerScriptsPath=this.libPath},EPUBJS.Unarchiver.prototype.openZip=function(a){var b=new RSVP.defer,c=this.zipFs;return c.importHttpContent(a,!1,function(){b.resolve(c)},this.failed),b.promise},EPUBJS.Unarchiver.prototype.getXml=function(a,b){return this.getText(a,b).then(function(a){var b=new DOMParser;return b.parseFromString(a,"application/xml")})},EPUBJS.Unarchiver.prototype.getUrl=function(a,b){var c=this,d=new RSVP.defer,e=window.decodeURIComponent(a),f=this.zipFs.find(e),g=window.URL||window.webkitURL||window.mozURL;return f?a in this.urlCache?(d.resolve(this.urlCache[a]),d.promise):(f.getBlob(b||zip.getMimeType(f.name),function(b){var e=g.createObjectURL(b);d.resolve(e),c.urlCache[a]=e}),d.promise):(d.reject({message:"File not found in the epub: "+a,stack:(new Error).stack}),d.promise)},EPUBJS.Unarchiver.prototype.getText=function(a,b){{var c=new RSVP.defer,d=window.decodeURIComponent(a),e=this.zipFs.find(d);window.URL||window.webkitURL||window.mozURL}return e?(e.getText(function(a){c.resolve(a)},null,null,b||"UTF-8"),c.promise):(console.warn("File not found in the contained epub:",a),c.promise)},EPUBJS.Unarchiver.prototype.revokeUrl=function(a){var b=window.URL||window.webkitURL||window.mozURL,c=unarchiver.urlCache[a];c&&b.revokeObjectURL(c)},EPUBJS.Unarchiver.prototype.failed=function(a){console.error(a)},EPUBJS.Unarchiver.prototype.afterSaved=function(){this.callback()},EPUBJS.Unarchiver.prototype.toStorage=function(a){function b(){f--,0===f&&e.afterSaved()}var c=0,d=20,e=this,f=a.length;a.forEach(function(a){setTimeout(function(a){e.saveEntryFileToStorage(a,b)},c,a),c+=d}),console.log("time",c)},EPUBJS.Unarchiver.prototype.saveEntryFileToStorage=function(a,b){a.getData(new zip.BlobWriter,function(c){EPUBJS.storage.save(a.filename,c,b)})};
+//# sourceMappingURL=epub.min.map
\ No newline at end of file
diff --git a/files_reader/js/hooks.min.js b/files_reader/js/hooks.min.js
new file mode 100644
index 0000000..33049a9
--- /dev/null
+++ b/files_reader/js/hooks.min.js
@@ -0,0 +1,2 @@
+EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e,f=b.height,j=b.width,p=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(i[k]),i[k].addEventListener("mouseover",d,!1),i[k].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",h,this),b.on("renderer:pageChanged",g,this)),c=i[k],e=a.getBoundingClientRect(),m=e.left,n=e.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width/2+"px",c.style.top=n+"px",p>f/2.5&&(p=f/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),m-popRect.width<=0?(c.style.left=m+"px",c.classList.add("left")):c.classList.remove("left"),m+popRect.width/2>=j?(c.style.left=m-300+"px",popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width+"px",popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){i[k].classList.add("on")}function g(){i[k].classList.remove("on")}function h(){setTimeout(function(){i[k].classList.remove("show")},100)}var j,k,l,m,n,o,p=a.getAttribute(e);p==f&&(j=a.getAttribute("href"),k=j.replace("#",""),l=b.render.document.getElementById(k),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",h,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?void a():(d.forEach(function(a){function c(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,0>g&&(g=0),i+g>=e?(e/2>g?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))}a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnloaded",function(){a.removeEventListener("load",c),b.off("renderer:resized",c)}),c()}),void(a&&a()))},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};
+//# sourceMappingURL=hooks.min.map
\ No newline at end of file
diff --git a/files_reader/js/hooks/extensions/highlight.js b/files_reader/js/hooks/extensions/highlight.js
new file mode 100644
index 0000000..1dd1c67
--- /dev/null
+++ b/files_reader/js/hooks/extensions/highlight.js
@@ -0,0 +1,14 @@
+EPUBJS.Hooks.register("beforeChapterDisplay").highlight = function(callback, renderer){
+
+ // EPUBJS.core.addScript("js/libs/jquery.highlight.js", null, renderer.doc.head);
+
+ var s = document.createElement("style");
+ s.innerHTML =".highlight { background: yellow; font-weight: normal; }";
+
+ renderer.render.document.head.appendChild(s);
+
+ if(callback) callback();
+
+}
+
+
diff --git a/files_reader/js/libs/blob.js b/files_reader/js/libs/blob.js
new file mode 100644
index 0000000..b20ed0b
--- /dev/null
+++ b/files_reader/js/libs/blob.js
@@ -0,0 +1,31 @@
+Blob = (function() {
+ var nativeBlob = Blob;
+
+ // Add unprefixed slice() method.
+ if (Blob.prototype.webkitSlice) {
+ Blob.prototype.slice = Blob.prototype.webkitSlice;
+ }
+ else if (Blob.prototype.mozSlice) {
+ Blob.prototype.slice = Blob.prototype.mozSlice;
+ }
+
+ // Temporarily replace Blob() constructor with one that checks support.
+ return function(parts, properties) {
+ try {
+ // Restore native Blob() constructor, so this check is only evaluated once.
+ Blob = nativeBlob;
+ return new Blob(parts || [], properties || {});
+ }
+ catch (e) {
+ // If construction fails provide one that uses BlobBuilder.
+ Blob = function (parts, properties) {
+ var bb = new (WebKitBlobBuilder || MozBlobBuilder), i;
+ for (i in parts) {
+ bb.append(parts[i]);
+ }
+
+ return bb.getBlob(properties && properties.type ? properties.type : undefined);
+ };
+ }
+ };
+}());
diff --git a/files_reader/js/libs/inflate.js b/files_reader/js/libs/inflate.js
new file mode 100644
index 0000000..cc0e012
--- /dev/null
+++ b/files_reader/js/libs/inflate.js
@@ -0,0 +1,2163 @@
+/*
+ Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
+
+ 3. The names of the authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
+ * JZlib is based on zlib-1.1.3, so all credit should go authors
+ * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ * and contributors of zlib.
+ */
+
+(function(obj) {
+
+ // Global
+ var MAX_BITS = 15;
+
+ var Z_OK = 0;
+ var Z_STREAM_END = 1;
+ var Z_NEED_DICT = 2;
+ var Z_STREAM_ERROR = -2;
+ var Z_DATA_ERROR = -3;
+ var Z_MEM_ERROR = -4;
+ var Z_BUF_ERROR = -5;
+
+ var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff,
+ 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
+
+ var MANY = 1440;
+
+ // JZlib version : "1.0.2"
+ var Z_NO_FLUSH = 0;
+ var Z_FINISH = 4;
+
+ // InfTree
+ var fixed_bl = 9;
+ var fixed_bd = 5;
+
+ var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0,
+ 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40,
+ 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13,
+ 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60,
+ 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7,
+ 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8,
+ 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80,
+ 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0,
+ 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0,
+ 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97,
+ 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210,
+ 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117,
+ 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
+ 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83,
+ 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230,
+ 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139,
+ 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174,
+ 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
+ 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9,
+ 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8,
+ 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8,
+ 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8,
+ 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9,
+ 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8,
+ 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9,
+ 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8,
+ 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9,
+ 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
+ 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9,
+ 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8,
+ 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9,
+ 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8,
+ 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9,
+ 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8,
+ 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9,
+ 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8,
+ 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ];
+ var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5,
+ 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5,
+ 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ];
+
+ // Tables for deflate from PKZIP's appnote.txt.
+ var cplens = [ // Copy lengths for literal codes 257..285
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ];
+
+ // see note #13 above about 258
+ var cplext = [ // Extra bits for literal codes 257..285
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
+ ];
+
+ var cpdist = [ // Copy offsets for distance codes 0..29
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
+
+ var cpdext = [ // Extra bits for distance codes
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
+
+ // If BMAX needs to be larger than 16, then h and x[] should be uLong.
+ var BMAX = 15; // maximum bit length of any code
+
+ function InfTree() {
+ var that = this;
+
+ var hn; // hufts used in space
+ var v; // work area for huft_build
+ var c; // bit length count table
+ var r; // table entry for structure assignment
+ var u; // table stack
+ var x; // bit offsets, then code stack
+
+ function huft_build(b, // code lengths in bits (all assumed <=
+ // BMAX)
+ bindex, n, // number of codes (assumed <= 288)
+ s, // number of simple-valued codes (0..s-1)
+ d, // list of base values for non-simple codes
+ e, // list of extra bits for non-simple codes
+ t, // result: starting table
+ m, // maximum lookup bits, returns actual
+ hp,// space for trees
+ hn,// hufts used in space
+ v // working area: values in order of bit length
+ ) {
+ // Given a list of code lengths and a maximum table size, make a set of
+ // tables to decode that set of codes. Return Z_OK on success,
+ // Z_BUF_ERROR
+ // if the given code set is incomplete (the tables are still built in
+ // this
+ // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set
+ // of
+ // lengths), or Z_MEM_ERROR if not enough memory.
+
+ var a; // counter for codes of length k
+ var f; // i repeats in table every f entries
+ var g; // maximum code length
+ var h; // table level
+ var i; // counter, current code
+ var j; // counter
+ var k; // number of bits in current code
+ var l; // bits per table (returned in m)
+ var mask; // (1 << w) - 1, to avoid cc -O bug on HP
+ var p; // pointer into c[], b[], or v[]
+ var q; // points to current table
+ var w; // bits before this table == (l * h)
+ var xp; // pointer into x
+ var y; // number of dummy codes added
+ var z; // number of entries in current table
+
+ // Generate counts for each bit length
+
+ p = 0;
+ i = n;
+ do {
+ c[b[bindex + p]]++;
+ p++;
+ i--; // assume all entries <= BMAX
+ } while (i !== 0);
+
+ if (c[0] == n) { // null input--all zero length codes
+ t[0] = -1;
+ m[0] = 0;
+ return Z_OK;
+ }
+
+ // Find minimum and maximum length, bound *m by those
+ l = m[0];
+ for (j = 1; j <= BMAX; j++)
+ if (c[j] !== 0)
+ break;
+ k = j; // minimum code length
+ if (l < j) {
+ l = j;
+ }
+ for (i = BMAX; i !== 0; i--) {
+ if (c[i] !== 0)
+ break;
+ }
+ g = i; // maximum code length
+ if (l > i) {
+ l = i;
+ }
+ m[0] = l;
+
+ // Adjust last length count to fill out codes, if needed
+ for (y = 1 << j; j < i; j++, y <<= 1) {
+ if ((y -= c[j]) < 0) {
+ return Z_DATA_ERROR;
+ }
+ }
+ if ((y -= c[i]) < 0) {
+ return Z_DATA_ERROR;
+ }
+ c[i] += y;
+
+ // Generate starting offsets into the value table for each length
+ x[1] = j = 0;
+ p = 1;
+ xp = 2;
+ while (--i !== 0) { // note that i == g from above
+ x[xp] = (j += c[p]);
+ xp++;
+ p++;
+ }
+
+ // Make a table of values in order of bit lengths
+ i = 0;
+ p = 0;
+ do {
+ if ((j = b[bindex + p]) !== 0) {
+ v[x[j]++] = i;
+ }
+ p++;
+ } while (++i < n);
+ n = x[g]; // set n to length of v
+
+ // Generate the Huffman codes and for each, make the table entries
+ x[0] = i = 0; // first Huffman code is zero
+ p = 0; // grab values in bit order
+ h = -1; // no tables yet--level -1
+ w = -l; // bits decoded == (l * h)
+ u[0] = 0; // just to keep compilers happy
+ q = 0; // ditto
+ z = 0; // ditto
+
+ // go through the bit lengths (k already is bits in shortest code)
+ for (; k <= g; k++) {
+ a = c[k];
+ while (a-- !== 0) {
+ // here i is the Huffman code of length k bits for value *p
+ // make tables up to required level
+ while (k > w + l) {
+ h++;
+ w += l; // previous table always l bits
+ // compute minimum size table less than or equal to l bits
+ z = g - w;
+ z = (z > l) ? l : z; // table size upper limit
+ if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
+ // too few codes for
+ // k-w bit table
+ f -= a + 1; // deduct codes from patterns left
+ xp = k;
+ if (j < z) {
+ while (++j < z) { // try smaller tables up to z bits
+ if ((f <<= 1) <= c[++xp])
+ break; // enough codes to use up j bits
+ f -= c[xp]; // else deduct codes from patterns
+ }
+ }
+ }
+ z = 1 << j; // table entries for j-bit table
+
+ // allocate new table
+ if (hn[0] + z > MANY) { // (note: doesn't matter for fixed)
+ return Z_DATA_ERROR; // overflow of MANY
+ }
+ u[h] = q = /* hp+ */hn[0]; // DEBUG
+ hn[0] += z;
+
+ // connect to last table, if there is one
+ if (h !== 0) {
+ x[h] = i; // save pattern for backing up
+ r[0] = /* (byte) */j; // bits in this table
+ r[1] = /* (byte) */l; // bits to dump before this table
+ j = i >>> (w - l);
+ r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table
+ hp.set(r, (u[h - 1] + j) * 3);
+ // to
+ // last
+ // table
+ } else {
+ t[0] = q; // first table is returned result
+ }
+ }
+
+ // set up table entry in r
+ r[1] = /* (byte) */(k - w);
+ if (p >= n) {
+ r[0] = 128 + 64; // out of values--invalid code
+ } else if (v[p] < s) {
+ r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is
+ // end-of-block
+ r[2] = v[p++]; // simple code is just the value
+ } else {
+ r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look
+ // up in lists
+ r[2] = d[v[p++] - s];
+ }
+
+ // fill code-like entries with r
+ f = 1 << (k - w);
+ for (j = i >>> w; j < z; j += f) {
+ hp.set(r, (q + j) * 3);
+ }
+
+ // backwards increment the k-bit code i
+ for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) {
+ i ^= j;
+ }
+ i ^= j;
+
+ // backup over finished tables
+ mask = (1 << w) - 1; // needed on HP, cc -O bug
+ while ((i & mask) != x[h]) {
+ h--; // don't need to update q
+ w -= l;
+ mask = (1 << w) - 1;
+ }
+ }
+ }
+ // Return Z_BUF_ERROR if we were given an incomplete table
+ return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+ }
+
+ function initWorkArea(vsize) {
+ var i;
+ if (!hn) {
+ hn = []; // []; //new Array(1);
+ v = []; // new Array(vsize);
+ c = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+ r = []; // new Array(3);
+ u = new Int32Array(BMAX); // new Array(BMAX);
+ x = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+ }
+ if (v.length < vsize) {
+ v = []; // new Array(vsize);
+ }
+ for (i = 0; i < vsize; i++) {
+ v[i] = 0;
+ }
+ for (i = 0; i < BMAX + 1; i++) {
+ c[i] = 0;
+ }
+ for (i = 0; i < 3; i++) {
+ r[i] = 0;
+ }
+ // for(int i=0; i 257)) {
+ if (result == Z_DATA_ERROR) {
+ z.msg = "oversubscribed distance tree";
+ } else if (result == Z_BUF_ERROR) {
+ z.msg = "incomplete distance tree";
+ result = Z_DATA_ERROR;
+ } else if (result != Z_MEM_ERROR) {
+ z.msg = "empty distance tree with lengths";
+ result = Z_DATA_ERROR;
+ }
+ return result;
+ }
+
+ return Z_OK;
+ };
+
+ }
+
+ InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth
+ bd, // distance desired/actual bit depth
+ tl,// literal/length tree result
+ td// distance tree result
+ ) {
+ bl[0] = fixed_bl;
+ bd[0] = fixed_bd;
+ tl[0] = fixed_tl;
+ td[0] = fixed_td;
+ return Z_OK;
+ };
+
+ // InfCodes
+
+ // waiting for "i:"=input,
+ // "o:"=output,
+ // "x:"=nothing
+ var START = 0; // x: set up for LEN
+ var LEN = 1; // i: get length/literal/eob next
+ var LENEXT = 2; // i: getting length extra (have base)
+ var DIST = 3; // i: get distance next
+ var DISTEXT = 4;// i: getting distance extra
+ var COPY = 5; // o: copying bytes in window, waiting
+ // for space
+ var LIT = 6; // o: got literal, waiting for output
+ // space
+ var WASH = 7; // o: got eob, possibly still output
+ // waiting
+ var END = 8; // x: got eob and all data flushed
+ var BADCODE = 9;// x: got error
+
+ function InfCodes() {
+ var that = this;
+
+ var mode; // current inflate_codes mode
+
+ // mode dependent information
+ var len = 0;
+
+ var tree; // pointer into tree
+ var tree_index = 0;
+ var need = 0; // bits needed
+
+ var lit = 0;
+
+ // if EXT or COPY, where and how much
+ var get = 0; // bits to get for extra
+ var dist = 0; // distance back to copy from
+
+ var lbits = 0; // ltree bits decoded per branch
+ var dbits = 0; // dtree bits decoder per branch
+ var ltree; // literal/length/eob tree
+ var ltree_index = 0; // literal/length/eob tree
+ var dtree; // distance tree
+ var dtree_index = 0; // distance tree
+
+ // Called with number of bytes left to write in window at least 258
+ // (the maximum string length) and number of input bytes available
+ // at least ten. The ten bytes are six bytes for the longest length/
+ // distance pair plus four bytes for overloading the bit buffer.
+
+ function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) {
+ var t; // temporary pointer
+ var tp; // temporary pointer
+ var tp_index; // temporary pointer
+ var e; // extra bits or operation
+ var b; // bit buffer
+ var k; // bits in bit buffer
+ var p; // input data pointer
+ var n; // bytes available there
+ var q; // output window write pointer
+ var m; // bytes to end of window or read pointer
+ var ml; // mask for literal/length tree
+ var md; // mask for distance tree
+ var c; // bytes to copy
+ var d; // distance back to copy from
+ var r; // copy source pointer
+
+ var tp_index_t_3; // (tp_index+t)*3
+
+ // load input, output, bit values
+ p = z.next_in_index;
+ n = z.avail_in;
+ b = s.bitb;
+ k = s.bitk;
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ // initialize masks
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ // do until not enough input or output space for fast loop
+ do { // assume called with m >= 258 && n >= 10
+ // get literal/length code
+ while (k < (20)) { // max bits for literal/length code
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ t = b & ml;
+ tp = tl;
+ tp_index = tl_index;
+ tp_index_t_3 = (tp_index + t) * 3;
+ if ((e = tp[tp_index_t_3]) === 0) {
+ b >>= (tp[tp_index_t_3 + 1]);
+ k -= (tp[tp_index_t_3 + 1]);
+
+ s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+ m--;
+ continue;
+ }
+ do {
+
+ b >>= (tp[tp_index_t_3 + 1]);
+ k -= (tp[tp_index_t_3 + 1]);
+
+ if ((e & 16) !== 0) {
+ e &= 15;
+ c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]);
+
+ b >>= e;
+ k -= e;
+
+ // decode distance base of block to copy
+ while (k < (15)) { // max bits for distance code
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ t = b & md;
+ tp = td;
+ tp_index = td_index;
+ tp_index_t_3 = (tp_index + t) * 3;
+ e = tp[tp_index_t_3];
+
+ do {
+
+ b >>= (tp[tp_index_t_3 + 1]);
+ k -= (tp[tp_index_t_3 + 1]);
+
+ if ((e & 16) !== 0) {
+ // get extra bits to add to distance base
+ e &= 15;
+ while (k < (e)) { // get extra bits (up to 13)
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);
+
+ b >>= (e);
+ k -= (e);
+
+ // do the copy
+ m -= c;
+ if (q >= d) { // offset before dest
+ // just copy
+ r = q - d;
+ if (q - r > 0 && 2 > (q - r)) {
+ s.window[q++] = s.window[r++]; // minimum
+ // count is
+ // three,
+ s.window[q++] = s.window[r++]; // so unroll
+ // loop a
+ // little
+ c -= 2;
+ } else {
+ s.window.set(s.window.subarray(r, r + 2), q);
+ q += 2;
+ r += 2;
+ c -= 2;
+ }
+ } else { // else offset after destination
+ r = q - d;
+ do {
+ r += s.end; // force pointer in window
+ } while (r < 0); // covers invalid distances
+ e = s.end - r;
+ if (c > e) { // if source crosses,
+ c -= e; // wrapped copy
+ if (q - r > 0 && e > (q - r)) {
+ do {
+ s.window[q++] = s.window[r++];
+ } while (--e !== 0);
+ } else {
+ s.window.set(s.window.subarray(r, r + e), q);
+ q += e;
+ r += e;
+ e = 0;
+ }
+ r = 0; // copy rest from start of window
+ }
+
+ }
+
+ // copy all or what's left
+ if (q - r > 0 && c > (q - r)) {
+ do {
+ s.window[q++] = s.window[r++];
+ } while (--c !== 0);
+ } else {
+ s.window.set(s.window.subarray(r, r + c), q);
+ q += c;
+ r += c;
+ c = 0;
+ }
+ break;
+ } else if ((e & 64) === 0) {
+ t += tp[tp_index_t_3 + 2];
+ t += (b & inflate_mask[e]);
+ tp_index_t_3 = (tp_index + t) * 3;
+ e = tp[tp_index_t_3];
+ } else {
+ z.msg = "invalid distance code";
+
+ c = z.avail_in - n;
+ c = (k >> 3) < c ? k >> 3 : c;
+ n += c;
+ p -= c;
+ k -= c << 3;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+
+ return Z_DATA_ERROR;
+ }
+ } while (true);
+ break;
+ }
+
+ if ((e & 64) === 0) {
+ t += tp[tp_index_t_3 + 2];
+ t += (b & inflate_mask[e]);
+ tp_index_t_3 = (tp_index + t) * 3;
+ if ((e = tp[tp_index_t_3]) === 0) {
+
+ b >>= (tp[tp_index_t_3 + 1]);
+ k -= (tp[tp_index_t_3 + 1]);
+
+ s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+ m--;
+ break;
+ }
+ } else if ((e & 32) !== 0) {
+
+ c = z.avail_in - n;
+ c = (k >> 3) < c ? k >> 3 : c;
+ n += c;
+ p -= c;
+ k -= c << 3;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+
+ return Z_STREAM_END;
+ } else {
+ z.msg = "invalid literal/length code";
+
+ c = z.avail_in - n;
+ c = (k >> 3) < c ? k >> 3 : c;
+ n += c;
+ p -= c;
+ k -= c << 3;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+
+ return Z_DATA_ERROR;
+ }
+ } while (true);
+ } while (m >= 258 && n >= 10);
+
+ // not enough input or output--restore pointers and return
+ c = z.avail_in - n;
+ c = (k >> 3) < c ? k >> 3 : c;
+ n += c;
+ p -= c;
+ k -= c << 3;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+
+ return Z_OK;
+ }
+
+ that.init = function(bl, bd, tl, tl_index, td, td_index) {
+ mode = START;
+ lbits = /* (byte) */bl;
+ dbits = /* (byte) */bd;
+ ltree = tl;
+ ltree_index = tl_index;
+ dtree = td;
+ dtree_index = td_index;
+ tree = null;
+ };
+
+ that.proc = function(s, z, r) {
+ var j; // temporary storage
+ var tindex; // temporary pointer
+ var e; // extra bits or operation
+ var b = 0; // bit buffer
+ var k = 0; // bits in bit buffer
+ var p = 0; // input data pointer
+ var n; // bytes available there
+ var q; // output window write pointer
+ var m; // bytes to end of window or read pointer
+ var f; // pointer to copy strings from
+
+ // copy input/output information to locals (UPDATE macro restores)
+ p = z.next_in_index;
+ n = z.avail_in;
+ b = s.bitb;
+ k = s.bitk;
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ // process input and output based on current state
+ while (true) {
+ switch (mode) {
+ // waiting for "i:"=input, "o:"=output, "x:"=nothing
+ case START: // x: set up for LEN
+ if (m >= 258 && n >= 10) {
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
+
+ p = z.next_in_index;
+ n = z.avail_in;
+ b = s.bitb;
+ k = s.bitk;
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ if (r != Z_OK) {
+ mode = r == Z_STREAM_END ? WASH : BADCODE;
+ break;
+ }
+ }
+ need = lbits;
+ tree = ltree;
+ tree_index = ltree_index;
+
+ mode = LEN;
+ case LEN: // i: get length/literal/eob next
+ j = need;
+
+ while (k < (j)) {
+ if (n !== 0)
+ r = Z_OK;
+ else {
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+ b >>>= (tree[tindex + 1]);
+ k -= (tree[tindex + 1]);
+
+ e = tree[tindex];
+
+ if (e === 0) { // literal
+ lit = tree[tindex + 2];
+ mode = LIT;
+ break;
+ }
+ if ((e & 16) !== 0) { // length
+ get = e & 15;
+ len = tree[tindex + 2];
+ mode = LENEXT;
+ break;
+ }
+ if ((e & 64) === 0) { // next table
+ need = e;
+ tree_index = tindex / 3 + tree[tindex + 2];
+ break;
+ }
+ if ((e & 32) !== 0) { // end of block
+ mode = WASH;
+ break;
+ }
+ mode = BADCODE; // invalid code
+ z.msg = "invalid literal/length code";
+ r = Z_DATA_ERROR;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+ case LENEXT: // i: getting length extra (have base)
+ j = get;
+
+ while (k < (j)) {
+ if (n !== 0)
+ r = Z_OK;
+ else {
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ len += (b & inflate_mask[j]);
+
+ b >>= j;
+ k -= j;
+
+ need = dbits;
+ tree = dtree;
+ tree_index = dtree_index;
+ mode = DIST;
+ case DIST: // i: get distance next
+ j = need;
+
+ while (k < (j)) {
+ if (n !== 0)
+ r = Z_OK;
+ else {
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+ b >>= tree[tindex + 1];
+ k -= tree[tindex + 1];
+
+ e = (tree[tindex]);
+ if ((e & 16) !== 0) { // distance
+ get = e & 15;
+ dist = tree[tindex + 2];
+ mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) === 0) { // next table
+ need = e;
+ tree_index = tindex / 3 + tree[tindex + 2];
+ break;
+ }
+ mode = BADCODE; // invalid code
+ z.msg = "invalid distance code";
+ r = Z_DATA_ERROR;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+ case DISTEXT: // i: getting distance extra
+ j = get;
+
+ while (k < (j)) {
+ if (n !== 0)
+ r = Z_OK;
+ else {
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ dist += (b & inflate_mask[j]);
+
+ b >>= j;
+ k -= j;
+
+ mode = COPY;
+ case COPY: // o: copying bytes in window, waiting for space
+ f = q - dist;
+ while (f < 0) { // modulo window size-"while" instead
+ f += s.end; // of "if" handles invalid distances
+ }
+ while (len !== 0) {
+
+ if (m === 0) {
+ if (q == s.end && s.read !== 0) {
+ q = 0;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+ }
+ if (m === 0) {
+ s.write = q;
+ r = s.inflate_flush(z, r);
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ if (q == s.end && s.read !== 0) {
+ q = 0;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+ }
+
+ if (m === 0) {
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ }
+ }
+
+ s.window[q++] = s.window[f++];
+ m--;
+
+ if (f == s.end)
+ f = 0;
+ len--;
+ }
+ mode = START;
+ break;
+ case LIT: // o: got literal, waiting for output space
+ if (m === 0) {
+ if (q == s.end && s.read !== 0) {
+ q = 0;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+ }
+ if (m === 0) {
+ s.write = q;
+ r = s.inflate_flush(z, r);
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ if (q == s.end && s.read !== 0) {
+ q = 0;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+ }
+ if (m === 0) {
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ }
+ }
+ r = Z_OK;
+
+ s.window[q++] = /* (byte) */lit;
+ m--;
+
+ mode = START;
+ break;
+ case WASH: // o: got eob, possibly more output
+ if (k > 7) { // return unused byte, if any
+ k -= 8;
+ n++;
+ p--; // can always return one
+ }
+
+ s.write = q;
+ r = s.inflate_flush(z, r);
+ q = s.write;
+ m = q < s.read ? s.read - q - 1 : s.end - q;
+
+ if (s.read != s.write) {
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ mode = END;
+ case END:
+ r = Z_STREAM_END;
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+ case BADCODE: // x: got error
+
+ r = Z_DATA_ERROR;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+ default:
+ r = Z_STREAM_ERROR;
+
+ s.bitb = b;
+ s.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ }
+ };
+
+ that.free = function() {
+ // ZFREE(z, c);
+ };
+
+ }
+
+ // InfBlocks
+
+ // Table for deflate from PKZIP's appnote.txt.
+ var border = [ // Order of the bit length code lengths
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+ var TYPE = 0; // get type bits (3, including end bit)
+ var LENS = 1; // get lengths for stored
+ var STORED = 2;// processing stored block
+ var TABLE = 3; // get table lengths
+ var BTREE = 4; // get bit lengths tree for a dynamic
+ // block
+ var DTREE = 5; // get length, distance trees for a
+ // dynamic block
+ var CODES = 6; // processing fixed or dynamic block
+ var DRY = 7; // output remaining window bytes
+ var DONELOCKS = 8; // finished last block, done
+ var BADBLOCKS = 9; // ot a data error--stuck here
+
+ function InfBlocks(z, w) {
+ var that = this;
+
+ var mode = TYPE; // current inflate_block mode
+
+ var left = 0; // if STORED, bytes left to copy
+
+ var table = 0; // table lengths (14 bits)
+ var index = 0; // index into blens (or border)
+ var blens; // bit lengths of codes
+ var bb = [ 0 ]; // bit length tree depth
+ var tb = [ 0 ]; // bit length decoding tree
+
+ var codes = new InfCodes(); // if CODES, current state
+
+ var last = 0; // true if this block is the last block
+
+ var hufts = new Int32Array(MANY * 3); // single malloc for tree space
+ var check = 0; // check on output
+ var inftree = new InfTree();
+
+ that.bitk = 0; // bits in bit buffer
+ that.bitb = 0; // bit buffer
+ that.window = new Uint8Array(w); // sliding window
+ that.end = w; // one byte after sliding window
+ that.read = 0; // window read pointer
+ that.write = 0; // window write pointer
+
+ that.reset = function(z, c) {
+ if (c)
+ c[0] = check;
+ // if (mode == BTREE || mode == DTREE) {
+ // }
+ if (mode == CODES) {
+ codes.free(z);
+ }
+ mode = TYPE;
+ that.bitk = 0;
+ that.bitb = 0;
+ that.read = that.write = 0;
+ };
+
+ that.reset(z, null);
+
+ // copy as much as possible from the sliding window to the output area
+ that.inflate_flush = function(z, r) {
+ var n;
+ var p;
+ var q;
+
+ // local copies of source and destination pointers
+ p = z.next_out_index;
+ q = that.read;
+
+ // compute number of bytes to copy as far as end of window
+ n = /* (int) */((q <= that.write ? that.write : that.end) - q);
+ if (n > z.avail_out)
+ n = z.avail_out;
+ if (n !== 0 && r == Z_BUF_ERROR)
+ r = Z_OK;
+
+ // update counters
+ z.avail_out -= n;
+ z.total_out += n;
+
+ // copy as far as end of window
+ z.next_out.set(that.window.subarray(q, q + n), p);
+ p += n;
+ q += n;
+
+ // see if more to copy at beginning of window
+ if (q == that.end) {
+ // wrap pointers
+ q = 0;
+ if (that.write == that.end)
+ that.write = 0;
+
+ // compute bytes to copy
+ n = that.write - q;
+ if (n > z.avail_out)
+ n = z.avail_out;
+ if (n !== 0 && r == Z_BUF_ERROR)
+ r = Z_OK;
+
+ // update counters
+ z.avail_out -= n;
+ z.total_out += n;
+
+ // copy
+ z.next_out.set(that.window.subarray(q, q + n), p);
+ p += n;
+ q += n;
+ }
+
+ // update pointers
+ z.next_out_index = p;
+ that.read = q;
+
+ // done
+ return r;
+ };
+
+ that.proc = function(z, r) {
+ var t; // temporary storage
+ var b; // bit buffer
+ var k; // bits in bit buffer
+ var p; // input data pointer
+ var n; // bytes available there
+ var q; // output window write pointer
+ var m; // bytes to end of window or read pointer
+
+ var i;
+
+ // copy input/output information to locals (UPDATE macro restores)
+ // {
+ p = z.next_in_index;
+ n = z.avail_in;
+ b = that.bitb;
+ k = that.bitk;
+ // }
+ // {
+ q = that.write;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+ // }
+
+ // process input based on current state
+ // DEBUG dtree
+ while (true) {
+ switch (mode) {
+ case TYPE:
+
+ while (k < (3)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+ t = /* (int) */(b & 7);
+ last = t & 1;
+
+ switch (t >>> 1) {
+ case 0: // stored
+ // {
+ b >>>= (3);
+ k -= (3);
+ // }
+ t = k & 7; // go to byte boundary
+
+ // {
+ b >>>= (t);
+ k -= (t);
+ // }
+ mode = LENS; // get length of stored block
+ break;
+ case 1: // fixed
+ // {
+ var bl = []; // new Array(1);
+ var bd = []; // new Array(1);
+ var tl = [ [] ]; // new Array(1);
+ var td = [ [] ]; // new Array(1);
+
+ InfTree.inflate_trees_fixed(bl, bd, tl, td);
+ codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
+ // }
+
+ // {
+ b >>>= (3);
+ k -= (3);
+ // }
+
+ mode = CODES;
+ break;
+ case 2: // dynamic
+
+ // {
+ b >>>= (3);
+ k -= (3);
+ // }
+
+ mode = TABLE;
+ break;
+ case 3: // illegal
+
+ // {
+ b >>>= (3);
+ k -= (3);
+ // }
+ mode = BADBLOCKS;
+ z.msg = "invalid block type";
+ r = Z_DATA_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ break;
+ case LENS:
+
+ while (k < (32)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
+ mode = BADBLOCKS;
+ z.msg = "invalid stored block lengths";
+ r = Z_DATA_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ left = (b & 0xffff);
+ b = k = 0; // dump bits
+ mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE);
+ break;
+ case STORED:
+ if (n === 0) {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+
+ if (m === 0) {
+ if (q == that.end && that.read !== 0) {
+ q = 0;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+ }
+ if (m === 0) {
+ that.write = q;
+ r = that.inflate_flush(z, r);
+ q = that.write;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+ if (q == that.end && that.read !== 0) {
+ q = 0;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+ }
+ if (m === 0) {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ }
+ }
+ r = Z_OK;
+
+ t = left;
+ if (t > n)
+ t = n;
+ if (t > m)
+ t = m;
+ that.window.set(z.read_buf(p, t), q);
+ p += t;
+ n -= t;
+ q += t;
+ m -= t;
+ if ((left -= t) !== 0)
+ break;
+ mode = last !== 0 ? DRY : TYPE;
+ break;
+ case TABLE:
+
+ while (k < (14)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ table = t = (b & 0x3fff);
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
+ mode = BADBLOCKS;
+ z.msg = "too many length or distance symbols";
+ r = Z_DATA_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ if (!blens || blens.length < t) {
+ blens = []; // new Array(t);
+ } else {
+ for (i = 0; i < t; i++) {
+ blens[i] = 0;
+ }
+ }
+
+ // {
+ b >>>= (14);
+ k -= (14);
+ // }
+
+ index = 0;
+ mode = BTREE;
+ case BTREE:
+ while (index < 4 + (table >>> 10)) {
+ while (k < (3)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ blens[border[index++]] = b & 7;
+
+ // {
+ b >>>= (3);
+ k -= (3);
+ // }
+ }
+
+ while (index < 19) {
+ blens[border[index++]] = 0;
+ }
+
+ bb[0] = 7;
+ t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
+ if (t != Z_OK) {
+ r = t;
+ if (r == Z_DATA_ERROR) {
+ blens = null;
+ mode = BADBLOCKS;
+ }
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+
+ index = 0;
+ mode = DTREE;
+ case DTREE:
+ while (true) {
+ t = table;
+ if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
+ break;
+ }
+
+ var j, c;
+
+ t = bb[0];
+
+ while (k < (t)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ // if (tb[0] == -1) {
+ // System.err.println("null...");
+ // }
+
+ t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
+ c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
+
+ if (c < 16) {
+ b >>>= (t);
+ k -= (t);
+ blens[index++] = c;
+ } else { // c == 16..18
+ i = c == 18 ? 7 : c - 14;
+ j = c == 18 ? 11 : 3;
+
+ while (k < (t + i)) {
+ if (n !== 0) {
+ r = Z_OK;
+ } else {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.read_byte(p++) & 0xff) << k;
+ k += 8;
+ }
+
+ b >>>= (t);
+ k -= (t);
+
+ j += (b & inflate_mask[i]);
+
+ b >>>= (i);
+ k -= (i);
+
+ i = index;
+ t = table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) {
+ blens = null;
+ mode = BADBLOCKS;
+ z.msg = "invalid bit length repeat";
+ r = Z_DATA_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+
+ c = c == 16 ? blens[i - 1] : 0;
+ do {
+ blens[i++] = c;
+ } while (--j !== 0);
+ index = i;
+ }
+ }
+
+ tb[0] = -1;
+ // {
+ var bl_ = []; // new Array(1);
+ var bd_ = []; // new Array(1);
+ var tl_ = []; // new Array(1);
+ var td_ = []; // new Array(1);
+ bl_[0] = 9; // must be <= 9 for lookahead assumptions
+ bd_[0] = 6; // must be <= 9 for lookahead assumptions
+
+ t = table;
+ t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z);
+
+ if (t != Z_OK) {
+ if (t == Z_DATA_ERROR) {
+ blens = null;
+ mode = BADBLOCKS;
+ }
+ r = t;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0]);
+ // }
+ mode = CODES;
+ case CODES:
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+
+ if ((r = codes.proc(that, z, r)) != Z_STREAM_END) {
+ return that.inflate_flush(z, r);
+ }
+ r = Z_OK;
+ codes.free(z);
+
+ p = z.next_in_index;
+ n = z.avail_in;
+ b = that.bitb;
+ k = that.bitk;
+ q = that.write;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+
+ if (last === 0) {
+ mode = TYPE;
+ break;
+ }
+ mode = DRY;
+ case DRY:
+ that.write = q;
+ r = that.inflate_flush(z, r);
+ q = that.write;
+ m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+ if (that.read != that.write) {
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ mode = DONELOCKS;
+ case DONELOCKS:
+ r = Z_STREAM_END;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ case BADBLOCKS:
+ r = Z_DATA_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+
+ default:
+ r = Z_STREAM_ERROR;
+
+ that.bitb = b;
+ that.bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ that.write = q;
+ return that.inflate_flush(z, r);
+ }
+ }
+ };
+
+ that.free = function(z) {
+ that.reset(z, null);
+ that.window = null;
+ hufts = null;
+ // ZFREE(z, s);
+ };
+
+ that.set_dictionary = function(d, start, n) {
+ that.window.set(d.subarray(start, start + n), 0);
+ that.read = that.write = n;
+ };
+
+ // Returns true if inflate is currently at the end of a block generated
+ // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+ that.sync_point = function() {
+ return mode == LENS ? 1 : 0;
+ };
+
+ }
+
+ // Inflate
+
+ // preset dictionary flag in zlib header
+ var PRESET_DICT = 0x20;
+
+ var Z_DEFLATED = 8;
+
+ var METHOD = 0; // waiting for method byte
+ var FLAG = 1; // waiting for flag byte
+ var DICT4 = 2; // four dictionary check bytes to go
+ var DICT3 = 3; // three dictionary check bytes to go
+ var DICT2 = 4; // two dictionary check bytes to go
+ var DICT1 = 5; // one dictionary check byte to go
+ var DICT0 = 6; // waiting for inflateSetDictionary
+ var BLOCKS = 7; // decompressing blocks
+ var DONE = 12; // finished check, done
+ var BAD = 13; // got an error--stay here
+
+ var mark = [ 0, 0, 0xff, 0xff ];
+
+ function Inflate() {
+ var that = this;
+
+ that.mode = 0; // current inflate mode
+
+ // mode dependent information
+ that.method = 0; // if FLAGS, method byte
+
+ // if CHECK, check values to compare
+ that.was = [ 0 ]; // new Array(1); // computed check value
+ that.need = 0; // stream check value
+
+ // if BAD, inflateSync's marker bytes count
+ that.marker = 0;
+
+ // mode independent information
+ that.wbits = 0; // log2(window size) (8..15, defaults to 15)
+
+ // this.blocks; // current inflate_blocks state
+
+ function inflateReset(z) {
+ if (!z || !z.istate)
+ return Z_STREAM_ERROR;
+
+ z.total_in = z.total_out = 0;
+ z.msg = null;
+ z.istate.mode = BLOCKS;
+ z.istate.blocks.reset(z, null);
+ return Z_OK;
+ }
+
+ that.inflateEnd = function(z) {
+ if (that.blocks)
+ that.blocks.free(z);
+ that.blocks = null;
+ // ZFREE(z, z->state);
+ return Z_OK;
+ };
+
+ that.inflateInit = function(z, w) {
+ z.msg = null;
+ that.blocks = null;
+
+ // set window size
+ if (w < 8 || w > 15) {
+ that.inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ that.wbits = w;
+
+ z.istate.blocks = new InfBlocks(z, 1 << w);
+
+ // reset state
+ inflateReset(z);
+ return Z_OK;
+ };
+
+ that.inflate = function(z, f) {
+ var r;
+ var b;
+
+ if (!z || !z.istate || !z.next_in)
+ return Z_STREAM_ERROR;
+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+ r = Z_BUF_ERROR;
+ while (true) {
+ // System.out.println("mode: "+z.istate.mode);
+ switch (z.istate.mode) {
+ case METHOD:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) {
+ z.istate.mode = BAD;
+ z.msg = "unknown compression method";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+ if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
+ z.istate.mode = BAD;
+ z.msg = "invalid window size";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+ z.istate.mode = FLAG;
+ case FLAG:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ b = (z.read_byte(z.next_in_index++)) & 0xff;
+
+ if ((((z.istate.method << 8) + b) % 31) !== 0) {
+ z.istate.mode = BAD;
+ z.msg = "incorrect header check";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+
+ if ((b & PRESET_DICT) === 0) {
+ z.istate.mode = BLOCKS;
+ break;
+ }
+ z.istate.mode = DICT4;
+ case DICT4:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000;
+ z.istate.mode = DICT3;
+ case DICT3:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000;
+ z.istate.mode = DICT2;
+ case DICT2:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00;
+ z.istate.mode = DICT1;
+ case DICT1:
+
+ if (z.avail_in === 0)
+ return r;
+ r = f;
+
+ z.avail_in--;
+ z.total_in++;
+ z.istate.need += (z.read_byte(z.next_in_index++) & 0xff);
+ z.istate.mode = DICT0;
+ return Z_NEED_DICT;
+ case DICT0:
+ z.istate.mode = BAD;
+ z.msg = "need dictionary";
+ z.istate.marker = 0; // can try inflateSync
+ return Z_STREAM_ERROR;
+ case BLOCKS:
+
+ r = z.istate.blocks.proc(z, r);
+ if (r == Z_DATA_ERROR) {
+ z.istate.mode = BAD;
+ z.istate.marker = 0; // can try inflateSync
+ break;
+ }
+ if (r == Z_OK) {
+ r = f;
+ }
+ if (r != Z_STREAM_END) {
+ return r;
+ }
+ r = f;
+ z.istate.blocks.reset(z, z.istate.was);
+ z.istate.mode = DONE;
+ case DONE:
+ return Z_STREAM_END;
+ case BAD:
+ return Z_DATA_ERROR;
+ default:
+ return Z_STREAM_ERROR;
+ }
+ }
+ };
+
+ that.inflateSetDictionary = function(z, dictionary, dictLength) {
+ var index = 0;
+ var length = dictLength;
+ if (!z || !z.istate || z.istate.mode != DICT0)
+ return Z_STREAM_ERROR;
+
+ if (length >= (1 << z.istate.wbits)) {
+ length = (1 << z.istate.wbits) - 1;
+ index = dictLength - length;
+ }
+ z.istate.blocks.set_dictionary(dictionary, index, length);
+ z.istate.mode = BLOCKS;
+ return Z_OK;
+ };
+
+ that.inflateSync = function(z) {
+ var n; // number of bytes to look at
+ var p; // pointer to bytes
+ var m; // number of marker bytes found in a row
+ var r, w; // temporaries to save total_in and total_out
+
+ // set up
+ if (!z || !z.istate)
+ return Z_STREAM_ERROR;
+ if (z.istate.mode != BAD) {
+ z.istate.mode = BAD;
+ z.istate.marker = 0;
+ }
+ if ((n = z.avail_in) === 0)
+ return Z_BUF_ERROR;
+ p = z.next_in_index;
+ m = z.istate.marker;
+
+ // search
+ while (n !== 0 && m < 4) {
+ if (z.read_byte(p) == mark[m]) {
+ m++;
+ } else if (z.read_byte(p) !== 0) {
+ m = 0;
+ } else {
+ m = 4 - m;
+ }
+ p++;
+ n--;
+ }
+
+ // restore
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ z.avail_in = n;
+ z.istate.marker = m;
+
+ // return no joy or set up to restart on a new block
+ if (m != 4) {
+ return Z_DATA_ERROR;
+ }
+ r = z.total_in;
+ w = z.total_out;
+ inflateReset(z);
+ z.total_in = r;
+ z.total_out = w;
+ z.istate.mode = BLOCKS;
+ return Z_OK;
+ };
+
+ // Returns true if inflate is currently at the end of a block generated
+ // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ // implementation to provide an additional safety check. PPP uses
+ // Z_SYNC_FLUSH
+ // but removes the length bytes of the resulting empty stored block. When
+ // decompressing, PPP checks that at the end of input packet, inflate is
+ // waiting for these length bytes.
+ that.inflateSyncPoint = function(z) {
+ if (!z || !z.istate || !z.istate.blocks)
+ return Z_STREAM_ERROR;
+ return z.istate.blocks.sync_point();
+ };
+ }
+
+ // ZStream
+
+ function ZStream() {
+ }
+
+ ZStream.prototype = {
+ inflateInit : function(bits) {
+ var that = this;
+ that.istate = new Inflate();
+ if (!bits)
+ bits = MAX_BITS;
+ return that.istate.inflateInit(that, bits);
+ },
+
+ inflate : function(f) {
+ var that = this;
+ if (!that.istate)
+ return Z_STREAM_ERROR;
+ return that.istate.inflate(that, f);
+ },
+
+ inflateEnd : function() {
+ var that = this;
+ if (!that.istate)
+ return Z_STREAM_ERROR;
+ var ret = that.istate.inflateEnd(that);
+ that.istate = null;
+ return ret;
+ },
+
+ inflateSync : function() {
+ var that = this;
+ if (!that.istate)
+ return Z_STREAM_ERROR;
+ return that.istate.inflateSync(that);
+ },
+ inflateSetDictionary : function(dictionary, dictLength) {
+ var that = this;
+ if (!that.istate)
+ return Z_STREAM_ERROR;
+ return that.istate.inflateSetDictionary(that, dictionary, dictLength);
+ },
+ read_byte : function(start) {
+ var that = this;
+ return that.next_in.subarray(start, start + 1)[0];
+ },
+ read_buf : function(start, size) {
+ var that = this;
+ return that.next_in.subarray(start, start + size);
+ }
+ };
+
+ // Inflater
+
+ function Inflater() {
+ var that = this;
+ var z = new ZStream();
+ var bufsize = 512;
+ var flush = Z_NO_FLUSH;
+ var buf = new Uint8Array(bufsize);
+ var nomoreinput = false;
+
+ z.inflateInit();
+ z.next_out = buf;
+
+ that.append = function(data, onprogress) {
+ var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
+ if (data.length === 0)
+ return;
+ z.next_in_index = 0;
+ z.next_in = data;
+ z.avail_in = data.length;
+ do {
+ z.next_out_index = 0;
+ z.avail_out = bufsize;
+ if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it
+ z.next_in_index = 0;
+ nomoreinput = true;
+ }
+ err = z.inflate(flush);
+ if (nomoreinput && (err == Z_BUF_ERROR))
+ return -1;
+ if (err != Z_OK && err != Z_STREAM_END)
+ throw "inflating: " + z.msg;
+ if ((nomoreinput || err == Z_STREAM_END) && (z.avail_in == data.length))
+ return -1;
+ if (z.next_out_index)
+ if (z.next_out_index == bufsize)
+ buffers.push(new Uint8Array(buf));
+ else
+ buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+ bufferSize += z.next_out_index;
+ if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
+ onprogress(z.next_in_index);
+ lastIndex = z.next_in_index;
+ }
+ } while (z.avail_in > 0 || z.avail_out === 0);
+ array = new Uint8Array(bufferSize);
+ buffers.forEach(function(chunk) {
+ array.set(chunk, bufferIndex);
+ bufferIndex += chunk.length;
+ });
+ return array;
+ };
+ that.flush = function() {
+ z.inflateEnd();
+ };
+ }
+
+ var inflater;
+
+ if (obj.zip)
+ obj.zip.Inflater = Inflater;
+ else {
+ inflater = new Inflater();
+ obj.addEventListener("message", function(event) {
+ var message = event.data;
+
+ if (message.append)
+ obj.postMessage({
+ onappend : true,
+ data : inflater.append(message.data, function(current) {
+ obj.postMessage({
+ progress : true,
+ current : current
+ });
+ })
+ });
+ if (message.flush) {
+ inflater.flush();
+ obj.postMessage({
+ onflush : true
+ });
+ }
+ }, false);
+ }
+
+})(this);
diff --git a/files_reader/js/libs/jquery-2.1.0.min.js b/files_reader/js/libs/jquery-2.1.0.min.js
new file mode 100644
index 0000000..cbe6abe
--- /dev/null
+++ b/files_reader/js/libs/jquery-2.1.0.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;
+while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f;
+return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ –
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+ Settings
+
+
+
+
+
+
+ font scaled to
+
+ %
+
+
+ Et nos esse veri viri scire volemus
+
+
+
+
+
+
+ Night mode background
+
+ and text
+
+ colour
+
+
+
+ Et nos esse veri viri scire volemus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+