summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-09-17 21:53:37 +0300
committerAndrew Dolgov <[email protected]>2021-09-17 21:53:37 +0300
commit4fd9b8f2b5a98bfcde57970b48fed2488a80f356 (patch)
tree51e0ce9cd61c24916b7d5820ee69e74bd3e76aac
parentd0cd10f08286be33306336fe8c4cac26ea7ce637 (diff)
add in master snapshot of epubjs
-rw-r--r--lib/epub.js/.babelrc.json11
-rw-r--r--lib/epub.js/.eslintrc.js43
-rw-r--r--lib/epub.js/.gitignore11
-rw-r--r--lib/epub.js/.jshintrc23
-rw-r--r--lib/epub.js/.nojekyll0
-rw-r--r--lib/epub.js/.npmignore3
-rw-r--r--lib/epub.js/.travis.yml13
-rw-r--r--lib/epub.js/.watchmanconfig6
-rw-r--r--lib/epub.js/README.md197
-rw-r--r--lib/epub.js/bower.json39
-rw-r--r--lib/epub.js/documentation.yml6
-rw-r--r--lib/epub.js/documentation/md/API.md2310
-rw-r--r--lib/epub.js/examples/ajax-loader.gifbin0 -> 2545 bytes
-rw-r--r--lib/epub.js/examples/annotator.html103
-rw-r--r--lib/epub.js/examples/archived.html68
-rw-r--r--lib/epub.js/examples/contents.html29
-rw-r--r--lib/epub.js/examples/continuous-scrolled.html68
-rw-r--r--lib/epub.js/examples/continuous-spreads.html140
-rw-r--r--lib/epub.js/examples/embedded.html61
-rw-r--r--lib/epub.js/examples/examples.css282
-rw-r--r--lib/epub.js/examples/highlights.html176
-rw-r--r--lib/epub.js/examples/hooks.html100
-rw-r--r--lib/epub.js/examples/hypothesis-continuous.html136
-rw-r--r--lib/epub.js/examples/hypothesis-spreads.html58
-rw-r--r--lib/epub.js/examples/hypothesis.css329
-rw-r--r--lib/epub.js/examples/hypothesis.html369
-rw-r--r--lib/epub.js/examples/hypothesis.js214
-rw-r--r--lib/epub.js/examples/index.html107
-rw-r--r--lib/epub.js/examples/input.html91
-rw-r--r--lib/epub.js/examples/legacy.html157
-rw-r--r--lib/epub.js/examples/locations.html139
-rw-r--r--lib/epub.js/examples/manifest.html180
-rw-r--r--lib/epub.js/examples/marks.html108
-rw-r--r--lib/epub.js/examples/mathml.html163
-rw-r--r--lib/epub.js/examples/offline.html97
-rw-r--r--lib/epub.js/examples/renderless.html77
-rw-r--r--lib/epub.js/examples/scrolled.html87
-rw-r--r--lib/epub.js/examples/single-full.html280
-rw-r--r--lib/epub.js/examples/spreads.html157
-rw-r--r--lib/epub.js/examples/swipe.html110
-rw-r--r--lib/epub.js/examples/themes.css14
-rw-r--r--lib/epub.js/examples/themes.html117
-rw-r--r--lib/epub.js/examples/toc.html52
-rw-r--r--lib/epub.js/karma.conf.js147
-rw-r--r--lib/epub.js/license27
-rw-r--r--lib/epub.js/package-lock.json15988
-rw-r--r--lib/epub.js/package.json68
-rw-r--r--lib/epub.js/src/annotations.js301
-rw-r--r--lib/epub.js/src/archive.js255
-rw-r--r--lib/epub.js/src/book.js768
-rw-r--r--lib/epub.js/src/container.js50
-rw-r--r--lib/epub.js/src/contents.js1264
-rw-r--r--lib/epub.js/src/displayoptions.js70
-rw-r--r--lib/epub.js/src/epub.js35
-rw-r--r--lib/epub.js/src/epubcfi.js1048
-rw-r--r--lib/epub.js/src/index.js15
-rw-r--r--lib/epub.js/src/layout.js260
-rw-r--r--lib/epub.js/src/locations.js501
-rw-r--r--lib/epub.js/src/managers/continuous/index.js588
-rw-r--r--lib/epub.js/src/managers/default/index.js1073
-rw-r--r--lib/epub.js/src/managers/helpers/snap.js338
-rw-r--r--lib/epub.js/src/managers/helpers/stage.js363
-rw-r--r--lib/epub.js/src/managers/helpers/views.js167
-rw-r--r--lib/epub.js/src/managers/views/iframe.js835
-rw-r--r--lib/epub.js/src/managers/views/inline.js432
-rw-r--r--lib/epub.js/src/mapping.js511
-rw-r--r--lib/epub.js/src/navigation.js356
-rw-r--r--lib/epub.js/src/packaging.js372
-rw-r--r--lib/epub.js/src/pagelist.js274
-rw-r--r--lib/epub.js/src/rendition.js1064
-rw-r--r--lib/epub.js/src/resources.js320
-rw-r--r--lib/epub.js/src/section.js323
-rw-r--r--lib/epub.js/src/spine.js274
-rw-r--r--lib/epub.js/src/store.js384
-rw-r--r--lib/epub.js/src/themes.js268
-rw-r--r--lib/epub.js/src/utils/constants.js62
-rw-r--r--lib/epub.js/src/utils/core.js876
-rw-r--r--lib/epub.js/src/utils/hook.js82
-rw-r--r--lib/epub.js/src/utils/mime.js169
-rw-r--r--lib/epub.js/src/utils/path.js102
-rw-r--r--lib/epub.js/src/utils/queue.js246
-rw-r--r--lib/epub.js/src/utils/replacements.js138
-rw-r--r--lib/epub.js/src/utils/request.js150
-rw-r--r--lib/epub.js/src/utils/scrolltype.js55
-rw-r--r--lib/epub.js/src/utils/url.js108
-rw-r--r--lib/epub.js/test/book.js66
-rw-r--r--lib/epub.js/test/core.js199
-rw-r--r--lib/epub.js/test/epub.js52
-rw-r--r--lib/epub.js/test/epubcfi.js425
-rw-r--r--lib/epub.js/test/fixtures/alice.epubbin0 -> 536540 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/META-INF/container.xml5
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_001.xhtml139
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_002.xhtml141
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_003.xhtml177
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_004.xhtml159
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_005.xhtml149
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_006.xhtml122
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_007.xhtml98
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_008.xhtml151
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_009.xhtml100
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/chapter_010.xhtml104
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/cover.xhtml12
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/css/stylesheet.css105
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/cover_th.jpgbin0 -> 36192 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i001_th.jpgbin0 -> 7606 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i002_th.jpgbin0 -> 6100 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i003_th.jpgbin0 -> 13746 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i004_th.jpgbin0 -> 11550 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i005_th.jpgbin0 -> 15846 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i006_th.jpgbin0 -> 18305 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i007_th.jpgbin0 -> 6636 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i008_th.jpgbin0 -> 14681 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i009_th.jpgbin0 -> 21200 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i010_th.jpgbin0 -> 3448 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i011_th.jpgbin0 -> 17046 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i012_th.jpgbin0 -> 19514 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i013_th.jpgbin0 -> 17064 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i014_th.jpgbin0 -> 15247 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i015_th.jpgbin0 -> 14489 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i016_th.jpgbin0 -> 14909 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i017_th.jpgbin0 -> 18503 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i018_th.jpgbin0 -> 14143 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i019_th.jpgbin0 -> 7215 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i020_th.jpgbin0 -> 13649 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/i022_th.jpgbin0 -> 14295 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/ii021_th.jpgbin0 -> 10233 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/plate01_th.jpgbin0 -> 42546 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/plate02_th.jpgbin0 -> 42694 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/plate03_th.jpgbin0 -> 42230 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/plate04_th.jpgbin0 -> 44618 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/images/title.jpgbin0 -> 1667 bytes
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/package.opf84
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/titlepage.xhtml42
-rw-r--r--lib/epub.js/test/fixtures/alice/OPS/toc.xhtml33
-rw-r--r--lib/epub.js/test/fixtures/alice/mimetype1
-rw-r--r--lib/epub.js/test/fixtures/alice_without_cover.epubbin0 -> 2981 bytes
-rw-r--r--lib/epub.js/test/fixtures/chapter1-highlights.xhtml36
-rw-r--r--lib/epub.js/test/fixtures/chapter1.xhtml36
-rw-r--r--lib/epub.js/test/fixtures/highlight.xhtml28
-rw-r--r--lib/epub.js/test/fixtures/locations.xhtml28
-rw-r--r--lib/epub.js/test/index.html12
-rw-r--r--lib/epub.js/test/locations.js31
-rw-r--r--lib/epub.js/test/old/epub.js371
-rw-r--r--lib/epub.js/test/old/rendering.js16
-rw-r--r--lib/epub.js/test/section.js77
-rw-r--r--lib/epub.js/types/annotations.d.ts53
-rw-r--r--lib/epub.js/types/archive.d.ts27
-rw-r--r--lib/epub.js/types/book.d.ts122
-rw-r--r--lib/epub.js/types/container.d.ts7
-rw-r--r--lib/epub.js/types/contents.d.ts139
-rw-r--r--lib/epub.js/types/core.d.ts83
-rw-r--r--lib/epub.js/types/epub.d.ts6
-rw-r--r--lib/epub.js/types/epubcfi.d.ts97
-rw-r--r--lib/epub.js/types/epubjs-tests.ts9
-rw-r--r--lib/epub.js/types/index.d.ts20
-rw-r--r--lib/epub.js/types/layout.d.ts48
-rw-r--r--lib/epub.js/types/locations.d.ts41
-rw-r--r--lib/epub.js/types/managers/manager.d.ts90
-rw-r--r--lib/epub.js/types/managers/view.d.ts79
-rw-r--r--lib/epub.js/types/mapping.d.ts34
-rw-r--r--lib/epub.js/types/navigation.d.ts46
-rw-r--r--lib/epub.js/types/packaging.d.ts78
-rw-r--r--lib/epub.js/types/pagelist.d.ts29
-rw-r--r--lib/epub.js/types/rendition.d.ts151
-rw-r--r--lib/epub.js/types/resources.d.ts33
-rw-r--r--lib/epub.js/types/section.d.ts64
-rw-r--r--lib/epub.js/types/spine.d.ts30
-rw-r--r--lib/epub.js/types/store.d.ts30
-rw-r--r--lib/epub.js/types/themes.d.ts40
-rw-r--r--lib/epub.js/types/tsconfig.json24
-rw-r--r--lib/epub.js/types/tslint.json4
-rw-r--r--lib/epub.js/types/utils/constants.d.ts9
-rw-r--r--lib/epub.js/types/utils/core.d.ts79
-rw-r--r--lib/epub.js/types/utils/hook.d.ts18
-rw-r--r--lib/epub.js/types/utils/path.d.ts17
-rw-r--r--lib/epub.js/types/utils/queue.d.ts34
-rw-r--r--lib/epub.js/types/utils/replacements.d.ts12
-rw-r--r--lib/epub.js/types/utils/request.d.ts1
-rw-r--r--lib/epub.js/types/utils/scrolltype.d.ts3
-rw-r--r--lib/epub.js/types/utils/url.d.ts13
-rw-r--r--lib/epub.js/webpack.config.js83
181 files changed, 42110 insertions, 0 deletions
diff --git a/lib/epub.js/.babelrc.json b/lib/epub.js/.babelrc.json
new file mode 100644
index 0000000..9c7817a
--- /dev/null
+++ b/lib/epub.js/.babelrc.json
@@ -0,0 +1,11 @@
+{
+ "presets": [
+ ["@babel/preset-env", {
+ "targets": "last 2 Chrome versions, last 2 Safari versions, last 2 ChromeAndroid versions, last 2 iOS versions, last 2 Firefox versions, last 2 Edge versions",
+ "corejs": 3,
+ "useBuiltIns": "usage",
+ "bugfixes": true,
+ "modules": "auto"
+ }]
+ ],
+}
diff --git a/lib/epub.js/.eslintrc.js b/lib/epub.js/.eslintrc.js
new file mode 100644
index 0000000..1bfd1ae
--- /dev/null
+++ b/lib/epub.js/.eslintrc.js
@@ -0,0 +1,43 @@
+module.exports = {
+ "env": {
+ "browser": true,
+ "commonjs": true,
+ "es6": true,
+ "node": true
+ },
+ "globals": {
+ "ePub": true,
+ "JSZip": true
+ },
+ "extends": "eslint:recommended",
+ "parserOptions": {
+ "sourceType": "module"
+ },
+ "rules": {
+ "indent": [
+ "error",
+ "tab",
+ { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }
+ ],
+ "linebreak-style": [
+ "error",
+ "unix"
+ ],
+ "quotes": [
+ "warn",
+ "double"
+ ],
+ "semi": [
+ "error",
+ "always"
+ ],
+ "no-unused-vars" : ["warn"],
+ "no-console" : ["warn"],
+ "no-unused-vars": [
+ "error",
+ { "vars": "all", "args": "none" }
+ ],
+ "no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
+ "valid-jsdoc": ["warn"]
+ }
+};
diff --git a/lib/epub.js/.gitignore b/lib/epub.js/.gitignore
new file mode 100644
index 0000000..689df6c
--- /dev/null
+++ b/lib/epub.js/.gitignore
@@ -0,0 +1,11 @@
+.DS_Store
+*/**/.DS_Store
+node_modules/
+components
+node_modules
+bower_components
+books
+lib
+dist
+documentation/html
+types/*.js \ No newline at end of file
diff --git a/lib/epub.js/.jshintrc b/lib/epub.js/.jshintrc
new file mode 100644
index 0000000..c2b6f01
--- /dev/null
+++ b/lib/epub.js/.jshintrc
@@ -0,0 +1,23 @@
+{
+ "browser": true,
+ "devel": true,
+ "worker": true,
+
+ "trailing": true,
+ "strict": false,
+
+ "boss": true,
+ "funcscope": true,
+ "globalstrict": true,
+ "loopfunc": true,
+ "maxerr": 1000,
+ "nonstandard": true,
+ "sub": true,
+ "validthis": true,
+
+ "globals": {
+ "_": false,
+ "define" : false,
+ "module" : false
+ }
+}
diff --git a/lib/epub.js/.nojekyll b/lib/epub.js/.nojekyll
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/epub.js/.nojekyll
diff --git a/lib/epub.js/.npmignore b/lib/epub.js/.npmignore
new file mode 100644
index 0000000..9984ce6
--- /dev/null
+++ b/lib/epub.js/.npmignore
@@ -0,0 +1,3 @@
+books
+test
+.babelrc
diff --git a/lib/epub.js/.travis.yml b/lib/epub.js/.travis.yml
new file mode 100644
index 0000000..d0cd9d3
--- /dev/null
+++ b/lib/epub.js/.travis.yml
@@ -0,0 +1,13 @@
+language: node_js
+node_js:
+ - "node"
+notifications:
+ email: false
+sudo: false
+addons:
+ chrome: stable
+cache:
+ directories:
+ - node_modules
+script:
+ - npm test
diff --git a/lib/epub.js/.watchmanconfig b/lib/epub.js/.watchmanconfig
new file mode 100644
index 0000000..d92d987
--- /dev/null
+++ b/lib/epub.js/.watchmanconfig
@@ -0,0 +1,6 @@
+{
+ "ignore_dirs": [
+ ".git",
+ "node_modules"
+ ]
+}
diff --git a/lib/epub.js/README.md b/lib/epub.js/README.md
new file mode 100644
index 0000000..aab8a17
--- /dev/null
+++ b/lib/epub.js/README.md
@@ -0,0 +1,197 @@
+# Epub.js v0.3
+
+![FuturePress Views](http://fchasen.com/futurepress/fp.png)
+
+Epub.js is a JavaScript library for rendering ePub documents in the browser, across many devices.
+
+Epub.js provides an interface for common ebook functions (such as rendering, persistence and pagination) without the need to develop a dedicated application or plugin. Importantly, it has an incredibly permissive [Free BSD](http://en.wikipedia.org/wiki/BSD_licenses) license.
+
+[Try it while reading Moby Dick](https://futurepress.github.io/epubjs-reader/)
+
+## Why EPUB
+
+![Why EPUB](http://fchasen.com/futurepress/whyepub.png)
+
+The [EPUB standard](http://www.idpf.org/epub/30/spec/epub30-overview.html) is a widely used and easily convertible format. Many books are currently in this format, and it is convertible to many other formats (such as PDF, Mobi and iBooks).
+
+An unzipped EPUB3 is a collection of HTML5 files, CSS, images and other media – just like any other website. However, it enforces a schema of book components, which allows us to render a book and its parts based on a controlled vocabulary.
+
+More specifically, the EPUB schema standardizes the table of contents, provides a manifest that enables the caching of the entire book, and separates the storage of the content from how it’s displayed.
+
+## Getting Started
+
+Get the minified code from the build folder:
+
+```html
+<script src="../dist/epub.min.js"></script>
+```
+
+If using archived `.epub` files include JSZip:
+
+```html
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+```
+
+Set up a element to render to:
+
+```html
+<div id="area"></div>
+```
+
+Create the new ePub, and then render it to that element:
+
+```html
+<script>
+ var book = ePub("url/to/book/package.opf");
+ var rendition = book.renderTo("area", {width: 600, height: 400});
+ var displayed = rendition.display();
+</script>
+```
+
+## Render Methods
+
+### Default
+
+```js
+book.renderTo("area", { method: "default", width: "100%", height: "100%" });
+```
+
+[View example](http://futurepress.github.io/epub.js/examples/spreads.html)
+
+The default manager only displays a single section at a time.
+
+### Continuous
+
+```js
+book.renderTo("area", { method: "continuous", width: "100%", height: "100%" });
+```
+[View example](http://futurepress.github.io/epub.js/examples/continuous-scrolled.html)
+
+The continuous manager will display as many sections as need to fill the screen, and preload the next section offscreen. This enables seamless swiping / scrolling between pages on mobile and desktop, but is less performant than the default method.
+
+## Flow Overrides
+
+### Auto (Default)
+`book.renderTo("area", { flow: "auto", width: "900", height: "600" });`
+
+Flow will be based on the settings in the OPF, defaults to `paginated`.
+
+### Paginated
+
+```js
+book.renderTo("area", { flow: "paginated", width: "900", height: "600" });
+```
+
+[View example](http://futurepress.github.io/epub.js/examples/spreads.html)
+
+Scrolled: `book.renderTo("area", { flow: "scrolled-doc" });`
+
+[View example](http://futurepress.github.io/epub.js/examples/scrolled.html)
+
+## Documentation
+
+API documentation is available at [epubjs.org/documentation/0.3/](http://epubjs.org/documentation/0.3/)
+
+A Markdown version is included in the repo at [documentation/API.md](https://github.com/futurepress/epub.js/blob/master/documentation/md/API.md)
+
+## Running Locally
+
+install [node.js](http://nodejs.org/)
+
+Then install the project dependences with npm
+
+```javascript
+npm install
+```
+
+You can run the reader locally with the command
+
+```javascript
+npm start
+```
+
+## Examples
+
++ [Spreads](http://futurepress.github.io/epub.js/examples/spreads.html)
++ [Scrolled](http://futurepress.github.io/epub.js/examples/scrolled.html)
++ [Swipe](http://futurepress.github.io/epub.js/examples/swipe.html)
++ [Input](http://futurepress.github.io/epub.js/examples/input.html)
++ [Highlights](http://futurepress.github.io/epub.js/examples/highlights.html)
+
+[View All Examples](http://futurepress.github.io/epub.js/examples/)
+
+## Testing
+
+Test can be run by Karma from NPM
+
+```js
+npm test
+```
+
+## Building for Distribution
+
+Builds are concatenated and minified using [webpack](https://webpack.js.org/) and [babel](https://babeljs.io/)
+
+To generate a new build run
+
+```javascript
+npm run prepare
+```
+
+or to continuously build run
+
+```javascript
+npm run watch
+```
+
+## Hooks
+
+Similar to a plugins, Epub.js implements events that can be "hooked" into. Thus you can interact with and manipulate the contents of the book.
+
+Examples of this functionality is loading videos from YouTube links before displaying a chapter's contents or implementing annotation.
+
+Hooks require an event to register to and a can return a promise to block until they are finished.
+
+Example hook:
+
+```javascript
+rendition.hooks.content.register(function(contents, view) {
+
+ var elements = contents.document.querySelectorAll('[video]');
+ var items = Array.prototype.slice.call(elements);
+
+ items.forEach(function(item){
+ // do something with the video item
+ });
+
+})
+```
+
+The parts of the rendering process that can be hooked into are below.
+
+```js
+book.spine.hooks.serialize // Section is being converted to text
+book.spine.hooks.content // Section has been loaded and parsed
+rendition.hooks.render // Section is rendered to the screen
+rendition.hooks.content // Section contents have been loaded
+rendition.hooks.unloaded // Section contents are being unloaded
+```
+
+## Reader
+The reader has moved to its own repo at: https://github.com/futurepress/epubjs-reader/
+
+## Additional Resources
+
+[![Gitter Chat](https://badges.gitter.im/futurepress/epub.js.png)](https://gitter.im/futurepress/epub.js "Gitter Chat")
+
+[Epub.js Developer Mailing List](https://groups.google.com/forum/#!forum/epubjs)
+
+IRC Server: freenode.net Channel: #epub.js
+
+Follow us on twitter: @Epubjs
+
++ http://twitter.com/#!/Epubjs
+
+## Other
+
+EPUB is a registered trademark of the [IDPF](http://idpf.org/).
diff --git a/lib/epub.js/bower.json b/lib/epub.js/bower.json
new file mode 100644
index 0000000..b044630
--- /dev/null
+++ b/lib/epub.js/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "epubjs",
+ "version": "0.3.0",
+ "authors": [
+ "Fred Chasen <[email protected]>"
+ ],
+ "description": "Enhanced eBooks in the browser.",
+ "main": "dist/epub.js",
+ "moduleType": [
+ "amd",
+ "globals",
+ "node"
+ ],
+ "keywords": [
+ "epub"
+ ],
+ "license": "MIT",
+ "homepage": "http://futurepress.org",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tools",
+ "books",
+ "examples"
+ ],
+ "dependencies": {
+ "event-emitter": "^0.3.5",
+ "jszip": "^3.4.0",
+ "localforage": "^1.7.3",
+ "lodash": "^4.17.15",
+ "marks-pane": "^1.0.9",
+ "path-webpack": "0.0.3",
+ "stream-browserify": "^3.0.0",
+ "url-polyfill": "^1.1.9",
+ "xmldom": "^0.3.0"
+ }
+}
diff --git a/lib/epub.js/documentation.yml b/lib/epub.js/documentation.yml
new file mode 100644
index 0000000..26bd806
--- /dev/null
+++ b/lib/epub.js/documentation.yml
@@ -0,0 +1,6 @@
+toc:
+ - ePub
+ - name: ePubJS
+ description: |
+ main entry
+ - EpubCFI
diff --git a/lib/epub.js/documentation/md/API.md b/lib/epub.js/documentation/md/API.md
new file mode 100644
index 0000000..60a447b
--- /dev/null
+++ b/lib/epub.js/documentation/md/API.md
@@ -0,0 +1,2310 @@
+<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
+
+## ePub
+
+Creates a new Book
+
+**Parameters**
+
+- `url` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer))** URL, Path or ArrayBuffer
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** to pass to the book
+
+**Examples**
+
+```javascript
+ePub("/path/to/book.epub", {})
+```
+
+Returns **[Book](#book)** a new Book object
+
+## Book
+
+An Epub representation with methods for the loading, parsing and manipulation
+of its contents.
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
+ - `options.requestMethod` **method?** a request function to use instead of the default
+ - `options.requestCredentials` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** send the xhr request withCredentials (optional, default `undefined`)
+ - `options.requestHeaders` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** send the xhr request headers (optional, default `undefined`)
+ - `options.encoding` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** optional to pass 'binary' or base64' for archived Epubs (optional, default `binary`)
+ - `options.replacements` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** use base64, blobUrl, or none for replacing assets in archived Epubs (optional, default `none`)
+ - `options.canonical` **method?** optional function to determine canonical urls for a path
+ - `options.openAs` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** optional string to determine the input type
+
+**Examples**
+
+```javascript
+new Book("/path/to/book.epub", {})
+```
+
+```javascript
+new Book({ replacements: "blobUrl" })
+```
+
+Returns **[Book](#book)**
+
+### open
+
+Open a epub or url
+
+**Parameters**
+
+- `input` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer))** Url, Path or ArrayBuffer
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** force opening as a certain type (optional, default `"binary","base64","epub","opf","json","directory"`)
+
+**Examples**
+
+```javascript
+book.open("/path/to/book.epub")
+```
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** of when the book has been loaded
+
+### load
+
+Load a resource from the Book
+
+**Parameters**
+
+- `path` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** path to the resource to load
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** returns a promise with the requested resource
+
+### resolve
+
+Resolve a path to it's absolute position in the Book
+
+**Parameters**
+
+- `path` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `absolute` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** force resolving the full URL
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the resolved path string
+
+### canonical
+
+Get a canonical link to a path
+
+**Parameters**
+
+- `path` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the canonical path string
+
+### section
+
+Gets a Section of the Book from the Spine
+Alias for `book.spine.get`
+
+**Parameters**
+
+- `target` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[Section](#section)**
+
+### renderTo
+
+Sugar to render a book to an element
+
+**Parameters**
+
+- `element` **([element](https://developer.mozilla.org/en-US/docs/Web/API/Element) \| [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))** element or string to add a rendition to
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
+
+Returns **[Rendition](#rendition)**
+
+### setRequestCredentials
+
+Set if request should use withCredentials
+
+**Parameters**
+
+- `credentials` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### setRequestHeaders
+
+Set headers request should use
+
+**Parameters**
+
+- `headers` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### coverUrl
+
+Get the cover url if there is a cover
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[?string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)&gt;** Promise resolves with maybe a url string
+
+### getRange
+
+Find a DOM Range for a given CFI Range
+
+**Parameters**
+
+- `cfiRange` **[EpubCFI](#epubcfi)** a epub cfi range
+
+Returns **[Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+
+### key
+
+Generates the Book Key using the identifer in the manifest or other string provided
+
+**Parameters**
+
+- `identifier` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** to use instead of metadata identifier
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** key
+
+### destroy
+
+Destroy the Book and all associated objects
+
+### opened
+
+### spine
+
+Type: [Spine](#spine)
+
+### locations
+
+Type: [Locations](#locations)
+
+### navigation
+
+Type: [Navigation](#navigation)
+
+### pagelist
+
+Type: [PageList](#pagelist)
+
+## Url
+
+creates a Url object for parsing and manipulation of a url string
+
+**Parameters**
+
+- `urlString` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** a url string (relative or absolute)
+- `baseString` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** optional base for the url,
+ default to window.location.href
+
+### path
+
+Returns **[Path](#path)**
+
+### resolve
+
+Resolves a relative path to a absolute url
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+### relative
+
+Resolve a path relative to the url
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** path
+
+### toString
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+## Path
+
+Creates a Path object for parsing and manipulation of a path strings
+
+Uses a polyfill for Nodejs path: <https://nodejs.org/api/path.html>
+
+**Parameters**
+
+- `pathString` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** a url string (relative or absolute)
+
+### parse
+
+Parse the path: <https://nodejs.org/api/path.html#path_path_parse_path>
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### isAbsolute
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### isDirectory
+
+Check if path ends with a directory
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### resolve
+
+Resolve a path against the directory of the Path
+
+<https://nodejs.org/api/path.html#path_path_resolve_paths>
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** resolved
+
+### relative
+
+Resolve a path relative to the directory of the Path
+
+<https://nodejs.org/api/path.html#path_path_relative_from_to>
+
+**Parameters**
+
+- `what` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** relative
+
+### toString
+
+Return the path string
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** path
+
+## Spine
+
+A collection of Spine Items
+
+### unpack
+
+Unpack items from a opf into spine items
+
+**Parameters**
+
+- `_package` **[Packaging](#packaging)**
+- `resolver` **method** URL resolver
+- `canonical` **method** Resolve canonical url
+
+### get
+
+Get an item from the spine
+
+**Parameters**
+
+- `target` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))?**
+
+**Examples**
+
+```javascript
+spine.get();
+```
+
+```javascript
+spine.get(1);
+```
+
+```javascript
+spine.get("chap1.html");
+```
+
+```javascript
+spine.get("#id1234");
+```
+
+Returns **[Section](#section)** section
+
+### each
+
+Loop over the Sections in the Spine
+
+Returns **method** forEach
+
+### first
+
+Find the first Section in the Spine
+
+Returns **[Section](#section)** first section
+
+### last
+
+Find the last Section in the Spine
+
+Returns **[Section](#section)** last section
+
+## Section
+
+Represents a Section of the Book
+
+In most books this is equivelent to a Chapter
+
+**Parameters**
+
+- `item` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** The spine item representing the section
+- `hooks` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** hooks for serialize and content
+
+### load
+
+Load the section from its url
+
+**Parameters**
+
+- `_request` **method?** a request method to use for loading
+
+Returns **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** a promise with the xml document
+
+### render
+
+Render the contents of a section
+
+**Parameters**
+
+- `_request` **method?** a request method to use for loading
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** output a serialized XML Document
+
+### find
+
+Find a string in a section
+
+**Parameters**
+
+- `_query` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The query string to find
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>** A list of matches, with form {cfi, excerpt}
+
+### reconcileLayoutSettings
+
+Reconciles the current chapters layout properies with
+the global layout properities.
+
+**Parameters**
+
+- `globalLayout` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** The global layout settings object, chapter properties string
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** layoutProperties Object with layout properties
+
+### cfiFromRange
+
+Get a CFI from a Range in the Section
+
+**Parameters**
+
+- `_range` **[range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** cfi an EpubCFI string
+
+### cfiFromElement
+
+Get a CFI from an Element in the Section
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** cfi an EpubCFI string
+
+### unload
+
+Unload the section document
+
+## Locations
+
+Find Locations for a Book
+
+**Parameters**
+
+- `spine` **[Spine](#spine)**
+- `request` **[request](https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/request)**
+- `pause` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** (optional, default `100`)
+
+### generate
+
+Load all of sections in the book to generate locations
+
+**Parameters**
+
+- `chars` **int** how many chars to split on
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** locations
+
+### locationFromCfi
+
+Get a location from an EpubCFI
+
+**Parameters**
+
+- `cfi` **[EpubCFI](#epubcfi)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### percentageFromCfi
+
+Get a percentage position in locations from an EpubCFI
+
+**Parameters**
+
+- `cfi` **[EpubCFI](#epubcfi)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### percentageFromLocation
+
+Get a percentage position from a location index
+
+**Parameters**
+
+- `loc`
+- `location` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### cfiFromLocation
+
+Get an EpubCFI from location index
+
+**Parameters**
+
+- `loc` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+Returns **[EpubCFI](#epubcfi)** cfi
+
+### cfiFromPercentage
+
+Get an EpubCFI from location percentage
+
+**Parameters**
+
+- `percentage` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+Returns **[EpubCFI](#epubcfi)** cfi
+
+### load
+
+Load locations from JSON
+
+**Parameters**
+
+- `locations` **[json](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)**
+
+### save
+
+Save locations to JSON
+
+Returns **[json](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)**
+
+### currentLocation
+
+Get the current location
+
+### currentLocation
+
+Set the current location
+
+**Parameters**
+
+- `curr`
+
+### length
+
+Locations length
+
+## Container
+
+Handles Parsing and Accessing an Epub Container
+
+**Parameters**
+
+- `containerDocument` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)?** xml document
+
+### parse
+
+Parse the Container XML
+
+**Parameters**
+
+- `containerDocument` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)**
+
+## Packaging
+
+Open Packaging Format Parser
+
+**Parameters**
+
+- `packageDocument` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** OPF XML
+
+### parse
+
+Parse OPF XML
+
+**Parameters**
+
+- `packageDocument` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** OPF XML
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** parsed package parts
+
+### load
+
+Load JSON Manifest
+
+**Parameters**
+
+- `json`
+- `packageDocument` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** OPF XML
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** parsed package parts
+
+## Navigation
+
+Navigation Parser
+
+**Parameters**
+
+- `xml` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** navigation html / xhtml / ncx
+
+### parse
+
+Parse out the navigation items
+
+**Parameters**
+
+- `xml` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** navigation html / xhtml / ncx
+
+### get
+
+Get an item from the navigation
+
+**Parameters**
+
+- `target` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** navItem
+
+### landmark
+
+Get a landmark by type
+List of types: <https://idpf.github.io/epub-vocabs/structure/>
+
+**Parameters**
+
+- `type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** landmarkItem
+
+### load
+
+Load Spine Items
+
+**Parameters**
+
+- `json` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** the items to be loaded
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** navItems
+
+### forEach
+
+forEach pass through
+
+**Parameters**
+
+- `fn` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function to run on each item
+
+Returns **method** forEach loop
+
+## Resources
+
+Handle Package Resources
+
+**Parameters**
+
+- `manifest` **Manifest**
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
+ - `options.replacements` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** (optional, default `"base64"`)
+ - `options.archive` **[Archive](#archive)?**
+ - `options.resolver` **method?**
+
+### createUrl
+
+Create a url to a resource
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>** Promise resolves with url string
+
+### replacements
+
+Create blob urls for all the assets
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** returns replacement urls
+
+### relativeTo
+
+Resolve all resources URLs relative to an absolute URL
+
+**Parameters**
+
+- `absolute` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** to be resolved to
+- `resolver` **resolver?**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>** array with relative Urls
+
+### get
+
+Get a URL for a resource
+
+**Parameters**
+
+- `path` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+### substitute
+
+Substitute urls in content, with replacements,
+relative to a url if provided
+
+**Parameters**
+
+- `content` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** url to resolve to
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** content with urls substituted
+
+## PageList
+
+Page List Parser
+
+**Parameters**
+
+- `xml` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)?**
+
+### parse
+
+Parse PageList Xml
+
+**Parameters**
+
+- `xml` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)**
+
+### pageFromCfi
+
+Get a PageList result from a EpubCFI
+
+**Parameters**
+
+- `cfi` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** EpubCFI String
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** page
+
+### cfiFromPage
+
+Get an EpubCFI from a Page List Item
+
+**Parameters**
+
+- `pg` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** cfi
+
+### pageFromPercentage
+
+Get a Page from Book percentage
+
+**Parameters**
+
+- `percent` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** page
+
+### percentageFromPage
+
+Returns a value between 0 - 1 corresponding to the location of a page
+
+**Parameters**
+
+- `pg` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** the page
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** percentage
+
+### percentageFromCfi
+
+Returns a value between 0 - 1 corresponding to the location of a cfi
+
+**Parameters**
+
+- `cfi` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** EpubCFI String
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** percentage
+
+### destroy
+
+Destroy
+
+## Archive
+
+Handles Unzipping a requesting files from an Epub Archive
+
+### open
+
+Open an archive
+
+**Parameters**
+
+- `input` **binary**
+- `isBase64` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** tells JSZip if the input data is base64 encoded
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** zipfile
+
+### openUrl
+
+Load and Open an archive
+
+**Parameters**
+
+- `zipUrl` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `isBase64` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** tells JSZip if the input data is base64 encoded
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** zipfile
+
+### request
+
+Request a url from the archive
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** a url to request from the archive
+- `type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** specify the type of the returned result
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;([Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) \| [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) \| [Document](https://developer.mozilla.org/en-US/docs/Web/JavaScript) | XMLDocument)>**
+
+### getBlob
+
+Get a Blob from Archive by Url
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `mimeType` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)**
+
+### getText
+
+Get Text from Archive by Url
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `encoding` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### getBase64
+
+Get a base64 encoded result from Archive by Url
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `mimeType` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** base64 encoded
+
+### createUrl
+
+Create a Url from an unarchived item
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `options`
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** url promise with Url string
+
+### revokeUrl
+
+Revoke Temp Url for a achive item
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url of the item in the archive
+
+## Rendition
+
+Displays an Epub as a series of Views for each Section.
+Requires Manager and View class to handle specifics of rendering
+the section content.
+
+**Parameters**
+
+- `book` **[Book](#book)**
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
+ - `options.width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+ - `options.height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+ - `options.ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** class for the cfi parser to ignore
+ - `options.manager` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** (optional, default `'default'`)
+ - `options.view` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function))** (optional, default `'iframe'`)
+ - `options.layout` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** layout to force
+ - `options.spread` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** force spread value
+ - `options.minSpreadWidth` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** overridden by spread: none (never) / both (always)
+ - `options.stylesheet` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** url of stylesheet to be injected
+ - `options.resizeOnOrientationChange` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** false to disable orientation events
+ - `options.script` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** url of script to be injected
+
+### setManager
+
+Set the manager function
+
+**Parameters**
+
+- `manager` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
+
+### requireManager
+
+Require the manager from passed string, or as a class function
+
+**Parameters**
+
+- `manager` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** [description]
+
+Returns **method**
+
+### requireView
+
+Require the view from passed string, or as a class function
+
+**Parameters**
+
+- `view` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))**
+
+Returns **view**
+
+### start
+
+Start the rendering
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** rendering has started
+
+### attachTo
+
+Call to attach the container to an element in the dom
+Container must be attached before rendering can begin
+
+**Parameters**
+
+- `element` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** to attach to
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### display
+
+Display a point in the book
+The request will be added to the rendering Queue,
+so it will wait until book is opened, rendering started
+and all other rendering tasks have finished to be called.
+
+**Parameters**
+
+- `target` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Url or EpubCFI
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### moveTo
+
+Move the Rendition to a specific offset
+Usually you would be better off calling display()
+
+**Parameters**
+
+- `offset` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### resize
+
+Trigger a resize of the views
+
+**Parameters**
+
+- `width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+- `height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+### clear
+
+Clear all rendered views
+
+### next
+
+Go to the next "page" in the rendition
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### prev
+
+Go to the previous "page" in the rendition
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### flow
+
+Adjust the flow of the rendition to paginated or scrolled
+(scrolled-continuous vs scrolled-doc are handled by different view managers)
+
+**Parameters**
+
+- `flow` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### layout
+
+Adjust the layout of the rendition to reflowable or pre-paginated
+
+**Parameters**
+
+- `settings` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### spread
+
+Adjust if the rendition uses spreads
+
+**Parameters**
+
+- `spread` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** none | auto (TODO: implement landscape, portrait, both)
+- `min` **int** min width to use spreads at
+
+### direction
+
+Adjust the direction of the rendition
+
+**Parameters**
+
+- `dir` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### reportLocation
+
+Report the current location
+
+### currentLocation
+
+Get the Current Location object
+
+Returns **(displayedLocation | [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise))** location (may be a promise)
+
+### destroy
+
+Remove and Clean Up the Rendition
+
+### getRange
+
+Get a Range from a Visible CFI
+
+**Parameters**
+
+- `cfi` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** EpubCfi String
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+
+### getContents
+
+Get the Contents object of each rendered view
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Contents](#contents)>**
+
+### views
+
+Get the views member from the manager
+
+Returns **Views**
+
+### hooks
+
+Adds Hook methods to the Rendition prototype
+
+Type: [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
+
+### themes
+
+Type: [Themes](#themes)
+
+### annotations
+
+Type: [Annotations](#annotations)
+
+### location
+
+A Rendered Location Range
+
+**Properties**
+
+- `start` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `start.index` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+ - `start.href` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+ - `start.displayed` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `start.displayed.page` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `start.displayed.total` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `start.cfi` **[EpubCFI](#epubcfi)**
+ - `start.location` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `start.percentage` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `end` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `end.index` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+ - `end.href` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+ - `end.displayed` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `end.displayed.page` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `end.displayed.total` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `end.cfi` **[EpubCFI](#epubcfi)**
+ - `end.location` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+ - `end.percentage` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `atStart` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+- `atEnd` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### started
+
+## Hook
+
+Hooks allow for injecting functions that must all complete in order before finishing
+They will execute in parallel but all must finish before continuing
+Functions may return a promise if they are asycn.
+
+**Parameters**
+
+- `context` **any** scope of this
+
+**Examples**
+
+```javascript
+this.content = new EPUBJS.Hook(this);
+```
+
+### register
+
+Adds a function to be run before a hook completes
+
+**Examples**
+
+```javascript
+this.content.register(function(){...});
+```
+
+### trigger
+
+Triggers a hook to run all functions
+
+**Examples**
+
+```javascript
+this.content.trigger(args).then(function(){...});
+```
+
+## Queue
+
+Queue for handling tasks one at a time
+
+**Parameters**
+
+- `context` **scope** what this will resolve to in the tasks
+
+### enqueue
+
+Add an item to the queue
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### dequeue
+
+Run one item
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### run
+
+Run all tasks sequentially, at convince
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### flush
+
+Flush all, as quickly as possible
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### clear
+
+Clear all items in wait
+
+### length
+
+Get the number of tasks in the queue
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** tasks
+
+### pause
+
+Pause a running queue
+
+### stop
+
+End the queue
+
+## Layout
+
+Figures out the CSS values to apply for a layout
+
+**Parameters**
+
+- `settings` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `settings.layout` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** (optional, default `'reflowable'`)
+ - `settings.spread` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `settings.minSpreadWidth` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** (optional, default `800`)
+ - `settings.evenSpreads` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (optional, default `false`)
+
+### flow
+
+Switch the flow between paginated and scrolled
+
+**Parameters**
+
+- `flow` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** paginated | scrolled
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** simplified flow
+
+### spread
+
+Switch between using spreads or not, and set the
+width at which they switch to single.
+
+**Parameters**
+
+- `spread` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** "none" | "always" | "auto"
+- `min` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** integer in pixels
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** spread true | false
+
+### calculate
+
+Calculate the dimensions of the pagination
+
+**Parameters**
+
+- `_width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width of the rendering
+- `_height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height of the rendering
+- `_gap` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width of the gap between columns
+
+### format
+
+Apply Css to a Document
+
+**Parameters**
+
+- `contents` **[Contents](#contents)**
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
+
+### count
+
+Count number of pages
+
+**Parameters**
+
+- `totalLength` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `pageLength` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+Returns **{spreads: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), pages: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)}**
+
+## Themes
+
+Themes to apply to displayed content
+
+**Parameters**
+
+- `rendition` **[Rendition](#rendition)**
+
+### register
+
+Add themes to be used by a rendition
+
+**Examples**
+
+```javascript
+themes.register("light", "http://example.com/light.css")
+```
+
+```javascript
+themes.register("light", { "body": { "color": "purple"}})
+```
+
+```javascript
+themes.register({ "light" : {...}, "dark" : {...}})
+```
+
+### default
+
+Add a default theme to be used by a rendition
+
+**Parameters**
+
+- `theme` **([object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))**
+
+**Examples**
+
+```javascript
+themes.register("http://example.com/default.css")
+```
+
+```javascript
+themes.register({ "body": { "color": "purple"}})
+```
+
+### registerThemes
+
+Register themes object
+
+**Parameters**
+
+- `themes` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### registerUrl
+
+Register a url
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `input` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### registerRules
+
+Register rule
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `rules` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### select
+
+Select a theme
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### update
+
+Update a theme
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### inject
+
+Inject all themes into contents
+
+**Parameters**
+
+- `contents` **[Contents](#contents)**
+
+### add
+
+Add Theme to contents
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `contents` **[Contents](#contents)**
+
+### override
+
+Add override
+
+**Parameters**
+
+- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `value` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `priority` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### overrides
+
+Add all overrides
+
+**Parameters**
+
+- `contents`
+- `content` **Content**
+
+### fontSize
+
+Adjust the font size of a rendition
+
+**Parameters**
+
+- `size` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### font
+
+Adjust the font-family of a rendition
+
+**Parameters**
+
+- `f` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+## Annotations
+
+Handles managing adding & removing Annotations
+
+**Parameters**
+
+- `rendition` **[Rendition](#rendition)**
+
+### add
+
+Add an annotation to store
+
+**Parameters**
+
+- `type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Type of annotation to add: "highlight", "underline", "mark"
+- `cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range to attach annotation to
+- `data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Data to assign to annotation
+- `cb` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?** Callback after annotation is added
+- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** CSS class to assign to annotation
+- `styles` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** CSS styles to assign to annotation
+
+Returns **[Annotation](#annotation)** annotation
+
+### remove
+
+Remove an annotation from store
+
+**Parameters**
+
+- `cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range the annotation is attached to
+- `type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Type of annotation to add: "highlight", "underline", "mark"
+
+### highlight
+
+Add a highlight to the store
+
+**Parameters**
+
+- `cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range to attach annotation to
+- `data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Data to assign to annotation
+- `cb` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Callback after annotation is added
+- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** CSS class to assign to annotation
+- `styles` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** CSS styles to assign to annotation
+
+### underline
+
+Add a underline to the store
+
+**Parameters**
+
+- `cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range to attach annotation to
+- `data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Data to assign to annotation
+- `cb` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Callback after annotation is added
+- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** CSS class to assign to annotation
+- `styles` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** CSS styles to assign to annotation
+
+### mark
+
+Add a mark to the store
+
+**Parameters**
+
+- `cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range to attach annotation to
+- `data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Data to assign to annotation
+- `cb` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Callback after annotation is added
+
+### each
+
+iterate over annotations in the store
+
+### show
+
+[Not Implemented] Show annotations
+
+### hide
+
+[Not Implemented] Hide annotations
+
+## Annotation
+
+Annotation object
+
+**Parameters**
+
+- `$0` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `$0.type`
+ - `$0.cfiRange`
+ - `$0.data`
+ - `$0.sectionIndex`
+ - `$0.cb`
+ - `$0.className`
+ - `$0.styles`
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+ - `options.type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Type of annotation to add: "highlight", "underline", "mark"
+ - `options.cfiRange` **[EpubCFI](#epubcfi)** EpubCFI range to attach annotation to
+ - `options.data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Data to assign to annotation
+ - `options.sectionIndex` **int** Index in the Spine of the Section annotation belongs to
+ - `options.cb` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?** Callback after annotation is added
+- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** CSS class to assign to annotation
+- `styles` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** CSS styles to assign to annotation
+
+Returns **[Annotation](#annotation)** annotation
+
+### update
+
+Update stored data
+
+**Parameters**
+
+- `data` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### attach
+
+Add to a view
+
+**Parameters**
+
+- `view` **View**
+
+### detach
+
+Remove from a view
+
+**Parameters**
+
+- `view` **View**
+
+### text
+
+[Not Implemented] Get text of an annotation
+
+## EpubCFI
+
+Parsing and creation of EpubCFIs: <http://www.idpf.org/epub/linking/cfi/epub-cfi.html>
+
+Implements:
+
+- Character Offset: epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)
+- Simple Ranges : epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)
+
+Does Not Implement:
+
+- Temporal Offset (~)
+- Spatial Offset (@)
+- Temporal-Spatial Offset (~ + @)
+- Text Location Assertion (\[)
+
+**Parameters**
+
+- `cfiFrom` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input) \| [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling))?**
+- `base` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))?**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** class to ignore when parsing DOM
+
+### parse
+
+Parse a cfi string to a CFI object representation
+
+**Parameters**
+
+- `cfiStr` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** cfi
+
+### toString
+
+Convert CFI to a epubcfi(...) string
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** epubcfi
+
+### compare
+
+Compare which of two CFIs is earlier in the text
+
+**Parameters**
+
+- `cfiOne`
+- `cfiTwo`
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** First is earlier = -1, Second is earlier = 1, They are equal = 0
+
+### fromRange
+
+Create a CFI object from a Range
+
+**Parameters**
+
+- `range` **[Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+- `base` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** cfi
+
+### fromNode
+
+Create a CFI object from a Node
+
+**Parameters**
+
+- `anchor` **[Node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+- `base` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** cfi
+
+### toRange
+
+Creates a DOM range representing a CFI
+
+**Parameters**
+
+- `_doc` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** document referenced in the base
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+
+### isCfiString
+
+Check if a string is wrapped with "epubcfi()"
+
+**Parameters**
+
+- `str` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### collapse
+
+Collapse a CFI Range to a single CFI Position
+
+**Parameters**
+
+- `toStart` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (optional, default `false`)
+
+## Contents
+
+Handles DOM manipulation, queries and events for View contents
+
+**Parameters**
+
+- `doc` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** Document
+- `content` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** Parent Element (typically Body)
+- `cfiBase` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Section component of CFIs
+- `sectionIndex` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Index in Spine of Conntent's Section
+
+### width
+
+Get or Set width
+
+**Parameters**
+
+- `w` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width
+
+### height
+
+Get or Set height
+
+**Parameters**
+
+- `h` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height
+
+### contentWidth
+
+Get or Set width of the contents
+
+**Parameters**
+
+- `w` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width
+
+### contentHeight
+
+Get or Set height of the contents
+
+**Parameters**
+
+- `h` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height
+
+### textWidth
+
+Get the width of the text using Range
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width
+
+### textHeight
+
+Get the height of the text using Range
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height
+
+### scrollWidth
+
+Get documentElement scrollWidth
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** width
+
+### scrollHeight
+
+Get documentElement scrollHeight
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height
+
+### overflow
+
+Set overflow css style of the contents
+
+**Parameters**
+
+- `overflow` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+### overflowX
+
+Set overflowX css style of the documentElement
+
+**Parameters**
+
+- `overflow` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+### overflowY
+
+Set overflowY css style of the documentElement
+
+**Parameters**
+
+- `overflow` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+### css
+
+Set Css styles on the contents element (typically Body)
+
+**Parameters**
+
+- `property` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `value` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `priority` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** set as "important"
+
+### viewport
+
+Get or Set the viewport element
+
+**Parameters**
+
+- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
+ - `options.width` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `options.height` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `options.scale` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `options.minimum` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `options.maximum` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+ - `options.scalable` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+### root
+
+Get the documentElement
+
+Returns **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** documentElement
+
+### locationOf
+
+Get the location offset of a EpubCFI or an #id
+
+**Parameters**
+
+- `target` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [EpubCFI](#epubcfi))**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** for the cfi
+
+### addStylesheet
+
+Append a stylesheet link to the document head
+
+**Parameters**
+
+- `src` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+### addStylesheetRules
+
+Append stylesheet rules to a generate stylesheet
+Array: <https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule>
+Object: <https://github.com/desirable-objects/json-to-css>
+
+**Parameters**
+
+- `rules` **([array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))**
+
+### addScript
+
+Append a script tag to the document head
+
+**Parameters**
+
+- `src` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** loaded
+
+### addClass
+
+Add a class to the contents container
+
+**Parameters**
+
+- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### removeClass
+
+Remove a class from the contents container
+
+**Parameters**
+
+- `className`
+- `removeClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### range
+
+Get a Dom Range from EpubCFI
+
+**Parameters**
+
+- `_cfi` **[EpubCFI](#epubcfi)**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)** range
+
+### cfiFromRange
+
+Get an EpubCFI from a Dom Range
+
+**Parameters**
+
+- `range` **[Range](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[EpubCFI](#epubcfi)** cfi
+
+### cfiFromNode
+
+Get an EpubCFI from a Dom node
+
+**Parameters**
+
+- `node` **[node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+- `ignoreClass` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+Returns **[EpubCFI](#epubcfi)** cfi
+
+### size
+
+Size the contents to a given width and height
+
+**Parameters**
+
+- `width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+- `height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
+
+### columns
+
+Apply columns to the contents for pagination
+
+**Parameters**
+
+- `width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `columnWidth` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `gap` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### scaler
+
+Scale contents from center
+
+**Parameters**
+
+- `scale` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `offsetX` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `offsetY` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### fit
+
+Fit contents into a fixed width and height
+
+**Parameters**
+
+- `width` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+- `height` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)**
+
+### direction
+
+Set the direction of the text
+
+**Parameters**
+
+- `dir` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** "rtl" | "ltr" (optional, default `"ltr"`)
+
+### writingMode
+
+Set the writingMode of the text
+
+**Parameters**
+
+- `mode` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** "horizontal-tb" | "vertical-rl" | "vertical-lr" (optional, default `"horizontal-tb"`)
+
+### listenedEvents
+
+Get DOM events that are listened for and passed along
+
+## Mapping
+
+Map text locations to CFI ranges
+
+**Parameters**
+
+- `layout` **[Layout](#layout)** Layout to apply
+- `direction` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Text direction (optional, default `"ltr"`)
+- `axis` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** vertical or horizontal axis (optional, default `"horizontal"`)
+- `dev` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** toggle developer highlighting
+
+### section
+
+Find CFI pairs for entire section at once
+
+**Parameters**
+
+- `view`
+
+### page
+
+Find CFI pairs for a page
+
+**Parameters**
+
+- `contents` **[Contents](#contents)** Contents from view
+- `cfiBase` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** string of the base for a cfi
+- `start` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** position to start at
+- `end` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** position to end at
+
+### axis
+
+Set the axis for mapping
+
+**Parameters**
+
+- `axis` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** horizontal | vertical
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** is it horizontal?
+
+## Core
+
+Core Utilities and Helpers
+
+### requestAnimationFrame
+
+Vendor prefixed requestAnimationFrame
+
+Returns **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** requestAnimationFrame
+
+### uuid
+
+Generates a UUID
+based on: <http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript>
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** uuid
+
+### documentHeight
+
+Gets the height of a document
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** height
+
+### isElement
+
+Checks if a node is an element
+
+**Parameters**
+
+- `obj` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### isNumber
+
+**Parameters**
+
+- `n` **any**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### isFloat
+
+**Parameters**
+
+- `n` **any**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### prefixed
+
+Get a prefixed css property
+
+**Parameters**
+
+- `unprefixed` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### defaults
+
+Apply defaults to an object
+
+**Parameters**
+
+- `obj` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### extend
+
+Extend properties of an object
+
+**Parameters**
+
+- `target` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+### insert
+
+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>
+
+**Parameters**
+
+- `item` **any**
+- `array` **[array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)**
+- `compareFunction` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** location (in array)
+
+### locationOf
+
+Finds where something would fit into a sorted array
+
+**Parameters**
+
+- `item` **any**
+- `array` **[array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)**
+- `compareFunction` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+- `_start` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+- `_end` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** location (in array)
+
+### indexOfSorted
+
+Finds index of something in a sorted array
+Returns -1 if not found
+
+**Parameters**
+
+- `item` **any**
+- `array` **[array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)**
+- `compareFunction` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+- `_start` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+- `_end` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** index (in array) or -1
+
+### bounds
+
+Find the bounds of an element
+taking padding and margin into account
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **{width: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), height: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)}**
+
+### borders
+
+Find the bounds of an element
+taking padding, margin and borders into account
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **{width: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), height: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)}**
+
+### nodeBounds
+
+Find the bounds of any node
+allows for getting bounds of text nodes by wrapping them in a range
+
+**Parameters**
+
+- `node` **[node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+
+Returns **BoundingClientRect**
+
+### windowBounds
+
+Find the equivelent of getBoundingClientRect of a browser window
+
+Returns **{width: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), height: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), top: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), left: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), right: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), bottom: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)}**
+
+### indexOfNode
+
+Gets the index of a node in its parent
+
+**Parameters**
+
+- `node` **[Node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+- `typeId` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** index
+
+### indexOfTextNode
+
+Gets the index of a text node in its parent
+
+**Parameters**
+
+- `textNode` **[node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** index
+
+### indexOfElementNode
+
+Gets the index of an element node in its parent
+
+**Parameters**
+
+- `elementNode` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** index
+
+### isXml
+
+Check if extension is xml
+
+**Parameters**
+
+- `ext` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
+
+### createBlob
+
+Create a new blob
+
+**Parameters**
+
+- `content` **any**
+- `mime` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)**
+
+### createBlobUrl
+
+Create a new blob url
+
+**Parameters**
+
+- `content` **any**
+- `mime` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+### revokeBlobUrl
+
+Remove a blob url
+
+**Parameters**
+
+- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### createBase64Url
+
+Create a new base64 encoded url
+
+**Parameters**
+
+- `content` **any**
+- `mime` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** url
+
+### type
+
+Get type of an object
+
+**Parameters**
+
+- `obj` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** type
+
+### parse
+
+Parse xml (or html) markup
+
+**Parameters**
+
+- `markup` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `mime` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `forceXMLDom` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** force using xmlDom to parse instead of native parser
+
+Returns **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** document
+
+### qs
+
+querySelector polyfill
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `sel` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** selector string
+
+Returns **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** element
+
+### qsa
+
+querySelectorAll polyfill
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `sel` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** selector string
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** elements
+
+### qsp
+
+querySelector by property
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `sel` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** selector string
+- `props` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** elements
+
+### sprint
+
+Sprint through all text nodes in a document
+
+**Parameters**
+
+- `root` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** element to start with
+- `func` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function to run on each element
+
+### treeWalker
+
+Create a treeWalker
+
+**Parameters**
+
+- `root` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)** element to start with
+- `func` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function to run on each element
+- `filter` **([function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** funtion or object to filter with
+
+### walk
+
+**Parameters**
+
+- `node` **[node](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)**
+- `callback`
+- `return` **callback** false for continue,true for break inside callback
+
+### blob2base64
+
+Convert a blob to a base64 encoded string
+
+**Parameters**
+
+- `blob` **Blog**
+
+Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+### defer
+
+Creates a new pending promise and provides methods to resolve or reject it.
+From: <https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible>
+
+### querySelectorByType
+
+querySelector with filter by epub type
+
+**Parameters**
+
+- `html` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `element` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** element type to find
+- `type` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** epub type to find
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** elements
+
+### findChildren
+
+Find direct decendents of an element
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** children
+
+### parents
+
+Find all parents (ancestors) of an element
+
+**Parameters**
+
+- `node` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** parents
+
+### filterChildren
+
+Find all direct decendents of a specific type
+
+**Parameters**
+
+- `el` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `nodeName` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `single` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** children
+
+### getParentByTagName
+
+Filter all parents (ancestors) with tag name
+
+**Parameters**
+
+- `node` **[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)**
+- `tagname` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+
+Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[element](https://developer.mozilla.org/en-US/docs/Web/API/Element)>** parents
+
+### RangeObject
+
+Lightweight Polyfill for DOM Range
diff --git a/lib/epub.js/examples/ajax-loader.gif b/lib/epub.js/examples/ajax-loader.gif
new file mode 100644
index 0000000..1c72ebb
--- /dev/null
+++ b/lib/epub.js/examples/ajax-loader.gif
Binary files differ
diff --git a/lib/epub.js/examples/annotator.html b/lib/epub.js/examples/annotator.html
new file mode 100644
index 0000000..aa88478
--- /dev/null
+++ b/lib/epub.js/examples/annotator.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Annotator Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <!-- <script type="text/javascript" src="https://cdn.jsdelivr.net/annotator/1.2.9/annotator.min.js"></script> -->
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="viewer" class="spreads"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+ <script>
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ ignoreClass: 'annotator-hl'
+ });
+
+ var displayed = rendition.display(3);
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ rendition.on("relocated", function(location){
+ // console.log(location);
+ });
+
+ rendition.hooks.render.register(function (view) {
+
+ var adder = [
+ ['.annotator-adder, .annotator-outer', ['position', 'fixed']]
+ ];
+
+ view.addScript('https://cdn.jsdelivr.net/jquery/3.0.0-beta1/jquery.min.js').
+ then(function () {
+ return view.addScript('https://cdn.jsdelivr.net/annotator/1.2.9/annotator-full.min.js');
+ }).
+ then(function () {
+ return view.addCss('https://cdn.jsdelivr.net/annotator/1.2.9/annotator.min.css');
+ }).
+ then(function () {
+
+ view.addStylesheetRules(adder);
+
+ view.window.Annotator.Util.mousePosition = function(event) {
+ var body = view.document.body;
+ // var offset = view.position();
+
+ return {
+ top: event.pageY,
+ left: event.pageX
+ };
+ };
+ var ann = new view.window.Annotator(view.document.body);
+ });
+
+
+ })
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/archived.html b/lib/epub.js/examples/archived.html
new file mode 100644
index 0000000..fc45b8c
--- /dev/null
+++ b/lib/epub.js/examples/archived.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Archived Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="viewer" class="spreads"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+ <script>
+ var book = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ var displayed = rendition.display();
+
+
+ displayed.then(function(renderer){
+ // -- do stuff
+ });
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/contents.html b/lib/epub.js/examples/contents.html
new file mode 100644
index 0000000..67031ce
--- /dev/null
+++ b/lib/epub.js/examples/contents.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>EPUB.js Basic Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="viewer" class="scrolled"></div>
+
+ <script>
+ var $viewer = document.getElementById("viewer");
+
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf");
+ book.ready.then(function(){
+ book.getRange("epubcfi(/6/14[xchapter_001]!/4/2,/2/2/2[c001s0000]/1:0,/8/2[c001p0003]/1:663)").then(function(range) {
+ let text = range.toString()
+ console.log(text);
+ $viewer.textContent = text;
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/continuous-scrolled.html b/lib/epub.js/examples/continuous-scrolled.html
new file mode 100644
index 0000000..3d8a63c
--- /dev/null
+++ b/lib/epub.js/examples/continuous-scrolled.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Continuous Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+ <style type="text/css">
+
+ .epub-container {
+ /* min-width: 320px; */
+ /* margin: 0 auto; */
+ /* position: relative; */
+ }
+
+ .epub-container .epub-view > iframe {
+ background: white;
+ box-shadow: 0 0 4px #ccc;
+ /*margin: 10px;
+ padding: 20px;*/
+ }
+
+ #viewer {
+ width: 600px;
+ height: 100vh;
+ /* overflow: auto; */
+ margin: 0 auto;
+ }
+
+ </style>
+</head>
+<body>
+ <div id="viewer"></div>
+
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ // Load the opf
+ var book = ePub(url || "https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("viewer", {
+ manager: "continuous",
+ flow: "scrolled",
+ width: "100%",
+ height: "100%"
+ });
+ var displayed = rendition.display(currentSectionIndex);
+
+
+ displayed.then(function(renderer){
+ // -- do stuff
+ });
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/continuous-spreads.html b/lib/epub.js/examples/continuous-spreads.html
new file mode 100644
index 0000000..b5a9116
--- /dev/null
+++ b/lib/epub.js/examples/continuous-spreads.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Continuous Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+
+</head>
+<body>
+ <select id="toc"></select>
+ <div id="viewer" class="spreads"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ // Load the opf
+ window.book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ manager: "continuous",
+ flow: "paginated",
+ width: "100%",
+ height: 600
+ });
+
+ var displayed = rendition.display(currentSectionIndex);
+
+
+ displayed.then(function(renderer){
+ // -- do stuff
+ });
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ book.ready.then(() => {
+
+ var next = document.getElementById("next");
+
+ next.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ });
+
+ rendition.on("selected", function(range) {
+ console.log("selected", range);
+ });
+
+ rendition.on("layout", function(layout) {
+ let viewer = document.getElementById("viewer");
+
+ if (layout.spread) {
+ viewer.classList.remove('single');
+ } else {
+ viewer.classList.add('single');
+ }
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+
+ var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
+ var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
+
+ if (location.atEnd) {
+ next.style.visibility = "hidden";
+ } else {
+ next.style.visibility = "visible";
+ }
+
+ if (location.atStart) {
+ prev.style.visibility = "hidden";
+ } else {
+ prev.style.visibility = "visible";
+ }
+
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.ref = chapter.href;
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].ref;
+ rendition.display(url);
+ return false;
+ };
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/embedded.html b/lib/epub.js/examples/embedded.html
new file mode 100644
index 0000000..e9946f8
--- /dev/null
+++ b/lib/epub.js/examples/embedded.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <title></title>
+
+ <script src="../dist/epub.js"></script>
+
+ <style>
+
+ body {
+ margin: 0;
+ }
+
+ </style>
+</head>
+<body>
+
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentCfi = (params && params.get("cfi")) ? params.get("cfi") : undefined;
+ var currentSectionIndex = (params && params.get("loc")) ? parseInt(params.get("loc")) : undefined;
+
+ // Load the opf
+ var book = ePub(url || "https://s3.amazonaws.com/moby-dick/");
+ var rendition = book.renderTo(document.body, {
+ manager: "continuous",
+ snap: true
+ });
+
+ rendition.display(currentCfi || currentSectionIndex);
+
+
+ rendition.on("rendered", function(section){
+ // console.log("rendered", section);
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ var current = book.navigation && book.navigation.get(section.href);
+
+ if (current) {
+ document.title = current.label;
+ }
+ });
+
+ rendition.on("relocated", function(location){
+ // console.log("locationChanged", location)
+ console.log("locationChanged start", location.start.cfi)
+ // console.log("locationChanged end", location.end.cfi)
+ });
+
+ window.addEventListener("unload", function () {
+ console.log("unloading");
+ this.book.destroy();
+ });
+
+ </script>
+</body>
+</html>
diff --git a/lib/epub.js/examples/examples.css b/lib/epub.js/examples/examples.css
new file mode 100644
index 0000000..a259072
--- /dev/null
+++ b/lib/epub.js/examples/examples.css
@@ -0,0 +1,282 @@
+body {
+ margin: 0;
+ background: #fafafa;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #333;
+
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ min-height: 800px;
+}
+
+#title {
+ width: 900px;
+ min-height: 18px;
+ margin: 10px auto;
+ text-align: center;
+ font-size: 16px;
+ color: #E2E2E2;
+ font-weight: 400;
+}
+
+#title:hover {
+ color: #777;
+}
+
+#viewer.spreads {
+ width: 900px;
+ height: 600px;
+ box-shadow: 0 0 4px #ccc;
+ border-radius: 5px;
+ padding: 0;
+ position: relative;
+ margin: 10px auto;
+ background: white url('ajax-loader.gif') center center no-repeat;
+ top: calc(50vh - 400px);
+}
+
+#viewer.spreads .epub-view > iframe {
+ background: white;
+}
+
+#viewer.scrolled {
+ overflow: hidden;
+ width: 800px;
+ margin: 0 auto;
+ position: relative;
+ background: url('ajax-loader.gif') center center no-repeat;
+ box-shadow: 0 0 4px #ccc;
+ padding: 20px;
+ background: white;
+}
+
+#viewer.scrolled .epub-view > iframe {
+ background: white;
+}
+
+#prev {
+ left: 0;
+}
+
+#next {
+ right: 0;
+}
+
+#toc {
+ display: block;
+ margin: 10px auto;
+}
+
+@media (min-width: 1000px) {
+ #viewer.spreads:after {
+ position: absolute;
+ width: 1px;
+ border-right: 1px #000 solid;
+ height: 90%;
+ z-index: 1;
+ left: 50%;
+ margin-left: -1px;
+ top: 5%;
+ opacity: .15;
+ box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
+ content: "";
+ }
+
+ #viewer.spreads.single:after {
+ display: none;
+ }
+
+ #prev {
+ left: 40px;
+ }
+
+ #next {
+ right: 40px;
+ }
+}
+
+.arrow {
+ position: fixed;
+ top: 50%;
+ margin-top: -32px;
+ font-size: 64px;
+ color: #E2E2E2;
+ font-family: arial, sans-serif;
+ font-weight: bold;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ text-decoration: none;
+}
+
+.navlink {
+ margin: 14px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: #ccc;
+}
+
+.arrow:hover, .navlink:hover {
+ color: #777;
+}
+
+.arrow:active, .navlink:hover {
+ color: #000;
+}
+
+#book-wrapper {
+ width: 480px;
+ height: 640px;
+ overflow: hidden;
+ border: 1px solid #ccc;
+ margin: 28px auto;
+ background: #fff;
+ border-radius: 0 5px 5px 0;
+ position: absolute;
+}
+
+#book-viewer {
+ width: 480px;
+ height: 660px;
+ margin: -30px auto;
+ -moz-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ -webkit-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+}
+
+#book-viewer iframe {
+ padding: 40px 40px;
+}
+
+#controls {
+ position: absolute;
+ bottom: 16px;
+ left: 50%;
+ width: 400px;
+ margin-left: -200px;
+ text-align: center;
+ display: none;
+}
+
+#controls > input[type=range] {
+ width: 400px;
+}
+
+#navigation {
+ width: 400px;
+ height: 100vh;
+ position: absolute;
+ overflow: auto;
+ top: 0;
+ left: 0;
+ background: #777;
+ -webkit-transition: -webkit-transform .25s ease-out;
+ -moz-transition: -moz-transform .25s ease-out;
+ -ms-transition: -moz-transform .25s ease-out;
+ transition: transform .25s ease-out;
+
+}
+
+#navigation.fixed {
+ position: fixed;
+}
+
+#navigation h1 {
+ width: 200px;
+ font-size: 16px;
+ font-weight: normal;
+ color: #fff;
+ margin-bottom: 10px;
+}
+
+#navigation h2 {
+ font-size: 14px;
+ font-weight: normal;
+ color: #B0B0B0;
+ margin-bottom: 20px;
+}
+
+#navigation ul {
+ padding-left: 36px;
+ margin-left: 0;
+ margin-top: 12px;
+ margin-bottom: 12px;
+ width: 340px;
+}
+
+#navigation ul li {
+ list-style: decimal;
+ margin-bottom: 10px;
+ color: #cccddd;
+ font-size: 12px;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+#navigation ul li a {
+ color: #ccc;
+ text-decoration: none;
+}
+
+#navigation ul li a:hover {
+ color: #fff;
+ text-decoration: underline;
+}
+
+#navigation ul li a.active {
+ color: #fff;
+}
+
+#navigation #cover {
+ display: block;
+ margin: 24px auto;
+}
+
+#navigation #closer {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 12px;
+ color: #cccddd;
+ width: 24px;
+}
+
+#navigation.closed {
+ -webkit-transform: translate(-400px, 0);
+ -moz-transform: translate(-400px, 0);
+ -ms-transform: translate(-400px, 0);
+ transform: translate(-400px, 0);
+}
+
+svg {
+ display: block;
+}
+
+.close-x {
+ stroke: #cccddd;
+ fill: transparent;
+ stroke-linecap: round;
+ stroke-width: 5;
+}
+
+.close-x:hover {
+ stroke: #fff;
+}
+
+#opener {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ stroke: #E2E2E2;
+ fill: #E2E2E2;
+
+}
+
+#opener:hover {
+ stroke: #777;
+ fill: #777;
+}
diff --git a/lib/epub.js/examples/highlights.html b/lib/epub.js/examples/highlights.html
new file mode 100644
index 0000000..665c2de
--- /dev/null
+++ b/lib/epub.js/examples/highlights.html
@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Highlights Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+ <style type="text/css">
+ ::selection {
+ background: yellow;
+ }
+
+ #extras {
+ width: 600px;
+ margin: 40px auto;
+ }
+
+ #highlights {
+ list-style: none;
+ margin-left: 0;
+ padding: 0;
+ }
+
+ #highlights li {
+ list-style: none;
+ margin-bottom: 20px;
+ border-top: 1px solid #E2E2E2;
+ padding: 10px;
+ }
+
+ #highlights a {
+ display: block;
+ }
+
+ #viewer.spreads {
+ top: 0;
+ margin-top: 50px;
+ }
+
+ [ref="epubjs-mk"] {
+ background: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgNzUgNzUnPjxnIGZpbGw9JyNCREJEQkQnIGlkPSdidWJibGUnPjxwYXRoIGNsYXNzPSdzdDAnIGQ9J00zNy41LDkuNEMxOS42LDkuNCw1LDIwLjUsNSwzNC4zYzAsNS45LDIuNywxMS4zLDcuMSwxNS42TDkuNiw2NS42bDE5LTcuM2MyLjgsMC42LDUuOCwwLjksOC45LDAuOSBDNTUuNSw1OS4yLDcwLDQ4LjEsNzAsMzQuM0M3MCwyMC41LDU1LjQsOS40LDM3LjUsOS40eicvPjwvZz48L3N2Zz4=") no-repeat;
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+ margin-left: 0;
+ }
+
+ </style>
+</head>
+<body>
+ <div id="frame">
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+ </div>
+ <div id="extras">
+ <ul id="highlights"></ul>
+ </div>
+
+ <script>
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
+
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ ignoreClass: 'annotator-hl',
+ manager: "continuous"
+ });
+
+ var displayed = rendition.display(6);
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ rendition.on("relocated", function(location){
+ // console.log(location);
+ });
+
+
+ // Apply a class to selected text
+ rendition.on("selected", function(cfiRange, contents) {
+ rendition.annotations.highlight(cfiRange, {}, (e) => {
+ console.log("highlight clicked", e.target);
+ });
+ contents.window.getSelection().removeAllRanges();
+
+ });
+
+ this.rendition.themes.default({
+ '::selection': {
+ 'background': 'rgba(255,255,0, 0.3)'
+ },
+ '.epubjs-hl' : {
+ 'fill': 'yellow', 'fill-opacity': '0.3', 'mix-blend-mode': 'multiply'
+ }
+ });
+
+ // Illustration of how to get text from a saved cfiRange
+ var highlights = document.getElementById('highlights');
+
+ rendition.on("selected", function(cfiRange) {
+
+ book.getRange(cfiRange).then(function (range) {
+ var text;
+ var li = document.createElement('li');
+ var a = document.createElement('a');
+ var remove = document.createElement('a');
+ var textNode;
+
+ if (range) {
+ text = range.toString();
+ textNode = document.createTextNode(text);
+
+ a.textContent = cfiRange;
+ a.href = "#" + cfiRange;
+ a.onclick = function () {
+ rendition.display(cfiRange);
+ };
+
+ remove.textContent = "remove";
+ remove.href = "#" + cfiRange;
+ remove.onclick = function () {
+ rendition.annotations.remove(cfiRange);
+ return false;
+ };
+
+ li.appendChild(a);
+ li.appendChild(textNode);
+ li.appendChild(remove);
+ highlights.appendChild(li);
+ }
+
+ })
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/hooks.html b/lib/epub.js/examples/hooks.html
new file mode 100644
index 0000000..c5841b8
--- /dev/null
+++ b/lib/epub.js/examples/hooks.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Single Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <a id="prev" href="#prev" class="navlink">...</a>
+ <div id="viewer" class="scrolled"></div>
+ <a id="next" href="#next" class="navlink">...</a>
+
+ <script>
+ var currentSectionIndex = 8;
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("viewer", { flow: "scrolled-doc" });
+
+ rendition.display("chapter_001.xhtml");
+
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ if(nextSection) {
+ nextNav = book.navigation.get(nextSection.href);
+
+ if(nextNav) {
+ nextLabel = nextNav.label;
+ } else {
+ nextLabel = "next";
+ }
+
+ next.textContent = nextLabel + " »";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prevNav = book.navigation.get(prevSection.href);
+
+ if(prevNav) {
+ prevLabel = prevNav.label;
+ } else {
+ prevLabel = "previous";
+ }
+
+ prev.textContent = "« " + prevLabel;
+ } else {
+ prev.textContent = "";
+ }
+
+ });
+
+ // Hooks
+
+ // Add a single script
+ rendition.hooks.content.register(function(contents){
+ return contents.addScript("https://code.jquery.com/jquery-2.1.4.min.js")
+ .then(function(){
+ // init code
+ });
+ });
+
+ // Add several scripts / css
+ rendition.hooks.content.register(function(contents){
+
+ var loaded = Promise.all([
+ contents.addScript("https://code.jquery.com/jquery-2.1.4.min.js"),
+ contents.addStylesheet("http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css")
+ ]);
+
+ // return loaded promise
+ return loaded;
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/hypothesis-continuous.html b/lib/epub.js/examples/hypothesis-continuous.html
new file mode 100644
index 0000000..8ed8f75
--- /dev/null
+++ b/lib/epub.js/examples/hypothesis-continuous.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Continuous Example</title>
+
+ <script src="../dist/epub.js"></script>
+ <!-- <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> -->
+ <script src="//hypothes.is/embed.js"></script>
+
+ <style type="text/css">
+ body {
+ margin: 0 auto;
+ background: #fafafa;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #333;
+ height: 100%;
+ width: 100%;
+ max-width: 1200px;
+ }
+
+ .epub-container {
+ min-width: 320px;
+ margin: 0 auto;
+ }
+
+ /*.epub-container > div {
+ padding: 0 20% 0 20%;
+ }*/
+
+ .epub-container .epub-view > iframe {
+ background: white;
+ box-shadow: 0 0 4px #ccc;
+ margin: 10px;
+ padding: 20px;
+ }
+
+
+ #prev {
+ left: 40px;
+ }
+
+ #next {
+ right: 40px;
+ }
+
+ .arrow {
+ position: fixed;
+ top: 50%;
+ margin-top: -32px;
+ font-size: 64px;
+ color: #E2E2E2;
+ font-family: arial, sans-serif;
+ font-weight: bold;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ }
+
+ .arrow:hover {
+ color: #777;
+ }
+
+ .arrow:active {
+ color: #000;
+ }
+
+ #toc {
+ display: block;
+ margin: 10px auto;
+ }
+
+ </style>
+</head>
+<body>
+ <div id="viewer"></div>
+
+ <script>
+ // var currentSectionIndex = 8;
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/alice/OPS/package.opf");
+ var rendition = book.renderTo(document.body, { method: "continuous", flow: "scrolled-continuous", width: "60%" });
+ var displayed = rendition.display();
+
+
+ displayed.then(function(renderer){
+ // -- do stuff
+ });
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ book.rendition.hooks.content.register(function(view) {
+ return view.addScript("//hypothes.is/embed.js").then(function() {
+ view.window.hypothesisConfig = function () {
+
+ return {
+ constructor: this.Annotator.Guest,
+ app: 'https://hypothes.is/app.html'
+ };
+ };
+
+ // view.window.hypothesisInstall();
+ });
+ });
+
+ book.rendition.hooks.render.register(function(view) {
+ var getVisibleAnnotations = function ($) {
+ var height = document.documentElement.clientHeight;
+ return $('.annotator-hl').map(function() {
+ var $this = $(this),
+ pos = view.position().top,
+ top = pos + this.getBoundingClientRect().top;
+ if (top >= 0 && top <= height) {
+ return $this.data('annotation');
+ }
+ }).get();
+ };
+ book.rendition.on("scroll", function() {
+ var annotator = view.window.annotator;
+ var annotations;
+ if(annotator && annotator.constructor.$) {
+ annotations = getVisibleAnnotations(annotator.constructor.$);
+ annotator.showAnnotations(annotations);
+ }
+ });
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/hypothesis-spreads.html b/lib/epub.js/examples/hypothesis-spreads.html
new file mode 100644
index 0000000..acd259f
--- /dev/null
+++ b/lib/epub.js/examples/hypothesis-spreads.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js + Hypothes.is Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <script type="text/javascript">
+ window.hypothesisConfig = function () {
+ return {
+ openSidebar: false,
+ enableMultiFrameSupport: true,
+ onLayoutChange: function(state) {
+ var nav = document.getElementById("navigation");
+ if (state.expanded === true) {
+ nav.classList.remove("open");
+ }
+ }
+ };
+ };
+ </script>
+ <script src="https://cdn.hypothes.is/hypothesis"></script>
+
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+ <link rel="stylesheet" type="text/css" href="hypothesis.css">
+
+ <script src="hypothesis.js"></script>
+
+</head>
+<body>
+ <div id="main">
+ <a id="opener">
+ <i class="material-icons">menu</i>
+ </a>
+ <div id="viewer" class="spreads"></div>
+ <span id="hiddenTitle"></span>
+ <a id="prev" href="#prev" class="arrow">
+ <i class="material-icons">chevron_left</i>
+ </a>
+ <a id="next" href="#next" class="arrow">
+ <i class="material-icons">chevron_right</i>
+ </a>
+ </div>
+ <div id="navigation">
+ <a id="closer">
+ <i class="material-icons">close</i>
+ </a>
+ <h1 id="title">...</h1>
+ <image id="cover" width="150px"/>
+ <h2 id="author">...</h2>
+ <ul id="toc"></ul>
+ </div>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/hypothesis.css b/lib/epub.js/examples/hypothesis.css
new file mode 100644
index 0000000..4a53bed
--- /dev/null
+++ b/lib/epub.js/examples/hypothesis.css
@@ -0,0 +1,329 @@
+body {
+ margin: 0;
+ background: #fafafa;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #333;
+}
+
+svg {
+ display: block;
+}
+
+.close-x {
+ stroke: #cccddd;
+ fill: transparent;
+ stroke-linecap: round;
+ stroke-width: 5;
+}
+
+.close-x:hover {
+ stroke: #fff;
+}
+
+#opener {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ stroke: #E2E2E2;
+ fill: #E2E2E2;
+
+}
+
+#opener:hover {
+ stroke: #777;
+ fill: #777;
+}
+
+#navigation {
+ width: 400px;
+ position: fixed;
+ overflow: auto;
+ top: 0;
+ left: -425px;
+
+ background: #ECECEC;
+ min-height: 100%;
+ height: 100%;
+ height: 100vh;
+
+ overflow: scroll;
+ -webkit-overflow-scrolling: touch;
+ padding: 9px;
+ padding-top: 10px;
+
+ transition: left .2s ease-out;
+ box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
+}
+
+#navigation.open {
+ left: 0;
+}
+
+#navigation.fixed {
+ position: fixed;
+}
+
+#navigation h1 {
+ width: 200px;
+ font-size: 16px;
+ font-weight: normal;
+ color: #777;
+ margin-bottom: 10px;
+}
+
+#navigation h2 {
+ font-size: 14px;
+ font-weight: normal;
+ color: #B0B0B0;
+ margin-bottom: 20px;
+}
+
+#navigation ul {
+ padding-left: 28px;
+ margin-left: 0;
+}
+
+#navigation ul li {
+ list-style: decimal;
+ margin-bottom: 10px;
+ color: #585858;
+ font-size: 12px;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+#navigation ul li a {
+ color: #585858;
+ text-decoration: none;
+}
+
+#navigation ul li a:hover {
+ color: #585858;
+ text-decoration: underline;
+}
+
+#navigation ul li a.active {
+ color: #000;
+ font-weight: 400;
+}
+
+#navigation #author {
+ text-align: center;
+}
+
+#cover {
+ display: inline;
+}
+
+#main {
+ margin-top: 60px;
+}
+
+#pagination {
+ text-align: center;
+ margin: 20px;
+ /*padding: 0 50px;*/
+}
+
+.arrow:hover {
+ color: #777;
+}
+
+.arrow:active {
+ color: #000;
+}
+
+.arrow .material-icons {
+ font-size: 64px;
+}
+
+#prev {
+ float: left;
+}
+
+#next {
+ float: right;
+}
+
+#toc {
+ display: block;
+ margin: 10px auto;
+}
+
+#hypothesis-custom {
+ overflow: hidden;
+ /*position: absolute;*/
+ right: 0;
+ /*top: 0;*/
+ height: 100%;
+ width: 200px;
+ /*z-index: -2;*/
+}
+
+#hypothesis-custom iframe {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+#navigation #cover {
+ display: block;
+ margin: 24px auto;
+}
+
+#closer {
+ position: absolute;
+ padding: 12px;
+ left: 0;
+ top: 0;
+ color: #333;
+ cursor: pointer;
+}
+
+#closer .material-icons {
+ color: #333;
+}
+
+#opener {
+ position: absolute;
+ left: 0;
+ top: 0;
+ cursor: pointer;
+}
+
+#hiddenTitle {
+ display: none;
+}
+
+#title {
+ width: 900px;
+ min-height: 18px;
+ margin: 10px auto;
+ text-align: center;
+ font-size: 16px;
+ color: #E2E2E2;
+ font-weight: 400;
+}
+
+#title:hover {
+ color: #777;
+}
+
+#prev {
+ left: 0;
+}
+
+#next {
+ right: 0;
+}
+
+#toc {
+ display: block;
+ margin: 10px auto;
+}
+
+@media (min-width: 1000px) {
+ #viewer.spreads:after {
+ position: absolute;
+ width: 1px;
+ border-right: 1px #000 solid;
+ height: 90%;
+ z-index: 1;
+ left: 50%;
+ margin-left: -1px;
+ top: 5%;
+ opacity: .15;
+ box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
+ content: "";
+ }
+
+ #prev {
+ left: 40px;
+ }
+
+ #next {
+ right: 40px;
+ }
+}
+
+#viewer.spreads {
+ width: 84vw;
+ height: 80vh;
+ box-shadow: 0 0 4px #ccc;
+ border-radius: 5px;
+ padding: 0;
+ position: relative;
+ margin: 10vh auto;
+ background: white;
+ top: 0;
+}
+
+.arrow {
+ position: fixed;
+ top: 50%;
+ margin-top: -32px;
+ font-size: 64px;
+ color: #E2E2E2;
+ font-family: arial, sans-serif;
+ font-weight: bold;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ text-decoration: none;
+}
+
+.navlink {
+ margin: 14px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: #ccc;
+}
+
+.arrow:hover, .navlink:hover {
+ color: #777;
+}
+
+.arrow:active, .navlink:hover {
+ color: #000;
+}
+
+#book-wrapper {
+ width: 480px;
+ height: 640px;
+ overflow: hidden;
+ border: 1px solid #ccc;
+ margin: 28px auto;
+ background: #fff;
+ border-radius: 0 5px 5px 0;
+ position: absolute;
+}
+
+#book-viewer {
+ width: 480px;
+ height: 660px;
+ margin: -30px auto;
+ -moz-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ -webkit-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+}
+
+#book-viewer iframe {
+ padding: 40px 40px;
+}
+
+#controls {
+ position: absolute;
+ bottom: 16px;
+ left: 50%;
+ width: 400px;
+ margin-left: -200px;
+ text-align: center;
+ display: none;
+}
+
+#controls > input[type=range] {
+ width: 400px;
+}
diff --git a/lib/epub.js/examples/hypothesis.html b/lib/epub.js/examples/hypothesis.html
new file mode 100644
index 0000000..7cb5c45
--- /dev/null
+++ b/lib/epub.js/examples/hypothesis.html
@@ -0,0 +1,369 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js + Hypothes.is Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <!-- <script>
+ window.hypothesisConfig = function () {
+ return {
+ // constructor: this.Annotator.Sidebar,
+ app: 'https://hypothes.is/app.html',
+ };
+ };
+ </script> -->
+
+ <script type="text/javascript">
+ window.hypothesisConfig = function () {
+ return {
+ openSidebar: false,
+ enableMultiFrameSupport: true,
+ onLayoutChange: function(state) {
+ var main = document.querySelector('#main');
+ if (state.expanded === true) {
+ main.classList.add("open");
+ } else {
+ main.classList.remove("open");
+ }
+ }
+ };
+ };
+ </script>
+ <script src="https://cdn.hypothes.is/hypothesis"></script>
+
+ <style type="text/css">
+ body {
+ margin: 0;
+ background: #fafafa;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #333;
+ }
+
+ #navigation {
+ width: 300px;
+ position: absolute;
+ overflow: auto;
+ top: 60px;
+ left: 1000px
+ }
+
+ #navigation.fixed {
+ position: fixed;
+ }
+
+ #navigation h1 {
+ width: 200px;
+ font-size: 16px;
+ font-weight: normal;
+ color: #777;
+ margin-bottom: 10px;
+ }
+
+ #navigation h2 {
+ font-size: 14px;
+ font-weight: normal;
+ color: #B0B0B0;
+ margin-bottom: 20px;
+ }
+
+ #navigation ul {
+ padding-left: 18px;
+ margin-left: 0;
+ }
+
+ #navigation ul li {
+ list-style: decimal;
+ margin-bottom: 10px;
+ color: #cccddd;
+ font-size: 12px;
+ padding-left: 0;
+ margin-left: 0;
+ }
+
+ #navigation ul li a {
+ color: #ccc;
+ text-decoration: none;
+ }
+
+ #navigation ul li a:hover {
+ color: #777;
+ text-decoration: underline;
+ }
+
+ #navigation ul li a.active {
+ color: #000;
+ }
+
+ #viewer {
+ overflow: hidden;
+ width: 620px;
+ margin: 0 50px;
+ /*background: url('ajax-loader.gif') center center no-repeat;*/
+ background-color: white;
+ box-shadow: 0 0 4px #ccc;
+ margin: 20px;
+ padding: 40px 80px;
+ }
+
+ #main {
+ position: absolute;
+ top: 50px;
+ left: 100px;
+ width: 800px;
+ z-index: 2;
+ transition: left .15s cubic-bezier(.55, 0, .2, .8) .08s;
+ }
+
+ #main.open {
+ left: 0;
+ }
+
+ #pagination {
+ text-align: center;
+ margin: 20px;
+ /*padding: 0 50px;*/
+ }
+
+ .arrow {
+ margin: 14px;
+ display: inline-block;
+ text-align: center;
+ text-decoration: none;
+ color: #ccc;
+ }
+
+ .arrow:hover {
+ color: #777;
+ }
+
+ .arrow:active {
+ color: #000;
+ }
+
+ #prev {
+ float: left;
+ }
+
+ #next {
+ float: right;
+ }
+
+ #toc {
+ display: block;
+ margin: 10px auto;
+ }
+
+ #hypothesis-custom {
+ overflow: hidden;
+ /*position: absolute;*/
+ right: 0;
+ /*top: 0;*/
+ height: 100%;
+ width: 200px;
+ /*z-index: -2;*/
+ }
+
+ #hypothesis-custom iframe {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ }
+
+ </style>
+</head>
+<body>
+ <div id="navigation">
+ <h1 id="title">...</h1>
+ <image id="cover" width="150px"/>
+ <h2 id="author">...</h2>
+ <ul id="toc"></ul>
+ </div>
+ <div id="main">
+ <div id="viewer"></div>
+ <div id="pagination">
+ <a id="prev" href="#prev" class="arrow">...</a>
+ <a id="next" href="#next" class="arrow">...</a>
+ </div>
+ </div>
+
+ <script>
+ // Load the opf
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+
+ // Load the opf
+ var book = ePub(url || window.location.protocol + "//s3.amazonaws.com/epubjs.org/books/moby-dick-hypothesis-demo.epub");
+ var rendition = book.renderTo("viewer", {
+ flow: "scrolled-doc",
+ ignoreClass: "annotator-hl"
+ });
+
+ // var hash = window.location.hash.slice(2);
+ var loc = window.location.href.indexOf("?loc=");
+ if (loc > -1) {
+ var href = window.location.href.slice(loc + 5);
+ var hash = decodeURIComponent(href);
+ }
+ rendition.display(hash || undefined);
+
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ window.scrollTo(0,0);
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ window.scrollTo(0,0);
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ if(nextSection) {
+ nextNav = book.navigation.get(nextSection.href);
+
+ if(nextNav) {
+ nextLabel = nextNav.label;
+ } else {
+ nextLabel = "next";
+ }
+
+ next.textContent = nextLabel + " »";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prevNav = book.navigation.get(prevSection.href);
+
+ if(prevNav) {
+ prevLabel = prevNav.label;
+ } else {
+ prevLabel = "previous";
+ }
+
+ prev.textContent = "« " + prevLabel;
+ } else {
+ prev.textContent = "";
+ }
+
+ var old = document.querySelectorAll('.active');
+ Array.prototype.slice.call(old, 0).forEach(function (link) {
+ link.classList.remove("active");
+ })
+
+ var active = document.querySelector('a[href="'+section.href+'"]');
+ if (active) {
+ active.classList.add("active");
+ }
+ // Add CFI fragment to the history
+ history.pushState({}, '', "?loc=" + encodeURIComponent(section.href));
+ // window.location.hash = "#/"+section.href
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $nav = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter, index) {
+ var item = document.createElement("li");
+ var link = document.createElement("a");
+ link.id = "chap-" + chapter.id;
+ link.textContent = chapter.label;
+ link.href = chapter.href;
+ item.appendChild(link);
+ docfrag.appendChild(item);
+
+ link.onclick = function(){
+ var url = link.getAttribute("href");
+ console.log(url)
+ rendition.display(url);
+ return false;
+ };
+
+ });
+
+ $nav.appendChild(docfrag);
+
+
+ });
+
+ book.loaded.metadata.then(function(meta){
+ var $title = document.getElementById("title");
+ var $author = document.getElementById("author");
+ var $cover = document.getElementById("cover");
+ var $nav = document.getElementById('navigation');
+
+ $title.textContent = meta.title;
+ $author.textContent = meta.creator;
+ if (book.archive) {
+ book.archive.createUrl(book.cover)
+ .then(function (url) {
+ $cover.src = url;
+ })
+ } else {
+ $cover.src = book.cover;
+ }
+
+ if ($nav.offsetHeight + 60 < window.innerHeight) {
+ $nav.classList.add("fixed");
+ }
+
+ });
+
+ function checkForAnnotator(cb, w) {
+ if (!w) {
+ w = window;
+ }
+ setTimeout(function () {
+ if (w && w.annotator) {
+ cb();
+ } else {
+ checkForAnnotator(cb, w);
+ }
+ }, 100);
+ }
+
+ book.rendition.hooks.content.register(function(contents, view) {
+
+ checkForAnnotator(function () {
+
+ var annotator = contents.window.annotator;
+
+ contents.window.addEventListener('scrolltorange', function (e) {
+ var range = e.detail;
+ var cfi = new ePub.CFI(range, contents.cfiBase).toString();
+ if (cfi) {
+ book.rendition.display(cfi);
+ }
+ e.preventDefault();
+ });
+
+
+ annotator.on("highlightClick", function (annotation) {
+ console.log(annotation);
+ window.annotator.show();
+ })
+
+ annotator.on("beforeAnnotationCreated", function (annotation) {
+ console.log(annotation);
+ window.annotator.show();
+ })
+
+ }, contents.window);
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/hypothesis.js b/lib/epub.js/examples/hypothesis.js
new file mode 100644
index 0000000..1a0e8e0
--- /dev/null
+++ b/lib/epub.js/examples/hypothesis.js
@@ -0,0 +1,214 @@
+(function() {
+
+ function start() {
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var defaultUrl = window.location.protocol + "//s3.amazonaws.com/epubjs.org/books/moby-dick-hypothesis-demo.epub";
+ // Load the opf
+ var book = ePub(url || defaultUrl, {
+ canonical: function(path) {
+ var url = window.location.href.replace(/loc=([^&]*)/, "loc="+path);
+ return url;
+ }
+ });
+ var rendition = book.renderTo("viewer", {
+ ignoreClass: "annotator-hl",
+ width: "100%",
+ height: "100%"
+ });
+
+ // var hash = window.location.hash.slice(2);
+ var loc = window.location.href.indexOf("?loc=");
+ if (loc > -1) {
+ var href = window.location.href.slice(loc + 5);
+ var hash = decodeURIComponent(href);
+ }
+
+ rendition.display(hash || undefined);
+
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var nav = document.getElementById("navigation");
+ var opener = document.getElementById("opener");
+ opener.addEventListener("click", function(e){
+ nav.classList.add("open");
+ }, false);
+
+ var closer = document.getElementById("closer");
+ closer.addEventListener("click", function(e){
+ nav.classList.remove("open");
+ }, false);
+
+ // Hidden
+ var hiddenTitle = document.getElementById("hiddenTitle");
+
+ rendition.on("rendered", function(section){
+ var current = book.navigation && book.navigation.get(section.href);
+
+ if (current) {
+ document.title = current.label;
+ }
+
+ // TODO: this is needed to trigger the hypothesis client
+ // to inject into the iframe
+ requestAnimationFrame(function () {
+ hiddenTitle.textContent = section.href;
+ })
+
+ var old = document.querySelectorAll('.active');
+ Array.prototype.slice.call(old, 0).forEach(function (link) {
+ link.classList.remove("active");
+ })
+
+ var active = document.querySelector('a[href="'+section.href+'"]');
+ if (active) {
+ active.classList.add("active");
+ }
+
+ let urlParam = params && params.get("url");
+ let url = '';
+ if (urlParam) {
+ url = "url=" + urlParam + "&";
+ }
+ // Add CFI fragment to the history
+ history.pushState({}, '', "?" + url + "loc=" + encodeURIComponent(section.href));
+ // window.location.hash = "#/"+section.href
+ });
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ book.loaded.navigation.then(function(toc){
+ var $nav = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ var processTocItem = function(chapter, parent) {
+ var item = document.createElement("li");
+ var link = document.createElement("a");
+ link.id = "chap-" + chapter.id;
+ link.textContent = chapter.label;
+ link.href = chapter.href;
+ item.appendChild(link);
+ parent.appendChild(item);
+
+ if (chapter.subitems.length) {
+ var ul = document.createElement("ul");
+ item.appendChild(ul);
+ chapter.subitems.forEach(function(subchapter) {
+ processTocItem(subchapter, ul);
+ });
+ }
+
+ link.onclick = function(){
+ var url = link.getAttribute("href");
+ console.log(url)
+ rendition.display(url);
+ return false;
+ };
+
+ }
+
+ toc.forEach(function(chapter) {
+ processTocItem(chapter, docfrag);
+ });
+
+ $nav.appendChild(docfrag);
+
+
+ });
+
+ book.loaded.metadata.then(function(meta){
+ var $title = document.getElementById("title");
+ var $author = document.getElementById("author");
+ var $cover = document.getElementById("cover");
+ var $nav = document.getElementById('navigation');
+
+ $title.textContent = meta.title;
+ $author.textContent = meta.creator;
+ if (book.archive) {
+ book.archive.createUrl(book.cover)
+ .then(function (url) {
+ $cover.src = url;
+ })
+ } else {
+ $cover.src = book.cover;
+ }
+
+ // if ($nav.offsetHeight + 60 < window.innerHeight) {
+ // $nav.classList.add("fixed");
+ // }
+
+ });
+
+ var tm;
+ function checkForAnnotator(cb, w) {
+ if (!w) {
+ w = window;
+ }
+ tm = setTimeout(function () {
+ if (w && w.annotator) {
+ clearTimeout(tm);
+ cb();
+ } else {
+ checkForAnnotator(cb, w);
+ }
+ }, 100);
+ }
+
+ book.rendition.hooks.content.register(function(contents, view) {
+ checkForAnnotator(function () {
+
+ var annotator = contents.window.annotator;
+
+ contents.window.addEventListener('scrolltorange', function (e) {
+ var range = e.detail;
+ var cfi = new ePub.CFI(range, contents.cfiBase).toString();
+ if (cfi) {
+ book.rendition.display(cfi);
+ }
+ e.preventDefault();
+ });
+
+
+ annotator.on("highlightClick", function (annotation) {
+ console.log(annotation);
+ window.annotator.show();
+ })
+
+ annotator.on("beforeAnnotationCreated", function (annotation) {
+ console.log(annotation);
+ window.annotator.show();
+ })
+
+ }, contents.window);
+
+ });
+ }
+
+ document.addEventListener('DOMContentLoaded', start, false);
+})();
diff --git a/lib/epub.js/examples/index.html b/lib/epub.js/examples/index.html
new file mode 100644
index 0000000..707b1d8
--- /dev/null
+++ b/lib/epub.js/examples/index.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html class="no-js">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>ePubJS Examples</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <style type="text/css">
+
+ body {
+ margin: 0;
+ background: #fafafa;
+ font-family: serif;
+ color: #333;
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ min-height: 800px;
+ }
+
+ h1 {
+ text-align: center;
+ font-size: 1.5em;
+ line-height: 1.33em;
+ text-align: center;
+ padding-bottom: 0em;
+ text-align: center;
+ text-transform: uppercase;
+ font-weight: normal;
+ letter-spacing: 4px;
+ padding-top: 60px;
+ }
+
+ ol {
+ margin: 28px auto;
+ }
+
+ a {
+ font-size: 1.2em;
+ line-height: 1.33em;
+ color: #000;
+ }
+
+ #main {
+ width: 100%
+ }
+
+ #example-wrapper {
+ width: 695px;
+ overflow: hidden;
+ border: 1px solid #ccc;
+ margin: 28px auto;
+ background: #fff;
+ border-radius: 5px;
+ }
+
+ #example-viewer {
+ width: 680px;
+ height: 100%;
+ margin: -30px 10px 0 0;
+ -moz-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ -webkit-box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ box-shadow: inset 10px 0 20px rgba(0,0,0,.1);
+ }
+ </style>
+
+
+ </head>
+ <body>
+ <div id="main">
+ <div id="example-wrapper">
+ <div id="example-viewer">
+
+ <h1>Examples</h1>
+ <ol>
+ <li><a href="spreads.html">Spreads</a><p>
+ Display an ebook two pages at a time. Also includes code to provide table-of-contents in a select object above the rendered ebook. Sections of the ebook are displayed separately so if a section has a single page or an odd number of pages it will display with a blank page on the right.</p></li>
+ <li><a href="archived.html">Archived</a><p>
+ Display ebook from an XXXX.epub file rather than an unzipped folder. This may be substantially slower for large ebooks.</p></li>
+ <li><a href="scrolled.html">Scrolled Doc</a><p>
+ Displays each "section" or "chapter" of the ebook in its entirety as a single page of variable height that you can scroll up and down. Includes code to provide navigation links above and below the rendered section to go to the previous or next section.</p></li>
+ <li><a href="continuous-spreads.html">Spreads Continuous</a><p>
+ The view is the same as 1) above except that the entire document is rendered at once without breaks so if a section has one page, the next section is shown beginning on the right-hand-page rather than a blank page. </p></li>
+ <li><a href="continuous-scrolled.html">Scrolled Continuous</a><p>
+ The view is the same as 3) except the entire ebook is rendered in the browser at once so there are no navigation links above and below each chapter. This version may take longer to render and uses more memory since the whole ebook is loaded into memory. This version has no links to navigate or jump between chapters.</p></li>
+ <li><a href="swipe.html">Swipe</a><p>
+ This example includes a function in the script to link "swipe" events on touchscreens, particularly mobile devices, to navigate forward and back. Note that swipes do not work in Chrome Desktop even if you turn on device emulation in the "inspect" toolbar. </p></li>
+ <li><a href="input.html">Open from File</a><p>
+ Allows you to select an epub file from your local computer that gets rendered in the browser. As of 5/14/2019 only the cover renders.</p></li>
+ <li><a href="renderless.html">Renderless</a><p>
+ The name for this example is misleading since the book certainly does render. What's unique in this example is that the book's table of contents is read in and a list of sections in developed, then each section is rendered as it is called for by a section.render() call, but there's no master book.renderTo() call. Functionlly this seems exactly the same as 1) and 3).</p></li>
+ <li><a href="hooks.html">Hooks</a><p>
+ This example shows how to insert external javascript and external css files into a book after the book has been loaded into memory. This might, for example, allow you to override internal css from the ebook to change fonts and text-size by either replacing a css file from the ebook or calling a javascript that gets added to the inside of the ebook such as adding jQuery inside the ebook. For example: this could be used to have + and - buttons that increase or decrease the font-size in the ebook. When the + or - button is pressed it could call to insert and execute a script to replace the font-size of paragraph elements with one slightly larger or smaller. This example doesn't actually implement any such thing, it just shows how to insert the code, or insert a css file.</p><p>
+ You can't just run a script on the outer page to change things inside the rendered ebook because the ebook is rendered inside an iframe. This mechanism lets you inject things into the iframe and run them after the book is rendered.</p></li>
+ <li><a href="highlights.html">Highlights</a><p>
+ Adds the ability to highlight text in the ebook. This version provides no mechanism for saving highlights after the browser is closed. It is an example of capability rather than a working implementation. It works as follows: When a section of text is selected a rendition.on("selected"...) function notes the location of the beginning and ending of the selected text. Two things happen. The code adds a new element to the outer page in a list at the bottom describing the selection and providing a "remove" link. The code also paints a yellow block in an SVG overlay to highlight the selected text. Unfortunately as of 5/14/2019 the remove link does remove the yellow overlay from the highlighted text but, does not remove the annotation from the list at the bottom of the page.</p></li>
+ <li><a href="hypothesis.html">Hypothes.is</a><p>
+ Visit their site for an explanation at <a href="https://web.hypothes.is/demos/epubjs/">https://web.hypothes.is/demos/epubjs/</a>.</p></li>
+ </ol>
+
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/lib/epub.js/examples/input.html b/lib/epub.js/examples/input.html
new file mode 100644
index 0000000..375b4ef
--- /dev/null
+++ b/lib/epub.js/examples/input.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Input Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="title"><input type="file" id="input"></div>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+
+ var book = ePub();
+ var rendition;
+
+ var inputElement = document.getElementById("input");
+
+ inputElement.addEventListener('change', function (e) {
+ var file = e.target.files[0];
+ if (window.FileReader) {
+ var reader = new FileReader();
+ reader.onload = openBook;
+ reader.readAsArrayBuffer(file);
+ }
+ });
+
+ function openBook(e){
+ var bookData = e.target.result;
+ var title = document.getElementById("title");
+ var next = document.getElementById("next");
+ var prev = document.getElementById("prev");
+
+ book.open(bookData, "binary");
+
+ rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ rendition.display();
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ rendition.on("relocated", function(location){
+ console.log(location);
+ });
+
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+
+
+
+ document.addEventListener("keyup", keyListener, false);
+ }
+
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/legacy.html b/lib/epub.js/examples/legacy.html
new file mode 100644
index 0000000..e6fda7e
--- /dev/null
+++ b/lib/epub.js/examples/legacy.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.legacy.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <!-- <div id="title"></div> -->
+ <select id="toc"></select>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ // Load the opf
+ var book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ spread: "always"
+ });
+
+ rendition.display(currentSectionIndex);
+
+ book.ready.then(function() {
+
+ var next = document.getElementById("next");
+
+ next.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ })
+
+ var title = document.getElementById("title");
+
+ rendition.on("rendered", function(section){
+ var current = book.navigation && book.navigation.get(section.href);
+
+ if (current) {
+ var $select = document.getElementById("toc");
+ var $selected = $select.querySelector("option[selected]");
+ if ($selected) {
+ $selected.removeAttribute("selected");
+ }
+
+ var $options = $select.querySelectorAll("option");
+ for (var i = 0; i < $options.length; ++i) {
+ let selected = $options[i].getAttribute("ref") === current.href;
+ if (selected) {
+ $options[i].setAttribute("selected", "");
+ }
+ }
+ }
+
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+
+ var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
+ var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
+
+ if (location.atEnd) {
+ next.style.visibility = "hidden";
+ } else {
+ next.style.visibility = "visible";
+ }
+
+ if (location.atStart) {
+ prev.style.visibility = "hidden";
+ } else {
+ prev.style.visibility = "visible";
+ }
+
+ });
+
+ rendition.on("layout", function(layout) {
+ let viewer = document.getElementById("viewer");
+
+ if (layout.spread) {
+ viewer.classList.remove('single');
+ } else {
+ viewer.classList.add('single');
+ }
+ });
+
+ window.addEventListener("unload", function () {
+ console.log("unloading");
+ this.book.destroy();
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.setAttribute("ref", chapter.href);
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].getAttribute("ref");
+ rendition.display(url);
+ return false;
+ };
+
+ });
+
+
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/locations.html b/lib/epub.js/examples/locations.html
new file mode 100644
index 0000000..c572e7d
--- /dev/null
+++ b/lib/epub.js/examples/locations.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="title"></div>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+ <div id="controls">
+ <input id="current-percent" size="3" value="0" /> %
+ </div>
+ <script>
+
+ var controls = document.getElementById("controls");
+ var currentPage = document.getElementById("current-percent");
+ var slider = document.createElement("input");
+ var slide = function(){
+ var cfi = book.locations.cfiFromPercentage(slider.value / 100);
+ rendition.display(cfi);
+ };
+ var mouseDown = false;
+
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ var displayed = rendition.display();
+
+ var title = document.getElementById("title");
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ book.ready.then(function(){
+ // Load in stored locations from json or local storage
+ var key = book.key()+'-locations';
+ var stored = localStorage.getItem(key);
+ if (stored) {
+ return book.locations.load(stored);
+ } else {
+ // Or generate the locations on the fly
+ // Can pass an option number of chars to break sections by
+ // default is 150 chars
+ return book.locations.generate(1600);
+ }
+ })
+ .then(function(locations){
+ controls.style.display = "block";
+ slider.setAttribute("type", "range");
+ slider.setAttribute("min", 0);
+ slider.setAttribute("max", 100);
+ // slider.setAttribute("max", book.locations.total+1);
+ slider.setAttribute("step", 1);
+ slider.setAttribute("value", 0);
+
+ slider.addEventListener("change", slide, false);
+ slider.addEventListener("mousedown", function(){
+ mouseDown = true;
+ }, false);
+ slider.addEventListener("mouseup", function(){
+ mouseDown = false;
+ }, false);
+
+ // Wait for book to be rendered to get current page
+ displayed.then(function(){
+ // Get the current CFI
+ var currentLocation = rendition.currentLocation();
+ // Get the Percentage (or location) from that CFI
+ var currentPage = book.locations.percentageFromCfi(currentLocation.start.cfi);
+ slider.value = currentPage;
+ currentPage.value = currentPage;
+ });
+
+ controls.appendChild(slider);
+
+ currentPage.addEventListener("change", function(){
+ var cfi = book.locations.cfiFromPercentage(currentPage.value/100);
+ rendition.display(cfi);
+ }, false);
+
+ // Listen for location changed event, get percentage from CFI
+ rendition.on('relocated', function(location){
+ var percent = book.locations.percentageFromCfi(location.start.cfi);
+ var percentage = Math.floor(percent * 100);
+ if(!mouseDown) {
+ slider.value = percentage;
+ }
+ currentPage.value = percentage;
+ console.log(location);
+ });
+
+ // Save out the generated locations to JSON
+ localStorage.setItem(book.key()+'-locations', book.locations.save());
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/manifest.html b/lib/epub.js/examples/manifest.html
new file mode 100644
index 0000000..3f7b869
--- /dev/null
+++ b/lib/epub.js/examples/manifest.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <h1 id="title">...</h1>
+ <div id="opener">
+ <svg height="24px" id="hamburger" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <path d="M4,10h24c1.104,0,2-0.896,2-2s-0.896-2-2-2H4C2.896,6,2,6.896,2,8S2.896,10,4,10z M28,14H4c-1.104,0-2,0.896-2,2 s0.896,2,2,2h24c1.104,0,2-0.896,2-2S29.104,14,28,14z M28,22H4c-1.104,0-2,0.896-2,2s0.896,2,2,2h24c1.104,0,2-0.896,2-2 S29.104,22,28,22z"/>
+ </svg>
+ </div>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+ <div id="navigation" class="closed">
+ <div id="closer">
+ <svg viewbox="0 0 40 40">
+ <path class="close-x" d="M 10,10 L 30,30 M 30,10 L 10,30" />
+ </svg>
+ </div>
+ <image id="cover" width="150px"/>
+ <h2 id="author">...</h2>
+ <div id="toc"></div>
+ </div>
+
+ <script>
+ var src = window.location.search ?
+ window.location.search.replace("?href=", '') :
+ "https://readium2.now.sh/pub/L2hvbWUvbm93dXNlci9zcmMvbWlzYy9lcHVicy9jaGlsZHJlbnMtbGl0ZXJhdHVyZS5lcHVi/manifest.json" ;
+ var book = ePub(src);
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ rendition.display();
+
+ var title = document.getElementById("title");
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ var navigation = document.getElementById("navigation");
+ var opener = document.getElementById("opener");
+ opener.addEventListener("click", function(e){
+ navigation.classList.remove("closed");
+ e.preventDefault();
+ }, false);
+
+ var closer = document.getElementById("closer");
+ closer.addEventListener("click", function(e){
+ navigation.classList.add("closed");
+ e.preventDefault();
+ }, false);
+
+ book.loaded.navigation.then(function(toc){
+ var $nav = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+ var addTocItems = function (parent, tocItems) {
+ var $ul = document.createElement("ul");
+ tocItems.forEach(function(chapter) {
+ var item = document.createElement("li");
+ var link = document.createElement("a");
+ link.textContent = chapter.label;
+ link.href = chapter.href;
+ item.appendChild(link);
+
+ if (chapter.subitems) {
+ addTocItems(item, chapter.subitems)
+ }
+
+ link.onclick = function(){
+ var url = link.getAttribute("href");
+ rendition.display(url);
+ navigation.classList.add("closed");
+ return false;
+ };
+
+ $ul.appendChild(item);
+ });
+ parent.appendChild($ul);
+ };
+
+ addTocItems(docfrag, toc);
+
+ $nav.appendChild(docfrag);
+
+ if ($nav.offsetHeight + 60 < window.innerHeight) {
+ $nav.classList.add("fixed");
+ }
+
+ });
+
+ book.loaded.metadata.then(function(meta){
+ var $title = document.getElementById("title");
+ var $author = document.getElementById("author");
+ var $cover = document.getElementById("cover");
+
+ $title.textContent = meta.title;
+ $author.textContent = meta.creator;
+ if (book.archive) {
+ book.archive.createUrl(book.cover)
+ .then(function (url) {
+ $cover.src = url;
+ })
+ } else {
+ $cover.src = book.cover;
+ }
+ });
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ if(nextSection) {
+ next.textContent = "›";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prev.textContent = "‹";
+ } else {
+ prev.textContent = "";
+ }
+
+ });
+
+ rendition.on("relocated", function(location){
+ var current = book.navigation.get(location.href);
+
+ if (current) {
+ title.textContent = current.label;
+ }
+
+ console.log(location);
+ });
+
+ window.addEventListener("unload", function () {
+ this.book.destroy();
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/marks.html b/lib/epub.js/examples/marks.html
new file mode 100644
index 0000000..bbcb29a
--- /dev/null
+++ b/lib/epub.js/examples/marks.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Pagination Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="title"></div>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
+
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ var displayed = rendition.display(6);
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ rendition.on("relocated", function(location){
+ // console.log(location);
+ });
+
+
+ // Apply a class to selected text
+ rendition.on("selected", function(cfiRange, contents) {
+
+ var m = contents.mark(cfiRange, {'something' : true}, (e) => {
+ var bounds = e.target.getBoundingClientRect();
+ var clientX = e.clientX;
+
+ if (clientX > bounds.right) {
+ console.log("mark clicked", e.target);
+ }
+ });
+
+ contents.window.getSelection().removeAllRanges();
+
+ });
+
+ this.rendition.themes.default({
+ 'p': {
+ 'padding': '0 20px 0 0',
+ 'text-align': 'left',
+ 'position': 'relative'
+ },
+ '[ref="epubjs-mk"]::before' : {
+ 'content': '""',
+ 'background': 'url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgNzUgNzUnPjxnIGZpbGw9JyNCREJEQkQnIGlkPSdidWJibGUnPjxwYXRoIGNsYXNzPSdzdDAnIGQ9J00zNy41LDkuNEMxOS42LDkuNCw1LDIwLjUsNSwzNC4zYzAsNS45LDIuNywxMS4zLDcuMSwxNS42TDkuNiw2NS42bDE5LTcuM2MyLjgsMC42LDUuOCwwLjksOC45LDAuOSBDNTUuNSw1OS4yLDcwLDQ4LjEsNzAsMzQuM0M3MCwyMC41LDU1LjQsOS40LDM3LjUsOS40eicvPjwvZz48L3N2Zz4=") no-repeat',
+ 'display': 'block',
+ 'right' : '0',
+ 'position' : 'absolute',
+ 'width': '20px',
+ 'height': '20px',
+ 'margin': '0',
+ 'cursor': 'pointer'
+ }
+ });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/mathml.html b/lib/epub.js/examples/mathml.html
new file mode 100644
index 0000000..0daaa2f
--- /dev/null
+++ b/lib/epub.js/examples/mathml.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <!-- <div id="title"></div> -->
+ <select id="toc"></select>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ // Load the opf
+ var book = ePub(url || "http://epubjs.org/books/linear-algebra.epub");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ spread: "always"
+ });
+
+ rendition.display(currentSectionIndex);
+
+ book.ready.then(() => {
+
+ var next = document.getElementById("next");
+
+ next.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ })
+
+ var title = document.getElementById("title");
+
+ rendition.on("rendered", function(section){
+ var current = book.navigation && book.navigation.get(section.href);
+
+ if (current) {
+ var $select = document.getElementById("toc");
+ var $selected = $select.querySelector("option[selected]");
+ if ($selected) {
+ $selected.removeAttribute("selected");
+ }
+
+ var $options = $select.querySelectorAll("option");
+ for (var i = 0; i < $options.length; ++i) {
+ let selected = $options[i].getAttribute("ref") === current.href;
+ if (selected) {
+ $options[i].setAttribute("selected", "");
+ }
+ }
+ }
+
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+
+ var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
+ var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
+
+ if (location.atEnd) {
+ next.style.visibility = "hidden";
+ } else {
+ next.style.visibility = "visible";
+ }
+
+ if (location.atStart) {
+ prev.style.visibility = "hidden";
+ } else {
+ prev.style.visibility = "visible";
+ }
+
+ });
+
+ rendition.on("layout", function(layout) {
+ let viewer = document.getElementById("viewer");
+
+ if (layout.spread) {
+ viewer.classList.remove('single');
+ } else {
+ viewer.classList.add('single');
+ }
+ });
+
+ window.addEventListener("unload", function () {
+ console.log("unloading");
+ this.book.destroy();
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.setAttribute("ref", chapter.href);
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].getAttribute("ref");
+ rendition.display(url);
+ return false;
+ };
+
+ });
+
+ rendition.hooks.content.register(function (content) {
+ let section = book.section(content.sectionIndex);
+ let mathml = section.properties.includes("mathml");
+
+ if (mathml) {
+ return content.addScript('https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML');
+ }
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/offline.html b/lib/epub.js/examples/offline.html
new file mode 100644
index 0000000..ae5043b
--- /dev/null
+++ b/lib/epub.js/examples/offline.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Storage Example</title>
+
+ <script src="../node_modules/jszip/dist/jszip.min.js"></script>
+ <script src="../node_modules/localforage/dist/localforage.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+ <style type="text/css">
+
+ #offline {
+ position: fixed;
+ top: -40px;
+ left: 0;
+ background-color: yellow;
+ width: 100%;
+ text-align: center;
+ padding: 10px 0;
+ transition: top .5s;
+ z-index: 99;
+ }
+ </style>
+
+</head>
+<body>
+ <div id="offline">You are offline. Loading from Storage.</div>
+ <div id="viewer" class="spreads"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+ <script>
+ var book = ePub("https://s3.amazonaws.com/moby-dick/", {
+ store: "epubjs-test"
+ });
+
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600
+ });
+
+ var displayed = rendition.display();
+
+ displayed.then(function(renderer){
+ // Add all resources to the store
+ // Add `true` to force re-saving resources
+ book.storage.add(book.resources, true).then(() => {
+ console.log("stored");
+ })
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ var msg = document.getElementById('offline');
+ book.storage.on("online", function () {
+ console.log("online");
+ msg.style.top = "-40px";
+ });
+
+ book.storage.on("offline", function () {
+ console.log("offline");
+ msg.style.top = "0px";
+ });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/renderless.html b/lib/epub.js/examples/renderless.html
new file mode 100644
index 0000000..d5bb106
--- /dev/null
+++ b/lib/epub.js/examples/renderless.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>EPUB.js Basic Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <select id="toc"></select>
+ <div id="viewer" class="scrolled"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+
+ <script>
+ var $viewer = document.getElementById("viewer");
+ var $next = document.getElementById("next");
+ var $prev = document.getElementById("prev");
+ var currentSection;
+ var currentSectionIndex = 6;
+
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf");
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.ref = chapter.href;
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].ref;
+ display(url);
+ return false;
+ };
+
+ book.opened.then(function(){
+ display(currentSectionIndex);
+ });
+
+ $next.addEventListener("click", function(){
+ var displayed = display(currentSectionIndex+1);
+ if(displayed) currentSectionIndex++;
+ }, false);
+
+ $prev.addEventListener("click", function(){
+ var displayed = display(currentSectionIndex-1);
+ if(displayed) currentSectionIndex--;
+ }, false);
+
+ function display(item){
+ var section = book.spine.get(item);
+ if(section) {
+ currentSection = section;
+ section.render().then(function(html){
+ // $viewer.srcdoc = html;
+ $viewer.innerHTML = html;
+ });
+ }
+ return section;
+ }
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/scrolled.html b/lib/epub.js/examples/scrolled.html
new file mode 100644
index 0000000..bbc0923
--- /dev/null
+++ b/lib/epub.js/examples/scrolled.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Scrolled Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <a id="prev" href="#prev" class="navlink">...</a>
+ <div id="viewer" class="scrolled"></div>
+ <a id="next" href="#next" class="navlink">...</a>
+
+ <script>
+ // Load the opf
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ var book = ePub(url || "https://s3.amazonaws.com/epubjs/books/alice/OPS/package.opf");
+ var rendition = book.renderTo("viewer", {
+ flow: "scrolled-doc",
+ width: "100%",
+ fullsize: true
+ });
+
+ rendition.display(currentSectionIndex);
+
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+ });
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ if(nextSection) {
+ nextNav = book.navigation.get(nextSection.href);
+
+ if(nextNav) {
+ nextLabel = nextNav.label;
+ } else {
+ nextLabel = "next";
+ }
+
+ next.textContent = nextLabel + " »";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prevNav = book.navigation.get(prevSection.href);
+
+ if(prevNav) {
+ prevLabel = prevNav.label;
+ } else {
+ prevLabel = "previous";
+ }
+
+ prev.textContent = "« " + prevLabel;
+ } else {
+ prev.textContent = "";
+ }
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/single-full.html b/lib/epub.js/examples/single-full.html
new file mode 100644
index 0000000..cf96238
--- /dev/null
+++ b/lib/epub.js/examples/single-full.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Scrolled Full Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+
+ <style type="text/css">
+ body {
+ margin: 0;
+ background: #fafafa;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #333;
+ }
+
+ #navigation {
+ width: 300px;
+ position: absolute;
+ overflow: auto;
+ top: 60px;
+ left: 1000px
+ }
+
+ #navigation.fixed {
+ position: fixed;
+ }
+
+ #navigation h1 {
+ width: 200px;
+ font-size: 16px;
+ font-weight: normal;
+ color: #777;
+ margin-bottom: 10px;
+ }
+
+ #navigation h2 {
+ font-size: 14px;
+ font-weight: normal;
+ color: #B0B0B0;
+ margin-bottom: 20px;
+ }
+
+ #navigation ul {
+ padding-left: 18px;
+ margin-left: 0;
+ margin-top: 12px;
+ margin-bottom: 12px;
+ }
+
+ #navigation ul li {
+ list-style: decimal;
+ margin-bottom: 10px;
+ color: #cccddd;
+ font-size: 12px;
+ padding-left: 0;
+ margin-left: 0;
+ }
+
+ #navigation ul li a {
+ color: #ccc;
+ text-decoration: none;
+ }
+
+ #navigation ul li a:hover {
+ color: #777;
+ text-decoration: underline;
+ }
+
+ #navigation ul li a.active {
+ color: #000;
+ }
+
+ #viewer {
+
+ overflow: hidden;
+ width: 800px;
+ margin: 0 50px;
+ background: url('ajax-loader.gif') center center no-repeat;
+
+ }
+
+ #viewer .epub-view {
+ background: white;
+ box-shadow: 0 0 4px #ccc;
+ /*margin: 10px;*/
+ /*padding: 40px 80px;*/
+ }
+
+ #main {
+ position: absolute;
+ top: 50px;
+ left: 50px;
+ width: 800px;
+ z-index: 2;
+ transition: left .15s cubic-bezier(.55, 0, .2, .8) .08s;
+ }
+
+ #main.open {
+ left: 0;
+ }
+
+ #pagination {
+ text-align: center;
+ margin-left: 80px;
+ /*padding: 0 50px;*/
+ }
+
+ .arrow {
+ margin: 14px;
+ display: inline-block;
+ text-align: center;
+ text-decoration: none;
+ color: #ccc;
+ }
+
+ .arrow:hover {
+ color: #777;
+ }
+
+ .arrow:active {
+ color: #000;
+ }
+
+ #prev {
+ float: left;
+ }
+
+ #next {
+ float: right;
+ }
+
+ #toc {
+ display: block;
+ margin: 10px auto;
+ }
+ </style>
+</head>
+<body>
+ <div id="navigation">
+ <h1 id="title">...</h1>
+ <image id="cover" width="150px"/>
+ <h2 id="author">...</h2>
+ <div id="toc"></div>
+ </div>
+ <div id="main">
+ <div id="viewer"></div>
+ <div id="pagination">
+ <a id="prev" href="#prev" class="arrow">...</a>
+ <a id="next" href="#next" class="arrow">...</a>
+ </div>
+ </div>
+
+ <script>
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ flow: "scrolled-doc"
+ });
+ var hash = window.location.hash.slice(2);
+ console.log(hash);
+ rendition.display(hash || undefined);
+
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+
+ if(nextSection) {
+ nextNav = book.navigation.get(nextSection.href);
+
+ if(nextNav) {
+ nextLabel = nextNav.label;
+ } else {
+ nextLabel = "next";
+ }
+
+ next.textContent = nextLabel + " »";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prevNav = book.navigation.get(prevSection.href);
+
+ if(prevNav) {
+ prevLabel = prevNav.label;
+ } else {
+ prevLabel = "previous";
+ }
+
+ prev.textContent = "« " + prevLabel;
+ } else {
+ prev.textContent = "";
+ }
+
+ // Add CFI fragment to the history
+ //history.pushState({}, '', section.href);
+ window.location.hash = "#/"+section.href
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $nav = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+ var addTocItems = function (parent, tocItems) {
+ var $ul = document.createElement("ul");
+ tocItems.forEach(function(chapter) {
+ var item = document.createElement("li");
+ var link = document.createElement("a");
+ link.textContent = chapter.label;
+ link.href = chapter.href;
+ item.appendChild(link);
+
+ if (chapter.subitems) {
+ addTocItems(item, chapter.subitems)
+ }
+
+ link.onclick = function(){
+ var url = link.getAttribute("href");
+ rendition.display(url);
+ return false;
+ };
+
+ $ul.appendChild(item);
+ });
+ parent.appendChild($ul);
+ };
+
+ addTocItems(docfrag, toc);
+
+ $nav.appendChild(docfrag);
+
+ if ($nav.offsetHeight + 60 < window.innerHeight) {
+ $nav.classList.add("fixed");
+ }
+
+ });
+
+ book.loaded.metadata.then(function(meta){
+ var $title = document.getElementById("title");
+ var $author = document.getElementById("author");
+ var $cover = document.getElementById("cover");
+
+ $title.textContent = meta.title;
+ $author.textContent = meta.creator;
+ if (book.archive) {
+ book.archive.createUrl(book.cover)
+ .then(function (url) {
+ $cover.src = url;
+ })
+ } else {
+ $cover.src = book.cover;
+ }
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/spreads.html b/lib/epub.js/examples/spreads.html
new file mode 100644
index 0000000..8d66bce
--- /dev/null
+++ b/lib/epub.js/examples/spreads.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <!-- <div id="title"></div> -->
+ <select id="toc"></select>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+ var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
+ var url = params && params.get("url") && decodeURIComponent(params.get("url"));
+ var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
+
+ // Load the opf
+ var book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ spread: "always"
+ });
+
+ rendition.display(currentSectionIndex);
+
+ book.ready.then(function() {
+
+ var next = document.getElementById("next");
+
+ next.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+ })
+
+ var title = document.getElementById("title");
+
+ rendition.on("rendered", function(section){
+ var current = book.navigation && book.navigation.get(section.href);
+
+ if (current) {
+ var $select = document.getElementById("toc");
+ var $selected = $select.querySelector("option[selected]");
+ if ($selected) {
+ $selected.removeAttribute("selected");
+ }
+
+ var $options = $select.querySelectorAll("option");
+ for (var i = 0; i < $options.length; ++i) {
+ let selected = $options[i].getAttribute("ref") === current.href;
+ if (selected) {
+ $options[i].setAttribute("selected", "");
+ }
+ }
+ }
+
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+
+ var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
+ var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
+
+ if (location.atEnd) {
+ next.style.visibility = "hidden";
+ } else {
+ next.style.visibility = "visible";
+ }
+
+ if (location.atStart) {
+ prev.style.visibility = "hidden";
+ } else {
+ prev.style.visibility = "visible";
+ }
+
+ });
+
+ rendition.on("layout", function(layout) {
+ let viewer = document.getElementById("viewer");
+
+ if (layout.spread) {
+ viewer.classList.remove('single');
+ } else {
+ viewer.classList.add('single');
+ }
+ });
+
+ window.addEventListener("unload", function () {
+ console.log("unloading");
+ this.book.destroy();
+ });
+
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.setAttribute("ref", chapter.href);
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].getAttribute("ref");
+ rendition.display(url);
+ return false;
+ };
+
+ });
+
+
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/swipe.html b/lib/epub.js/examples/swipe.html
new file mode 100644
index 0000000..6154be4
--- /dev/null
+++ b/lib/epub.js/examples/swipe.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Pagination Example</title>
+ <!-- <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> -->
+ <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/detect_swipe/2.1.1/jquery.detect_swipe.min.js"></script> -->
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+ <style type="text/css">
+ body {
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-justify-content: center;
+ }
+
+ #viewer {
+ width: 290px;
+ height: 580px;
+ box-shadow: 0 0 4px #ccc;
+ padding: 10px 10px 0px 10px;
+ margin: 5px auto;
+ background: white;
+ }
+
+
+ @media only screen
+ and (min-device-width : 320px)
+ and (max-device-width : 667px) {
+ #viewer {
+ height: 96.5%;
+ }
+ #viewer iframe {
+ /* pointer-events: none; */
+ }
+ .arrow {
+ position: inherit;
+ display: none;
+ }
+ }
+
+ </style>
+</head>
+<body>
+ <div id="viewer"></div>
+ <div id="prev" class="arrow">‹</div>
+ <div id="next" class="arrow">›</div>
+ <script>
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("viewer", {
+ manager: "continuous",
+ flow: "paginated",
+ width: "100%",
+ height: "100%",
+ snap: true
+ });
+
+ var displayed = rendition.display("chapter_001.xhtml");
+
+ displayed.then(function(renderer){
+ // -- do stuff
+ });
+
+ // Navigation loaded
+ book.loaded.navigation.then(function(toc){
+ // console.log(toc);
+ });
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(){
+ rendition.next();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(){
+ rendition.prev();
+ }, false);
+
+ document.addEventListener("keyup", function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ }, false);
+
+ // $(window).on( "swipeleft", function( event ) {
+ // rendition.next();
+ // });
+ //
+ // $(window).on( "swiperight", function( event ) {
+ // rendition.prev();
+ // });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/themes.css b/lib/epub.js/examples/themes.css
new file mode 100644
index 0000000..0bb5eef
--- /dev/null
+++ b/lib/epub.js/examples/themes.css
@@ -0,0 +1,14 @@
+.dark {
+ background: #000;
+ color: #fff
+}
+
+.light {
+ background: #fff;
+ color: #000;
+}
+
+.tan {
+ background: tan;
+ color: #ccc;
+}
diff --git a/lib/epub.js/examples/themes.html b/lib/epub.js/examples/themes.html
new file mode 100644
index 0000000..4b7d204
--- /dev/null
+++ b/lib/epub.js/examples/themes.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>EPUB.js Spreads Example</title>
+
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <div id="title"></div>
+ <div id="viewer" class="spreads"></div>
+ <a id="prev" href="#prev" class="arrow">‹</a>
+ <a id="next" href="#next" class="arrow">›</a>
+
+ <script>
+ var currentSectionIndex = 8;
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/epubjs/books/alice/OPS/package.opf");
+ var rendition = book.renderTo("viewer", {
+ width: "100%",
+ height: 600,
+ manager: "continuous"
+ });
+
+ rendition.display("chapter_007.xhtml");
+
+ var title = document.getElementById("title");
+
+ var next = document.getElementById("next");
+ next.addEventListener("click", function(e){
+ rendition.next();
+ e.preventDefault();
+ }, false);
+
+ var prev = document.getElementById("prev");
+ prev.addEventListener("click", function(e){
+ rendition.prev();
+ e.preventDefault();
+ }, false);
+
+ var keyListener = function(e){
+
+ // Left Key
+ if ((e.keyCode || e.which) == 37) {
+ rendition.prev();
+ }
+
+ // Right Key
+ if ((e.keyCode || e.which) == 39) {
+ rendition.next();
+ }
+
+ };
+
+ rendition.on("keyup", keyListener);
+ document.addEventListener("keyup", keyListener, false);
+
+
+
+ rendition.on("rendered", function(section){
+ var nextSection = section.next();
+ var prevSection = section.prev();
+ var current = book.navigation.get(section.href);
+
+ if (current) {
+ title.textContent = current.label;
+ }
+
+ if(nextSection) {
+ next.textContent = "›";
+ } else {
+ next.textContent = "";
+ }
+
+ if(prevSection) {
+ prev.textContent = "‹";
+ } else {
+ prev.textContent = "";
+ }
+
+
+
+ });
+
+ rendition.on("relocated", function(location){
+ console.log(location);
+ });
+
+
+ rendition.themes.register("dark", "themes.css");
+ rendition.themes.register("light", "themes.css");
+ rendition.themes.register("tan", "themes.css");
+
+
+
+ rendition.themes.default({
+ h2: {
+ 'font-size': '32px',
+ color: 'purple'
+ },
+ p: {
+ "margin": '10px'
+ }
+ });
+
+ rendition.themes.select("tan");
+ rendition.themes.fontSize("140%");
+
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/examples/toc.html b/lib/epub.js/examples/toc.html
new file mode 100644
index 0000000..b5de364
--- /dev/null
+++ b/lib/epub.js/examples/toc.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>EPUB.js Basic Example</title>
+
+ <script src="../dist/epub.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="examples.css">
+
+</head>
+<body>
+ <select id="toc"></select>
+ <div id="viewer" class="scrolled"></div>
+
+ <script>
+ var $viewer = document.getElementById("viewer");
+ var $next = document.getElementById("next");
+ var $prev = document.getElementById("prev");
+ var currentSectionIndex = 9;
+ // Load the opf
+ var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("viewer", { flow: "scrolled-doc", width: 600, height: 400});
+ var displayed = rendition.display(currentSectionIndex);
+
+ book.loaded.navigation.then(function(toc){
+ var $select = document.getElementById("toc"),
+ docfrag = document.createDocumentFragment();
+
+ toc.forEach(function(chapter) {
+ var option = document.createElement("option");
+ option.textContent = chapter.label;
+ option.ref = chapter.href;
+
+ docfrag.appendChild(option);
+ });
+
+ $select.appendChild(docfrag);
+
+ $select.onchange = function(){
+ var index = $select.selectedIndex,
+ url = $select.options[index].ref;
+ rendition.display(url);
+ return false;
+ };
+
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/lib/epub.js/karma.conf.js b/lib/epub.js/karma.conf.js
new file mode 100644
index 0000000..fa83072
--- /dev/null
+++ b/lib/epub.js/karma.conf.js
@@ -0,0 +1,147 @@
+let webpackConfig = require("./webpack.config.js");
+webpackConfig.mode = "development";
+webpackConfig.externals = {};
+webpackConfig.module.rules.push({
+ test: /\.xhtml$/i,
+ use: 'raw-loader',
+});
+
+module.exports = function(config) {
+ config.set({
+
+ // base path that will be used to resolve all patterns (eg. files, exclude)
+ basePath: '',
+
+
+ // frameworks to use
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+ frameworks: ['mocha'],
+
+
+ // list of files / patterns to load in the browser
+ files: [
+
+ {pattern: 'src/*.js', watched: true, included: false, served: false},
+
+ {pattern: 'test/*.js', watched: false},
+
+ {pattern: 'test/fixtures/**/*', watched: false, included: false, served: true},
+
+ // {pattern: 'node_modules/jszip/dist/jszip.js', watched: false, included: true, served: true},
+
+ // {pattern: 'node_modules/es6-promise/dist/es6-promise.auto.js', watched: false, included: true, served: true},
+
+ // {pattern: 'libs/url/url-polyfill.js', watched: false, included: true, served: true}
+
+ ],
+
+ // list of files to exclude
+ exclude: [
+ ],
+
+
+ // preprocess matching files before serving them to the browser
+ // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+ preprocessors: {
+ // add webpack as preprocessor
+ 'test/*.js': ['webpack', 'sourcemap'],
+ // 'test/**/*.js': ['webpack', 'sourcemap']
+ },
+
+ webpack: webpackConfig,
+
+ // {
+ // mode: "development",
+ // externals: {
+ // "jszip": "JSZip"
+ // // "xmldom": "xmldom"
+ // },
+ // devtool: 'inline-source-map',
+ // resolve: {
+ // alias: {
+ // path: "path-webpack"
+ // }
+ // },
+ // module: {
+ // rules: [
+ // {
+ // test: /\.js$/,
+ // exclude: /node_modules/,
+ // loader: "babel-loader",
+ // query: {
+ // presets: [["@babel/preset-env", {
+ // targets: "defaults",
+ // }]],
+ // }
+ // },
+ // {
+ // test: /\.xhtml$/i,
+ // use: 'raw-loader',
+ // }
+ // ]
+ // }
+ // },
+
+ webpackMiddleware: {
+ stats: 'errors-only'
+ },
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress'
+ // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+ reporters: ['mocha'],
+
+ // web server port
+ port: 9876,
+
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_INFO,
+
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: true,
+
+
+ // start these browsers
+ // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+ browsers: ['ChromeHeadless', 'ChromeHeadlessNoSandbox'],
+
+
+ // Continuous Integration mode
+ // if true, Karma captures browsers, runs the tests and exits
+ singleRun: false,
+
+ // Concurrency level
+ // how many browser should be started simultaneous
+ concurrency: Infinity,
+
+ proxies: {
+ "/fixtures/": "/base/test/fixtures/"
+ },
+
+ client: {
+ config: {
+ browserConsoleLogOptions: true
+ },
+ captureConsole: true,
+ mocha: {
+ reporter: 'html'
+ // bail: true
+ }
+ },
+
+ customLaunchers: {
+ ChromeHeadlessNoSandbox: {
+ base: 'ChromeHeadless',
+ flags: ['--no-sandbox']
+ }
+ }
+
+ })
+}
diff --git a/lib/epub.js/license b/lib/epub.js/license
new file mode 100644
index 0000000..f294d33
--- /dev/null
+++ b/lib/epub.js/license
@@ -0,0 +1,27 @@
+Copyright (c) 2013, FuturePress
+
+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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
diff --git a/lib/epub.js/package-lock.json b/lib/epub.js/package-lock.json
new file mode 100644
index 0000000..4cd93d4
--- /dev/null
+++ b/lib/epub.js/package-lock.json
@@ -0,0 +1,15988 @@
+{
+ "name": "epubjs",
+ "version": "0.3.88",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/cli": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.10.1.tgz",
+ "integrity": "sha512-cVB+dXeGhMOqViIaZs3A9OUAe4pKw4SBNdMw6yHJMYR7s4TB+Cei7ThquV/84O19PdIFWuwe03vxxES0BHUm5g==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^2.1.8",
+ "commander": "^4.0.1",
+ "convert-source-map": "^1.1.0",
+ "fs-readdir-recursive": "^1.1.0",
+ "glob": "^7.0.0",
+ "lodash": "^4.17.13",
+ "make-dir": "^2.1.0",
+ "slash": "^2.0.0",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/code-frame": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+ "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.8.3"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz",
+ "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.12.0",
+ "invariant": "^2.2.4",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/core": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz",
+ "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.1",
+ "@babel/generator": "^7.10.2",
+ "@babel/helper-module-transforms": "^7.10.1",
+ "@babel/helpers": "^7.10.1",
+ "@babel/parser": "^7.10.2",
+ "@babel/template": "^7.10.1",
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.2",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.13",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
+ "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.1"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
+ "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
+ "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.1",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
+ "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz",
+ "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.2",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.13",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz",
+ "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz",
+ "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-explode-assignable-expression": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-builder-react-jsx": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz",
+ "integrity": "sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-builder-react-jsx-experimental": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz",
+ "integrity": "sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-module-imports": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz",
+ "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.10.1",
+ "browserslist": "^4.12.0",
+ "invariant": "^2.2.4",
+ "levenary": "^1.1.1",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/helper-create-class-features-plugin": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz",
+ "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/helper-member-expression-to-functions": "^7.10.1",
+ "@babel/helper-optimise-call-expression": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-replace-supers": "^7.10.1",
+ "@babel/helper-split-export-declaration": "^7.10.1"
+ }
+ },
+ "@babel/helper-create-regexp-features-plugin": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz",
+ "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-regex": "^7.10.1",
+ "regexpu-core": "^4.7.0"
+ }
+ },
+ "@babel/helper-define-map": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz",
+ "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/types": "^7.10.1",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-explode-assignable-expression": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz",
+ "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==",
+ "dev": true,
+ "requires": {
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz",
+ "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.10.1",
+ "@babel/template": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz",
+ "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz",
+ "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz",
+ "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz",
+ "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz",
+ "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.10.1",
+ "@babel/helper-replace-supers": "^7.10.1",
+ "@babel/helper-simple-access": "^7.10.1",
+ "@babel/helper-split-export-declaration": "^7.10.1",
+ "@babel/template": "^7.10.1",
+ "@babel/types": "^7.10.1",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz",
+ "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz",
+ "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==",
+ "dev": true
+ },
+ "@babel/helper-regex": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz",
+ "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-remap-async-to-generator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz",
+ "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-wrap-function": "^7.10.1",
+ "@babel/template": "^7.10.1",
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz",
+ "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.10.1",
+ "@babel/helper-optimise-call-expression": "^7.10.1",
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz",
+ "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
+ "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+ "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+ "dev": true
+ },
+ "@babel/helper-wrap-function": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz",
+ "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/template": "^7.10.1",
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz",
+ "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.10.1",
+ "@babel/traverse": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+ "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.9.0",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/parser": {
+ "version": "7.9.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+ "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+ "dev": true
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz",
+ "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-remap-async-to-generator": "^7.10.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-class-properties": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz",
+ "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-decorators": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.1.tgz",
+ "integrity": "sha512-xBfteh352MTke2U1NpclzMDmAmCdQ2fBZjhZQQfGTjXw6qcRYMkt528sA1U8o0ThDCSeuETXIj5bOGdxN+5gkw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-decorators": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-do-expressions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-do-expressions/-/plugin-proposal-do-expressions-7.10.1.tgz",
+ "integrity": "sha512-rjAoAQl6YLsY9C60zQBVTBsDP8YUWlgSv7qRdG8rapQYl+WL1LIVq23SHDCPllaNrE8bqO9csBooTL4yXr7FnA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-do-expressions": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-dynamic-import": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz",
+ "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-export-default-from": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.10.1.tgz",
+ "integrity": "sha512-Xfc1CfHapIkwZ/+AI+j4Ha3g233ol0EEdy6SmnUuQQiZX78SfQXHd8tmntc5zqCkwPnIHoiZa6l6p0OAvxYXHw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-export-default-from": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.1.tgz",
+ "integrity": "sha512-eR4CoYb6mh5y9LWjnb4CyUatuhtZ8pNLXLDi46GkqtF7WPafFqXycHdvF5qWviozZVGRSAmHzdayc8wUReCdjA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-function-bind": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.10.1.tgz",
+ "integrity": "sha512-NgVBGHC8kpnyPP0LtRRe5ElE/17QoAKf3BoqQY+A7MqBsPK+DorfyeRo27EU4f/i49MDdFAXz2yZvhUnHFOxmQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-function-bind": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-function-sent": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.10.1.tgz",
+ "integrity": "sha512-mpfEbRcwHvDA6k19ZFsGkW4Q+AF7DekafKTTfn2Ihz1cs6/qL+KgAJlcHBY6XnW1OW1zDaNCR0i28Blonl8/Bg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-wrap-function": "^7.10.1",
+ "@babel/plugin-syntax-function-sent": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-json-strings": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz",
+ "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-json-strings": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.10.1.tgz",
+ "integrity": "sha512-+0uLbTZhTvSet8KpTMMaL2p7p12/b//sKbFzDPAMk6z4rlYbTtyFZmq65KJMLGLio9AVjq2VKF8mxxJMXKUMwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz",
+ "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-numeric-separator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz",
+ "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz",
+ "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz",
+ "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-optional-chaining": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz",
+ "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-pipeline-operator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.10.1.tgz",
+ "integrity": "sha512-P+WKKsi7XBEvvTaregnYZIF+aLoCTNt0T21tbzeGlOdERmR1X0iFXJKqZbxsJooa+a3f/tKYFhbJYqnKt70x2w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-pipeline-operator": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-private-methods": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz",
+ "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-throw-expressions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.10.1.tgz",
+ "integrity": "sha512-wyhTn1ebUbbphDJVVUpg1wikUOIW8Lg93ng0aDGv07+MxINPS4d0ju68JVH06W4oMnZTwgELA5AImrah9RULYA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-throw-expressions": "^7.10.1"
+ }
+ },
+ "@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz",
+ "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz",
+ "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-decorators": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz",
+ "integrity": "sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-do-expressions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-do-expressions/-/plugin-syntax-do-expressions-7.10.1.tgz",
+ "integrity": "sha512-Me/wISm2f76puo3Heyu01tthw7/8HSTn2aaiDahWD1K9oRPfzygW0eBcLIrTUdhr58MUyrSLduhUM7uZry6vzg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-export-default-from": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.10.1.tgz",
+ "integrity": "sha512-+rcL4S/mN1Ss4zhSCbxzv1Wsf12eauvgTjWi0krXEeX1zd6qSxYnJoniE5Ssr5w2WPt61oUCJyXIFQIqO/29zw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ }
+ },
+ "@babel/plugin-syntax-flow": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.1.tgz",
+ "integrity": "sha512-b3pWVncLBYoPP60UOTc7NMlbtsHQ6ITim78KQejNHK6WJ2mzV5kCcg4mIWpasAfJEgwVTibwo2e+FU7UEIKQUg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-function-bind": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.10.1.tgz",
+ "integrity": "sha512-eb+muGp2AzVPYnAof+IYuTjyHsbMRKn+hVSEhCzKlPVcGemJPnv9buhDhvgcQGTo1yZnOh6O+YNWMq9g9QAalg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-function-sent": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.10.1.tgz",
+ "integrity": "sha512-Ze/5A9mFucmT7UyEA8D60YijmclEZQp3kjzbbEImWnyMLmjE/3S5x7lkCr+W7g2wc00nqk1QLsloa4+1EiHULA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.1.tgz",
+ "integrity": "sha512-ypC4jwfIVF72og0dgvEcFRdOM2V9Qm1tu7RGmdZOlhsccyK0wisXmMObGuWEOd5jQ+K9wcIgSNftCpk2vkjUfQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz",
+ "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz",
+ "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz",
+ "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-pipeline-operator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.10.1.tgz",
+ "integrity": "sha512-6jvu8KNBnEGuwlRpAQxTHsKcYuGqSf1gAv1c7j+CP7evNU8atjCRW6pK/W1AxeTz1WXWpzciOQTK4hLfPlXKDQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-throw-expressions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.10.1.tgz",
+ "integrity": "sha512-1ieYCCX6HCEvBefYt1Njja2XFrbThi2pffdfpPeB7WzVwbX/UlVOrPw9WSPQyVoyo+kqO0l/KGRNZyrTKo0bew==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz",
+ "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-arrow-functions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz",
+ "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz",
+ "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-remap-async-to-generator": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz",
+ "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-block-scoping": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz",
+ "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/plugin-transform-classes": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz",
+ "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-define-map": "^7.10.1",
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/helper-optimise-call-expression": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-replace-supers": "^7.10.1",
+ "@babel/helper-split-export-declaration": "^7.10.1",
+ "globals": "^11.1.0"
+ },
+ "dependencies": {
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/plugin-transform-computed-properties": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz",
+ "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz",
+ "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-dotall-regex": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz",
+ "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-duplicate-keys": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz",
+ "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz",
+ "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-flow-strip-types": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.10.1.tgz",
+ "integrity": "sha512-i4o0YwiJBIsIx7/liVCZ3Q2WkWr1/Yu39PksBOnh/khW2SwIFsGa5Ze+MSon5KbDfrEHP9NeyefAgvUSXzaEkw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-flow": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-for-of": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz",
+ "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-function-name": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz",
+ "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-literals": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz",
+ "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-member-expression-literals": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz",
+ "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-modules-amd": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz",
+ "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz",
+ "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-simple-access": "^7.10.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-systemjs": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz",
+ "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-hoist-variables": "^7.10.1",
+ "@babel/helper-module-transforms": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-umd": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz",
+ "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz",
+ "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.8.3"
+ }
+ },
+ "@babel/plugin-transform-new-target": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz",
+ "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-object-super": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz",
+ "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-replace-supers": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-parameters": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz",
+ "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-property-literals": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz",
+ "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-display-name": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz",
+ "integrity": "sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-jsx": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz",
+ "integrity": "sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-react-jsx": "^7.10.1",
+ "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-jsx": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-jsx-development": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz",
+ "integrity": "sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-jsx": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-jsx-self": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz",
+ "integrity": "sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-jsx": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-jsx-source": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz",
+ "integrity": "sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-syntax-jsx": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.1.tgz",
+ "integrity": "sha512-mfhoiai083AkeewsBHUpaS/FM1dmUENHBMpS/tugSJ7VXqXO5dCN1Gkint2YvM1Cdv1uhmAKt1ZOuAjceKmlLA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-regenerator": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz",
+ "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.14.2"
+ }
+ },
+ "@babel/plugin-transform-reserved-words": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz",
+ "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-shorthand-properties": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz",
+ "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-spread": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz",
+ "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-sticky-regex": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz",
+ "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-regex": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-template-literals": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz",
+ "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-typeof-symbol": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz",
+ "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-unicode-escapes": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz",
+ "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/plugin-transform-unicode-regex": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz",
+ "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz",
+ "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.10.1",
+ "@babel/helper-compilation-targets": "^7.10.2",
+ "@babel/helper-module-imports": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-proposal-async-generator-functions": "^7.10.1",
+ "@babel/plugin-proposal-class-properties": "^7.10.1",
+ "@babel/plugin-proposal-dynamic-import": "^7.10.1",
+ "@babel/plugin-proposal-json-strings": "^7.10.1",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1",
+ "@babel/plugin-proposal-numeric-separator": "^7.10.1",
+ "@babel/plugin-proposal-object-rest-spread": "^7.10.1",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.10.1",
+ "@babel/plugin-proposal-optional-chaining": "^7.10.1",
+ "@babel/plugin-proposal-private-methods": "^7.10.1",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.10.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0",
+ "@babel/plugin-syntax-class-properties": "^7.10.1",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+ "@babel/plugin-syntax-json-strings": "^7.8.0",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.1",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+ "@babel/plugin-syntax-top-level-await": "^7.10.1",
+ "@babel/plugin-transform-arrow-functions": "^7.10.1",
+ "@babel/plugin-transform-async-to-generator": "^7.10.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.10.1",
+ "@babel/plugin-transform-block-scoping": "^7.10.1",
+ "@babel/plugin-transform-classes": "^7.10.1",
+ "@babel/plugin-transform-computed-properties": "^7.10.1",
+ "@babel/plugin-transform-destructuring": "^7.10.1",
+ "@babel/plugin-transform-dotall-regex": "^7.10.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.10.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.10.1",
+ "@babel/plugin-transform-for-of": "^7.10.1",
+ "@babel/plugin-transform-function-name": "^7.10.1",
+ "@babel/plugin-transform-literals": "^7.10.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.10.1",
+ "@babel/plugin-transform-modules-amd": "^7.10.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.10.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.10.1",
+ "@babel/plugin-transform-modules-umd": "^7.10.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
+ "@babel/plugin-transform-new-target": "^7.10.1",
+ "@babel/plugin-transform-object-super": "^7.10.1",
+ "@babel/plugin-transform-parameters": "^7.10.1",
+ "@babel/plugin-transform-property-literals": "^7.10.1",
+ "@babel/plugin-transform-regenerator": "^7.10.1",
+ "@babel/plugin-transform-reserved-words": "^7.10.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.10.1",
+ "@babel/plugin-transform-spread": "^7.10.1",
+ "@babel/plugin-transform-sticky-regex": "^7.10.1",
+ "@babel/plugin-transform-template-literals": "^7.10.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.10.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.10.1",
+ "@babel/plugin-transform-unicode-regex": "^7.10.1",
+ "@babel/preset-modules": "^0.1.3",
+ "@babel/types": "^7.10.2",
+ "browserslist": "^4.12.0",
+ "core-js-compat": "^3.6.2",
+ "invariant": "^2.2.2",
+ "levenary": "^1.1.1",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/preset-flow": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.10.1.tgz",
+ "integrity": "sha512-FuQsibb5PaX07fF1XUO5gjjxdEZbcJv8+ugPDaeFEsBIvUTib8hCtEJow/c2F0jq9ZUjpHCQ8IQKNHRvKE1kJQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-transform-flow-strip-types": "^7.10.1"
+ }
+ },
+ "@babel/preset-modules": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz",
+ "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ }
+ },
+ "@babel/preset-react": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.1.tgz",
+ "integrity": "sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/plugin-transform-react-display-name": "^7.10.1",
+ "@babel/plugin-transform-react-jsx": "^7.10.1",
+ "@babel/plugin-transform-react-jsx-development": "^7.10.1",
+ "@babel/plugin-transform-react-jsx-self": "^7.10.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.10.1",
+ "@babel/plugin-transform-react-pure-annotations": "^7.10.1"
+ }
+ },
+ "@babel/preset-stage-0": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/preset-stage-0/-/preset-stage-0-7.8.3.tgz",
+ "integrity": "sha512-+l6FlG1j73t4wh78W41StbcCz0/9a1/y+vxfnjtHl060kSmcgMfGzK9MEkLvrCOXfhp9RCX+d88sm6rOqxEIEQ==",
+ "dev": true
+ },
+ "@babel/runtime": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+ "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+ "dev": true,
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/template": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz",
+ "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.1",
+ "@babel/parser": "^7.10.1",
+ "@babel/types": "^7.10.1"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
+ "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.1"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
+ "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
+ "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.1",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
+ "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ }
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz",
+ "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.1",
+ "@babel/generator": "^7.10.1",
+ "@babel/helper-function-name": "^7.10.1",
+ "@babel/helper-split-export-declaration": "^7.10.1",
+ "@babel/parser": "^7.10.1",
+ "@babel/types": "^7.10.1",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.13"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
+ "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.1"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
+ "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
+ "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.1",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
+ "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
+ "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.1",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
+ "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+ "dev": true
+ }
+ }
+ },
+ "@npmcli/move-file": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz",
+ "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^1.0.4"
+ },
+ "dependencies": {
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ }
+ }
+ },
+ "@types/color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+ "dev": true
+ },
+ "@types/events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+ "dev": true,
+ "requires": {
+ "@types/events": "*",
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/localforage": {
+ "version": "0.0.34",
+ "resolved": "https://registry.npmjs.org/@types/localforage/-/localforage-0.0.34.tgz",
+ "integrity": "sha1-XjHDLdh5HsS5/z70fJy1Wy0NlDg=",
+ "requires": {
+ "localforage": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "14.0.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
+ "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
+ "dev": true
+ },
+ "@types/unist": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+ "dev": true
+ },
+ "@webassemblyjs/ast": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+ "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/helper-module-context": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/wast-parser": "1.9.0"
+ }
+ },
+ "@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+ "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-api-error": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+ "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-buffer": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+ "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-code-frame": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+ "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/wast-printer": "1.9.0"
+ }
+ },
+ "@webassemblyjs/helper-fsm": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+ "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-module-context": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+ "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0"
+ }
+ },
+ "@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+ "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-wasm-section": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+ "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0"
+ }
+ },
+ "@webassemblyjs/ieee754": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+ "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+ "dev": true,
+ "requires": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "@webassemblyjs/leb128": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+ "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+ "dev": true,
+ "requires": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/utf8": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+ "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+ "dev": true
+ },
+ "@webassemblyjs/wasm-edit": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+ "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/helper-wasm-section": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0",
+ "@webassemblyjs/wasm-opt": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0",
+ "@webassemblyjs/wast-printer": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-gen": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+ "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/ieee754": "1.9.0",
+ "@webassemblyjs/leb128": "1.9.0",
+ "@webassemblyjs/utf8": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-opt": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+ "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+ "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-api-error": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/ieee754": "1.9.0",
+ "@webassemblyjs/leb128": "1.9.0",
+ "@webassemblyjs/utf8": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wast-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+ "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+ "@webassemblyjs/helper-api-error": "1.9.0",
+ "@webassemblyjs/helper-code-frame": "1.9.0",
+ "@webassemblyjs/helper-fsm": "1.9.0",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/wast-printer": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+ "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/wast-parser": "1.9.0",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ }
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.44.0"
+ }
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "dev": true
+ }
+ }
+ },
+ "acorn": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
+ "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
+ "dev": true
+ },
+ "after": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+ "dev": true
+ },
+ "aggregate-error": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
+ "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.12.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
+ "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+ "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+ "dev": true
+ },
+ "ajv-keywords": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
+ "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "ansi-html": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+ "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "append-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+ "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+ "dev": true,
+ "requires": {
+ "buffer-equal": "^1.0.0"
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "arraybuffer.slice": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "asn1.js": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "assert": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+ "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.1",
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+ "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "babel-loader": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
+ "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^2.1.0",
+ "loader-utils": "^1.4.0",
+ "mkdirp": "^0.5.3",
+ "pify": "^4.0.1",
+ "schema-utils": "^2.6.5"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ }
+ }
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "babelify": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz",
+ "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==",
+ "dev": true
+ },
+ "backo2": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+ "dev": true
+ },
+ "bail": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+ "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+ "dev": true
+ },
+ "base64-js": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+ "dev": true
+ },
+ "base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "dev": true
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "better-assert": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+ "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+ "dev": true,
+ "requires": {
+ "callsite": "1.0.0"
+ }
+ },
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "blob": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+ "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "bn.js": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
+ "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==",
+ "dev": true
+ },
+ "body": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
+ "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=",
+ "dev": true,
+ "requires": {
+ "continuable-cache": "^0.3.1",
+ "error": "^7.0.0",
+ "raw-body": "~1.1.0",
+ "safe-json-parse": "~1.0.1"
+ }
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ }
+ }
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "dev": true,
+ "requires": {
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
+ },
+ "dependencies": {
+ "array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+ "dev": true
+ }
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
+ },
+ "browser-resolve": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+ "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "browserify-sign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
+ "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.2",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "~1.0.5"
+ }
+ },
+ "browserslist": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
+ "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001043",
+ "electron-to-chromium": "^1.3.413",
+ "node-releases": "^1.1.53",
+ "pkg-up": "^2.0.0"
+ }
+ },
+ "buffer": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+ "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "buffer-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+ "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+ "dev": true
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=",
+ "dev": true
+ },
+ "cacache": {
+ "version": "15.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.4.tgz",
+ "integrity": "sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw==",
+ "dev": true,
+ "requires": {
+ "@npmcli/move-file": "^1.0.1",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "glob": "^7.1.4",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^5.1.1",
+ "minipass": "^3.1.1",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.2",
+ "mkdirp": "^1.0.3",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^8.0.0",
+ "tar": "^6.0.2",
+ "unique-filename": "^1.1.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "cached-path-relative": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz",
+ "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==",
+ "dev": true
+ },
+ "callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001077",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001077.tgz",
+ "integrity": "sha512-AEzsGvjBJL0lby/87W96PyEvwN0GsYvk5LHsglLg9tW37K4BqvAvoSCdWIE13OZQ8afupqZ73+oL/1LkedN8hA==",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "catharsis": {
+ "version": "0.8.11",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz",
+ "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "ccount": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz",
+ "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "dev": true
+ },
+ "character-entities-html4": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz",
+ "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==",
+ "dev": true
+ },
+ "character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "dev": true
+ },
+ "character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "dev": true
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ },
+ "dependencies": {
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ }
+ }
+ },
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
+ "chrome-trace-event": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+ "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+ "dev": true
+ },
+ "cloneable-readable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz",
+ "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^1.0.6",
+ "through2": "^2.0.1"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "collapse-white-space": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
+ "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
+ "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.1"
+ }
+ },
+ "color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+ "dev": true
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "component-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+ "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
+ "component-inherit": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+ "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+ "dev": true
+ },
+ "compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "requires": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "dev": true
+ }
+ }
+ },
+ "compression": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+ "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.5",
+ "bytes": "3.0.0",
+ "compressible": "~2.0.16",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.1.2",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+ "dev": true
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "continuable-cache": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
+ "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz",
+ "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=",
+ "dev": true
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+ "dev": true
+ },
+ "copy-concurrently": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1",
+ "fs-write-stream-atomic": "^1.0.8",
+ "iferr": "^0.1.5",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.0"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ },
+ "core-js-compat": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz",
+ "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.8.5",
+ "semver": "7.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true
+ }
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "create-ecdh": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "css-loader": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz",
+ "integrity": "sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "cssesc": "^3.0.0",
+ "icss-utils": "^4.1.1",
+ "loader-utils": "^1.2.3",
+ "normalize-path": "^3.0.0",
+ "postcss": "^7.0.27",
+ "postcss-modules-extract-imports": "^2.0.0",
+ "postcss-modules-local-by-default": "^3.0.2",
+ "postcss-modules-scope": "^2.2.0",
+ "postcss-modules-values": "^3.0.0",
+ "postcss-value-parser": "^4.0.3",
+ "schema-utils": "^2.6.6",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true
+ },
+ "custom-event": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+ "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+ "dev": true
+ },
+ "cyclist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "date-format": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
+ "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
+ "dev": true
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+ "dev": true
+ },
+ "de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+ "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "dev": true,
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "default-gateway": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
+ "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "ip-regex": "^2.1.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "dev": true
+ },
+ "del": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+ "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "globby": "^6.1.0",
+ "is-path-cwd": "^2.0.0",
+ "is-path-in-cwd": "^2.0.0",
+ "p-map": "^2.0.0",
+ "pify": "^4.0.1",
+ "rimraf": "^2.6.3"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "des.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+ "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
+ },
+ "detab": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.3.tgz",
+ "integrity": "sha512-Up8P0clUVwq0FnFjDclzZsy9PadzRn5FFxrr47tQQvMHqyiFYVbpH8oXDzWtF0Q7pYy3l+RPmtBl+BsFF6wH0A==",
+ "dev": true,
+ "requires": {
+ "repeat-string": "^1.5.4"
+ }
+ },
+ "detect-node": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+ "dev": true
+ },
+ "detective": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz",
+ "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.2.1",
+ "defined": "^1.0.0"
+ }
+ },
+ "di": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+ "dev": true
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "dev": true,
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "dev": true,
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "doctrine-temporary-fork": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine-temporary-fork/-/doctrine-temporary-fork-2.1.0.tgz",
+ "integrity": "sha512-nliqOv5NkE4zMON4UA6AMJE6As35afs8aYXATpU4pTUdIKiARZwrJVEP1boA3Rx1ZXHVkwxkhcq4VkqvsuRLsA==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "documentation": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/documentation/-/documentation-13.0.1.tgz",
+ "integrity": "sha512-lFNDhc287R0W9k+tlmDyE9+L9x1HOePLJm6zv2tqiEzoin6yPURJz6GSYhL0KMMB7HPCi1brdxwYWXiuHrvBdA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.9.0",
+ "@babel/generator": "^7.9.4",
+ "@babel/parser": "7.10.2",
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
+ "@babel/plugin-proposal-decorators": "^7.8.3",
+ "@babel/plugin-proposal-do-expressions": "^7.8.3",
+ "@babel/plugin-proposal-export-default-from": "^7.8.3",
+ "@babel/plugin-proposal-export-namespace-from": "^7.8.3",
+ "@babel/plugin-proposal-function-bind": "^7.8.3",
+ "@babel/plugin-proposal-function-sent": "^7.8.3",
+ "@babel/plugin-proposal-json-strings": "^7.8.3",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-proposal-numeric-separator": "^7.8.3",
+ "@babel/plugin-proposal-optional-chaining": "^7.9.0",
+ "@babel/plugin-proposal-pipeline-operator": "^7.8.3",
+ "@babel/plugin-proposal-private-methods": "^7.8.3",
+ "@babel/plugin-proposal-throw-expressions": "^7.8.3",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/preset-env": "^7.9.0",
+ "@babel/preset-flow": "^7.9.0",
+ "@babel/preset-react": "^7.9.4",
+ "@babel/preset-stage-0": "^7.8.3",
+ "@babel/traverse": "^7.9.0",
+ "@babel/types": "^7.9.0",
+ "ansi-html": "^0.0.7",
+ "babelify": "^10.0.0",
+ "chalk": "^2.3.0",
+ "chokidar": "^3.4.0",
+ "concat-stream": "^1.6.0",
+ "diff": "^4.0.1",
+ "doctrine-temporary-fork": "2.1.0",
+ "get-port": "^5.0.0",
+ "git-url-parse": "^11.1.2",
+ "github-slugger": "1.2.0",
+ "glob": "^7.1.2",
+ "globals-docs": "^2.4.0",
+ "highlight.js": "^9.15.5",
+ "ini": "^1.3.5",
+ "js-yaml": "^3.10.0",
+ "lodash": "^4.17.10",
+ "mdast-util-inject": "^1.1.0",
+ "micromatch": "^3.1.5",
+ "mime": "^2.2.0",
+ "module-deps-sortable": "5.0.0",
+ "parse-filepath": "^1.0.2",
+ "pify": "^5.0.0",
+ "read-pkg-up": "^4.0.0",
+ "remark": "^9.0.0",
+ "remark-html": "^8.0.0",
+ "remark-reference-links": "^4.0.1",
+ "remark-toc": "^5.0.0",
+ "resolve": "^1.8.1",
+ "stream-array": "^1.1.2",
+ "strip-json-comments": "^2.0.1",
+ "tiny-lr": "^1.1.0",
+ "unist-builder": "^1.0.2",
+ "unist-util-visit": "^1.3.0",
+ "vfile": "^4.0.0",
+ "vfile-reporter": "^6.0.0",
+ "vfile-sort": "^2.1.0",
+ "vinyl": "^2.1.0",
+ "vinyl-fs": "^3.0.2",
+ "vue-template-compiler": "^2.5.16",
+ "yargs": "^12.0.2"
+ },
+ "dependencies": {
+ "@babel/parser": {
+ "version": "7.10.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
+ "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chokidar": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+ "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.4.0"
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "pify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz",
+ "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+ "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "vinyl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ }
+ }
+ }
+ },
+ "dom-serialize": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+ "dev": true,
+ "requires": {
+ "custom-event": "~1.0.0",
+ "ent": "~2.2.0",
+ "extend": "^3.0.0",
+ "void-elements": "^2.0.0"
+ }
+ },
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
+ "duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ },
+ "dependencies": {
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ }
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "~0.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.3.459",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.459.tgz",
+ "integrity": "sha512-aN3Z89qEYIwVjzGi9SrcTjjopRZ3STUA6xTufS0fxZy8xOO2iqVw8rYKdT32CHgOKHOYj5KGmz3n6xUKE4QJiQ==",
+ "dev": true
+ },
+ "elliptic": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
+ "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "emoji-regex": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz",
+ "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "engine.io": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.1.tgz",
+ "integrity": "sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "0.3.1",
+ "debug": "~4.1.0",
+ "engine.io-parser": "~2.2.0",
+ "ws": "^7.1.2"
+ },
+ "dependencies": {
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "engine.io-client": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.2.tgz",
+ "integrity": "sha512-AWjc1Xg06a6UPFOBAzJf48W1UR/qKYmv/ubgSCumo9GXgvL/xGIvo05dXoBL+2NTLMipDI7in8xK61C17L25xg==",
+ "dev": true,
+ "requires": {
+ "component-emitter": "~1.3.0",
+ "component-inherit": "0.0.3",
+ "debug": "~4.1.0",
+ "engine.io-parser": "~2.2.0",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "ws": "~6.1.0",
+ "xmlhttprequest-ssl": "~1.5.4",
+ "yeast": "0.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "ws": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
+ "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
+ "engine.io-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
+ "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
+ "dev": true,
+ "requires": {
+ "after": "0.8.2",
+ "arraybuffer.slice": "~0.0.7",
+ "base64-arraybuffer": "0.1.5",
+ "blob": "0.0.5",
+ "has-binary2": "~1.0.2"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
+ "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.5.0",
+ "tapable": "^1.0.0"
+ },
+ "dependencies": {
+ "memory-fs": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+ "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ }
+ }
+ }
+ },
+ "ent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+ "dev": true
+ },
+ "entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.2.tgz",
+ "integrity": "sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw==",
+ "dev": true
+ },
+ "errno": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+ "dev": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
+ "error": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
+ "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
+ "dev": true,
+ "requires": {
+ "string-template": "~0.2.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.17.5",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
+ "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.1.5",
+ "is-regex": "^1.0.5",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimleft": "^2.1.1",
+ "string.prototype.trimright": "^2.1.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es6-promise": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
+ "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=",
+ "dev": true
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.1.0.tgz",
+ "integrity": "sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^2.0.0",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^7.0.0",
+ "esquery": "^1.2.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "progress": "^2.0.0",
+ "regexpp": "^3.1.0",
+ "semver": "^7.2.1",
+ "strip-ansi": "^6.0.0",
+ "strip-json-comments": "^3.1.0",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
+ "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
+ "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "eslint-scope": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+ "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
+ "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
+ "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "dev": true
+ },
+ "espree": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz",
+ "integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+ "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+ "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
+ "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ },
+ "dependencies": {
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "requires": {
+ "es5-ext": "^0.10.9"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.24",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
+ "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=",
+ "requires": {
+ "es6-iterator": "2",
+ "es6-symbol": "~3.1"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
+ "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.14",
+ "es6-symbol": "^3.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ }
+ }
+ },
+ "eventemitter3": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+ "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+ "dev": true
+ },
+ "events": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
+ "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
+ "dev": true
+ },
+ "eventsource": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+ "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+ "dev": true,
+ "requires": {
+ "original": "^1.0.0"
+ }
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "extract-zip": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz",
+ "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.5.0",
+ "debug": "0.7.4",
+ "mkdirp": "0.5.0",
+ "yauzl": "2.4.1"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz",
+ "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "~2.0.0",
+ "typedarray": "~0.0.5"
+ }
+ },
+ "debug": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz",
+ "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=",
+ "dev": true
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "readable-stream": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
+ "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "faye-websocket": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "figgy-pudding": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+ "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+ "dev": true
+ },
+ "figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "dev": true,
+ "optional": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ },
+ "dependencies": {
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "find-cache-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^2.0.0",
+ "pkg-dir": "^3.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "flat": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
+ "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "~2.0.3"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true
+ }
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ }
+ },
+ "flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+ "dev": true
+ },
+ "flush-write-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
+ },
+ "dependencies": {
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "follow-redirects": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz",
+ "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "fs-mkdirp-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+ "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "through2": "^2.0.3"
+ }
+ },
+ "fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+ "dev": true
+ },
+ "fs-write-stream-atomic": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "iferr": "^0.1.5",
+ "imurmurhash": "^0.1.4",
+ "readable-stream": "1 || 2"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.0"
+ }
+ },
+ "gensync": {
+ "version": "1.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+ "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "get-port": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz",
+ "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "git-up": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz",
+ "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==",
+ "dev": true,
+ "requires": {
+ "is-ssh": "^1.3.0",
+ "parse-url": "^5.0.0"
+ }
+ },
+ "git-url-parse": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.1.2.tgz",
+ "integrity": "sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==",
+ "dev": true,
+ "requires": {
+ "git-up": "^4.0.0"
+ }
+ },
+ "github-slugger": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.0.tgz",
+ "integrity": "sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": ">=6.0.0 <=6.1.1"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "glob-stream": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+ "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "glob": "^7.1.1",
+ "glob-parent": "^3.1.0",
+ "is-negated-glob": "^1.0.0",
+ "ordered-read-streams": "^1.0.0",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.1.5",
+ "remove-trailing-separator": "^1.0.1",
+ "to-absolute-glob": "^2.0.0",
+ "unique-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "globals": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "globals-docs": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/globals-docs/-/globals-docs-2.4.1.tgz",
+ "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==",
+ "dev": true
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "commander": "^2.9.0",
+ "is-my-json-valid": "^2.12.4",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-binary2": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+ "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+ "dev": true,
+ "requires": {
+ "isarray": "2.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+ "dev": true
+ }
+ }
+ },
+ "has-cors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "^1.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "hast-util-is-element": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.4.tgz",
+ "integrity": "sha512-NFR6ljJRvDcyPP5SbV7MyPBgF47X3BsskLnmw1U34yL+X6YC0MoBx9EyMg8Jtx4FzGH95jw8+c1VPLHaRA0wDQ==",
+ "dev": true
+ },
+ "hast-util-sanitize": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz",
+ "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==",
+ "dev": true,
+ "requires": {
+ "xtend": "^4.0.1"
+ }
+ },
+ "hast-util-to-html": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-4.0.1.tgz",
+ "integrity": "sha512-2emzwyf0xEsc4TBIPmDJmBttIw8R4SXAJiJZoiRR/s47ODYWgOqNoDbf2SJAbMbfNdFWMiCSOrI3OVnX6Qq2Mg==",
+ "dev": true,
+ "requires": {
+ "ccount": "^1.0.0",
+ "comma-separated-tokens": "^1.0.1",
+ "hast-util-is-element": "^1.0.0",
+ "hast-util-whitespace": "^1.0.0",
+ "html-void-elements": "^1.0.0",
+ "property-information": "^4.0.0",
+ "space-separated-tokens": "^1.0.0",
+ "stringify-entities": "^1.0.1",
+ "unist-util-is": "^2.0.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "unist-util-is": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz",
+ "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==",
+ "dev": true
+ }
+ }
+ },
+ "hast-util-whitespace": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz",
+ "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==",
+ "dev": true
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x",
+ "cryptiles": "2.x.x",
+ "hoek": "2.x.x",
+ "sntp": "1.x.x"
+ }
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
+ },
+ "highlight.js": {
+ "version": "9.18.1",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz",
+ "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==",
+ "dev": true
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+ "dev": true
+ },
+ "hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "html-entities": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
+ "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
+ "dev": true
+ },
+ "html-void-elements": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz",
+ "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==",
+ "dev": true
+ },
+ "http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ }
+ }
+ },
+ "http-parser-js": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz",
+ "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==",
+ "dev": true
+ },
+ "http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "http-proxy-middleware": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+ "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+ "dev": true,
+ "requires": {
+ "http-proxy": "^1.17.0",
+ "is-glob": "^4.0.0",
+ "lodash": "^4.17.11",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "icss-utils": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
+ "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ }
+ },
+ "ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+ "dev": true
+ },
+ "iferr": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
+ },
+ "import-fresh": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+ "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "import-local": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+ "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^3.0.0",
+ "resolve-cwd": "^2.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+ "dev": true
+ },
+ "infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
+ "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^3.0.0",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.15",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.4.0",
+ "rxjs": "^6.5.3",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "internal-ip": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
+ "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+ "dev": true,
+ "requires": {
+ "default-gateway": "^4.2.0",
+ "ipaddr.js": "^1.9.0"
+ },
+ "dependencies": {
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true
+ }
+ }
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "invert-kv": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+ "dev": true
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+ "dev": true
+ },
+ "ip-regex": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+ "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-absolute-url": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
+ "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "dev": true
+ },
+ "is-alphanumeric": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz",
+ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=",
+ "dev": true
+ },
+ "is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "dev": true,
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
+ "is-arguments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+ "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+ "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true
+ },
+ "is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
+ "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=",
+ "dev": true,
+ "requires": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "jsonpointer": "^4.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+ "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "^2.1.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+ "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "^1.0.2"
+ }
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+ "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-ssh": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz",
+ "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==",
+ "dev": true,
+ "requires": {
+ "protocols": "^1.1.0"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+ "dev": true
+ },
+ "is-whitespace-character": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz",
+ "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-word-character": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz",
+ "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isbinaryfile": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz",
+ "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz",
+ "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+ "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "js2xmlparser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
+ "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "dev": true,
+ "requires": {
+ "xmlcreate": "^2.0.3"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "jsdoc": {
+ "version": "3.6.4",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.4.tgz",
+ "integrity": "sha512-3G9d37VHv7MFdheviDCjUfQoIjdv4TC5zTTf5G9VODLtOnVS6La1eoYBDlbWfsRT3/Xo+j2MIqki2EV12BZfwA==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.9.4",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.8.11",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.1",
+ "klaw": "^3.0.0",
+ "markdown-it": "^10.0.0",
+ "markdown-it-anchor": "^5.2.7",
+ "marked": "^0.8.2",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "taffydb": "2.6.2",
+ "underscore": "~1.10.2"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
+ "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
+ "dev": true
+ },
+ "underscore": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
+ "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==",
+ "dev": true
+ }
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "json3": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
+ "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
+ "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
+ "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.0.2",
+ "json-schema": "0.2.3",
+ "verror": "1.3.6"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "jszip": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz",
+ "integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==",
+ "requires": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "set-immediate-shim": "~1.0.1"
+ },
+ "dependencies": {
+ "lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "requires": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "karma": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/karma/-/karma-5.0.9.tgz",
+ "integrity": "sha512-dUA5z7Lo7G4FRSe1ZAXqOINEEWxmCjDBbfRBmU/wYlSMwxUQJP/tEEP90yJt3Uqo03s9rCgVnxtlfq+uDhxSPg==",
+ "dev": true,
+ "requires": {
+ "body-parser": "^1.19.0",
+ "braces": "^3.0.2",
+ "chokidar": "^3.0.0",
+ "colors": "^1.4.0",
+ "connect": "^3.7.0",
+ "di": "^0.0.1",
+ "dom-serialize": "^2.2.1",
+ "flatted": "^2.0.2",
+ "glob": "^7.1.6",
+ "graceful-fs": "^4.2.4",
+ "http-proxy": "^1.18.1",
+ "isbinaryfile": "^4.0.6",
+ "lodash": "^4.17.15",
+ "log4js": "^6.2.1",
+ "mime": "^2.4.5",
+ "minimatch": "^3.0.4",
+ "qjobs": "^1.2.0",
+ "range-parser": "^1.2.1",
+ "rimraf": "^3.0.2",
+ "socket.io": "^2.3.0",
+ "source-map": "^0.6.1",
+ "tmp": "0.2.1",
+ "ua-parser-js": "0.7.21",
+ "yargs": "^15.3.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+ "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.4.0"
+ }
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+ "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "yargs": {
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
+ "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+ "dev": true,
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "karma-chrome-launcher": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
+ "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==",
+ "dev": true,
+ "requires": {
+ "which": "^1.2.1"
+ }
+ },
+ "karma-mocha": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz",
+ "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.3"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
+ "karma-mocha-reporter": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz",
+ "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.1.0",
+ "log-symbols": "^2.1.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "karma-phantomjs-launcher": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz",
+ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.0.1",
+ "phantomjs-prebuilt": "^2.1.7"
+ }
+ },
+ "karma-sourcemap-loader": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz",
+ "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2"
+ }
+ },
+ "karma-webpack": {
+ "version": "5.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0-alpha.6.tgz",
+ "integrity": "sha512-XgU3sHtXgRAnteMw0UNGjixzmOxxDv/Z7SwSS4D6jyaeNIDMZSMbwjfqikTej3md4nFZ9v117pjgzKpQwflxyw==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3",
+ "minimatch": "^3.0.4",
+ "webpack-merge": "^4.1.5"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "killable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+ "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "lazystream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.5"
+ }
+ },
+ "lcid": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^2.0.0"
+ }
+ },
+ "lead": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+ "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+ "dev": true,
+ "requires": {
+ "flush-write-stream": "^1.0.2"
+ }
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "levenary": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz",
+ "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==",
+ "dev": true,
+ "requires": {
+ "leven": "^3.1.0"
+ }
+ },
+ "levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ }
+ },
+ "lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
+ "requires": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "livereload-js": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
+ "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "loader-runner": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+ "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ }
+ }
+ },
+ "localforage": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
+ "integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
+ "requires": {
+ "lie": "3.1.1"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ },
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ }
+ }
+ },
+ "log4js": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.2.1.tgz",
+ "integrity": "sha512-7n+Oqxxz7VcQJhIlqhcYZBTpbcQ7XsR0MUIfJkx/n3VUjkAS4iUr+4UJlhxf28RvP9PMGQXbgTUhLApnu0XXgA==",
+ "dev": true,
+ "requires": {
+ "date-format": "^3.0.0",
+ "debug": "^4.1.1",
+ "flatted": "^2.0.1",
+ "rfdc": "^1.1.4",
+ "streamroller": "^2.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "loglevel": {
+ "version": "1.6.8",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
+ "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==",
+ "dev": true
+ },
+ "longest-streak": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz",
+ "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "map-age-cleaner": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+ "dev": true,
+ "requires": {
+ "p-defer": "^1.0.0"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "markdown-escapes": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz",
+ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==",
+ "dev": true
+ },
+ "markdown-it": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
+ "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~2.0.0",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ }
+ },
+ "markdown-it-anchor": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
+ "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "dev": true
+ },
+ "markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
+ "dev": true
+ },
+ "marked": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz",
+ "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==",
+ "dev": true
+ },
+ "marks-pane": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.9.tgz",
+ "integrity": "sha512-Ahs4oeG90tbdPWwAJkAAoHg2lRR8lAs9mZXETNPO9hYg3AkjUJBKi1NQ4aaIQZVGrig7c/3NUV1jANl8rFTeMg=="
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "mdast-util-compact": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz",
+ "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "mdast-util-definitions": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz",
+ "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.0.0"
+ }
+ },
+ "mdast-util-inject": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz",
+ "integrity": "sha1-2wa4tYW+lZotzS+H9HK6m3VvNnU=",
+ "dev": true,
+ "requires": {
+ "mdast-util-to-string": "^1.0.0"
+ }
+ },
+ "mdast-util-to-hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.4.tgz",
+ "integrity": "sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==",
+ "dev": true,
+ "requires": {
+ "collapse-white-space": "^1.0.0",
+ "detab": "^2.0.0",
+ "mdast-util-definitions": "^1.2.0",
+ "mdurl": "^1.0.1",
+ "trim": "0.0.1",
+ "trim-lines": "^1.0.0",
+ "unist-builder": "^1.0.1",
+ "unist-util-generated": "^1.1.0",
+ "unist-util-position": "^3.0.0",
+ "unist-util-visit": "^1.1.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "mdast-util-to-string": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz",
+ "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==",
+ "dev": true
+ },
+ "mdast-util-toc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz",
+ "integrity": "sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==",
+ "dev": true,
+ "requires": {
+ "github-slugger": "^1.2.1",
+ "mdast-util-to-string": "^1.0.5",
+ "unist-util-is": "^2.1.2",
+ "unist-util-visit": "^1.1.0"
+ },
+ "dependencies": {
+ "github-slugger": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz",
+ "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": ">=6.0.0 <=6.1.1"
+ }
+ },
+ "unist-util-is": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz",
+ "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==",
+ "dev": true
+ }
+ }
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
+ },
+ "mem": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+ "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.1",
+ "mimic-fn": "^2.0.0",
+ "p-is-promise": "^2.0.0"
+ }
+ },
+ "memory-fs": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "mime": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
+ "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
+ "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.15",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
+ "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
+ "dev": true,
+ "requires": {
+ "mime-db": "~1.27.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "minipass": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-pipeline": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz",
+ "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
+ "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mississippi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+ "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.5.0",
+ "duplexify": "^3.4.2",
+ "end-of-stream": "^1.1.0",
+ "flush-write-stream": "^1.0.0",
+ "from2": "^2.1.0",
+ "parallel-transform": "^1.1.0",
+ "pump": "^3.0.0",
+ "pumpify": "^1.3.3",
+ "stream-each": "^1.1.0",
+ "through2": "^2.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
+ }
+ },
+ "mocha": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
+ "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "3.2.3",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.3.0",
+ "debug": "3.2.6",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "find-up": "3.0.0",
+ "glob": "7.1.3",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "3.13.1",
+ "log-symbols": "3.0.0",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.5",
+ "ms": "2.1.1",
+ "node-environment-flags": "1.0.6",
+ "object.assign": "4.1.0",
+ "strip-json-comments": "2.0.1",
+ "supports-color": "6.0.0",
+ "which": "1.3.1",
+ "wide-align": "1.1.3",
+ "yargs": "13.3.2",
+ "yargs-parser": "13.1.2",
+ "yargs-unparser": "1.6.0"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "chokidar": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+ "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.1",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.2.0"
+ }
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
+ "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.0.4"
+ }
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+ "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ }
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "mocha-loader": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/mocha-loader/-/mocha-loader-5.0.0.tgz",
+ "integrity": "sha512-8aWeTPZ/cSHxgK+M/WhXqeda00AT5bQeq9F63IKSHnKPmUjUU/oF/wKwTaKyxwacM471HQwipBBAhhtq84TWZg==",
+ "dev": true,
+ "requires": {
+ "css-loader": "^3.4.2",
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^2.6.5",
+ "style-loader": "^1.1.3"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ }
+ }
+ },
+ "module-deps-sortable": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/module-deps-sortable/-/module-deps-sortable-5.0.0.tgz",
+ "integrity": "sha512-bnGGeghQmz/t/6771/KC4FmxpVm126iR6AAzzq4N6hVZQVl4+ZZBv+VF3PJmDyxXtVtgcgTSSP7NL+jq1QAHrg==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "browser-resolve": "^1.7.0",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "~1.5.0",
+ "defined": "^1.0.0",
+ "detective": "^4.0.0",
+ "duplexer2": "^0.1.2",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.3",
+ "stream-combiner2": "^1.1.1",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
+ "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "~2.0.0",
+ "typedarray": "~0.0.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ }
+ }
+ }
+ },
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "move-concurrently": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1",
+ "copy-concurrently": "^1.0.0",
+ "fs-write-stream-atomic": "^1.0.8",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.3"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "dev": true,
+ "requires": {
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
+ "dev": true,
+ "optional": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "dev": true,
+ "requires": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ }
+ },
+ "node-forge": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
+ "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
+ "dev": true
+ },
+ "node-libs-browser": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+ "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+ "dev": true,
+ "requires": {
+ "assert": "^1.1.1",
+ "browserify-zlib": "^0.2.0",
+ "buffer": "^4.3.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "^1.0.0",
+ "crypto-browserify": "^3.11.0",
+ "domain-browser": "^1.1.1",
+ "events": "^3.0.0",
+ "https-browserify": "^1.0.0",
+ "os-browserify": "^0.3.0",
+ "path-browserify": "0.0.1",
+ "process": "^0.11.10",
+ "punycode": "^1.2.4",
+ "querystring-es3": "^0.2.0",
+ "readable-stream": "^2.3.3",
+ "stream-browserify": "^2.0.1",
+ "stream-http": "^2.7.2",
+ "string_decoder": "^1.0.0",
+ "timers-browserify": "^2.0.4",
+ "tty-browserify": "0.0.0",
+ "url": "^0.11.0",
+ "util": "^0.11.0",
+ "vm-browserify": "^1.0.1"
+ },
+ "dependencies": {
+ "stream-browserify": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+ "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ }
+ }
+ },
+ "node-releases": {
+ "version": "1.1.58",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz",
+ "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "dependencies": {
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ },
+ "normalize-url": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+ "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+ "dev": true
+ },
+ "now-and-later": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.2"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-component": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+ "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+ "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+ "dev": true
+ },
+ "object-is": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+ "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+ "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+ "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "opn": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+ "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "requires": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ }
+ },
+ "ordered-read-streams": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+ "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "original": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
+ "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+ "dev": true,
+ "requires": {
+ "url-parse": "^1.4.3"
+ }
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "lcid": "^2.0.0",
+ "mem": "^4.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-defer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+ "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+ "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ },
+ "p-retry": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
+ "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
+ "dev": true,
+ "requires": {
+ "retry": "^0.12.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "pako": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
+ },
+ "parallel-transform": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+ "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+ "dev": true,
+ "requires": {
+ "cyclist": "^1.0.1",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.1.5"
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+ "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "parse-entities": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
+ "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
+ "dev": true,
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
+ "parse-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz",
+ "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==",
+ "dev": true,
+ "requires": {
+ "is-ssh": "^1.3.0",
+ "protocols": "^1.4.0"
+ }
+ },
+ "parse-url": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz",
+ "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==",
+ "dev": true,
+ "requires": {
+ "is-ssh": "^1.3.0",
+ "normalize-url": "^3.3.0",
+ "parse-path": "^4.0.0",
+ "protocols": "^1.4.0"
+ }
+ },
+ "parseqs": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+ "dev": true,
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseuri": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+ "dev": true,
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "path-webpack": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/path-webpack/-/path-webpack-0.0.3.tgz",
+ "integrity": "sha1-/23sdJ7sWpRgXATV9j/FVgegOhY="
+ },
+ "pbkdf2": {
+ "version": "3.0.17",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.14",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz",
+ "integrity": "sha1-1T0xH8+30dCN2yQBRVjxGIxRbaA=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "~4.0.3",
+ "extract-zip": "~1.5.0",
+ "fs-extra": "~1.0.0",
+ "hasha": "~2.2.0",
+ "kew": "~0.7.0",
+ "progress": "~1.1.8",
+ "request": "~2.79.0",
+ "request-progress": "~2.0.1",
+ "which": "~1.2.10"
+ }
+ },
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ }
+ }
+ },
+ "pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
+ "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.1.0"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.30",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.30.tgz",
+ "integrity": "sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-modules-extract-imports": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+ "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.5"
+ }
+ },
+ "postcss-modules-local-by-default": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz",
+ "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^4.1.1",
+ "postcss": "^7.0.16",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.0.0"
+ }
+ },
+ "postcss-modules-scope": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
+ "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.6",
+ "postcss-selector-parser": "^6.0.0"
+ }
+ },
+ "postcss-modules-values": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
+ "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^4.0.0",
+ "postcss": "^7.0.6"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
+ "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^3.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+ "dev": true
+ },
+ "property-information": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-4.2.0.tgz",
+ "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==",
+ "dev": true,
+ "requires": {
+ "xtend": "^4.0.1"
+ }
+ },
+ "protocols": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz",
+ "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==",
+ "dev": true
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+ "dev": true
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
+ }
+ },
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ },
+ "dependencies": {
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ }
+ }
+ },
+ "pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "dev": true,
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qjobs": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+ "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.9.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
+ "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
+ "dev": true
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
+ "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=",
+ "dev": true,
+ "requires": {
+ "bytes": "1",
+ "string_decoder": "0.10"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "raw-loader": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.1.tgz",
+ "integrity": "sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^2.6.5"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ }
+ }
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
+ "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0",
+ "read-pkg": "^3.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.0.3",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+ "dev": true
+ },
+ "regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+ "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==",
+ "dev": true
+ },
+ "regenerator-transform": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz",
+ "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.8.4",
+ "private": "^0.1.8"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regexp.prototype.flags": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+ "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz",
+ "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.2.0"
+ }
+ },
+ "regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+ "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ }
+ }
+ },
+ "remark": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz",
+ "integrity": "sha512-amw8rGdD5lHbMEakiEsllmkdBP+/KpjW/PRK6NSGPZKCQowh0BT4IWXDAkRMyG3SB9dKPXWMviFjNusXzXNn3A==",
+ "dev": true,
+ "requires": {
+ "remark-parse": "^5.0.0",
+ "remark-stringify": "^5.0.0",
+ "unified": "^6.0.0"
+ }
+ },
+ "remark-html": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-8.0.0.tgz",
+ "integrity": "sha512-3V2391GL3hxKhrkzYOyfPpxJ6taIKLCfuLVqumeWQOk3H9nTtSQ8St8kMYkBVIEAquXN1chT83qJ/2lAW+dpEg==",
+ "dev": true,
+ "requires": {
+ "hast-util-sanitize": "^1.0.0",
+ "hast-util-to-html": "^4.0.0",
+ "mdast-util-to-hast": "^3.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "remark-parse": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz",
+ "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==",
+ "dev": true,
+ "requires": {
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^1.1.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^1.0.0",
+ "vfile-location": "^2.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "remark-reference-links": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/remark-reference-links/-/remark-reference-links-4.0.4.tgz",
+ "integrity": "sha512-+2X8hwSQqxG4tvjYZNrTcEC+bXp8shQvwRGG6J/rnFTvBoU4G0BBviZoqKGZizLh/DG+0gSYhiDDWCqyxXW1iQ==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.0.0"
+ }
+ },
+ "remark-slug": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz",
+ "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==",
+ "dev": true,
+ "requires": {
+ "github-slugger": "^1.0.0",
+ "mdast-util-to-string": "^1.0.0",
+ "unist-util-visit": "^1.0.0"
+ }
+ },
+ "remark-stringify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-5.0.0.tgz",
+ "integrity": "sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==",
+ "dev": true,
+ "requires": {
+ "ccount": "^1.0.0",
+ "is-alphanumeric": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "longest-streak": "^2.0.1",
+ "markdown-escapes": "^1.0.0",
+ "markdown-table": "^1.1.0",
+ "mdast-util-compact": "^1.0.0",
+ "parse-entities": "^1.0.2",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "stringify-entities": "^1.0.1",
+ "unherit": "^1.0.4",
+ "xtend": "^4.0.1"
+ }
+ },
+ "remark-toc": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-5.1.1.tgz",
+ "integrity": "sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow==",
+ "dev": true,
+ "requires": {
+ "mdast-util-toc": "^3.0.0",
+ "remark-slug": "^5.0.0"
+ }
+ },
+ "remove-bom-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+ "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5",
+ "is-utf8": "^0.2.1"
+ }
+ },
+ "remove-bom-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+ "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+ "dev": true,
+ "requires": {
+ "remove-bom-buffer": "^3.0.0",
+ "safe-buffer": "^5.1.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz",
+ "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "caseless": "~0.11.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.1.1",
+ "har-validator": "~2.0.6",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "oauth-sign": "~0.8.1",
+ "qs": "~6.3.0",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "~0.4.1",
+ "uuid": "^3.0.0"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+ "dev": true
+ }
+ }
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
+ },
+ "requizzle": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
+ "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "resolve": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz",
+ "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "resolve-options": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+ "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+ "dev": true,
+ "requires": {
+ "value-or-function": "^3.0.0"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+ "dev": true
+ },
+ "rfdc": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz",
+ "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "run-queue": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1"
+ }
+ },
+ "rxjs": {
+ "version": "6.5.5",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
+ "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "safe-json-parse": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
+ "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "2.6.6",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz",
+ "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.0",
+ "ajv-keywords": "^3.4.1"
+ }
+ },
+ "select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+ "dev": true
+ },
+ "selfsigned": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
+ "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
+ "dev": true,
+ "requires": {
+ "node-forge": "0.9.0"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "serialize-javascript": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+ "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.44.0"
+ }
+ }
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "socket.io": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
+ "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
+ "dev": true,
+ "requires": {
+ "debug": "~4.1.0",
+ "engine.io": "~3.4.0",
+ "has-binary2": "~1.0.2",
+ "socket.io-adapter": "~1.1.0",
+ "socket.io-client": "2.3.0",
+ "socket.io-parser": "~3.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-adapter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
+ "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==",
+ "dev": true
+ },
+ "socket.io-client": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
+ "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
+ "dev": true,
+ "requires": {
+ "backo2": "1.0.2",
+ "base64-arraybuffer": "0.1.5",
+ "component-bind": "1.0.0",
+ "component-emitter": "1.2.1",
+ "debug": "~4.1.0",
+ "engine.io-client": "~3.4.0",
+ "has-binary2": "~1.0.2",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "object-component": "0.0.3",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "socket.io-parser": "~3.3.0",
+ "to-array": "0.1.4"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "isarray": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "socket.io-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
+ "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.2.1",
+ "debug": "~3.1.0",
+ "isarray": "2.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "socket.io-parser": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
+ "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.2.1",
+ "debug": "~4.1.0",
+ "isarray": "2.0.1"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "isarray": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "sockjs": {
+ "version": "0.3.20",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz",
+ "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "^0.10.0",
+ "uuid": "^3.4.0",
+ "websocket-driver": "0.6.5"
+ },
+ "dependencies": {
+ "websocket-driver": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
+ "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
+ "dev": true,
+ "requires": {
+ "websocket-extensions": ">=0.1.1"
+ }
+ }
+ }
+ },
+ "sockjs-client": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
+ "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.5",
+ "eventsource": "^1.0.7",
+ "faye-websocket": "~0.11.1",
+ "inherits": "^2.0.3",
+ "json3": "^3.3.2",
+ "url-parse": "^1.4.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "faye-websocket": {
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
+ "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "source-list-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
+ "dev": true
+ },
+ "spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "tweetnacl": "~0.14.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "ssri": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz",
+ "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.1.1"
+ }
+ },
+ "state-toggle": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz",
+ "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
+ "stream-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/stream-array/-/stream-array-1.1.2.tgz",
+ "integrity": "sha1-nl9zRfITfDDuO0mLkRToC1K7frU=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.1.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz",
+ "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=",
+ "dev": true,
+ "requires": {
+ "buffer-shims": "^1.0.0",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+ "dev": true,
+ "requires": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ }
+ }
+ }
+ },
+ "stream-each": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+ "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "stream-http": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-shift": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+ "dev": true
+ },
+ "streamroller": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
+ "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
+ "dev": true,
+ "requires": {
+ "date-format": "^2.1.0",
+ "debug": "^4.1.1",
+ "fs-extra": "^8.1.0"
+ },
+ "dependencies": {
+ "date-format": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
+ "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "string-template": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
+ "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ }
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+ "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "string.prototype.trimleft": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
+ "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5",
+ "string.prototype.trimstart": "^1.0.0"
+ }
+ },
+ "string.prototype.trimright": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
+ "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5",
+ "string.prototype.trimend": "^1.0.0"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+ "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "stringify-entities": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz",
+ "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==",
+ "dev": true,
+ "requires": {
+ "character-entities-html4": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "style-loader": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz",
+ "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^2.6.6"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ }
+ }
+ },
+ "subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ }
+ }
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
+ "tapable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+ "dev": true
+ },
+ "tar": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz",
+ "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==",
+ "dev": true,
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.0",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "dependencies": {
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ }
+ }
+ },
+ "terser": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz",
+ "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.3.tgz",
+ "integrity": "sha512-bZFnotuIKq5Rqzrs+qIwFzGdKdffV9epG5vDSEbYzvKAhPeR5RbbrQysfPgbIIMhNAQtZD2hGwBfSKUXjXZZZw==",
+ "dev": true,
+ "requires": {
+ "cacache": "^15.0.4",
+ "find-cache-dir": "^3.3.1",
+ "jest-worker": "^26.0.0",
+ "p-limit": "^2.3.0",
+ "schema-utils": "^2.6.6",
+ "serialize-javascript": "^3.1.0",
+ "source-map": "^0.6.1",
+ "terser": "^4.6.13",
+ "webpack-sources": "^1.4.3"
+ },
+ "dependencies": {
+ "find-cache-dir": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
+ }
+ },
+ "through2-filter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+ "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+ "dev": true,
+ "requires": {
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true
+ },
+ "timers-browserify": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
+ "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
+ "dev": true,
+ "requires": {
+ "setimmediate": "^1.0.4"
+ }
+ },
+ "tiny-lr": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
+ "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
+ "dev": true,
+ "requires": {
+ "body": "^5.1.0",
+ "debug": "^3.1.0",
+ "faye-websocket": "~0.10.0",
+ "livereload-js": "^2.3.0",
+ "object-assign": "^4.1.0",
+ "qs": "^6.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "to-absolute-glob": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+ "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "is-negated-glob": "^1.0.0"
+ }
+ },
+ "to-array": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+ "dev": true
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ }
+ }
+ },
+ "to-through": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+ "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+ "dev": true,
+ "requires": {
+ "through2": "^2.0.3"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
+ "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
+ "dev": true,
+ "requires": {
+ "punycode": "^1.4.1"
+ }
+ },
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+ "dev": true
+ },
+ "trim-lines": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.3.tgz",
+ "integrity": "sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==",
+ "dev": true
+ },
+ "trim-trailing-lines": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz",
+ "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==",
+ "dev": true
+ },
+ "trough": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
+ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
+ "dev": true
+ },
+ "tsd-jsdoc": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tsd-jsdoc/-/tsd-jsdoc-2.5.0.tgz",
+ "integrity": "sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g==",
+ "dev": true,
+ "requires": {
+ "typescript": "^3.2.1"
+ }
+ },
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ },
+ "tty-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.44.0"
+ }
+ }
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "typescript": {
+ "version": "3.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz",
+ "integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==",
+ "dev": true
+ },
+ "ua-parser-js": {
+ "version": "0.7.21",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
+ "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==",
+ "dev": true
+ },
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+ "dev": true
+ },
+ "unherit": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz",
+ "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "dev": true
+ },
+ "unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dev": true,
+ "requires": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ }
+ },
+ "unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "dev": true
+ },
+ "unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "dev": true
+ },
+ "unified": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz",
+ "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==",
+ "dev": true,
+ "requires": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "trough": "^1.0.0",
+ "vfile": "^2.0.0",
+ "x-is-string": "^0.1.0"
+ },
+ "dependencies": {
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
+ },
+ "vfile": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz",
+ "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.4",
+ "replace-ext": "1.0.0",
+ "unist-util-stringify-position": "^1.0.0",
+ "vfile-message": "^1.0.0"
+ }
+ }
+ }
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "unique-filename": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+ "dev": true,
+ "requires": {
+ "unique-slug": "^2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4"
+ }
+ },
+ "unique-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+ "dev": true,
+ "requires": {
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
+ }
+ },
+ "unist-builder": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz",
+ "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.0"
+ }
+ },
+ "unist-util-generated": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz",
+ "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==",
+ "dev": true
+ },
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==",
+ "dev": true
+ },
+ "unist-util-position": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz",
+ "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==",
+ "dev": true
+ },
+ "unist-util-remove-position": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz",
+ "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz",
+ "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==",
+ "dev": true
+ },
+ "unist-util-visit": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
+ "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit-parents": "^2.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
+ "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-parse": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
+ "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+ "dev": true,
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+ "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ },
+ "v8-compile-cache": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
+ "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "value-or-function": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
+ "dev": true
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
+ "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
+ "dev": true,
+ "requires": {
+ "extsprintf": "1.0.2"
+ }
+ },
+ "vfile": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.1.tgz",
+ "integrity": "sha512-lRjkpyDGjVlBA7cDQhQ+gNcvB1BGaTHYuSOcY3S7OhDmBtnzX95FhtZZDecSTDm6aajFymyve6S5DN4ZHGezdQ==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "replace-ext": "1.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
+ },
+ "unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.2"
+ }
+ },
+ "vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
+ }
+ }
+ },
+ "vfile-location": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz",
+ "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==",
+ "dev": true
+ },
+ "vfile-message": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz",
+ "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==",
+ "dev": true,
+ "requires": {
+ "unist-util-stringify-position": "^1.1.1"
+ }
+ },
+ "vfile-reporter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.1.tgz",
+ "integrity": "sha512-0OppK9mo8G2XUpv+hIKLVSDsoxJrXnOy73+vIm0jQUOUFYRduqpFHX+QqAQfvRHyX9B0UFiRuNJnBOjQCIsw1g==",
+ "dev": true,
+ "requires": {
+ "repeat-string": "^1.5.0",
+ "string-width": "^4.0.0",
+ "supports-color": "^6.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-sort": "^2.1.2",
+ "vfile-statistics": "^1.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.2"
+ }
+ }
+ }
+ },
+ "vfile-sort": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz",
+ "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==",
+ "dev": true
+ },
+ "vfile-statistics": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz",
+ "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==",
+ "dev": true
+ },
+ "vinyl-fs": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+ "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+ "dev": true,
+ "requires": {
+ "fs-mkdirp-stream": "^1.0.0",
+ "glob-stream": "^6.1.0",
+ "graceful-fs": "^4.0.0",
+ "is-valid-glob": "^1.0.0",
+ "lazystream": "^1.0.0",
+ "lead": "^1.0.0",
+ "object.assign": "^4.0.4",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.3.3",
+ "remove-bom-buffer": "^3.0.0",
+ "remove-bom-stream": "^1.2.0",
+ "resolve-options": "^1.1.0",
+ "through2": "^2.0.0",
+ "to-through": "^2.0.0",
+ "value-or-function": "^3.0.0",
+ "vinyl": "^2.0.0",
+ "vinyl-sourcemap": "^1.1.0"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ }
+ }
+ }
+ },
+ "vinyl-sourcemap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+ "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+ "dev": true,
+ "requires": {
+ "append-buffer": "^1.0.2",
+ "convert-source-map": "^1.5.0",
+ "graceful-fs": "^4.1.6",
+ "normalize-path": "^2.1.1",
+ "now-and-later": "^2.0.0",
+ "remove-bom-buffer": "^3.0.0",
+ "vinyl": "^2.0.0"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ }
+ }
+ }
+ },
+ "vm-browserify": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+ "dev": true
+ },
+ "void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+ "dev": true
+ },
+ "vue-template-compiler": {
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
+ "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==",
+ "dev": true,
+ "requires": {
+ "de-indent": "^1.0.2",
+ "he": "^1.1.0"
+ }
+ },
+ "watchpack": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
+ "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^3.4.0",
+ "graceful-fs": "^4.1.2",
+ "neo-async": "^2.5.0",
+ "watchpack-chokidar2": "^2.0.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true,
+ "optional": true
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "chokidar": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+ "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.4.0"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ },
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "optional": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "optional": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "optional": true
+ },
+ "readdirp": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+ "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "watchpack-chokidar2": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz",
+ "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chokidar": "^2.1.8"
+ }
+ },
+ "wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "requires": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "webpack": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz",
+ "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-module-context": "1.9.0",
+ "@webassemblyjs/wasm-edit": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0",
+ "acorn": "^6.4.1",
+ "ajv": "^6.10.2",
+ "ajv-keywords": "^3.4.1",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^4.1.0",
+ "eslint-scope": "^4.0.3",
+ "json-parse-better-errors": "^1.0.2",
+ "loader-runner": "^2.4.0",
+ "loader-utils": "^1.2.3",
+ "memory-fs": "^0.4.1",
+ "micromatch": "^3.1.10",
+ "mkdirp": "^0.5.3",
+ "neo-async": "^2.6.1",
+ "node-libs-browser": "^2.2.1",
+ "schema-utils": "^1.0.0",
+ "tapable": "^1.1.3",
+ "terser-webpack-plugin": "^1.4.3",
+ "watchpack": "^1.6.1",
+ "webpack-sources": "^1.4.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+ "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
+ "dev": true
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "cacache": {
+ "version": "12.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+ "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.5",
+ "chownr": "^1.1.1",
+ "figgy-pudding": "^3.5.1",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.1.15",
+ "infer-owner": "^1.0.3",
+ "lru-cache": "^5.1.1",
+ "mississippi": "^3.0.0",
+ "mkdirp": "^0.5.1",
+ "move-concurrently": "^1.0.1",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^2.6.3",
+ "ssri": "^6.0.1",
+ "unique-filename": "^1.1.1",
+ "y18n": "^4.0.0"
+ }
+ },
+ "chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "serialize-javascript": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
+ "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "ssri": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+ "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+ "dev": true,
+ "requires": {
+ "figgy-pudding": "^3.5.1"
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
+ "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
+ "dev": true,
+ "requires": {
+ "cacache": "^12.0.2",
+ "find-cache-dir": "^2.1.0",
+ "is-wsl": "^1.1.0",
+ "schema-utils": "^1.0.0",
+ "serialize-javascript": "^2.1.2",
+ "source-map": "^0.6.1",
+ "terser": "^4.1.2",
+ "webpack-sources": "^1.4.0",
+ "worker-farm": "^1.7.0"
+ }
+ },
+ "webpack-sources": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-cli": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz",
+ "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.4.2",
+ "cross-spawn": "6.0.5",
+ "enhanced-resolve": "4.1.0",
+ "findup-sync": "3.0.0",
+ "global-modules": "2.0.0",
+ "import-local": "2.0.0",
+ "interpret": "1.2.0",
+ "loader-utils": "1.2.3",
+ "supports-color": "6.1.0",
+ "v8-compile-cache": "2.0.3",
+ "yargs": "13.2.4"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz",
+ "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.4.0",
+ "tapable": "^1.0.0"
+ }
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+ "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^3.0.0"
+ },
+ "dependencies": {
+ "global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ }
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "interpret": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
+ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+ "dev": true
+ },
+ "invert-kv": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "lcid": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^2.0.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^2.0.0",
+ "json5": "^1.0.1"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "mem": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+ "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.1",
+ "mimic-fn": "^2.0.0",
+ "p-is-promise": "^2.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "os-locale": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "lcid": "^2.0.0",
+ "mem": "^4.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ },
+ "dependencies": {
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ }
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "13.2.4",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz",
+ "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "os-locale": "^3.1.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz",
+ "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
+ "dev": true,
+ "requires": {
+ "memory-fs": "^0.4.1",
+ "mime": "^2.4.4",
+ "mkdirp": "^0.5.1",
+ "range-parser": "^1.2.1",
+ "webpack-log": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+ "dev": true
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "webpack-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^3.0.0",
+ "uuid": "^3.3.2"
+ }
+ }
+ }
+ },
+ "webpack-dev-server": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz",
+ "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "0.0.7",
+ "bonjour": "^3.5.0",
+ "chokidar": "^2.1.8",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^1.6.0",
+ "debug": "^4.1.1",
+ "del": "^4.1.1",
+ "express": "^4.17.1",
+ "html-entities": "^1.3.1",
+ "http-proxy-middleware": "0.19.1",
+ "import-local": "^2.0.0",
+ "internal-ip": "^4.3.0",
+ "ip": "^1.1.5",
+ "is-absolute-url": "^3.0.3",
+ "killable": "^1.0.1",
+ "loglevel": "^1.6.8",
+ "opn": "^5.5.0",
+ "p-retry": "^3.0.1",
+ "portfinder": "^1.0.26",
+ "schema-utils": "^1.0.0",
+ "selfsigned": "^1.10.7",
+ "semver": "^6.3.0",
+ "serve-index": "^1.9.1",
+ "sockjs": "0.3.20",
+ "sockjs-client": "1.4.0",
+ "spdy": "^4.0.2",
+ "strip-ansi": "^3.0.1",
+ "supports-color": "^6.1.0",
+ "url": "^0.11.0",
+ "webpack-dev-middleware": "^3.7.2",
+ "webpack-log": "^2.0.0",
+ "ws": "^6.2.1",
+ "yargs": "^13.3.2"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "async": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
+ "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "portfinder": {
+ "version": "1.0.26",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
+ "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.2",
+ "debug": "^3.1.1",
+ "mkdirp": "^0.5.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+ "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "dev": true,
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "webpack-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^3.0.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "ws": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "webpack-merge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
+ "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15"
+ }
+ },
+ "webpack-sources": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "requires": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.2.14",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
+ "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "worker-farm": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+ "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.7"
+ }
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "ws": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
+ "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
+ "dev": true
+ },
+ "x-is-string": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
+ "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
+ "dev": true
+ },
+ "xmlcreate": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
+ "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "dev": true
+ },
+ "xmldom": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.3.0.tgz",
+ "integrity": "sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g=="
+ },
+ "xmlhttprequest-ssl": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "12.0.5",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+ "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^3.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1 || ^4.0.0",
+ "yargs-parser": "^11.1.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
+ "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "yargs-unparser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+ "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+ "dev": true,
+ "requires": {
+ "flat": "^4.1.0",
+ "lodash": "^4.17.15",
+ "yargs": "^13.3.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ }
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "~1.0.1"
+ }
+ },
+ "yeast": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+ "dev": true
+ }
+ }
+}
diff --git a/lib/epub.js/package.json b/lib/epub.js/package.json
new file mode 100644
index 0000000..76b2d8c
--- /dev/null
+++ b/lib/epub.js/package.json
@@ -0,0 +1,68 @@
+{
+ "name": "epubjs",
+ "version": "0.3.88",
+ "description": "Parse and Render Epubs",
+ "main": "lib/index.js",
+ "module": "src/index.js",
+ "types": "types/index.d.ts",
+ "repository": "https://github.com/futurepress/epub.js",
+ "directories": {
+ "test": "test"
+ },
+ "scripts": {
+ "test": "karma start --single-run --browsers ChromeHeadlessNoSandbox",
+ "docs": "documentation build src/epub.js -f html -o documentation/html/",
+ "docs:html": "documentation build src/epub.js -f html -o documentation/html/",
+ "docs:md": "documentation build src/epub.js -f md -o documentation/md/API.md",
+ "lint": "eslint -c .eslintrc.js src; exit 0",
+ "start": "webpack-dev-server --inline --d",
+ "build": "NODE_ENV=production webpack --progress",
+ "minify": "NODE_ENV=production MINIMIZE=true webpack --progress",
+ "legacy": "NODE_ENV=production LEGACY=true webpack --progress",
+ "productionLegacy": "NODE_ENV=production MINIMIZE=true LEGACY=true webpack --progress",
+ "compile": "babel -d lib/ src/",
+ "watch": "babel --watch -d lib/ src/",
+ "prepare": "npm run compile && npm run build && npm run minify && npm run legacy && npm run productionLegacy"
+ },
+ "author": "[email protected]",
+ "license": "BSD-2-Clause",
+ "devDependencies": {
+ "@babel/cli": "^7.10.1",
+ "@babel/core": "^7.10.2",
+ "@babel/plugin-proposal-export-default-from": "^7.10.1",
+ "@babel/plugin-proposal-export-namespace-from": "^7.10.1",
+ "@babel/preset-env": "^7.10.2",
+ "@babel/runtime": "^7.10.2",
+ "babel-loader": "^8.1.0",
+ "documentation": "^13.0.1",
+ "eslint": "^7.1.0",
+ "jsdoc": "^3.6.4",
+ "karma": "^5.0.9",
+ "karma-chrome-launcher": "^3.1.0",
+ "karma-mocha": "^2.0.1",
+ "karma-mocha-reporter": "^2.2.5",
+ "karma-phantomjs-launcher": "^1.0.4",
+ "karma-sourcemap-loader": "^0.3.7",
+ "karma-webpack": "next",
+ "mocha": "^7.2.0",
+ "mocha-loader": "^5.0.0",
+ "raw-loader": "^4.0.1",
+ "terser-webpack-plugin": "^3.0.3",
+ "tsd-jsdoc": "^2.5.0",
+ "webpack": "^4.43.0",
+ "webpack-cli": "^3.3.11",
+ "webpack-dev-middleware": "^3.7.2",
+ "webpack-dev-server": "^3.11.0"
+ },
+ "dependencies": {
+ "@types/localforage": "0.0.34",
+ "core-js": "^3.6.5",
+ "event-emitter": "^0.3.5",
+ "jszip": "^3.4.0",
+ "localforage": "^1.7.3",
+ "lodash": "^4.17.15",
+ "marks-pane": "^1.0.9",
+ "path-webpack": "0.0.3",
+ "xmldom": "^0.3.0"
+ }
+}
diff --git a/lib/epub.js/src/annotations.js b/lib/epub.js/src/annotations.js
new file mode 100644
index 0000000..ecbcb56
--- /dev/null
+++ b/lib/epub.js/src/annotations.js
@@ -0,0 +1,301 @@
+import EventEmitter from "event-emitter";
+import EpubCFI from "./epubcfi";
+import { EVENTS } from "./utils/constants";
+
+/**
+ * Handles managing adding & removing Annotations
+ * @param {Rendition} rendition
+ * @class
+ */
+class Annotations {
+
+ constructor (rendition) {
+ this.rendition = rendition;
+ this.highlights = [];
+ this.underlines = [];
+ this.marks = [];
+ this._annotations = {};
+ this._annotationsBySectionIndex = {};
+
+ this.rendition.hooks.render.register(this.inject.bind(this));
+ this.rendition.hooks.unloaded.register(this.clear.bind(this));
+ }
+
+ /**
+ * Add an annotation to store
+ * @param {string} type Type of annotation to add: "highlight", "underline", "mark"
+ * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
+ * @param {object} data Data to assign to annotation
+ * @param {function} [cb] Callback after annotation is added
+ * @param {string} className CSS class to assign to annotation
+ * @param {object} styles CSS styles to assign to annotation
+ * @returns {Annotation} annotation
+ */
+ add (type, cfiRange, data, cb, className, styles) {
+ let hash = encodeURI(cfiRange + type);
+ let cfi = new EpubCFI(cfiRange);
+ let sectionIndex = cfi.spinePos;
+ let annotation = new Annotation({
+ type,
+ cfiRange,
+ data,
+ sectionIndex,
+ cb,
+ className,
+ styles
+ });
+
+ this._annotations[hash] = annotation;
+
+ if (sectionIndex in this._annotationsBySectionIndex) {
+ this._annotationsBySectionIndex[sectionIndex].push(hash);
+ } else {
+ this._annotationsBySectionIndex[sectionIndex] = [hash];
+ }
+
+ let views = this.rendition.views();
+
+ views.forEach( (view) => {
+ if (annotation.sectionIndex === view.index) {
+ annotation.attach(view);
+ }
+ });
+
+ return annotation;
+ }
+
+ /**
+ * Remove an annotation from store
+ * @param {EpubCFI} cfiRange EpubCFI range the annotation is attached to
+ * @param {string} type Type of annotation to add: "highlight", "underline", "mark"
+ */
+ remove (cfiRange, type) {
+ let hash = encodeURI(cfiRange + type);
+
+ if (hash in this._annotations) {
+ let annotation = this._annotations[hash];
+
+ if (type && annotation.type !== type) {
+ return;
+ }
+
+ let views = this.rendition.views();
+ views.forEach( (view) => {
+ this._removeFromAnnotationBySectionIndex(annotation.sectionIndex, hash);
+ if (annotation.sectionIndex === view.index) {
+ annotation.detach(view);
+ }
+ });
+
+ delete this._annotations[hash];
+ }
+ }
+
+ /**
+ * Remove an annotations by Section Index
+ * @private
+ */
+ _removeFromAnnotationBySectionIndex (sectionIndex, hash) {
+ this._annotationsBySectionIndex[sectionIndex] = this._annotationsAt(sectionIndex).filter(h => h !== hash);
+ }
+
+ /**
+ * Get annotations by Section Index
+ * @private
+ */
+ _annotationsAt (index) {
+ return this._annotationsBySectionIndex[index];
+ }
+
+
+ /**
+ * Add a highlight to the store
+ * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
+ * @param {object} data Data to assign to annotation
+ * @param {function} cb Callback after annotation is clicked
+ * @param {string} className CSS class to assign to annotation
+ * @param {object} styles CSS styles to assign to annotation
+ */
+ highlight (cfiRange, data, cb, className, styles) {
+ return this.add("highlight", cfiRange, data, cb, className, styles);
+ }
+
+ /**
+ * Add a underline to the store
+ * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
+ * @param {object} data Data to assign to annotation
+ * @param {function} cb Callback after annotation is clicked
+ * @param {string} className CSS class to assign to annotation
+ * @param {object} styles CSS styles to assign to annotation
+ */
+ underline (cfiRange, data, cb, className, styles) {
+ return this.add("underline", cfiRange, data, cb, className, styles);
+ }
+
+ /**
+ * Add a mark to the store
+ * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
+ * @param {object} data Data to assign to annotation
+ * @param {function} cb Callback after annotation is clicked
+ */
+ mark (cfiRange, data, cb) {
+ return this.add("mark", cfiRange, data, cb);
+ }
+
+ /**
+ * iterate over annotations in the store
+ */
+ each () {
+ return this._annotations.forEach.apply(this._annotations, arguments);
+ }
+
+ /**
+ * Hook for injecting annotation into a view
+ * @param {View} view
+ * @private
+ */
+ inject (view) {
+ let sectionIndex = view.index;
+ if (sectionIndex in this._annotationsBySectionIndex) {
+ let annotations = this._annotationsBySectionIndex[sectionIndex];
+ annotations.forEach((hash) => {
+ let annotation = this._annotations[hash];
+ annotation.attach(view);
+ });
+ }
+ }
+
+ /**
+ * Hook for removing annotation from a view
+ * @param {View} view
+ * @private
+ */
+ clear (view) {
+ let sectionIndex = view.index;
+ if (sectionIndex in this._annotationsBySectionIndex) {
+ let annotations = this._annotationsBySectionIndex[sectionIndex];
+ annotations.forEach((hash) => {
+ let annotation = this._annotations[hash];
+ annotation.detach(view);
+ });
+ }
+ }
+
+ /**
+ * [Not Implemented] Show annotations
+ * @TODO: needs implementation in View
+ */
+ show () {
+
+ }
+
+ /**
+ * [Not Implemented] Hide annotations
+ * @TODO: needs implementation in View
+ */
+ hide () {
+
+ }
+
+}
+
+/**
+ * Annotation object
+ * @class
+ * @param {object} options
+ * @param {string} options.type Type of annotation to add: "highlight", "underline", "mark"
+ * @param {EpubCFI} options.cfiRange EpubCFI range to attach annotation to
+ * @param {object} options.data Data to assign to annotation
+ * @param {int} options.sectionIndex Index in the Spine of the Section annotation belongs to
+ * @param {function} [options.cb] Callback after annotation is clicked
+ * @param {string} className CSS class to assign to annotation
+ * @param {object} styles CSS styles to assign to annotation
+ * @returns {Annotation} annotation
+ */
+class Annotation {
+
+ constructor ({
+ type,
+ cfiRange,
+ data,
+ sectionIndex,
+ cb,
+ className,
+ styles
+ }) {
+ this.type = type;
+ this.cfiRange = cfiRange;
+ this.data = data;
+ this.sectionIndex = sectionIndex;
+ this.mark = undefined;
+ this.cb = cb;
+ this.className = className;
+ this.styles = styles;
+ }
+
+ /**
+ * Update stored data
+ * @param {object} data
+ */
+ update (data) {
+ this.data = data;
+ }
+
+ /**
+ * Add to a view
+ * @param {View} view
+ */
+ attach (view) {
+ let {cfiRange, data, type, mark, cb, className, styles} = this;
+ let result;
+
+ if (type === "highlight") {
+ result = view.highlight(cfiRange, data, cb, className, styles);
+ } else if (type === "underline") {
+ result = view.underline(cfiRange, data, cb, className, styles);
+ } else if (type === "mark") {
+ result = view.mark(cfiRange, data, cb);
+ }
+
+ this.mark = result;
+ this.emit(EVENTS.ANNOTATION.ATTACH, result);
+ return result;
+ }
+
+ /**
+ * Remove from a view
+ * @param {View} view
+ */
+ detach (view) {
+ let {cfiRange, type} = this;
+ let result;
+
+ if (view) {
+ if (type === "highlight") {
+ result = view.unhighlight(cfiRange);
+ } else if (type === "underline") {
+ result = view.ununderline(cfiRange);
+ } else if (type === "mark") {
+ result = view.unmark(cfiRange);
+ }
+ }
+
+ this.mark = undefined;
+ this.emit(EVENTS.ANNOTATION.DETACH, result);
+ return result;
+ }
+
+ /**
+ * [Not Implemented] Get text of an annotation
+ * @TODO: needs implementation in contents
+ */
+ text () {
+
+ }
+
+}
+
+EventEmitter(Annotation.prototype);
+
+
+export default Annotations
diff --git a/lib/epub.js/src/archive.js b/lib/epub.js/src/archive.js
new file mode 100644
index 0000000..ea22a81
--- /dev/null
+++ b/lib/epub.js/src/archive.js
@@ -0,0 +1,255 @@
+import {defer, isXml, parse} from "./utils/core";
+import request from "./utils/request";
+import mime from "./utils/mime";
+import Path from "./utils/path";
+import JSZip from "jszip/dist/jszip";
+
+/**
+ * Handles Unzipping a requesting files from an Epub Archive
+ * @class
+ */
+class Archive {
+
+ constructor() {
+ this.zip = undefined;
+ this.urlCache = {};
+
+ this.checkRequirements();
+
+ }
+
+ /**
+ * Checks to see if JSZip exists in global namspace,
+ * Requires JSZip if it isn't there
+ * @private
+ */
+ checkRequirements(){
+ try {
+ this.zip = new JSZip();
+ } catch (e) {
+ throw new Error("JSZip lib not loaded");
+ }
+ }
+
+ /**
+ * Open an archive
+ * @param {binary} input
+ * @param {boolean} [isBase64] tells JSZip if the input data is base64 encoded
+ * @return {Promise} zipfile
+ */
+ open(input, isBase64){
+ return this.zip.loadAsync(input, {"base64": isBase64});
+ }
+
+ /**
+ * Load and Open an archive
+ * @param {string} zipUrl
+ * @param {boolean} [isBase64] tells JSZip if the input data is base64 encoded
+ * @return {Promise} zipfile
+ */
+ openUrl(zipUrl, isBase64){
+ return request(zipUrl, "binary")
+ .then(function(data){
+ return this.zip.loadAsync(data, {"base64": isBase64});
+ }.bind(this));
+ }
+
+ /**
+ * Request a url from the archive
+ * @param {string} url a url to request from the archive
+ * @param {string} [type] specify the type of the returned result
+ * @return {Promise<Blob | string | JSON | Document | XMLDocument>}
+ */
+ request(url, type){
+ var deferred = new defer();
+ var response;
+ var path = new Path(url);
+
+ // If type isn't set, determine it from the file extension
+ if(!type) {
+ type = path.extension;
+ }
+
+ if(type == "blob"){
+ response = this.getBlob(url);
+ } else {
+ response = this.getText(url);
+ }
+
+ if (response) {
+ response.then(function (r) {
+ let result = this.handleResponse(r, type);
+ deferred.resolve(result);
+ }.bind(this));
+ } else {
+ deferred.reject({
+ message : "File not found in the epub: " + url,
+ stack : new Error().stack
+ });
+ }
+ return deferred.promise;
+ }
+
+ /**
+ * Handle the response from request
+ * @private
+ * @param {any} response
+ * @param {string} [type]
+ * @return {any} the parsed result
+ */
+ handleResponse(response, type){
+ var r;
+
+ if(type == "json") {
+ r = JSON.parse(response);
+ }
+ else
+ if(isXml(type)) {
+ r = parse(response, "text/xml");
+ }
+ else
+ if(type == "xhtml") {
+ r = parse(response, "application/xhtml+xml");
+ }
+ else
+ if(type == "html" || type == "htm") {
+ r = parse(response, "text/html");
+ } else {
+ r = response;
+ }
+
+ return r;
+ }
+
+ /**
+ * Get a Blob from Archive by Url
+ * @param {string} url
+ * @param {string} [mimeType]
+ * @return {Blob}
+ */
+ getBlob(url, mimeType){
+ var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
+ var entry = this.zip.file(decodededUrl);
+
+ if(entry) {
+ mimeType = mimeType || mime.lookup(entry.name);
+ return entry.async("uint8array").then(function(uint8array) {
+ return new Blob([uint8array], {type : mimeType});
+ });
+ }
+ }
+
+ /**
+ * Get Text from Archive by Url
+ * @param {string} url
+ * @param {string} [encoding]
+ * @return {string}
+ */
+ getText(url, encoding){
+ var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
+ var entry = this.zip.file(decodededUrl);
+
+ if(entry) {
+ return entry.async("string").then(function(text) {
+ return text;
+ });
+ }
+ }
+
+ /**
+ * Get a base64 encoded result from Archive by Url
+ * @param {string} url
+ * @param {string} [mimeType]
+ * @return {string} base64 encoded
+ */
+ getBase64(url, mimeType){
+ var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
+ var entry = this.zip.file(decodededUrl);
+
+ if(entry) {
+ mimeType = mimeType || mime.lookup(entry.name);
+ return entry.async("base64").then(function(data) {
+ return "data:" + mimeType + ";base64," + data;
+ });
+ }
+ }
+
+ /**
+ * Create a Url from an unarchived item
+ * @param {string} url
+ * @param {object} [options.base64] use base64 encoding or blob url
+ * @return {Promise} url promise with Url string
+ */
+ createUrl(url, options){
+ var deferred = new defer();
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ var tempUrl;
+ var response;
+ var useBase64 = options && options.base64;
+
+ if(url in this.urlCache) {
+ deferred.resolve(this.urlCache[url]);
+ return deferred.promise;
+ }
+
+ if (useBase64) {
+ response = this.getBase64(url);
+
+ if (response) {
+ response.then(function(tempUrl) {
+
+ this.urlCache[url] = tempUrl;
+ deferred.resolve(tempUrl);
+
+ }.bind(this));
+
+ }
+
+ } else {
+
+ response = this.getBlob(url);
+
+ if (response) {
+ response.then(function(blob) {
+
+ tempUrl = _URL.createObjectURL(blob);
+ this.urlCache[url] = tempUrl;
+ deferred.resolve(tempUrl);
+
+ }.bind(this));
+
+ }
+ }
+
+
+ if (!response) {
+ deferred.reject({
+ message : "File not found in the epub: " + url,
+ stack : new Error().stack
+ });
+ }
+
+ return deferred.promise;
+ }
+
+ /**
+ * Revoke Temp Url for a achive item
+ * @param {string} url url of the item in the archive
+ */
+ revokeUrl(url){
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ var fromCache = this.urlCache[url];
+ if(fromCache) _URL.revokeObjectURL(fromCache);
+ }
+
+ destroy() {
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ for (let fromCache in this.urlCache) {
+ _URL.revokeObjectURL(fromCache);
+ }
+ this.zip = undefined;
+ this.urlCache = {};
+ }
+}
+
+export default Archive;
diff --git a/lib/epub.js/src/book.js b/lib/epub.js/src/book.js
new file mode 100644
index 0000000..4243bd1
--- /dev/null
+++ b/lib/epub.js/src/book.js
@@ -0,0 +1,768 @@
+import EventEmitter from "event-emitter";
+import {extend, defer} from "./utils/core";
+import Url from "./utils/url";
+import Path from "./utils/path";
+import Spine from "./spine";
+import Locations from "./locations";
+import Container from "./container";
+import Packaging from "./packaging";
+import Navigation from "./navigation";
+import Resources from "./resources";
+import PageList from "./pagelist";
+import Rendition from "./rendition";
+import Archive from "./archive";
+import request from "./utils/request";
+import EpubCFI from "./epubcfi";
+import Store from "./store";
+import DisplayOptions from "./displayoptions";
+import { EPUBJS_VERSION, EVENTS } from "./utils/constants";
+
+const CONTAINER_PATH = "META-INF/container.xml";
+const IBOOKS_DISPLAY_OPTIONS_PATH = "META-INF/com.apple.ibooks.display-options.xml";
+
+const INPUT_TYPE = {
+ BINARY: "binary",
+ BASE64: "base64",
+ EPUB: "epub",
+ OPF: "opf",
+ MANIFEST: "json",
+ DIRECTORY: "directory"
+};
+
+/**
+ * An Epub representation with methods for the loading, parsing and manipulation
+ * of its contents.
+ * @class
+ * @param {string} [url]
+ * @param {object} [options]
+ * @param {method} [options.requestMethod] a request function to use instead of the default
+ * @param {boolean} [options.requestCredentials=undefined] send the xhr request withCredentials
+ * @param {object} [options.requestHeaders=undefined] send the xhr request headers
+ * @param {string} [options.encoding=binary] optional to pass 'binary' or base64' for archived Epubs
+ * @param {string} [options.replacements=none] use base64, blobUrl, or none for replacing assets in archived Epubs
+ * @param {method} [options.canonical] optional function to determine canonical urls for a path
+ * @param {string} [options.openAs] optional string to determine the input type
+ * @param {string} [options.store=false] cache the contents in local storage, value should be the name of the reader
+ * @returns {Book}
+ * @example new Book("/path/to/book.epub", {})
+ * @example new Book({ replacements: "blobUrl" })
+ */
+class Book {
+ constructor(url, options) {
+ // Allow passing just options to the Book
+ if (typeof(options) === "undefined" &&
+ typeof(url) !== "string" &&
+ url instanceof Blob === false &&
+ url instanceof ArrayBuffer === false) {
+ options = url;
+ url = undefined;
+ }
+
+ this.settings = extend(this.settings || {}, {
+ requestMethod: undefined,
+ requestCredentials: undefined,
+ requestHeaders: undefined,
+ encoding: undefined,
+ replacements: undefined,
+ canonical: undefined,
+ openAs: undefined,
+ store: undefined
+ });
+
+ extend(this.settings, options);
+
+
+ // Promises
+ this.opening = new defer();
+ /**
+ * @member {promise} opened returns after the book is loaded
+ * @memberof Book
+ */
+ this.opened = this.opening.promise;
+ this.isOpen = false;
+
+ this.loading = {
+ manifest: new defer(),
+ spine: new defer(),
+ metadata: new defer(),
+ cover: new defer(),
+ navigation: new defer(),
+ pageList: new defer(),
+ resources: new defer(),
+ displayOptions: new defer()
+ };
+
+ this.loaded = {
+ manifest: this.loading.manifest.promise,
+ spine: this.loading.spine.promise,
+ metadata: this.loading.metadata.promise,
+ cover: this.loading.cover.promise,
+ navigation: this.loading.navigation.promise,
+ pageList: this.loading.pageList.promise,
+ resources: this.loading.resources.promise,
+ displayOptions: this.loading.displayOptions.promise
+ };
+
+ /**
+ * @member {promise} ready returns after the book is loaded and parsed
+ * @memberof Book
+ * @private
+ */
+ this.ready = Promise.all([
+ this.loaded.manifest,
+ this.loaded.spine,
+ this.loaded.metadata,
+ this.loaded.cover,
+ this.loaded.navigation,
+ this.loaded.resources,
+ this.loaded.displayOptions
+ ]);
+
+
+ // Queue for methods used before opening
+ this.isRendered = false;
+ // this._q = queue(this);
+
+ /**
+ * @member {method} request
+ * @memberof Book
+ * @private
+ */
+ this.request = this.settings.requestMethod || request;
+
+ /**
+ * @member {Spine} spine
+ * @memberof Book
+ */
+ this.spine = new Spine();
+
+ /**
+ * @member {Locations} locations
+ * @memberof Book
+ */
+ this.locations = new Locations(this.spine, this.load.bind(this));
+
+ /**
+ * @member {Navigation} navigation
+ * @memberof Book
+ */
+ this.navigation = undefined;
+
+ /**
+ * @member {PageList} pagelist
+ * @memberof Book
+ */
+ this.pageList = undefined;
+
+ /**
+ * @member {Url} url
+ * @memberof Book
+ * @private
+ */
+ this.url = undefined;
+
+ /**
+ * @member {Path} path
+ * @memberof Book
+ * @private
+ */
+ this.path = undefined;
+
+ /**
+ * @member {boolean} archived
+ * @memberof Book
+ * @private
+ */
+ this.archived = false;
+
+ /**
+ * @member {Archive} archive
+ * @memberof Book
+ * @private
+ */
+ this.archive = undefined;
+
+ /**
+ * @member {Store} storage
+ * @memberof Book
+ * @private
+ */
+ this.storage = undefined;
+
+ /**
+ * @member {Resources} resources
+ * @memberof Book
+ * @private
+ */
+ this.resources = undefined;
+
+ /**
+ * @member {Rendition} rendition
+ * @memberof Book
+ * @private
+ */
+ this.rendition = undefined;
+
+ /**
+ * @member {Container} container
+ * @memberof Book
+ * @private
+ */
+ this.container = undefined;
+
+ /**
+ * @member {Packaging} packaging
+ * @memberof Book
+ * @private
+ */
+ this.packaging = undefined;
+
+ /**
+ * @member {DisplayOptions} displayOptions
+ * @memberof DisplayOptions
+ * @private
+ */
+ this.displayOptions = undefined;
+
+ // this.toc = undefined;
+ if (this.settings.store) {
+ this.store(this.settings.store);
+ }
+
+ if(url) {
+ this.open(url, this.settings.openAs).catch((error) => {
+ var err = new Error("Cannot load book at "+ url );
+ this.emit(EVENTS.BOOK.OPEN_FAILED, err);
+ });
+ }
+ }
+
+ /**
+ * Open a epub or url
+ * @param {string | ArrayBuffer} input Url, Path or ArrayBuffer
+ * @param {string} [what="binary", "base64", "epub", "opf", "json", "directory"] force opening as a certain type
+ * @returns {Promise} of when the book has been loaded
+ * @example book.open("/path/to/book.epub")
+ */
+ open(input, what) {
+ var opening;
+ var type = what || this.determineType(input);
+
+ if (type === INPUT_TYPE.BINARY) {
+ this.archived = true;
+ this.url = new Url("/", "");
+ opening = this.openEpub(input);
+ } else if (type === INPUT_TYPE.BASE64) {
+ this.archived = true;
+ this.url = new Url("/", "");
+ opening = this.openEpub(input, type);
+ } else if (type === INPUT_TYPE.EPUB) {
+ this.archived = true;
+ this.url = new Url("/", "");
+ opening = this.request(input, "binary", this.settings.requestCredentials, this.settings.requestHeaders)
+ .then(this.openEpub.bind(this));
+ } else if(type == INPUT_TYPE.OPF) {
+ this.url = new Url(input);
+ opening = this.openPackaging(this.url.Path.toString());
+ } else if(type == INPUT_TYPE.MANIFEST) {
+ this.url = new Url(input);
+ opening = this.openManifest(this.url.Path.toString());
+ } else {
+ this.url = new Url(input);
+ opening = this.openContainer(CONTAINER_PATH)
+ .then(this.openPackaging.bind(this));
+ }
+
+ return opening;
+ }
+
+ /**
+ * Open an archived epub
+ * @private
+ * @param {binary} data
+ * @param {string} [encoding]
+ * @return {Promise}
+ */
+ openEpub(data, encoding) {
+ return this.unarchive(data, encoding || this.settings.encoding)
+ .then(() => {
+ return this.openContainer(CONTAINER_PATH);
+ })
+ .then((packagePath) => {
+ return this.openPackaging(packagePath);
+ });
+ }
+
+ /**
+ * Open the epub container
+ * @private
+ * @param {string} url
+ * @return {string} packagePath
+ */
+ openContainer(url) {
+ return this.load(url)
+ .then((xml) => {
+ this.container = new Container(xml);
+ return this.resolve(this.container.packagePath);
+ });
+ }
+
+ /**
+ * Open the Open Packaging Format Xml
+ * @private
+ * @param {string} url
+ * @return {Promise}
+ */
+ openPackaging(url) {
+ this.path = new Path(url);
+ return this.load(url)
+ .then((xml) => {
+ this.packaging = new Packaging(xml);
+ return this.unpack(this.packaging);
+ });
+ }
+
+ /**
+ * Open the manifest JSON
+ * @private
+ * @param {string} url
+ * @return {Promise}
+ */
+ openManifest(url) {
+ this.path = new Path(url);
+ return this.load(url)
+ .then((json) => {
+ this.packaging = new Packaging();
+ this.packaging.load(json);
+ return this.unpack(this.packaging);
+ });
+ }
+
+ /**
+ * Load a resource from the Book
+ * @param {string} path path to the resource to load
+ * @return {Promise} returns a promise with the requested resource
+ */
+ load(path) {
+ var resolved = this.resolve(path);
+ if(this.archived) {
+ return this.archive.request(resolved);
+ } else {
+ return this.request(resolved, null, this.settings.requestCredentials, this.settings.requestHeaders);
+ }
+ }
+
+ /**
+ * Resolve a path to it's absolute position in the Book
+ * @param {string} path
+ * @param {boolean} [absolute] force resolving the full URL
+ * @return {string} the resolved path string
+ */
+ resolve(path, absolute) {
+ if (!path) {
+ return;
+ }
+ var resolved = path;
+ var isAbsolute = (path.indexOf("://") > -1);
+
+ if (isAbsolute) {
+ return path;
+ }
+
+ if (this.path) {
+ resolved = this.path.resolve(path);
+ }
+
+ if(absolute != false && this.url) {
+ resolved = this.url.resolve(resolved);
+ }
+
+ return resolved;
+ }
+
+ /**
+ * Get a canonical link to a path
+ * @param {string} path
+ * @return {string} the canonical path string
+ */
+ canonical(path) {
+ var url = path;
+
+ if (!path) {
+ return "";
+ }
+
+ if (this.settings.canonical) {
+ url = this.settings.canonical(path);
+ } else {
+ url = this.resolve(path, true);
+ }
+
+ return url;
+ }
+
+ /**
+ * Determine the type of they input passed to open
+ * @private
+ * @param {string} input
+ * @return {string} binary | directory | epub | opf
+ */
+ determineType(input) {
+ var url;
+ var path;
+ var extension;
+
+ if (this.settings.encoding === "base64") {
+ return INPUT_TYPE.BASE64;
+ }
+
+ if(typeof(input) != "string") {
+ return INPUT_TYPE.BINARY;
+ }
+
+ url = new Url(input);
+ path = url.path();
+ extension = path.extension;
+
+ // If there's a search string, remove it before determining type
+ if (extension) {
+ extension = extension.replace(/\?.*$/, "");
+ }
+
+ if (!extension) {
+ return INPUT_TYPE.DIRECTORY;
+ }
+
+ if(extension === "epub"){
+ return INPUT_TYPE.EPUB;
+ }
+
+ if(extension === "opf"){
+ return INPUT_TYPE.OPF;
+ }
+
+ if(extension === "json"){
+ return INPUT_TYPE.MANIFEST;
+ }
+ }
+
+
+ /**
+ * unpack the contents of the Books packaging
+ * @private
+ * @param {Packaging} packaging object
+ */
+ unpack(packaging) {
+ this.package = packaging; //TODO: deprecated this
+
+ if (this.packaging.metadata.layout === "") {
+ // rendition:layout not set - check display options if book is pre-paginated
+ this.load(this.url.resolve(IBOOKS_DISPLAY_OPTIONS_PATH)).then((xml) => {
+ this.displayOptions = new DisplayOptions(xml);
+ this.loading.displayOptions.resolve(this.displayOptions);
+ }).catch((err) => {
+ this.displayOptions = new DisplayOptions();
+ this.loading.displayOptions.resolve(this.displayOptions);
+ });
+ } else {
+ this.displayOptions = new DisplayOptions();
+ this.loading.displayOptions.resolve(this.displayOptions);
+ }
+
+ this.spine.unpack(this.packaging, this.resolve.bind(this), this.canonical.bind(this));
+
+ this.resources = new Resources(this.packaging.manifest, {
+ archive: this.archive,
+ resolver: this.resolve.bind(this),
+ request: this.request.bind(this),
+ replacements: this.settings.replacements || (this.archived ? "blobUrl" : "base64")
+ });
+
+ this.loadNavigation(this.packaging).then(() => {
+ // this.toc = this.navigation.toc;
+ this.loading.navigation.resolve(this.navigation);
+ });
+
+ if (this.packaging.coverPath) {
+ this.cover = this.resolve(this.packaging.coverPath);
+ }
+ // Resolve promises
+ this.loading.manifest.resolve(this.packaging.manifest);
+ this.loading.metadata.resolve(this.packaging.metadata);
+ this.loading.spine.resolve(this.spine);
+ this.loading.cover.resolve(this.cover);
+ this.loading.resources.resolve(this.resources);
+ this.loading.pageList.resolve(this.pageList);
+
+ this.isOpen = true;
+
+ if(this.archived || this.settings.replacements && this.settings.replacements != "none") {
+ this.replacements().then(() => {
+ this.loaded.displayOptions.then(() => {
+ this.opening.resolve(this);
+ });
+ })
+ .catch((err) => {
+ console.error(err);
+ });
+ } else {
+ // Resolve book opened promise
+ this.loaded.displayOptions.then(() => {
+ this.opening.resolve(this);
+ });
+ }
+
+ }
+
+ /**
+ * Load Navigation and PageList from package
+ * @private
+ * @param {Packaging} packaging
+ */
+ loadNavigation(packaging) {
+ let navPath = packaging.navPath || packaging.ncxPath;
+ let toc = packaging.toc;
+
+ // From json manifest
+ if (toc) {
+ return new Promise((resolve, reject) => {
+ this.navigation = new Navigation(toc);
+
+ if (packaging.pageList) {
+ this.pageList = new PageList(packaging.pageList); // TODO: handle page lists from Manifest
+ }
+
+ resolve(this.navigation);
+ });
+ }
+
+ if (!navPath) {
+ return new Promise((resolve, reject) => {
+ this.navigation = new Navigation();
+ this.pageList = new PageList();
+
+ resolve(this.navigation);
+ });
+ }
+
+ return this.load(navPath, "xml")
+ .then((xml) => {
+ this.navigation = new Navigation(xml);
+ this.pageList = new PageList(xml);
+ return this.navigation;
+ });
+ }
+
+ /**
+ * Gets a Section of the Book from the Spine
+ * Alias for `book.spine.get`
+ * @param {string} target
+ * @return {Section}
+ */
+ section(target) {
+ return this.spine.get(target);
+ }
+
+ /**
+ * Sugar to render a book to an element
+ * @param {element | string} element element or string to add a rendition to
+ * @param {object} [options]
+ * @return {Rendition}
+ */
+ renderTo(element, options) {
+ this.rendition = new Rendition(this, options);
+ this.rendition.attachTo(element);
+
+ return this.rendition;
+ }
+
+ /**
+ * Set if request should use withCredentials
+ * @param {boolean} credentials
+ */
+ setRequestCredentials(credentials) {
+ this.settings.requestCredentials = credentials;
+ }
+
+ /**
+ * Set headers request should use
+ * @param {object} headers
+ */
+ setRequestHeaders(headers) {
+ this.settings.requestHeaders = headers;
+ }
+
+ /**
+ * Unarchive a zipped epub
+ * @private
+ * @param {binary} input epub data
+ * @param {string} [encoding]
+ * @return {Archive}
+ */
+ unarchive(input, encoding) {
+ this.archive = new Archive();
+ return this.archive.open(input, encoding);
+ }
+
+ /**
+ * Store the epubs contents
+ * @private
+ * @param {binary} input epub data
+ * @param {string} [encoding]
+ * @return {Store}
+ */
+ store(name) {
+ // Use "blobUrl" or "base64" for replacements
+ let replacementsSetting = this.settings.replacements && this.settings.replacements !== "none";
+ // Save original url
+ let originalUrl = this.url;
+ // Save original request method
+ let requester = this.settings.requestMethod || request.bind(this);
+ // Create new Store
+ this.storage = new Store(name, requester, this.resolve.bind(this));
+ // Replace request method to go through store
+ this.request = this.storage.request.bind(this.storage);
+
+ this.opened.then(() => {
+ if (this.archived) {
+ this.storage.requester = this.archive.request.bind(this.archive);
+ }
+ // Substitute hook
+ let substituteResources = (output, section) => {
+ section.output = this.resources.substitute(output, section.url);
+ };
+
+ // Set to use replacements
+ this.resources.settings.replacements = replacementsSetting || "blobUrl";
+ // Create replacement urls
+ this.resources.replacements().
+ then(() => {
+ return this.resources.replaceCss();
+ });
+
+ this.storage.on("offline", () => {
+ // Remove url to use relative resolving for hrefs
+ this.url = new Url("/", "");
+ // Add hook to replace resources in contents
+ this.spine.hooks.serialize.register(substituteResources);
+ });
+
+ this.storage.on("online", () => {
+ // Restore original url
+ this.url = originalUrl;
+ // Remove hook
+ this.spine.hooks.serialize.deregister(substituteResources);
+ });
+
+ });
+
+ return this.storage;
+ }
+
+ /**
+ * Get the cover url
+ * @return {Promise<?string>} coverUrl
+ */
+ coverUrl() {
+ return this.loaded.cover.then(() => {
+ if (!this.cover) {
+ return null;
+ }
+
+ if (this.archived) {
+ return this.archive.createUrl(this.cover);
+ } else {
+ return this.cover;
+ }
+ });
+ }
+
+ /**
+ * Load replacement urls
+ * @private
+ * @return {Promise} completed loading urls
+ */
+ replacements() {
+ this.spine.hooks.serialize.register((output, section) => {
+ section.output = this.resources.substitute(output, section.url);
+ });
+
+ return this.resources.replacements().
+ then(() => {
+ return this.resources.replaceCss();
+ });
+ }
+
+ /**
+ * Find a DOM Range for a given CFI Range
+ * @param {EpubCFI} cfiRange a epub cfi range
+ * @return {Promise}
+ */
+ getRange(cfiRange) {
+ var cfi = new EpubCFI(cfiRange);
+ var item = this.spine.get(cfi.spinePos);
+ var _request = this.load.bind(this);
+ if (!item) {
+ return new Promise((resolve, reject) => {
+ reject("CFI could not be found");
+ });
+ }
+ return item.load(_request).then(function (contents) {
+ var range = cfi.toRange(item.document);
+ return range;
+ });
+ }
+
+ /**
+ * Generates the Book Key using the identifer in the manifest or other string provided
+ * @param {string} [identifier] to use instead of metadata identifier
+ * @return {string} key
+ */
+ key(identifier) {
+ var ident = identifier || this.packaging.metadata.identifier || this.url.filename;
+ return `epubjs:${EPUBJS_VERSION}:${ident}`;
+ }
+
+ /**
+ * Destroy the Book and all associated objects
+ */
+ destroy() {
+ this.opened = undefined;
+ this.loading = undefined;
+ this.loaded = undefined;
+ this.ready = undefined;
+
+ this.isOpen = false;
+ this.isRendered = false;
+
+ this.spine && this.spine.destroy();
+ this.locations && this.locations.destroy();
+ this.pageList && this.pageList.destroy();
+ this.archive && this.archive.destroy();
+ this.resources && this.resources.destroy();
+ this.container && this.container.destroy();
+ this.packaging && this.packaging.destroy();
+ this.rendition && this.rendition.destroy();
+ this.displayOptions && this.displayOptions.destroy();
+
+ this.spine = undefined;
+ this.locations = undefined;
+ this.pageList = undefined;
+ this.archive = undefined;
+ this.resources = undefined;
+ this.container = undefined;
+ this.packaging = undefined;
+ this.rendition = undefined;
+
+ this.navigation = undefined;
+ this.url = undefined;
+ this.path = undefined;
+ this.archived = false;
+ }
+
+}
+
+//-- Enable binding events to book
+EventEmitter(Book.prototype);
+
+export default Book;
diff --git a/lib/epub.js/src/container.js b/lib/epub.js/src/container.js
new file mode 100644
index 0000000..f3a214f
--- /dev/null
+++ b/lib/epub.js/src/container.js
@@ -0,0 +1,50 @@
+import path from "path-webpack";
+import {qs} from "./utils/core";
+
+/**
+ * Handles Parsing and Accessing an Epub Container
+ * @class
+ * @param {document} [containerDocument] xml document
+ */
+class Container {
+ constructor(containerDocument) {
+ this.packagePath = '';
+ this.directory = '';
+ this.encoding = '';
+
+ if (containerDocument) {
+ this.parse(containerDocument);
+ }
+ }
+
+ /**
+ * Parse the Container XML
+ * @param {document} containerDocument
+ */
+ parse(containerDocument){
+ //-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
+ var rootfile;
+
+ if(!containerDocument) {
+ throw new Error("Container File Not Found");
+ }
+
+ rootfile = qs(containerDocument, "rootfile");
+
+ if(!rootfile) {
+ throw new Error("No RootFile Found");
+ }
+
+ this.packagePath = rootfile.getAttribute("full-path");
+ this.directory = path.dirname(this.packagePath);
+ this.encoding = containerDocument.xmlEncoding;
+ }
+
+ destroy() {
+ this.packagePath = undefined;
+ this.directory = undefined;
+ this.encoding = undefined;
+ }
+}
+
+export default Container;
diff --git a/lib/epub.js/src/contents.js b/lib/epub.js/src/contents.js
new file mode 100644
index 0000000..3effe72
--- /dev/null
+++ b/lib/epub.js/src/contents.js
@@ -0,0 +1,1264 @@
+import EventEmitter from "event-emitter";
+import {isNumber, prefixed, borders, defaults} from "./utils/core";
+import EpubCFI from "./epubcfi";
+import Mapping from "./mapping";
+import {replaceLinks} from "./utils/replacements";
+import { EPUBJS_VERSION, EVENTS, DOM_EVENTS } from "./utils/constants";
+
+const hasNavigator = typeof (navigator) !== "undefined";
+
+const isChrome = hasNavigator && /Chrome/.test(navigator.userAgent);
+const isWebkit = hasNavigator && !isChrome && /AppleWebKit/.test(navigator.userAgent);
+
+const ELEMENT_NODE = 1;
+const TEXT_NODE = 3;
+
+/**
+ * Handles DOM manipulation, queries and events for View contents
+ * @class
+ * @param {document} doc Document
+ * @param {element} content Parent Element (typically Body)
+ * @param {string} cfiBase Section component of CFIs
+ * @param {number} sectionIndex Index in Spine of Conntent's Section
+ */
+class Contents {
+ constructor(doc, content, cfiBase, sectionIndex) {
+ // Blank Cfi for Parsing
+ this.epubcfi = new EpubCFI();
+
+ this.document = doc;
+ this.documentElement = this.document.documentElement;
+ this.content = content || this.document.body;
+ this.window = this.document.defaultView;
+
+ this._size = {
+ width: 0,
+ height: 0
+ };
+
+ this.sectionIndex = sectionIndex || 0;
+ this.cfiBase = cfiBase || "";
+
+ this.epubReadingSystem("epub.js", EPUBJS_VERSION);
+ this.called = 0;
+ this.active = true;
+ this.listeners();
+ }
+
+ /**
+ * Get DOM events that are listened for and passed along
+ */
+ static get listenedEvents() {
+ return DOM_EVENTS;
+ }
+
+ /**
+ * Get or Set width
+ * @param {number} [w]
+ * @returns {number} width
+ */
+ width(w) {
+ // var frame = this.documentElement;
+ var frame = this.content;
+
+ if (w && isNumber(w)) {
+ w = w + "px";
+ }
+
+ if (w) {
+ frame.style.width = w;
+ // this.content.style.width = w;
+ }
+
+ return parseInt(this.window.getComputedStyle(frame)["width"]);
+
+
+ }
+
+ /**
+ * Get or Set height
+ * @param {number} [h]
+ * @returns {number} height
+ */
+ height(h) {
+ // var frame = this.documentElement;
+ var frame = this.content;
+
+ if (h && isNumber(h)) {
+ h = h + "px";
+ }
+
+ if (h) {
+ frame.style.height = h;
+ // this.content.style.height = h;
+ }
+
+ return parseInt(this.window.getComputedStyle(frame)["height"]);
+
+ }
+
+ /**
+ * Get or Set width of the contents
+ * @param {number} [w]
+ * @returns {number} width
+ */
+ contentWidth(w) {
+
+ var content = this.content || this.document.body;
+
+ if (w && isNumber(w)) {
+ w = w + "px";
+ }
+
+ if (w) {
+ content.style.width = w;
+ }
+
+ return parseInt(this.window.getComputedStyle(content)["width"]);
+
+
+ }
+
+ /**
+ * Get or Set height of the contents
+ * @param {number} [h]
+ * @returns {number} height
+ */
+ contentHeight(h) {
+
+ var content = this.content || this.document.body;
+
+ if (h && isNumber(h)) {
+ h = h + "px";
+ }
+
+ if (h) {
+ content.style.height = h;
+ }
+
+ return parseInt(this.window.getComputedStyle(content)["height"]);
+
+ }
+
+ /**
+ * Get the width of the text using Range
+ * @returns {number} width
+ */
+ textWidth() {
+ let rect;
+ let width;
+ let range = this.document.createRange();
+ let content = this.content || this.document.body;
+ let border = borders(content);
+
+ // Select the contents of frame
+ range.selectNodeContents(content);
+
+ // get the width of the text content
+ rect = range.getBoundingClientRect();
+ width = rect.width;
+
+ if (border && border.width) {
+ width += border.width;
+ }
+
+ return Math.round(width);
+ }
+
+ /**
+ * Get the height of the text using Range
+ * @returns {number} height
+ */
+ textHeight() {
+ let rect;
+ let height;
+ let range = this.document.createRange();
+ let content = this.content || this.document.body;
+
+ range.selectNodeContents(content);
+
+ rect = range.getBoundingClientRect();
+ height = rect.bottom;
+
+ return Math.round(height);
+ }
+
+ /**
+ * Get documentElement scrollWidth
+ * @returns {number} width
+ */
+ scrollWidth() {
+ var width = this.documentElement.scrollWidth;
+
+ return width;
+ }
+
+ /**
+ * Get documentElement scrollHeight
+ * @returns {number} height
+ */
+ scrollHeight() {
+ var height = this.documentElement.scrollHeight;
+
+ return height;
+ }
+
+ /**
+ * Set overflow css style of the contents
+ * @param {string} [overflow]
+ */
+ overflow(overflow) {
+
+ if (overflow) {
+ this.documentElement.style.overflow = overflow;
+ }
+
+ return this.window.getComputedStyle(this.documentElement)["overflow"];
+ }
+
+ /**
+ * Set overflowX css style of the documentElement
+ * @param {string} [overflow]
+ */
+ overflowX(overflow) {
+
+ if (overflow) {
+ this.documentElement.style.overflowX = overflow;
+ }
+
+ return this.window.getComputedStyle(this.documentElement)["overflowX"];
+ }
+
+ /**
+ * Set overflowY css style of the documentElement
+ * @param {string} [overflow]
+ */
+ overflowY(overflow) {
+
+ if (overflow) {
+ this.documentElement.style.overflowY = overflow;
+ }
+
+ return this.window.getComputedStyle(this.documentElement)["overflowY"];
+ }
+
+ /**
+ * Set Css styles on the contents element (typically Body)
+ * @param {string} property
+ * @param {string} value
+ * @param {boolean} [priority] set as "important"
+ */
+ css(property, value, priority) {
+ var content = this.content || this.document.body;
+
+ if (value) {
+ content.style.setProperty(property, value, priority ? "important" : "");
+ } else {
+ content.style.removeProperty(property);
+ }
+
+ return this.window.getComputedStyle(content)[property];
+ }
+
+ /**
+ * Get or Set the viewport element
+ * @param {object} [options]
+ * @param {string} [options.width]
+ * @param {string} [options.height]
+ * @param {string} [options.scale]
+ * @param {string} [options.minimum]
+ * @param {string} [options.maximum]
+ * @param {string} [options.scalable]
+ */
+ viewport(options) {
+ var _width, _height, _scale, _minimum, _maximum, _scalable;
+ // var width, height, scale, minimum, maximum, scalable;
+ var $viewport = this.document.querySelector("meta[name='viewport']");
+ var parsed = {
+ "width": undefined,
+ "height": undefined,
+ "scale": undefined,
+ "minimum": undefined,
+ "maximum": undefined,
+ "scalable": undefined
+ };
+ var newContent = [];
+ var settings = {};
+
+ /*
+ * check for the viewport size
+ * <meta name="viewport" content="width=1024,height=697" />
+ */
+ if($viewport && $viewport.hasAttribute("content")) {
+ let content = $viewport.getAttribute("content");
+ let _width = content.match(/width\s*=\s*([^,]*)/);
+ let _height = content.match(/height\s*=\s*([^,]*)/);
+ let _scale = content.match(/initial-scale\s*=\s*([^,]*)/);
+ let _minimum = content.match(/minimum-scale\s*=\s*([^,]*)/);
+ let _maximum = content.match(/maximum-scale\s*=\s*([^,]*)/);
+ let _scalable = content.match(/user-scalable\s*=\s*([^,]*)/);
+
+ if(_width && _width.length && typeof _width[1] !== "undefined"){
+ parsed.width = _width[1];
+ }
+ if(_height && _height.length && typeof _height[1] !== "undefined"){
+ parsed.height = _height[1];
+ }
+ if(_scale && _scale.length && typeof _scale[1] !== "undefined"){
+ parsed.scale = _scale[1];
+ }
+ if(_minimum && _minimum.length && typeof _minimum[1] !== "undefined"){
+ parsed.minimum = _minimum[1];
+ }
+ if(_maximum && _maximum.length && typeof _maximum[1] !== "undefined"){
+ parsed.maximum = _maximum[1];
+ }
+ if(_scalable && _scalable.length && typeof _scalable[1] !== "undefined"){
+ parsed.scalable = _scalable[1];
+ }
+ }
+
+ settings = defaults(options || {}, parsed);
+
+ if (options) {
+ if (settings.width) {
+ newContent.push("width=" + settings.width);
+ }
+
+ if (settings.height) {
+ newContent.push("height=" + settings.height);
+ }
+
+ if (settings.scale) {
+ newContent.push("initial-scale=" + settings.scale);
+ }
+
+ if (settings.scalable === "no") {
+ newContent.push("minimum-scale=" + settings.scale);
+ newContent.push("maximum-scale=" + settings.scale);
+ newContent.push("user-scalable=" + settings.scalable);
+ } else {
+
+ if (settings.scalable) {
+ newContent.push("user-scalable=" + settings.scalable);
+ }
+
+ if (settings.minimum) {
+ newContent.push("minimum-scale=" + settings.minimum);
+ }
+
+ if (settings.maximum) {
+ newContent.push("minimum-scale=" + settings.maximum);
+ }
+ }
+
+ if (!$viewport) {
+ $viewport = this.document.createElement("meta");
+ $viewport.setAttribute("name", "viewport");
+ this.document.querySelector("head").appendChild($viewport);
+ }
+
+ $viewport.setAttribute("content", newContent.join(", "));
+
+ this.window.scrollTo(0, 0);
+ }
+
+
+ return settings;
+ }
+
+ /**
+ * Event emitter for when the contents has expanded
+ * @private
+ */
+ expand() {
+ this.emit(EVENTS.CONTENTS.EXPAND);
+ }
+
+ /**
+ * Add DOM listeners
+ * @private
+ */
+ listeners() {
+ this.imageLoadListeners();
+
+ this.mediaQueryListeners();
+
+ // this.fontLoadListeners();
+
+ this.addEventListeners();
+
+ this.addSelectionListeners();
+
+ // this.transitionListeners();
+
+ if (typeof ResizeObserver === "undefined") {
+ this.resizeListeners();
+ this.visibilityListeners();
+ } else {
+ this.resizeObservers();
+ }
+
+ // this.mutationObservers();
+
+ this.linksHandler();
+ }
+
+ /**
+ * Remove DOM listeners
+ * @private
+ */
+ removeListeners() {
+
+ this.removeEventListeners();
+
+ this.removeSelectionListeners();
+
+ if (this.observer) {
+ this.observer.disconnect();
+ }
+
+ clearTimeout(this.expanding);
+ }
+
+ /**
+ * Check if size of contents has changed and
+ * emit 'resize' event if it has.
+ * @private
+ */
+ resizeCheck() {
+ let width = this.textWidth();
+ let height = this.textHeight();
+
+ if (width != this._size.width || height != this._size.height) {
+
+ this._size = {
+ width: width,
+ height: height
+ };
+
+ this.onResize && this.onResize(this._size);
+ this.emit(EVENTS.CONTENTS.RESIZE, this._size);
+ }
+ }
+
+ /**
+ * Poll for resize detection
+ * @private
+ */
+ resizeListeners() {
+ var width, height;
+ // Test size again
+ clearTimeout(this.expanding);
+ requestAnimationFrame(this.resizeCheck.bind(this));
+ this.expanding = setTimeout(this.resizeListeners.bind(this), 350);
+ }
+
+ /**
+ * Listen for visibility of tab to change
+ * @private
+ */
+ visibilityListeners() {
+ document.addEventListener("visibilitychange", () => {
+ if (document.visibilityState === "visible" && this.active === false) {
+ this.active = true;
+ this.resizeListeners();
+ } else {
+ this.active = false;
+ clearTimeout(this.expanding);
+ }
+ });
+ }
+
+ /**
+ * Use css transitions to detect resize
+ * @private
+ */
+ transitionListeners() {
+ let body = this.content;
+
+ body.style['transitionProperty'] = "font, font-size, font-size-adjust, font-stretch, font-variation-settings, font-weight, width, height";
+ body.style['transitionDuration'] = "0.001ms";
+ body.style['transitionTimingFunction'] = "linear";
+ body.style['transitionDelay'] = "0";
+
+ this._resizeCheck = this.resizeCheck.bind(this);
+ this.document.addEventListener('transitionend', this._resizeCheck);
+ }
+
+ /**
+ * Listen for media query changes and emit 'expand' event
+ * Adapted from: https://github.com/tylergaw/media-query-events/blob/master/js/mq-events.js
+ * @private
+ */
+ mediaQueryListeners() {
+ var sheets = this.document.styleSheets;
+ var mediaChangeHandler = function(m){
+ if(m.matches && !this._expanding) {
+ setTimeout(this.expand.bind(this), 1);
+ }
+ }.bind(this);
+
+ for (var i = 0; i < sheets.length; i += 1) {
+ var rules;
+ // Firefox errors if we access cssRules cross-domain
+ try {
+ rules = sheets[i].cssRules;
+ } catch (e) {
+ return;
+ }
+ if(!rules) return; // Stylesheets changed
+ for (var j = 0; j < rules.length; j += 1) {
+ //if (rules[j].constructor === CSSMediaRule) {
+ if(rules[j].media){
+ var mql = this.window.matchMedia(rules[j].media.mediaText);
+ mql.addListener(mediaChangeHandler);
+ //mql.onchange = mediaChangeHandler;
+ }
+ }
+ }
+ }
+
+ /**
+ * Use ResizeObserver to listen for changes in the DOM and check for resize
+ * @private
+ */
+ resizeObservers() {
+ // create an observer instance
+ this.observer = new ResizeObserver((e) => {
+ requestAnimationFrame(this.resizeCheck.bind(this));
+ });
+
+ // pass in the target node
+ this.observer.observe(this.document.documentElement);
+ }
+
+ /**
+ * Use MutationObserver to listen for changes in the DOM and check for resize
+ * @private
+ */
+ mutationObservers() {
+ // create an observer instance
+ this.observer = new MutationObserver((mutations) => {
+ this.resizeCheck();
+ });
+
+ // configuration of the observer:
+ let config = { attributes: true, childList: true, characterData: true, subtree: true };
+
+ // pass in the target node, as well as the observer options
+ this.observer.observe(this.document, config);
+ }
+
+ /**
+ * Test if images are loaded or add listener for when they load
+ * @private
+ */
+ imageLoadListeners() {
+ var images = this.document.querySelectorAll("img");
+ var img;
+ for (var i = 0; i < images.length; i++) {
+ img = images[i];
+
+ if (typeof img.naturalWidth !== "undefined" &&
+ img.naturalWidth === 0) {
+ img.onload = this.expand.bind(this);
+ }
+ }
+ }
+
+ /**
+ * Listen for font load and check for resize when loaded
+ * @private
+ */
+ fontLoadListeners() {
+ if (!this.document || !this.document.fonts) {
+ return;
+ }
+
+ this.document.fonts.ready.then(function () {
+ this.resizeCheck();
+ }.bind(this));
+
+ }
+
+ /**
+ * Get the documentElement
+ * @returns {element} documentElement
+ */
+ root() {
+ if(!this.document) return null;
+ return this.document.documentElement;
+ }
+
+ /**
+ * Get the location offset of a EpubCFI or an #id
+ * @param {string | EpubCFI} target
+ * @param {string} [ignoreClass] for the cfi
+ * @returns { {left: Number, top: Number }
+ */
+ locationOf(target, ignoreClass) {
+ var position;
+ var targetPos = {"left": 0, "top": 0};
+
+ if(!this.document) return targetPos;
+
+ if(this.epubcfi.isCfiString(target)) {
+ let range = new EpubCFI(target).toRange(this.document, ignoreClass);
+
+ if(range) {
+ try {
+ if (!range.endContainer ||
+ (range.startContainer == range.endContainer
+ && range.startOffset == range.endOffset)) {
+ // If the end for the range is not set, it results in collapsed becoming
+ // true. This in turn leads to inconsistent behaviour when calling
+ // getBoundingRect. Wrong bounds lead to the wrong page being displayed.
+ // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/15684911/
+ let pos = range.startContainer.textContent.indexOf(" ", range.startOffset);
+ if (pos == -1) {
+ pos = range.startContainer.textContent.length;
+ }
+ range.setEnd(range.startContainer, pos);
+ }
+ } catch (e) {
+ console.error("setting end offset to start container length failed", e);
+ }
+
+ if (range.startContainer.nodeType === Node.ELEMENT_NODE) {
+ position = range.startContainer.getBoundingClientRect();
+ targetPos.left = position.left;
+ targetPos.top = position.top;
+ } else {
+ // Webkit does not handle collapsed range bounds correctly
+ // https://bugs.webkit.org/show_bug.cgi?id=138949
+
+ // Construct a new non-collapsed range
+ if (isWebkit) {
+ let container = range.startContainer;
+ let newRange = new Range();
+ try {
+ if (container.nodeType === ELEMENT_NODE) {
+ position = container.getBoundingClientRect();
+ } else if (range.startOffset + 2 < container.length) {
+ newRange.setStart(container, range.startOffset);
+ newRange.setEnd(container, range.startOffset + 2);
+ position = newRange.getBoundingClientRect();
+ } else if (range.startOffset - 2 > 0) {
+ newRange.setStart(container, range.startOffset - 2);
+ newRange.setEnd(container, range.startOffset);
+ position = newRange.getBoundingClientRect();
+ } else { // empty, return the parent element
+ position = container.parentNode.getBoundingClientRect();
+ }
+ } catch (e) {
+ console.error(e, e.stack);
+ }
+ } else {
+ position = range.getBoundingClientRect();
+ }
+ }
+ }
+
+ } else if(typeof target === "string" &&
+ target.indexOf("#") > -1) {
+
+ let id = target.substring(target.indexOf("#")+1);
+ let el = this.document.getElementById(id);
+ if(el) {
+ if (isWebkit) {
+ // Webkit reports incorrect bounding rects in Columns
+ let newRange = new Range();
+ newRange.selectNode(el);
+ position = newRange.getBoundingClientRect();
+ } else {
+ position = el.getBoundingClientRect();
+ }
+ }
+ }
+
+ if (position) {
+ targetPos.left = position.left;
+ targetPos.top = position.top;
+ }
+
+ return targetPos;
+ }
+
+ /**
+ * Append a stylesheet link to the document head
+ * @param {string} src url
+ */
+ addStylesheet(src) {
+ return new Promise(function(resolve, reject){
+ var $stylesheet;
+ var ready = false;
+
+ if(!this.document) {
+ resolve(false);
+ return;
+ }
+
+ // Check if link already exists
+ $stylesheet = this.document.querySelector("link[href='"+src+"']");
+ if ($stylesheet) {
+ resolve(true);
+ return; // already present
+ }
+
+ $stylesheet = this.document.createElement("link");
+ $stylesheet.type = "text/css";
+ $stylesheet.rel = "stylesheet";
+ $stylesheet.href = src;
+ $stylesheet.onload = $stylesheet.onreadystatechange = function() {
+ if ( !ready && (!this.readyState || this.readyState == "complete") ) {
+ ready = true;
+ // Let apply
+ setTimeout(() => {
+ resolve(true);
+ }, 1);
+ }
+ };
+
+ this.document.head.appendChild($stylesheet);
+
+ }.bind(this));
+ }
+
+ _getStylesheetNode(key) {
+ var styleEl;
+ key = "epubjs-inserted-css-" + (key || '');
+
+ if(!this.document) return false;
+
+ // Check if link already exists
+ styleEl = this.document.getElementById(key);
+ if (!styleEl) {
+ styleEl = this.document.createElement("style");
+ styleEl.id = key;
+ // Append style element to head
+ this.document.head.appendChild(styleEl);
+ }
+ return styleEl;
+ }
+
+ /**
+ * Append stylesheet css
+ * @param {string} serializedCss
+ * @param {string} key If the key is the same, the CSS will be replaced instead of inserted
+ */
+ addStylesheetCss(serializedCss, key) {
+ if(!this.document || !serializedCss) return false;
+
+ var styleEl;
+ styleEl = this._getStylesheetNode(key);
+ styleEl.innerHTML = serializedCss;
+
+ return true;
+ }
+
+ /**
+ * Append stylesheet rules to a generate stylesheet
+ * Array: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule
+ * Object: https://github.com/desirable-objects/json-to-css
+ * @param {array | object} rules
+ * @param {string} key If the key is the same, the CSS will be replaced instead of inserted
+ */
+ addStylesheetRules(rules, key) {
+ var styleSheet;
+
+ if(!this.document || !rules || rules.length === 0) return;
+
+ // Grab style sheet
+ styleSheet = this._getStylesheetNode(key).sheet;
+
+ if (Object.prototype.toString.call(rules) === "[object Array]") {
+ for (var i = 0, rl = rules.length; i < rl; i++) {
+ var j = 1, rule = rules[i], selector = rules[i][0], propStr = "";
+ // If the second argument of a rule is an array of arrays, correct our variables.
+ if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") {
+ rule = rule[1];
+ j = 0;
+ }
+
+ for (var pl = rule.length; j < pl; j++) {
+ var prop = rule[j];
+ propStr += prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n";
+ }
+
+ // Insert CSS Rule
+ styleSheet.insertRule(selector + "{" + propStr + "}", styleSheet.cssRules.length);
+ }
+ } else {
+ const selectors = Object.keys(rules);
+ selectors.forEach((selector) => {
+ const definition = rules[selector];
+ if (Array.isArray(definition)) {
+ definition.forEach((item) => {
+ const _rules = Object.keys(item);
+ const result = _rules.map((rule) => {
+ return `${rule}:${item[rule]}`;
+ }).join(';');
+ styleSheet.insertRule(`${selector}{${result}}`, styleSheet.cssRules.length);
+ });
+ } else {
+ const _rules = Object.keys(definition);
+ const result = _rules.map((rule) => {
+ return `${rule}:${definition[rule]}`;
+ }).join(';');
+ styleSheet.insertRule(`${selector}{${result}}`, styleSheet.cssRules.length);
+ }
+ });
+ }
+ }
+
+ /**
+ * Append a script tag to the document head
+ * @param {string} src url
+ * @returns {Promise} loaded
+ */
+ addScript(src) {
+
+ return new Promise(function(resolve, reject){
+ var $script;
+ var ready = false;
+
+ if(!this.document) {
+ resolve(false);
+ return;
+ }
+
+ $script = this.document.createElement("script");
+ $script.type = "text/javascript";
+ $script.async = true;
+ $script.src = src;
+ $script.onload = $script.onreadystatechange = function() {
+ if ( !ready && (!this.readyState || this.readyState == "complete") ) {
+ ready = true;
+ setTimeout(function(){
+ resolve(true);
+ }, 1);
+ }
+ };
+
+ this.document.head.appendChild($script);
+
+ }.bind(this));
+ }
+
+ /**
+ * Add a class to the contents container
+ * @param {string} className
+ */
+ addClass(className) {
+ var content;
+
+ if(!this.document) return;
+
+ content = this.content || this.document.body;
+
+ if (content) {
+ content.classList.add(className);
+ }
+
+ }
+
+ /**
+ * Remove a class from the contents container
+ * @param {string} removeClass
+ */
+ removeClass(className) {
+ var content;
+
+ if(!this.document) return;
+
+ content = this.content || this.document.body;
+
+ if (content) {
+ content.classList.remove(className);
+ }
+
+ }
+
+ /**
+ * Add DOM event listeners
+ * @private
+ */
+ addEventListeners(){
+ if(!this.document) {
+ return;
+ }
+
+ this._triggerEvent = this.triggerEvent.bind(this);
+
+ DOM_EVENTS.forEach(function(eventName){
+ this.document.addEventListener(eventName, this._triggerEvent, { passive: true });
+ }, this);
+
+ }
+
+ /**
+ * Remove DOM event listeners
+ * @private
+ */
+ removeEventListeners(){
+ if(!this.document) {
+ return;
+ }
+ DOM_EVENTS.forEach(function(eventName){
+ this.document.removeEventListener(eventName, this._triggerEvent, { passive: true });
+ }, this);
+ this._triggerEvent = undefined;
+ }
+
+ /**
+ * Emit passed browser events
+ * @private
+ */
+ triggerEvent(e){
+ this.emit(e.type, e);
+ }
+
+ /**
+ * Add listener for text selection
+ * @private
+ */
+ addSelectionListeners(){
+ if(!this.document) {
+ return;
+ }
+ this._onSelectionChange = this.onSelectionChange.bind(this);
+ this.document.addEventListener("selectionchange", this._onSelectionChange, { passive: true });
+ }
+
+ /**
+ * Remove listener for text selection
+ * @private
+ */
+ removeSelectionListeners(){
+ if(!this.document) {
+ return;
+ }
+ this.document.removeEventListener("selectionchange", this._onSelectionChange, { passive: true });
+ this._onSelectionChange = undefined;
+ }
+
+ /**
+ * Handle getting text on selection
+ * @private
+ */
+ onSelectionChange(e){
+ if (this.selectionEndTimeout) {
+ clearTimeout(this.selectionEndTimeout);
+ }
+ this.selectionEndTimeout = setTimeout(function() {
+ var selection = this.window.getSelection();
+ this.triggerSelectedEvent(selection);
+ }.bind(this), 250);
+ }
+
+ /**
+ * Emit event on text selection
+ * @private
+ */
+ triggerSelectedEvent(selection){
+ var range, cfirange;
+
+ if (selection && selection.rangeCount > 0) {
+ range = selection.getRangeAt(0);
+ if(!range.collapsed) {
+ // cfirange = this.section.cfiFromRange(range);
+ cfirange = new EpubCFI(range, this.cfiBase).toString();
+ this.emit(EVENTS.CONTENTS.SELECTED, cfirange);
+ this.emit(EVENTS.CONTENTS.SELECTED_RANGE, range);
+ }
+ }
+ }
+
+ /**
+ * Get a Dom Range from EpubCFI
+ * @param {EpubCFI} _cfi
+ * @param {string} [ignoreClass]
+ * @returns {Range} range
+ */
+ range(_cfi, ignoreClass){
+ var cfi = new EpubCFI(_cfi);
+ return cfi.toRange(this.document, ignoreClass);
+ }
+
+ /**
+ * Get an EpubCFI from a Dom Range
+ * @param {Range} range
+ * @param {string} [ignoreClass]
+ * @returns {EpubCFI} cfi
+ */
+ cfiFromRange(range, ignoreClass){
+ return new EpubCFI(range, this.cfiBase, ignoreClass).toString();
+ }
+
+ /**
+ * Get an EpubCFI from a Dom node
+ * @param {node} node
+ * @param {string} [ignoreClass]
+ * @returns {EpubCFI} cfi
+ */
+ cfiFromNode(node, ignoreClass){
+ return new EpubCFI(node, this.cfiBase, ignoreClass).toString();
+ }
+
+ // TODO: find where this is used - remove?
+ map(layout){
+ var map = new Mapping(layout);
+ return map.section();
+ }
+
+ /**
+ * Size the contents to a given width and height
+ * @param {number} [width]
+ * @param {number} [height]
+ */
+ size(width, height){
+ var viewport = { scale: 1.0, scalable: "no" };
+
+ this.layoutStyle("scrolling");
+
+ if (width >= 0) {
+ this.width(width);
+ viewport.width = width;
+ this.css("padding", "0 "+(width/12)+"px");
+ }
+
+ if (height >= 0) {
+ this.height(height);
+ viewport.height = height;
+ }
+
+ this.css("margin", "0");
+ this.css("box-sizing", "border-box");
+
+
+ this.viewport(viewport);
+ }
+
+ /**
+ * Apply columns to the contents for pagination
+ * @param {number} width
+ * @param {number} height
+ * @param {number} columnWidth
+ * @param {number} gap
+ */
+ columns(width, height, columnWidth, gap, dir){
+ let COLUMN_AXIS = prefixed("column-axis");
+ let COLUMN_GAP = prefixed("column-gap");
+ let COLUMN_WIDTH = prefixed("column-width");
+ let COLUMN_FILL = prefixed("column-fill");
+
+ let writingMode = this.writingMode();
+ let axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
+
+ this.layoutStyle("paginated");
+
+ if (dir === "rtl" && axis === "horizontal") {
+ this.direction(dir);
+ }
+
+ this.width(width);
+ this.height(height);
+
+ // Deal with Mobile trying to scale to viewport
+ this.viewport({ width: width, height: height, scale: 1.0, scalable: "no" });
+
+ // TODO: inline-block needs more testing
+ // Fixes Safari column cut offs, but causes RTL issues
+ // this.css("display", "inline-block");
+
+ this.css("overflow-y", "hidden");
+ this.css("margin", "0", true);
+
+ if (axis === "vertical") {
+ this.css("padding-top", (gap / 2) + "px", true);
+ this.css("padding-bottom", (gap / 2) + "px", true);
+ this.css("padding-left", "20px");
+ this.css("padding-right", "20px");
+ this.css(COLUMN_AXIS, "vertical");
+ } else {
+ this.css("padding-top", "20px");
+ this.css("padding-bottom", "20px");
+ this.css("padding-left", (gap / 2) + "px", true);
+ this.css("padding-right", (gap / 2) + "px", true);
+ this.css(COLUMN_AXIS, "horizontal");
+ }
+
+ this.css("box-sizing", "border-box");
+ this.css("max-width", "inherit");
+
+ this.css(COLUMN_FILL, "auto");
+
+ this.css(COLUMN_GAP, gap+"px");
+ this.css(COLUMN_WIDTH, columnWidth+"px");
+
+ // Fix glyph clipping in WebKit
+ // https://github.com/futurepress/epub.js/issues/983
+ this.css("-webkit-line-box-contain", "block glyphs replaced");
+ }
+
+ /**
+ * Scale contents from center
+ * @param {number} scale
+ * @param {number} offsetX
+ * @param {number} offsetY
+ */
+ scaler(scale, offsetX, offsetY){
+ var scaleStr = "scale(" + scale + ")";
+ var translateStr = "";
+ // this.css("position", "absolute"));
+ this.css("transform-origin", "top left");
+
+ if (offsetX >= 0 || offsetY >= 0) {
+ translateStr = " translate(" + (offsetX || 0 )+ "px, " + (offsetY || 0 )+ "px )";
+ }
+
+ this.css("transform", scaleStr + translateStr);
+ }
+
+ /**
+ * Fit contents into a fixed width and height
+ * @param {number} width
+ * @param {number} height
+ */
+ fit(width, height, section){
+ var viewport = this.viewport();
+ var viewportWidth = parseInt(viewport.width);
+ var viewportHeight = parseInt(viewport.height);
+ var widthScale = width / viewportWidth;
+ var heightScale = height / viewportHeight;
+ var scale = widthScale < heightScale ? widthScale : heightScale;
+
+ // the translate does not work as intended, elements can end up unaligned
+ // var offsetY = (height - (viewportHeight * scale)) / 2;
+ // var offsetX = 0;
+ // if (this.sectionIndex % 2 === 1) {
+ // offsetX = width - (viewportWidth * scale);
+ // }
+
+ this.layoutStyle("paginated");
+
+ // scale needs width and height to be set
+ this.width(viewportWidth);
+ this.height(viewportHeight);
+ this.overflow("hidden");
+
+ // Scale to the correct size
+ this.scaler(scale, 0, 0);
+ // this.scaler(scale, offsetX > 0 ? offsetX : 0, offsetY);
+
+ // background images are not scaled by transform
+ this.css("background-size", viewportWidth * scale + "px " + viewportHeight * scale + "px");
+
+ this.css("background-color", "transparent");
+ if (section && section.properties.includes("page-spread-left")) {
+ // set margin since scale is weird
+ var marginLeft = width - (viewportWidth * scale);
+ this.css("margin-left", marginLeft + "px");
+ }
+ }
+
+ /**
+ * Set the direction of the text
+ * @param {string} [dir="ltr"] "rtl" | "ltr"
+ */
+ direction(dir) {
+ if (this.documentElement) {
+ this.documentElement.style["direction"] = dir;
+ }
+ }
+
+ mapPage(cfiBase, layout, start, end, dev) {
+ var mapping = new Mapping(layout, dev);
+
+ return mapping.page(this, cfiBase, start, end);
+ }
+
+ /**
+ * Emit event when link in content is clicked
+ * @private
+ */
+ linksHandler() {
+ replaceLinks(this.content, (href) => {
+ this.emit(EVENTS.CONTENTS.LINK_CLICKED, href);
+ });
+ }
+
+ /**
+ * Set the writingMode of the text
+ * @param {string} [mode="horizontal-tb"] "horizontal-tb" | "vertical-rl" | "vertical-lr"
+ */
+ writingMode(mode) {
+ let WRITING_MODE = prefixed("writing-mode");
+
+ if (mode && this.documentElement) {
+ this.documentElement.style[WRITING_MODE] = mode;
+ }
+
+ return this.window.getComputedStyle(this.documentElement)[WRITING_MODE] || '';
+ }
+
+ /**
+ * Set the layoutStyle of the content
+ * @param {string} [style="paginated"] "scrolling" | "paginated"
+ * @private
+ */
+ layoutStyle(style) {
+
+ if (style) {
+ this._layoutStyle = style;
+ navigator.epubReadingSystem.layoutStyle = this._layoutStyle;
+ }
+
+ return this._layoutStyle || "paginated";
+ }
+
+ /**
+ * Add the epubReadingSystem object to the navigator
+ * @param {string} name
+ * @param {string} version
+ * @private
+ */
+ epubReadingSystem(name, version) {
+ navigator.epubReadingSystem = {
+ name: name,
+ version: version,
+ layoutStyle: this.layoutStyle(),
+ hasFeature: function (feature) {
+ switch (feature) {
+ case "dom-manipulation":
+ return true;
+ case "layout-changes":
+ return true;
+ case "touch-events":
+ return true;
+ case "mouse-events":
+ return true;
+ case "keyboard-events":
+ return true;
+ case "spine-scripting":
+ return false;
+ default:
+ return false;
+ }
+ }
+ };
+ return navigator.epubReadingSystem;
+ }
+
+ destroy() {
+ // this.document.removeEventListener('transitionend', this._resizeCheck);
+
+ this.removeListeners();
+
+ }
+}
+
+EventEmitter(Contents.prototype);
+
+export default Contents;
diff --git a/lib/epub.js/src/displayoptions.js b/lib/epub.js/src/displayoptions.js
new file mode 100644
index 0000000..a2793e2
--- /dev/null
+++ b/lib/epub.js/src/displayoptions.js
@@ -0,0 +1,70 @@
+import {qs, qsa } from "./utils/core";
+
+/**
+ * Open DisplayOptions Format Parser
+ * @class
+ * @param {document} displayOptionsDocument XML
+ */
+class DisplayOptions {
+ constructor(displayOptionsDocument) {
+ this.interactive = "";
+ this.fixedLayout = "";
+ this.openToSpread = "";
+ this.orientationLock = "";
+
+ if (displayOptionsDocument) {
+ this.parse(displayOptionsDocument);
+ }
+ }
+
+ /**
+ * Parse XML
+ * @param {document} displayOptionsDocument XML
+ * @return {DisplayOptions} self
+ */
+ parse(displayOptionsDocument) {
+ if(!displayOptionsDocument) {
+ return this;
+ }
+
+ const displayOptionsNode = qs(displayOptionsDocument, "display_options");
+ if(!displayOptionsNode) {
+ return this;
+ }
+
+ const options = qsa(displayOptionsNode, "option");
+ options.forEach((el) => {
+ let value = "";
+
+ if (el.childNodes.length) {
+ value = el.childNodes[0].nodeValue;
+ }
+
+ switch (el.attributes.name.value) {
+ case "interactive":
+ this.interactive = value;
+ break;
+ case "fixed-layout":
+ this.fixedLayout = value;
+ break;
+ case "open-to-spread":
+ this.openToSpread = value;
+ break;
+ case "orientation-lock":
+ this.orientationLock = value;
+ break;
+ }
+ });
+
+ return this;
+ }
+
+ destroy() {
+ this.interactive = undefined;
+ this.fixedLayout = undefined;
+ this.openToSpread = undefined;
+ this.orientationLock = undefined;
+ }
+}
+
+export default DisplayOptions;
diff --git a/lib/epub.js/src/epub.js b/lib/epub.js/src/epub.js
new file mode 100644
index 0000000..e6fcdfb
--- /dev/null
+++ b/lib/epub.js/src/epub.js
@@ -0,0 +1,35 @@
+import Book from "./book";
+import Rendition from "./rendition";
+import CFI from "./epubcfi";
+import Contents from "./contents";
+import * as utils from "./utils/core";
+import { EPUBJS_VERSION } from "./utils/constants";
+
+import IframeView from "./managers/views/iframe";
+import DefaultViewManager from "./managers/default";
+import ContinuousViewManager from "./managers/continuous";
+
+/**
+ * Creates a new Book
+ * @param {string|ArrayBuffer} url URL, Path or ArrayBuffer
+ * @param {object} options to pass to the book
+ * @returns {Book} a new Book object
+ * @example ePub("/path/to/book.epub", {})
+ */
+function ePub(url, options) {
+ return new Book(url, options);
+}
+
+ePub.VERSION = EPUBJS_VERSION;
+
+if (typeof(global) !== "undefined") {
+ global.EPUBJS_VERSION = EPUBJS_VERSION;
+}
+
+ePub.Book = Book;
+ePub.Rendition = Rendition;
+ePub.Contents = Contents;
+ePub.CFI = CFI;
+ePub.utils = utils;
+
+export default ePub;
diff --git a/lib/epub.js/src/epubcfi.js b/lib/epub.js/src/epubcfi.js
new file mode 100644
index 0000000..77142a3
--- /dev/null
+++ b/lib/epub.js/src/epubcfi.js
@@ -0,0 +1,1048 @@
+import {extend, type, findChildren, RangeObject, isNumber} from "./utils/core";
+
+const ELEMENT_NODE = 1;
+const TEXT_NODE = 3;
+const COMMENT_NODE = 8;
+const DOCUMENT_NODE = 9;
+
+/**
+ * Parsing and creation of EpubCFIs: http://www.idpf.org/epub/linking/cfi/epub-cfi.html
+
+ * Implements:
+ * - Character Offset: epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)
+ * - Simple Ranges : epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)
+
+ * Does Not Implement:
+ * - Temporal Offset (~)
+ * - Spatial Offset (@)
+ * - Temporal-Spatial Offset (~ + @)
+ * - Text Location Assertion ([)
+ * @class
+ @param {string | Range | Node } [cfiFrom]
+ @param {string | object} [base]
+ @param {string} [ignoreClass] class to ignore when parsing DOM
+*/
+class EpubCFI {
+ constructor(cfiFrom, base, ignoreClass){
+ var type;
+
+ this.str = "";
+
+ this.base = {};
+ this.spinePos = 0; // For compatibility
+
+ this.range = false; // true || false;
+
+ this.path = {};
+ this.start = null;
+ this.end = null;
+
+ // Allow instantiation without the "new" keyword
+ if (!(this instanceof EpubCFI)) {
+ return new EpubCFI(cfiFrom, base, ignoreClass);
+ }
+
+ if(typeof base === "string") {
+ this.base = this.parseComponent(base);
+ } else if(typeof base === "object" && base.steps) {
+ this.base = base;
+ }
+
+ type = this.checkType(cfiFrom);
+
+
+ if(type === "string") {
+ this.str = cfiFrom;
+ return extend(this, this.parse(cfiFrom));
+ } else if (type === "range") {
+ return extend(this, this.fromRange(cfiFrom, this.base, ignoreClass));
+ } else if (type === "node") {
+ return extend(this, this.fromNode(cfiFrom, this.base, ignoreClass));
+ } else if (type === "EpubCFI" && cfiFrom.path) {
+ return cfiFrom;
+ } else if (!cfiFrom) {
+ return this;
+ } else {
+ throw new TypeError("not a valid argument for EpubCFI");
+ }
+
+ }
+
+ /**
+ * Check the type of constructor input
+ * @private
+ */
+ checkType(cfi) {
+
+ if (this.isCfiString(cfi)) {
+ return "string";
+ // Is a range object
+ } else if (cfi && typeof cfi === "object" && (type(cfi) === "Range" || typeof(cfi.startContainer) != "undefined")){
+ return "range";
+ } else if (cfi && typeof cfi === "object" && typeof(cfi.nodeType) != "undefined" ){ // || typeof cfi === "function"
+ return "node";
+ } else if (cfi && typeof cfi === "object" && cfi instanceof EpubCFI){
+ return "EpubCFI";
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Parse a cfi string to a CFI object representation
+ * @param {string} cfiStr
+ * @returns {object} cfi
+ */
+ parse(cfiStr) {
+ var cfi = {
+ spinePos: -1,
+ range: false,
+ base: {},
+ path: {},
+ start: null,
+ end: null
+ };
+ var baseComponent, pathComponent, range;
+
+ if(typeof cfiStr !== "string") {
+ return {spinePos: -1};
+ }
+
+ if(cfiStr.indexOf("epubcfi(") === 0 && cfiStr[cfiStr.length-1] === ")") {
+ // Remove intial epubcfi( and ending )
+ cfiStr = cfiStr.slice(8, cfiStr.length-1);
+ }
+
+ baseComponent = this.getChapterComponent(cfiStr);
+
+ // Make sure this is a valid cfi or return
+ if(!baseComponent) {
+ return {spinePos: -1};
+ }
+
+ cfi.base = this.parseComponent(baseComponent);
+
+ pathComponent = this.getPathComponent(cfiStr);
+ cfi.path = this.parseComponent(pathComponent);
+
+ range = this.getRange(cfiStr);
+
+ if(range) {
+ cfi.range = true;
+ cfi.start = this.parseComponent(range[0]);
+ cfi.end = this.parseComponent(range[1]);
+ }
+
+ // Get spine node position
+ // cfi.spineSegment = cfi.base.steps[1];
+
+ // Chapter segment is always the second step
+ cfi.spinePos = cfi.base.steps[1].index;
+
+ return cfi;
+ }
+
+ parseComponent(componentStr){
+ var component = {
+ steps: [],
+ terminal: {
+ offset: null,
+ assertion: null
+ }
+ };
+ var parts = componentStr.split(":");
+ var steps = parts[0].split("/");
+ var terminal;
+
+ if(parts.length > 1) {
+ terminal = parts[1];
+ component.terminal = this.parseTerminal(terminal);
+ }
+
+ if (steps[0] === "") {
+ steps.shift(); // Ignore the first slash
+ }
+
+ component.steps = steps.map(function(step){
+ return this.parseStep(step);
+ }.bind(this));
+
+ return component;
+ }
+
+ parseStep(stepStr){
+ var type, num, index, has_brackets, id;
+
+ has_brackets = stepStr.match(/\[(.*)\]/);
+ if(has_brackets && has_brackets[1]){
+ id = has_brackets[1];
+ }
+
+ //-- Check if step is a text node or element
+ num = parseInt(stepStr);
+
+ if(isNaN(num)) {
+ return;
+ }
+
+ if(num % 2 === 0) { // Even = is an element
+ type = "element";
+ index = num / 2 - 1;
+ } else {
+ type = "text";
+ index = (num - 1 ) / 2;
+ }
+
+ return {
+ "type" : type,
+ "index" : index,
+ "id" : id || null
+ };
+ }
+
+ parseTerminal(termialStr){
+ var characterOffset, textLocationAssertion;
+ var assertion = termialStr.match(/\[(.*)\]/);
+
+ if(assertion && assertion[1]){
+ characterOffset = parseInt(termialStr.split("[")[0]);
+ textLocationAssertion = assertion[1];
+ } else {
+ characterOffset = parseInt(termialStr);
+ }
+
+ if (!isNumber(characterOffset)) {
+ characterOffset = null;
+ }
+
+ return {
+ "offset": characterOffset,
+ "assertion": textLocationAssertion
+ };
+
+ }
+
+ getChapterComponent(cfiStr) {
+
+ var indirection = cfiStr.split("!");
+
+ return indirection[0];
+ }
+
+ getPathComponent(cfiStr) {
+
+ var indirection = cfiStr.split("!");
+
+ if(indirection[1]) {
+ let ranges = indirection[1].split(",");
+ return ranges[0];
+ }
+
+ }
+
+ getRange(cfiStr) {
+
+ var ranges = cfiStr.split(",");
+
+ if(ranges.length === 3){
+ return [
+ ranges[1],
+ ranges[2]
+ ];
+ }
+
+ return false;
+ }
+
+ getCharecterOffsetComponent(cfiStr) {
+ var splitStr = cfiStr.split(":");
+ return splitStr[1] || "";
+ }
+
+ joinSteps(steps) {
+ if(!steps) {
+ return "";
+ }
+
+ return steps.map(function(part){
+ var segment = "";
+
+ if(part.type === "element") {
+ segment += (part.index + 1) * 2;
+ }
+
+ if(part.type === "text") {
+ segment += 1 + (2 * part.index); // TODO: double check that this is odd
+ }
+
+ if(part.id) {
+ segment += "[" + part.id + "]";
+ }
+
+ return segment;
+
+ }).join("/");
+
+ }
+
+ segmentString(segment) {
+ var segmentString = "/";
+
+ segmentString += this.joinSteps(segment.steps);
+
+ if(segment.terminal && segment.terminal.offset != null){
+ segmentString += ":" + segment.terminal.offset;
+ }
+
+ if(segment.terminal && segment.terminal.assertion != null){
+ segmentString += "[" + segment.terminal.assertion + "]";
+ }
+
+ return segmentString;
+ }
+
+ /**
+ * Convert CFI to a epubcfi(...) string
+ * @returns {string} epubcfi
+ */
+ toString() {
+ var cfiString = "epubcfi(";
+
+ cfiString += this.segmentString(this.base);
+
+ cfiString += "!";
+ cfiString += this.segmentString(this.path);
+
+ // Add Range, if present
+ if(this.range && this.start) {
+ cfiString += ",";
+ cfiString += this.segmentString(this.start);
+ }
+
+ if(this.range && this.end) {
+ cfiString += ",";
+ cfiString += this.segmentString(this.end);
+ }
+
+ cfiString += ")";
+
+ return cfiString;
+ }
+
+
+ /**
+ * Compare which of two CFIs is earlier in the text
+ * @returns {number} First is earlier = -1, Second is earlier = 1, They are equal = 0
+ */
+ compare(cfiOne, cfiTwo) {
+ var stepsA, stepsB;
+ var terminalA, terminalB;
+
+ var rangeAStartSteps, rangeAEndSteps;
+ var rangeBEndSteps, rangeBEndSteps;
+ var rangeAStartTerminal, rangeAEndTerminal;
+ var rangeBStartTerminal, rangeBEndTerminal;
+
+ if(typeof cfiOne === "string") {
+ cfiOne = new EpubCFI(cfiOne);
+ }
+ if(typeof cfiTwo === "string") {
+ cfiTwo = new EpubCFI(cfiTwo);
+ }
+ // Compare Spine Positions
+ if(cfiOne.spinePos > cfiTwo.spinePos) {
+ return 1;
+ }
+ if(cfiOne.spinePos < cfiTwo.spinePos) {
+ return -1;
+ }
+
+ if (cfiOne.range) {
+ stepsA = cfiOne.path.steps.concat(cfiOne.start.steps);
+ terminalA = cfiOne.start.terminal;
+ } else {
+ stepsA = cfiOne.path.steps;
+ terminalA = cfiOne.path.terminal;
+ }
+
+ if (cfiTwo.range) {
+ stepsB = cfiTwo.path.steps.concat(cfiTwo.start.steps);
+ terminalB = cfiTwo.start.terminal;
+ } else {
+ stepsB = cfiTwo.path.steps;
+ terminalB = cfiTwo.path.terminal;
+ }
+
+ // Compare Each Step in the First item
+ for (var i = 0; i < stepsA.length; i++) {
+ if(!stepsA[i]) {
+ return -1;
+ }
+ if(!stepsB[i]) {
+ return 1;
+ }
+ if(stepsA[i].index > stepsB[i].index) {
+ return 1;
+ }
+ if(stepsA[i].index < stepsB[i].index) {
+ return -1;
+ }
+ // Otherwise continue checking
+ }
+
+ // All steps in First equal to Second and First is Less Specific
+ if(stepsA.length < stepsB.length) {
+ return -1;
+ }
+
+ // Compare the charecter offset of the text node
+ if(terminalA.offset > terminalB.offset) {
+ return 1;
+ }
+ if(terminalA.offset < terminalB.offset) {
+ return -1;
+ }
+
+ // CFI's are equal
+ return 0;
+ }
+
+ step(node) {
+ var nodeType = (node.nodeType === TEXT_NODE) ? "text" : "element";
+
+ return {
+ "id" : node.id,
+ "tagName" : node.tagName,
+ "type" : nodeType,
+ "index" : this.position(node)
+ };
+ }
+
+ filteredStep(node, ignoreClass) {
+ var filteredNode = this.filter(node, ignoreClass);
+ var nodeType;
+
+ // Node filtered, so ignore
+ if (!filteredNode) {
+ return;
+ }
+
+ // Otherwise add the filter node in
+ nodeType = (filteredNode.nodeType === TEXT_NODE) ? "text" : "element";
+
+ return {
+ "id" : filteredNode.id,
+ "tagName" : filteredNode.tagName,
+ "type" : nodeType,
+ "index" : this.filteredPosition(filteredNode, ignoreClass)
+ };
+ }
+
+ pathTo(node, offset, ignoreClass) {
+ var segment = {
+ steps: [],
+ terminal: {
+ offset: null,
+ assertion: null
+ }
+ };
+ var currentNode = node;
+ var step;
+
+ while(currentNode && currentNode.parentNode &&
+ currentNode.parentNode.nodeType != DOCUMENT_NODE) {
+
+ if (ignoreClass) {
+ step = this.filteredStep(currentNode, ignoreClass);
+ } else {
+ step = this.step(currentNode);
+ }
+
+ if (step) {
+ segment.steps.unshift(step);
+ }
+
+ currentNode = currentNode.parentNode;
+
+ }
+
+ if (offset != null && offset >= 0) {
+
+ segment.terminal.offset = offset;
+
+ // Make sure we are getting to a textNode if there is an offset
+ if(segment.steps[segment.steps.length-1].type != "text") {
+ segment.steps.push({
+ "type" : "text",
+ "index" : 0
+ });
+ }
+
+ }
+
+
+ return segment;
+ }
+
+ equalStep(stepA, stepB) {
+ if (!stepA || !stepB) {
+ return false;
+ }
+
+ if(stepA.index === stepB.index &&
+ stepA.id === stepB.id &&
+ stepA.type === stepB.type) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Create a CFI object from a Range
+ * @param {Range} range
+ * @param {string | object} base
+ * @param {string} [ignoreClass]
+ * @returns {object} cfi
+ */
+ fromRange(range, base, ignoreClass) {
+ var cfi = {
+ range: false,
+ base: {},
+ path: {},
+ start: null,
+ end: null
+ };
+
+ var start = range.startContainer;
+ var end = range.endContainer;
+
+ var startOffset = range.startOffset;
+ var endOffset = range.endOffset;
+
+ var needsIgnoring = false;
+
+ if (ignoreClass) {
+ // Tell pathTo if / what to ignore
+ needsIgnoring = (start.ownerDocument.querySelector("." + ignoreClass) != null);
+ }
+
+
+ if (typeof base === "string") {
+ cfi.base = this.parseComponent(base);
+ cfi.spinePos = cfi.base.steps[1].index;
+ } else if (typeof base === "object") {
+ cfi.base = base;
+ }
+
+ if (range.collapsed) {
+ if (needsIgnoring) {
+ startOffset = this.patchOffset(start, startOffset, ignoreClass);
+ }
+ cfi.path = this.pathTo(start, startOffset, ignoreClass);
+ } else {
+ cfi.range = true;
+
+ if (needsIgnoring) {
+ startOffset = this.patchOffset(start, startOffset, ignoreClass);
+ }
+
+ cfi.start = this.pathTo(start, startOffset, ignoreClass);
+ if (needsIgnoring) {
+ endOffset = this.patchOffset(end, endOffset, ignoreClass);
+ }
+
+ cfi.end = this.pathTo(end, endOffset, ignoreClass);
+
+ // Create a new empty path
+ cfi.path = {
+ steps: [],
+ terminal: null
+ };
+
+ // Push steps that are shared between start and end to the common path
+ var len = cfi.start.steps.length;
+ var i;
+
+ for (i = 0; i < len; i++) {
+ if (this.equalStep(cfi.start.steps[i], cfi.end.steps[i])) {
+ if(i === len-1) {
+ // Last step is equal, check terminals
+ if(cfi.start.terminal === cfi.end.terminal) {
+ // CFI's are equal
+ cfi.path.steps.push(cfi.start.steps[i]);
+ // Not a range
+ cfi.range = false;
+ }
+ } else {
+ cfi.path.steps.push(cfi.start.steps[i]);
+ }
+
+ } else {
+ break;
+ }
+ }
+
+ cfi.start.steps = cfi.start.steps.slice(cfi.path.steps.length);
+ cfi.end.steps = cfi.end.steps.slice(cfi.path.steps.length);
+
+ // TODO: Add Sanity check to make sure that the end if greater than the start
+ }
+
+ return cfi;
+ }
+
+ /**
+ * Create a CFI object from a Node
+ * @param {Node} anchor
+ * @param {string | object} base
+ * @param {string} [ignoreClass]
+ * @returns {object} cfi
+ */
+ fromNode(anchor, base, ignoreClass) {
+ var cfi = {
+ range: false,
+ base: {},
+ path: {},
+ start: null,
+ end: null
+ };
+
+ if (typeof base === "string") {
+ cfi.base = this.parseComponent(base);
+ cfi.spinePos = cfi.base.steps[1].index;
+ } else if (typeof base === "object") {
+ cfi.base = base;
+ }
+
+ cfi.path = this.pathTo(anchor, null, ignoreClass);
+
+ return cfi;
+ }
+
+ filter(anchor, ignoreClass) {
+ var needsIgnoring;
+ var sibling; // to join with
+ var parent, previousSibling, nextSibling;
+ var isText = false;
+
+ if (anchor.nodeType === TEXT_NODE) {
+ isText = true;
+ parent = anchor.parentNode;
+ needsIgnoring = anchor.parentNode.classList.contains(ignoreClass);
+ } else {
+ isText = false;
+ needsIgnoring = anchor.classList.contains(ignoreClass);
+ }
+
+ if (needsIgnoring && isText) {
+ previousSibling = parent.previousSibling;
+ nextSibling = parent.nextSibling;
+
+ // If the sibling is a text node, join the nodes
+ if (previousSibling && previousSibling.nodeType === TEXT_NODE) {
+ sibling = previousSibling;
+ } else if (nextSibling && nextSibling.nodeType === TEXT_NODE) {
+ sibling = nextSibling;
+ }
+
+ if (sibling) {
+ return sibling;
+ } else {
+ // Parent will be ignored on next step
+ return anchor;
+ }
+
+ } else if (needsIgnoring && !isText) {
+ // Otherwise just skip the element node
+ return false;
+ } else {
+ // No need to filter
+ return anchor;
+ }
+
+ }
+
+ patchOffset(anchor, offset, ignoreClass) {
+ if (anchor.nodeType != TEXT_NODE) {
+ throw new Error("Anchor must be a text node");
+ }
+
+ var curr = anchor;
+ var totalOffset = offset;
+
+ // If the parent is a ignored node, get offset from it's start
+ if (anchor.parentNode.classList.contains(ignoreClass)) {
+ curr = anchor.parentNode;
+ }
+
+ while (curr.previousSibling) {
+ if(curr.previousSibling.nodeType === ELEMENT_NODE) {
+ // Originally a text node, so join
+ if(curr.previousSibling.classList.contains(ignoreClass)){
+ totalOffset += curr.previousSibling.textContent.length;
+ } else {
+ break; // Normal node, dont join
+ }
+ } else {
+ // If the previous sibling is a text node, join the nodes
+ totalOffset += curr.previousSibling.textContent.length;
+ }
+
+ curr = curr.previousSibling;
+ }
+
+ return totalOffset;
+
+ }
+
+ normalizedMap(children, nodeType, ignoreClass) {
+ var output = {};
+ var prevIndex = -1;
+ var i, len = children.length;
+ var currNodeType;
+ var prevNodeType;
+
+ for (i = 0; i < len; i++) {
+
+ currNodeType = children[i].nodeType;
+
+ // Check if needs ignoring
+ if (currNodeType === ELEMENT_NODE &&
+ children[i].classList.contains(ignoreClass)) {
+ currNodeType = TEXT_NODE;
+ }
+
+ if (i > 0 &&
+ currNodeType === TEXT_NODE &&
+ prevNodeType === TEXT_NODE) {
+ // join text nodes
+ output[i] = prevIndex;
+ } else if (nodeType === currNodeType){
+ prevIndex = prevIndex + 1;
+ output[i] = prevIndex;
+ }
+
+ prevNodeType = currNodeType;
+
+ }
+
+ return output;
+ }
+
+ position(anchor) {
+ var children, index;
+ if (anchor.nodeType === ELEMENT_NODE) {
+ children = anchor.parentNode.children;
+ if (!children) {
+ children = findChildren(anchor.parentNode);
+ }
+ index = Array.prototype.indexOf.call(children, anchor);
+ } else {
+ children = this.textNodes(anchor.parentNode);
+ index = children.indexOf(anchor);
+ }
+
+ return index;
+ }
+
+ filteredPosition(anchor, ignoreClass) {
+ var children, index, map;
+
+ if (anchor.nodeType === ELEMENT_NODE) {
+ children = anchor.parentNode.children;
+ map = this.normalizedMap(children, ELEMENT_NODE, ignoreClass);
+ } else {
+ children = anchor.parentNode.childNodes;
+ // Inside an ignored node
+ if(anchor.parentNode.classList.contains(ignoreClass)) {
+ anchor = anchor.parentNode;
+ children = anchor.parentNode.childNodes;
+ }
+ map = this.normalizedMap(children, TEXT_NODE, ignoreClass);
+ }
+
+
+ index = Array.prototype.indexOf.call(children, anchor);
+
+ return map[index];
+ }
+
+ stepsToXpath(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("/");
+ }
+
+
+ /*
+
+ To get the last step if needed:
+
+ // Get the terminal step
+ lastStep = steps[steps.length-1];
+ // Get the query string
+ query = this.stepsToQuery(steps);
+ // Find the containing element
+ startContainerParent = doc.querySelector(query);
+ // Find the text node within that element
+ if(startContainerParent && lastStep.type == "text") {
+ container = startContainerParent.childNodes[lastStep.index];
+ }
+ */
+ stepsToQuerySelector(steps) {
+ var query = ["html"];
+
+ steps.forEach(function(step){
+ var position = step.index + 1;
+
+ if(step.id){
+ query.push("#" + step.id);
+ } else if(step.type === "text") {
+ // unsupported in querySelector
+ // query.push("text()[" + position + "]");
+ } else {
+ query.push("*:nth-child(" + position + ")");
+ }
+ });
+
+ return query.join(">");
+
+ }
+
+ textNodes(container, ignoreClass) {
+ return Array.prototype.slice.call(container.childNodes).
+ filter(function (node) {
+ if (node.nodeType === TEXT_NODE) {
+ return true;
+ } else if (ignoreClass && node.classList.contains(ignoreClass)) {
+ return true;
+ }
+ return false;
+ });
+ }
+
+ walkToNode(steps, _doc, ignoreClass) {
+ var doc = _doc || document;
+ var container = doc.documentElement;
+ var children;
+ var step;
+ var len = steps.length;
+ var i;
+
+ for (i = 0; i < len; i++) {
+ step = steps[i];
+
+ if(step.type === "element") {
+ //better to get a container using id as some times step.index may not be correct
+ //For ex.https://github.com/futurepress/epub.js/issues/561
+ if(step.id) {
+ container = doc.getElementById(step.id);
+ }
+ else {
+ children = container.children || findChildren(container);
+ container = children[step.index];
+ }
+ } else if(step.type === "text") {
+ container = this.textNodes(container, ignoreClass)[step.index];
+ }
+ if(!container) {
+ //Break the for loop as due to incorrect index we can get error if
+ //container is undefined so that other functionailties works fine
+ //like navigation
+ break;
+ }
+
+ }
+
+ return container;
+ }
+
+ findNode(steps, _doc, ignoreClass) {
+ var doc = _doc || document;
+ var container;
+ var xpath;
+
+ if(!ignoreClass && typeof doc.evaluate != "undefined") {
+ xpath = this.stepsToXpath(steps);
+ container = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+ } else if(ignoreClass) {
+ container = this.walkToNode(steps, doc, ignoreClass);
+ } else {
+ container = this.walkToNode(steps, doc);
+ }
+
+ return container;
+ }
+
+ fixMiss(steps, offset, _doc, ignoreClass) {
+ var container = this.findNode(steps.slice(0,-1), _doc, ignoreClass);
+ var children = container.childNodes;
+ var map = this.normalizedMap(children, TEXT_NODE, ignoreClass);
+ var child;
+ var len;
+ var lastStepIndex = steps[steps.length-1].index;
+
+ for (let childIndex in map) {
+ if (!map.hasOwnProperty(childIndex)) return;
+
+ if(map[childIndex] === lastStepIndex) {
+ child = children[childIndex];
+ len = child.textContent.length;
+ if(offset > len) {
+ offset = offset - len;
+ } else {
+ if (child.nodeType === ELEMENT_NODE) {
+ container = child.childNodes[0];
+ } else {
+ container = child;
+ }
+ break;
+ }
+ }
+ }
+
+ return {
+ container: container,
+ offset: offset
+ };
+
+ }
+
+ /**
+ * Creates a DOM range representing a CFI
+ * @param {document} _doc document referenced in the base
+ * @param {string} [ignoreClass]
+ * @return {Range}
+ */
+ toRange(_doc, ignoreClass) {
+ var doc = _doc || document;
+ var range;
+ var start, end, startContainer, endContainer;
+ var cfi = this;
+ var startSteps, endSteps;
+ var needsIgnoring = ignoreClass ? (doc.querySelector("." + ignoreClass) != null) : false;
+ var missed;
+
+ if (typeof(doc.createRange) !== "undefined") {
+ range = doc.createRange();
+ } else {
+ range = new RangeObject();
+ }
+
+ if (cfi.range) {
+ start = cfi.start;
+ startSteps = cfi.path.steps.concat(start.steps);
+ startContainer = this.findNode(startSteps, doc, needsIgnoring ? ignoreClass : null);
+ end = cfi.end;
+ endSteps = cfi.path.steps.concat(end.steps);
+ endContainer = this.findNode(endSteps, doc, needsIgnoring ? ignoreClass : null);
+ } else {
+ start = cfi.path;
+ startSteps = cfi.path.steps;
+ startContainer = this.findNode(cfi.path.steps, doc, needsIgnoring ? ignoreClass : null);
+ }
+
+ if(startContainer) {
+ try {
+
+ if(start.terminal.offset != null) {
+ range.setStart(startContainer, start.terminal.offset);
+ } else {
+ range.setStart(startContainer, 0);
+ }
+
+ } catch (e) {
+ missed = this.fixMiss(startSteps, start.terminal.offset, doc, needsIgnoring ? ignoreClass : null);
+ range.setStart(missed.container, missed.offset);
+ }
+ } else {
+ console.log("No startContainer found for", this.toString());
+ // No start found
+ return null;
+ }
+
+ if (endContainer) {
+ try {
+
+ if(end.terminal.offset != null) {
+ range.setEnd(endContainer, end.terminal.offset);
+ } else {
+ range.setEnd(endContainer, 0);
+ }
+
+ } catch (e) {
+ missed = this.fixMiss(endSteps, cfi.end.terminal.offset, doc, needsIgnoring ? ignoreClass : null);
+ range.setEnd(missed.container, missed.offset);
+ }
+ }
+
+
+ // doc.defaultView.getSelection().addRange(range);
+ return range;
+ }
+
+ /**
+ * Check if a string is wrapped with "epubcfi()"
+ * @param {string} str
+ * @returns {boolean}
+ */
+ isCfiString(str) {
+ if(typeof str === "string" &&
+ str.indexOf("epubcfi(") === 0 &&
+ str[str.length-1] === ")") {
+ return true;
+ }
+
+ return false;
+ }
+
+ generateChapterComponent(_spineNodeIndex, _pos, id) {
+ var pos = parseInt(_pos),
+ spineNodeIndex = (_spineNodeIndex + 1) * 2,
+ cfi = "/"+spineNodeIndex+"/";
+
+ cfi += (pos + 1) * 2;
+
+ if(id) {
+ cfi += "[" + id + "]";
+ }
+
+ return cfi;
+ }
+
+ /**
+ * Collapse a CFI Range to a single CFI Position
+ * @param {boolean} [toStart=false]
+ */
+ collapse(toStart) {
+ if (!this.range) {
+ return;
+ }
+
+ this.range = false;
+
+ if (toStart) {
+ this.path.steps = this.path.steps.concat(this.start.steps);
+ this.path.terminal = this.start.terminal;
+ } else {
+ this.path.steps = this.path.steps.concat(this.end.steps);
+ this.path.terminal = this.end.terminal;
+ }
+
+ }
+}
+
+export default EpubCFI;
diff --git a/lib/epub.js/src/index.js b/lib/epub.js/src/index.js
new file mode 100644
index 0000000..16ef8b6
--- /dev/null
+++ b/lib/epub.js/src/index.js
@@ -0,0 +1,15 @@
+import Book from "./book";
+import EpubCFI from "./epubcfi";
+import Rendition from "./rendition";
+import Contents from "./contents";
+import Layout from "./layout";
+import ePub from "./epub";
+
+export default ePub;
+export {
+ Book,
+ EpubCFI,
+ Rendition,
+ Contents,
+ Layout
+};
diff --git a/lib/epub.js/src/layout.js b/lib/epub.js/src/layout.js
new file mode 100644
index 0000000..4f16a0f
--- /dev/null
+++ b/lib/epub.js/src/layout.js
@@ -0,0 +1,260 @@
+import { extend } from "./utils/core";
+import { EVENTS } from "./utils/constants";
+import EventEmitter from "event-emitter";
+
+/**
+ * Figures out the CSS values to apply for a layout
+ * @class
+ * @param {object} settings
+ * @param {string} [settings.layout='reflowable']
+ * @param {string} [settings.spread]
+ * @param {number} [settings.minSpreadWidth=800]
+ * @param {boolean} [settings.evenSpreads=false]
+ */
+class Layout {
+ constructor(settings) {
+ this.settings = settings;
+ this.name = settings.layout || "reflowable";
+ this._spread = (settings.spread === "none") ? false : true;
+ this._minSpreadWidth = settings.minSpreadWidth || 800;
+ this._evenSpreads = settings.evenSpreads || false;
+
+ if (settings.flow === "scrolled" ||
+ settings.flow === "scrolled-continuous" ||
+ settings.flow === "scrolled-doc") {
+ this._flow = "scrolled";
+ } else {
+ this._flow = "paginated";
+ }
+
+
+ this.width = 0;
+ this.height = 0;
+ this.spreadWidth = 0;
+ this.delta = 0;
+
+ this.columnWidth = 0;
+ this.gap = 0;
+ this.divisor = 1;
+
+ this.props = {
+ name: this.name,
+ spread: this._spread,
+ flow: this._flow,
+ width: 0,
+ height: 0,
+ spreadWidth: 0,
+ delta: 0,
+ columnWidth: 0,
+ gap: 0,
+ divisor: 1
+ };
+
+ }
+
+ /**
+ * Switch the flow between paginated and scrolled
+ * @param {string} flow paginated | scrolled
+ * @return {string} simplified flow
+ */
+ flow(flow) {
+ if (typeof(flow) != "undefined") {
+ if (flow === "scrolled" ||
+ flow === "scrolled-continuous" ||
+ flow === "scrolled-doc") {
+ this._flow = "scrolled";
+ } else {
+ this._flow = "paginated";
+ }
+ // this.props.flow = this._flow;
+ this.update({flow: this._flow});
+ }
+ return this._flow;
+ }
+
+ /**
+ * Switch between using spreads or not, and set the
+ * width at which they switch to single.
+ * @param {string} spread "none" | "always" | "auto"
+ * @param {number} min integer in pixels
+ * @return {boolean} spread true | false
+ */
+ spread(spread, min) {
+
+ if (spread) {
+ this._spread = (spread === "none") ? false : true;
+ // this.props.spread = this._spread;
+ this.update({spread: this._spread});
+ }
+
+ if (min >= 0) {
+ this._minSpreadWidth = min;
+ }
+
+ return this._spread;
+ }
+
+ /**
+ * Calculate the dimensions of the pagination
+ * @param {number} _width width of the rendering
+ * @param {number} _height height of the rendering
+ * @param {number} _gap width of the gap between columns
+ */
+ calculate(_width, _height, _gap){
+
+ var divisor = 1;
+ var gap = _gap || 0;
+
+ //-- Check the width and create even width columns
+ // var fullWidth = Math.floor(_width);
+ var width = _width;
+ var height = _height;
+
+ var section = Math.floor(width / 12);
+
+ var columnWidth;
+ var spreadWidth;
+ var pageWidth;
+ var delta;
+
+ if (this._spread && width >= this._minSpreadWidth) {
+ divisor = 2;
+ } else {
+ divisor = 1;
+ }
+
+ if (this.name === "reflowable" && this._flow === "paginated" && !(_gap >= 0)) {
+ gap = ((section % 2 === 0) ? section : section - 1);
+ }
+
+ if (this.name === "pre-paginated" ) {
+ gap = 0;
+ }
+
+ //-- Double Page
+ if(divisor > 1) {
+ // width = width - gap;
+ // columnWidth = (width - gap) / divisor;
+ // gap = gap / divisor;
+ columnWidth = (width / divisor) - gap;
+ pageWidth = columnWidth + gap;
+ } else {
+ columnWidth = width;
+ pageWidth = width;
+ }
+
+ if (this.name === "pre-paginated" && divisor > 1) {
+ width = columnWidth;
+ }
+
+ spreadWidth = (columnWidth * divisor) + gap;
+
+ delta = width;
+
+ this.width = width;
+ this.height = height;
+ this.spreadWidth = spreadWidth;
+ this.pageWidth = pageWidth;
+ this.delta = delta;
+
+ this.columnWidth = columnWidth;
+ this.gap = gap;
+ this.divisor = divisor;
+
+ // this.props.width = width;
+ // this.props.height = _height;
+ // this.props.spreadWidth = spreadWidth;
+ // this.props.pageWidth = pageWidth;
+ // this.props.delta = delta;
+ //
+ // this.props.columnWidth = colWidth;
+ // this.props.gap = gap;
+ // this.props.divisor = divisor;
+
+ this.update({
+ width,
+ height,
+ spreadWidth,
+ pageWidth,
+ delta,
+ columnWidth,
+ gap,
+ divisor
+ });
+
+ }
+
+ /**
+ * Apply Css to a Document
+ * @param {Contents} contents
+ * @return {Promise}
+ */
+ format(contents, section, axis){
+ var formating;
+
+ if (this.name === "pre-paginated") {
+ formating = contents.fit(this.columnWidth, this.height, section);
+ } else if (this._flow === "paginated") {
+ formating = contents.columns(this.width, this.height, this.columnWidth, this.gap, this.settings.direction);
+ } else if (axis && axis === "horizontal") {
+ formating = contents.size(null, this.height);
+ } else {
+ formating = contents.size(this.width, null);
+ }
+
+ return formating; // might be a promise in some View Managers
+ }
+
+ /**
+ * Count number of pages
+ * @param {number} totalLength
+ * @param {number} pageLength
+ * @return {{spreads: Number, pages: Number}}
+ */
+ count(totalLength, pageLength) {
+
+ let spreads, pages;
+
+ if (this.name === "pre-paginated") {
+ spreads = 1;
+ pages = 1;
+ } else if (this._flow === "paginated") {
+ pageLength = pageLength || this.delta;
+ spreads = Math.ceil( totalLength / pageLength);
+ pages = spreads * this.divisor;
+ } else { // scrolled
+ pageLength = pageLength || this.height;
+ spreads = Math.ceil( totalLength / pageLength);
+ pages = spreads;
+ }
+
+ return {
+ spreads,
+ pages
+ };
+
+ }
+
+ /**
+ * Update props that have changed
+ * @private
+ * @param {object} props
+ */
+ update(props) {
+ // Remove props that haven't changed
+ Object.keys(props).forEach((propName) => {
+ if (this.props[propName] === props[propName]) {
+ delete props[propName];
+ }
+ });
+
+ if(Object.keys(props).length > 0) {
+ let newProps = extend(this.props, props);
+ this.emit(EVENTS.LAYOUT.UPDATED, newProps, props);
+ }
+ }
+}
+
+EventEmitter(Layout.prototype);
+
+export default Layout;
diff --git a/lib/epub.js/src/locations.js b/lib/epub.js/src/locations.js
new file mode 100644
index 0000000..913c40d
--- /dev/null
+++ b/lib/epub.js/src/locations.js
@@ -0,0 +1,501 @@
+import {qs, sprint, locationOf, defer} from "./utils/core";
+import Queue from "./utils/queue";
+import EpubCFI from "./epubcfi";
+import { EVENTS } from "./utils/constants";
+import EventEmitter from "event-emitter";
+
+/**
+ * Find Locations for a Book
+ * @param {Spine} spine
+ * @param {request} request
+ * @param {number} [pause=100]
+ */
+class Locations {
+ constructor(spine, request, pause) {
+ this.spine = spine;
+ this.request = request;
+ this.pause = pause || 100;
+
+ this.q = new Queue(this);
+ this.epubcfi = new EpubCFI();
+
+ this._locations = [];
+ this._locationsWords = [];
+ this.total = 0;
+
+ this.break = 150;
+
+ this._current = 0;
+
+ this._wordCounter = 0;
+
+ this.currentLocation = '';
+ this._currentCfi ='';
+ this.processingTimeout = undefined;
+ }
+
+ /**
+ * Load all of sections in the book to generate locations
+ * @param {int} chars how many chars to split on
+ * @return {object} locations
+ */
+ generate(chars) {
+
+ if (chars) {
+ this.break = chars;
+ }
+
+ this.q.pause();
+
+ this.spine.each(function(section) {
+ if (section.linear) {
+ this.q.enqueue(this.process.bind(this), section);
+ }
+ }.bind(this));
+
+ return this.q.run().then(function() {
+ this.total = this._locations.length - 1;
+
+ if (this._currentCfi) {
+ this.currentLocation = this._currentCfi;
+ }
+
+ return this._locations;
+ // console.log(this.percentage(this.book.rendition.location.start), this.percentage(this.book.rendition.location.end));
+ }.bind(this));
+
+ }
+
+ createRange () {
+ return {
+ startContainer: undefined,
+ startOffset: undefined,
+ endContainer: undefined,
+ endOffset: undefined
+ };
+ }
+
+ process(section) {
+
+ return section.load(this.request)
+ .then(function(contents) {
+ var completed = new defer();
+ var locations = this.parse(contents, section.cfiBase);
+ this._locations = this._locations.concat(locations);
+
+ section.unload();
+
+ this.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);
+ return completed.promise;
+ }.bind(this));
+
+ }
+
+ parse(contents, cfiBase, chars) {
+ var locations = [];
+ var range;
+ var doc = contents.ownerDocument;
+ var body = qs(doc, "body");
+ var counter = 0;
+ var prev;
+ var _break = chars || this.break;
+ var parser = function(node) {
+ var len = node.length;
+ var dist;
+ var pos = 0;
+
+ if (node.textContent.trim().length === 0) {
+ return false; // continue
+ }
+
+ // Start range
+ if (counter == 0) {
+ range = this.createRange();
+ range.startContainer = node;
+ range.startOffset = 0;
+ }
+
+ dist = _break - counter;
+
+ // Node is smaller than a break,
+ // skip over it
+ if(dist > len){
+ counter += len;
+ pos = len;
+ }
+
+
+ while (pos < len) {
+ dist = _break - counter;
+
+ if (counter === 0) {
+ // Start new range
+ pos += 1;
+ range = this.createRange();
+ range.startContainer = node;
+ range.startOffset = pos;
+ }
+
+ // pos += dist;
+
+ // Gone over
+ if(pos + dist >= len){
+ // Continue counter for next node
+ counter += len - pos;
+ // break
+ pos = len;
+ // At End
+ } else {
+ // Advance pos
+ pos += dist;
+
+ // End the previous range
+ range.endContainer = node;
+ range.endOffset = pos;
+ // cfi = section.cfiFromRange(range);
+ let cfi = new EpubCFI(range, cfiBase).toString();
+ locations.push(cfi);
+ counter = 0;
+ }
+ }
+ prev = node;
+ };
+
+ sprint(body, parser.bind(this));
+
+ // Close remaining
+ if (range && range.startContainer && prev) {
+ range.endContainer = prev;
+ range.endOffset = prev.length;
+ let cfi = new EpubCFI(range, cfiBase).toString();
+ locations.push(cfi);
+ counter = 0;
+ }
+
+ return locations;
+ }
+
+
+ /**
+ * Load all of sections in the book to generate locations
+ * @param {string} startCfi start position
+ * @param {int} wordCount how many words to split on
+ * @param {int} count result count
+ * @return {object} locations
+ */
+ generateFromWords(startCfi, wordCount, count) {
+ var start = startCfi ? new EpubCFI(startCfi) : undefined;
+ this.q.pause();
+ this._locationsWords = [];
+ this._wordCounter = 0;
+
+ this.spine.each(function(section) {
+ if (section.linear) {
+ if (start) {
+ if (section.index >= start.spinePos) {
+ this.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);
+ }
+ } else {
+ this.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);
+ }
+ }
+ }.bind(this));
+
+ return this.q.run().then(function() {
+ if (this._currentCfi) {
+ this.currentLocation = this._currentCfi;
+ }
+
+ return this._locationsWords;
+ }.bind(this));
+
+ }
+
+ processWords(section, wordCount, startCfi, count) {
+ if (count && this._locationsWords.length >= count) {
+ return Promise.resolve();
+ }
+
+ return section.load(this.request)
+ .then(function(contents) {
+ var completed = new defer();
+ var locations = this.parseWords(contents, section, wordCount, startCfi);
+ var remainingCount = count - this._locationsWords.length;
+ this._locationsWords = this._locationsWords.concat(locations.length >= count ? locations.slice(0, remainingCount) : locations);
+
+ section.unload();
+
+ this.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);
+ return completed.promise;
+ }.bind(this));
+ }
+
+ //http://stackoverflow.com/questions/18679576/counting-words-in-string
+ countWords(s) {
+ s = s.replace(/(^\s*)|(\s*$)/gi, "");//exclude start and end white-space
+ s = s.replace(/[ ]{2,}/gi, " ");//2 or more space to 1
+ s = s.replace(/\n /, "\n"); // exclude newline with a start spacing
+ return s.split(" ").length;
+ }
+
+ parseWords(contents, section, wordCount, startCfi) {
+ var cfiBase = section.cfiBase;
+ var locations = [];
+ var doc = contents.ownerDocument;
+ var body = qs(doc, "body");
+ var prev;
+ var _break = wordCount;
+ var foundStartNode = startCfi ? startCfi.spinePos !== section.index : true;
+ var startNode;
+ if (startCfi && section.index === startCfi.spinePos) {
+ startNode = startCfi.findNode(startCfi.range ? startCfi.path.steps.concat(startCfi.start.steps) : startCfi.path.steps, contents.ownerDocument);
+ }
+ var parser = function(node) {
+ if (!foundStartNode) {
+ if (node === startNode) {
+ foundStartNode = true;
+ } else {
+ return false;
+ }
+ }
+ if (node.textContent.length < 10) {
+ if (node.textContent.trim().length === 0) {
+ return false;
+ }
+ }
+ var len = this.countWords(node.textContent);
+ var dist;
+ var pos = 0;
+
+ if (len === 0) {
+ return false; // continue
+ }
+
+ dist = _break - this._wordCounter;
+
+ // Node is smaller than a break,
+ // skip over it
+ if (dist > len) {
+ this._wordCounter += len;
+ pos = len;
+ }
+
+
+ while (pos < len) {
+ dist = _break - this._wordCounter;
+
+ // Gone over
+ if (pos + dist >= len) {
+ // Continue counter for next node
+ this._wordCounter += len - pos;
+ // break
+ pos = len;
+ // At End
+ } else {
+ // Advance pos
+ pos += dist;
+
+ let cfi = new EpubCFI(node, cfiBase);
+ locations.push({ cfi: cfi.toString(), wordCount: this._wordCounter });
+ this._wordCounter = 0;
+ }
+ }
+ prev = node;
+ };
+
+ sprint(body, parser.bind(this));
+
+ return locations;
+ }
+
+ /**
+ * Get a location from an EpubCFI
+ * @param {EpubCFI} cfi
+ * @return {number}
+ */
+ locationFromCfi(cfi){
+ let loc;
+ if (EpubCFI.prototype.isCfiString(cfi)) {
+ cfi = new EpubCFI(cfi);
+ }
+ // Check if the location has not been set yet
+ if(this._locations.length === 0) {
+ return -1;
+ }
+
+ loc = locationOf(cfi, this._locations, this.epubcfi.compare);
+
+ if (loc > this.total) {
+ return this.total;
+ }
+
+ return loc;
+ }
+
+ /**
+ * Get a percentage position in locations from an EpubCFI
+ * @param {EpubCFI} cfi
+ * @return {number}
+ */
+ percentageFromCfi(cfi) {
+ if(this._locations.length === 0) {
+ return null;
+ }
+ // Find closest cfi
+ var loc = this.locationFromCfi(cfi);
+ // Get percentage in total
+ return this.percentageFromLocation(loc);
+ }
+
+ /**
+ * Get a percentage position from a location index
+ * @param {number} location
+ * @return {number}
+ */
+ percentageFromLocation(loc) {
+ if (!loc || !this.total) {
+ return 0;
+ }
+
+ return (loc / this.total);
+ }
+
+ /**
+ * Get an EpubCFI from location index
+ * @param {number} loc
+ * @return {EpubCFI} cfi
+ */
+ cfiFromLocation(loc){
+ var cfi = -1;
+ // check that pg is an int
+ if(typeof loc != "number"){
+ loc = parseInt(loc);
+ }
+
+ if(loc >= 0 && loc < this._locations.length) {
+ cfi = this._locations[loc];
+ }
+
+ return cfi;
+ }
+
+ /**
+ * Get an EpubCFI from location percentage
+ * @param {number} percentage
+ * @return {EpubCFI} cfi
+ */
+ cfiFromPercentage(percentage){
+ let loc;
+ if (percentage > 1) {
+ console.warn("Normalize cfiFromPercentage value to between 0 - 1");
+ }
+
+ // Make sure 1 goes to very end
+ if (percentage >= 1) {
+ let cfi = new EpubCFI(this._locations[this.total]);
+ cfi.collapse();
+ return cfi.toString();
+ }
+
+ loc = Math.ceil(this.total * percentage);
+ return this.cfiFromLocation(loc);
+ }
+
+ /**
+ * Load locations from JSON
+ * @param {json} locations
+ */
+ load(locations){
+ if (typeof locations === "string") {
+ this._locations = JSON.parse(locations);
+ } else {
+ this._locations = locations;
+ }
+ this.total = this._locations.length - 1;
+ return this._locations;
+ }
+
+ /**
+ * Save locations to JSON
+ * @return {json}
+ */
+ save(){
+ return JSON.stringify(this._locations);
+ }
+
+ getCurrent(){
+ return this._current;
+ }
+
+ setCurrent(curr){
+ var loc;
+
+ if(typeof curr == "string"){
+ this._currentCfi = curr;
+ } else if (typeof curr == "number") {
+ this._current = curr;
+ } else {
+ return;
+ }
+
+ if(this._locations.length === 0) {
+ return;
+ }
+
+ if(typeof curr == "string"){
+ loc = this.locationFromCfi(curr);
+ this._current = loc;
+ } else {
+ loc = curr;
+ }
+
+ this.emit(EVENTS.LOCATIONS.CHANGED, {
+ percentage: this.percentageFromLocation(loc)
+ });
+ }
+
+ /**
+ * Get the current location
+ */
+ get currentLocation() {
+ return this._current;
+ }
+
+ /**
+ * Set the current location
+ */
+ set currentLocation(curr) {
+ this.setCurrent(curr);
+ }
+
+ /**
+ * Locations length
+ */
+ length () {
+ return this._locations.length;
+ }
+
+ destroy () {
+ this.spine = undefined;
+ this.request = undefined;
+ this.pause = undefined;
+
+ this.q.stop();
+ this.q = undefined;
+ this.epubcfi = undefined;
+
+ this._locations = undefined
+ this.total = undefined;
+
+ this.break = undefined;
+ this._current = undefined;
+
+ this.currentLocation = undefined;
+ this._currentCfi = undefined;
+ clearTimeout(this.processingTimeout);
+ }
+}
+
+EventEmitter(Locations.prototype);
+
+export default Locations;
diff --git a/lib/epub.js/src/managers/continuous/index.js b/lib/epub.js/src/managers/continuous/index.js
new file mode 100644
index 0000000..e6a9e61
--- /dev/null
+++ b/lib/epub.js/src/managers/continuous/index.js
@@ -0,0 +1,588 @@
+import {extend, defer, requestAnimationFrame} from "../../utils/core";
+import DefaultViewManager from "../default";
+import Snap from "../helpers/snap";
+import { EVENTS } from "../../utils/constants";
+import debounce from "lodash/debounce";
+
+class ContinuousViewManager extends DefaultViewManager {
+ constructor(options) {
+ super(options);
+
+ this.name = "continuous";
+
+ this.settings = extend(this.settings || {}, {
+ infinite: true,
+ overflow: undefined,
+ axis: undefined,
+ writingMode: undefined,
+ flow: "scrolled",
+ offset: 500,
+ offsetDelta: 250,
+ width: undefined,
+ height: undefined,
+ snap: false,
+ afterScrolledTimeout: 10
+ });
+
+ extend(this.settings, options.settings || {});
+
+ // Gap can be 0, but defaults doesn't handle that
+ if (options.settings.gap != "undefined" && options.settings.gap === 0) {
+ this.settings.gap = options.settings.gap;
+ }
+
+ this.viewSettings = {
+ ignoreClass: this.settings.ignoreClass,
+ axis: this.settings.axis,
+ flow: this.settings.flow,
+ layout: this.layout,
+ width: 0,
+ height: 0,
+ forceEvenPages: false
+ };
+
+ this.scrollTop = 0;
+ this.scrollLeft = 0;
+ }
+
+ display(section, target){
+ return DefaultViewManager.prototype.display.call(this, section, target)
+ .then(function () {
+ return this.fill();
+ }.bind(this));
+ }
+
+ fill(_full){
+ var full = _full || new defer();
+
+ this.q.enqueue(() => {
+ return this.check();
+ }).then((result) => {
+ if (result) {
+ this.fill(full);
+ } else {
+ full.resolve();
+ }
+ });
+
+ return full.promise;
+ }
+
+ moveTo(offset){
+ // var bounds = this.stage.bounds();
+ // var dist = Math.floor(offset.top / bounds.height) * bounds.height;
+ var distX = 0,
+ distY = 0;
+
+ var offsetX = 0,
+ offsetY = 0;
+
+ if(!this.isPaginated) {
+ distY = offset.top;
+ offsetY = offset.top+this.settings.offsetDelta;
+ } else {
+ distX = Math.floor(offset.left / this.layout.delta) * this.layout.delta;
+ offsetX = distX+this.settings.offsetDelta;
+ }
+
+ if (distX > 0 || distY > 0) {
+ this.scrollBy(distX, distY, true);
+ }
+ }
+
+ afterResized(view){
+ this.emit(EVENTS.MANAGERS.RESIZE, view.section);
+ }
+
+ // Remove Previous Listeners if present
+ removeShownListeners(view){
+
+ // view.off("shown", this.afterDisplayed);
+ // view.off("shown", this.afterDisplayedAbove);
+ view.onDisplayed = function(){};
+
+ }
+
+ add(section){
+ var view = this.createView(section);
+
+ this.views.append(view);
+
+ view.on(EVENTS.VIEWS.RESIZED, (bounds) => {
+ view.expanded = true;
+ });
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ // view.on(EVENTS.VIEWS.SHOWN, this.afterDisplayed.bind(this));
+ view.onDisplayed = this.afterDisplayed.bind(this);
+ view.onResize = this.afterResized.bind(this);
+
+ return view.display(this.request);
+ }
+
+ append(section){
+ var view = this.createView(section);
+
+ view.on(EVENTS.VIEWS.RESIZED, (bounds) => {
+ view.expanded = true;
+ });
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ this.views.append(view);
+
+ view.onDisplayed = this.afterDisplayed.bind(this);
+
+ return view;
+ }
+
+ prepend(section){
+ var view = this.createView(section);
+
+ view.on(EVENTS.VIEWS.RESIZED, (bounds) => {
+ this.counter(bounds);
+ view.expanded = true;
+ });
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ this.views.prepend(view);
+
+ view.onDisplayed = this.afterDisplayed.bind(this);
+
+ return view;
+ }
+
+ counter(bounds){
+ if(this.settings.axis === "vertical") {
+ this.scrollBy(0, bounds.heightDelta, true);
+ } else {
+ this.scrollBy(bounds.widthDelta, 0, true);
+ }
+ }
+
+ update(_offset){
+ var container = this.bounds();
+ var views = this.views.all();
+ var viewsLength = views.length;
+ var visible = [];
+ var offset = typeof _offset != "undefined" ? _offset : (this.settings.offset || 0);
+ var isVisible;
+ var view;
+
+ var updating = new defer();
+ var promises = [];
+ for (var i = 0; i < viewsLength; i++) {
+ view = views[i];
+
+ isVisible = this.isVisible(view, offset, offset, container);
+
+ if(isVisible === true) {
+ // console.log("visible " + view.index, view.displayed);
+
+ if (!view.displayed) {
+ let displayed = view.display(this.request)
+ .then(function (view) {
+ view.show();
+ }, (err) => {
+ view.hide();
+ });
+ promises.push(displayed);
+ } else {
+ view.show();
+ }
+ visible.push(view);
+ } else {
+ this.q.enqueue(view.destroy.bind(view));
+ // console.log("hidden " + view.index, view.displayed);
+
+ clearTimeout(this.trimTimeout);
+ this.trimTimeout = setTimeout(function(){
+ this.q.enqueue(this.trim.bind(this));
+ }.bind(this), 250);
+ }
+
+ }
+
+ if(promises.length){
+ return Promise.all(promises)
+ .catch((err) => {
+ updating.reject(err);
+ });
+ } else {
+ updating.resolve();
+ return updating.promise;
+ }
+
+ }
+
+ check(_offsetLeft, _offsetTop){
+ var checking = new defer();
+ var newViews = [];
+
+ var horizontal = (this.settings.axis === "horizontal");
+ var delta = this.settings.offset || 0;
+
+ if (_offsetLeft && horizontal) {
+ delta = _offsetLeft;
+ }
+
+ if (_offsetTop && !horizontal) {
+ delta = _offsetTop;
+ }
+
+ var bounds = this._bounds; // bounds saved this until resize
+
+ let offset = horizontal ? this.scrollLeft : this.scrollTop;
+ let visibleLength = horizontal ? Math.floor(bounds.width) : bounds.height;
+ let contentLength = horizontal ? this.container.scrollWidth : this.container.scrollHeight;
+ let writingMode = (this.writingMode && this.writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
+ let rtlScrollType = this.settings.rtlScrollType;
+ let rtl = this.settings.direction === "rtl";
+
+ if (!this.settings.fullsize) {
+ // Scroll offset starts at width of element
+ if (rtl && rtlScrollType === "default" && writingMode === "horizontal") {
+ offset = contentLength - visibleLength - offset;
+ }
+ // Scroll offset starts at 0 and goes negative
+ if (rtl && rtlScrollType === "negative" && writingMode === "horizontal") {
+ offset = offset * -1;
+ }
+ } else {
+ // Scroll offset starts at 0 and goes negative
+ if ((horizontal && rtl && rtlScrollType === "negative") ||
+ (!horizontal && rtl && rtlScrollType === "default")) {
+ offset = offset * -1;
+ }
+ }
+
+ let prepend = () => {
+ let first = this.views.first();
+ let prev = first && first.section.prev();
+
+ if(prev) {
+ newViews.push(this.prepend(prev));
+ }
+ };
+
+ let append = () => {
+ let last = this.views.last();
+ let next = last && last.section.next();
+
+ if(next) {
+ newViews.push(this.append(next));
+ }
+
+ };
+
+ let end = offset + visibleLength + delta;
+ let start = offset - delta;
+
+ if (end >= contentLength) {
+ append();
+ }
+
+ if (start < 0) {
+ prepend();
+ }
+
+
+ let promises = newViews.map((view) => {
+ return view.display(this.request);
+ });
+
+ if(newViews.length){
+ return Promise.all(promises)
+ .then(() => {
+ return this.check();
+ })
+ .then(() => {
+ // Check to see if anything new is on screen after rendering
+ return this.update(delta);
+ }, (err) => {
+ return err;
+ });
+ } else {
+ this.q.enqueue(function(){
+ this.update();
+ }.bind(this));
+ checking.resolve(false);
+ return checking.promise;
+ }
+
+
+ }
+
+ trim(){
+ var task = new defer();
+ var displayed = this.views.displayed();
+ var first = displayed[0];
+ var last = displayed[displayed.length-1];
+ var firstIndex = this.views.indexOf(first);
+ var lastIndex = this.views.indexOf(last);
+ var above = this.views.slice(0, firstIndex);
+ var below = this.views.slice(lastIndex+1);
+
+ // Erase all but last above
+ for (var i = 0; i < above.length-1; i++) {
+ this.erase(above[i], above);
+ }
+
+ // Erase all except first below
+ for (var j = 1; j < below.length; j++) {
+ this.erase(below[j]);
+ }
+
+ task.resolve();
+ return task.promise;
+ }
+
+ erase(view, above){ //Trim
+
+ var prevTop;
+ var prevLeft;
+
+ if(!this.settings.fullsize) {
+ prevTop = this.container.scrollTop;
+ prevLeft = this.container.scrollLeft;
+ } else {
+ prevTop = window.scrollY;
+ prevLeft = window.scrollX;
+ }
+
+ var bounds = view.bounds();
+
+ this.views.remove(view);
+
+ if(above) {
+ if (this.settings.axis === "vertical") {
+ this.scrollTo(0, prevTop - bounds.height, true);
+ } else {
+ if(this.settings.direction === 'rtl') {
+ if (!this.settings.fullsize) {
+ this.scrollTo(prevLeft, 0, true);
+ } else {
+ this.scrollTo(prevLeft + Math.floor(bounds.width), 0, true);
+ }
+ } else {
+ this.scrollTo(prevLeft - Math.floor(bounds.width), 0, true);
+ }
+ }
+ }
+
+ }
+
+ addEventListeners(stage){
+
+ window.addEventListener("unload", function(e){
+ this.ignore = true;
+ // this.scrollTo(0,0);
+ this.destroy();
+ }.bind(this));
+
+ this.addScrollListeners();
+
+ if (this.isPaginated && this.settings.snap) {
+ this.snapper = new Snap(this, this.settings.snap && (typeof this.settings.snap === "object") && this.settings.snap);
+ }
+ }
+
+ addScrollListeners() {
+ var scroller;
+
+ this.tick = requestAnimationFrame;
+
+ let dir = this.settings.direction === "rtl" && this.settings.rtlScrollType === "default" ? -1 : 1;
+
+ this.scrollDeltaVert = 0;
+ this.scrollDeltaHorz = 0;
+
+ if(!this.settings.fullsize) {
+ scroller = this.container;
+ this.scrollTop = this.container.scrollTop;
+ this.scrollLeft = this.container.scrollLeft;
+ } else {
+ scroller = window;
+ this.scrollTop = window.scrollY * dir;
+ this.scrollLeft = window.scrollX * dir;
+ }
+
+ this._onScroll = this.onScroll.bind(this);
+ scroller.addEventListener("scroll", this._onScroll);
+ this._scrolled = debounce(this.scrolled.bind(this), 30);
+ // this.tick.call(window, this.onScroll.bind(this));
+
+ this.didScroll = false;
+
+ }
+
+ removeEventListeners(){
+ var scroller;
+
+ if(!this.settings.fullsize) {
+ scroller = this.container;
+ } else {
+ scroller = window;
+ }
+
+ scroller.removeEventListener("scroll", this._onScroll);
+ this._onScroll = undefined;
+ }
+
+ onScroll(){
+ let scrollTop;
+ let scrollLeft;
+ let dir = this.settings.direction === "rtl" && this.settings.rtlScrollType === "default" ? -1 : 1;
+
+ if(!this.settings.fullsize) {
+ scrollTop = this.container.scrollTop;
+ scrollLeft = this.container.scrollLeft;
+ } else {
+ scrollTop = window.scrollY * dir;
+ scrollLeft = window.scrollX * dir;
+ }
+
+ this.scrollTop = scrollTop;
+ this.scrollLeft = scrollLeft;
+
+ if(!this.ignore) {
+
+ this._scrolled();
+
+ } else {
+ this.ignore = false;
+ }
+
+ this.scrollDeltaVert += Math.abs(scrollTop-this.prevScrollTop);
+ this.scrollDeltaHorz += Math.abs(scrollLeft-this.prevScrollLeft);
+
+ this.prevScrollTop = scrollTop;
+ this.prevScrollLeft = scrollLeft;
+
+ clearTimeout(this.scrollTimeout);
+ this.scrollTimeout = setTimeout(function(){
+ this.scrollDeltaVert = 0;
+ this.scrollDeltaHorz = 0;
+ }.bind(this), 150);
+
+ clearTimeout(this.afterScrolled);
+
+ this.didScroll = false;
+
+ }
+
+ scrolled() {
+
+ this.q.enqueue(function() {
+ return this.check();
+ }.bind(this));
+
+ this.emit(EVENTS.MANAGERS.SCROLL, {
+ top: this.scrollTop,
+ left: this.scrollLeft
+ });
+
+ clearTimeout(this.afterScrolled);
+ this.afterScrolled = setTimeout(function () {
+
+ // Don't report scroll if we are about the snap
+ if (this.snapper && this.snapper.supportsTouch && this.snapper.needsSnap()) {
+ return;
+ }
+
+ this.emit(EVENTS.MANAGERS.SCROLLED, {
+ top: this.scrollTop,
+ left: this.scrollLeft
+ });
+
+ }.bind(this), this.settings.afterScrolledTimeout);
+ }
+
+ next(){
+
+ let delta = this.layout.props.name === "pre-paginated" &&
+ this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
+
+ if(!this.views.length) return;
+
+ if(this.isPaginated && this.settings.axis === "horizontal") {
+
+ this.scrollBy(delta, 0, true);
+
+ } else {
+
+ this.scrollBy(0, this.layout.height, true);
+
+ }
+
+ this.q.enqueue(function() {
+ return this.check();
+ }.bind(this));
+ }
+
+ prev(){
+
+ let delta = this.layout.props.name === "pre-paginated" &&
+ this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
+
+ if(!this.views.length) return;
+
+ if(this.isPaginated && this.settings.axis === "horizontal") {
+
+ this.scrollBy(-delta, 0, true);
+
+ } else {
+
+ this.scrollBy(0, -this.layout.height, true);
+
+ }
+
+ this.q.enqueue(function() {
+ return this.check();
+ }.bind(this));
+ }
+
+ updateFlow(flow){
+ if (this.rendered && this.snapper) {
+ this.snapper.destroy();
+ this.snapper = undefined;
+ }
+
+ super.updateFlow(flow, "scroll");
+
+ if (this.rendered && this.isPaginated && this.settings.snap) {
+ this.snapper = new Snap(this, this.settings.snap && (typeof this.settings.snap === "object") && this.settings.snap);
+ }
+ }
+
+ destroy(){
+ super.destroy();
+
+ if (this.snapper) {
+ this.snapper.destroy();
+ }
+ }
+
+}
+
+export default ContinuousViewManager;
diff --git a/lib/epub.js/src/managers/default/index.js b/lib/epub.js/src/managers/default/index.js
new file mode 100644
index 0000000..b24a4f6
--- /dev/null
+++ b/lib/epub.js/src/managers/default/index.js
@@ -0,0 +1,1073 @@
+import EventEmitter from "event-emitter";
+import {extend, defer, windowBounds, isNumber} from "../../utils/core";
+import scrollType from "../../utils/scrolltype";
+import Mapping from "../../mapping";
+import Queue from "../../utils/queue";
+import Stage from "../helpers/stage";
+import Views from "../helpers/views";
+import { EVENTS } from "../../utils/constants";
+
+class DefaultViewManager {
+ constructor(options) {
+
+ this.name = "default";
+ this.optsSettings = options.settings;
+ this.View = options.view;
+ this.request = options.request;
+ this.renditionQueue = options.queue;
+ this.q = new Queue(this);
+
+ this.settings = extend(this.settings || {}, {
+ infinite: true,
+ hidden: false,
+ width: undefined,
+ height: undefined,
+ axis: undefined,
+ writingMode: undefined,
+ flow: "scrolled",
+ ignoreClass: "",
+ fullsize: undefined
+ });
+
+ extend(this.settings, options.settings || {});
+
+ this.viewSettings = {
+ ignoreClass: this.settings.ignoreClass,
+ axis: this.settings.axis,
+ flow: this.settings.flow,
+ layout: this.layout,
+ method: this.settings.method, // srcdoc, blobUrl, write
+ width: 0,
+ height: 0,
+ forceEvenPages: true
+ };
+
+ this.rendered = false;
+
+ }
+
+ render(element, size){
+ let tag = element.tagName;
+
+ if (typeof this.settings.fullsize === "undefined" &&
+ tag && (tag.toLowerCase() == "body" ||
+ tag.toLowerCase() == "html")) {
+ this.settings.fullsize = true;
+ }
+
+ if (this.settings.fullsize) {
+ this.settings.overflow = "visible";
+ this.overflow = this.settings.overflow;
+ }
+
+ this.settings.size = size;
+
+ this.settings.rtlScrollType = scrollType();
+
+ // Save the stage
+ this.stage = new Stage({
+ width: size.width,
+ height: size.height,
+ overflow: this.overflow,
+ hidden: this.settings.hidden,
+ axis: this.settings.axis,
+ fullsize: this.settings.fullsize,
+ direction: this.settings.direction
+ });
+
+ this.stage.attachTo(element);
+
+ // Get this stage container div
+ this.container = this.stage.getContainer();
+
+ // Views array methods
+ this.views = new Views(this.container);
+
+ // Calculate Stage Size
+ this._bounds = this.bounds();
+ this._stageSize = this.stage.size();
+
+ // Set the dimensions for views
+ this.viewSettings.width = this._stageSize.width;
+ this.viewSettings.height = this._stageSize.height;
+
+ // Function to handle a resize event.
+ // Will only attach if width and height are both fixed.
+ this.stage.onResize(this.onResized.bind(this));
+
+ this.stage.onOrientationChange(this.onOrientationChange.bind(this));
+
+ // Add Event Listeners
+ this.addEventListeners();
+
+ // Add Layout method
+ // this.applyLayoutMethod();
+ if (this.layout) {
+ this.updateLayout();
+ }
+
+ this.rendered = true;
+
+ }
+
+ addEventListeners(){
+ var scroller;
+
+ window.addEventListener("unload", function(e){
+ this.destroy();
+ }.bind(this));
+
+ if(!this.settings.fullsize) {
+ scroller = this.container;
+ } else {
+ scroller = window;
+ }
+
+ this._onScroll = this.onScroll.bind(this);
+ scroller.addEventListener("scroll", this._onScroll);
+ }
+
+ removeEventListeners(){
+ var scroller;
+
+ if(!this.settings.fullsize) {
+ scroller = this.container;
+ } else {
+ scroller = window;
+ }
+
+ scroller.removeEventListener("scroll", this._onScroll);
+ this._onScroll = undefined;
+ }
+
+ destroy(){
+ clearTimeout(this.orientationTimeout);
+ clearTimeout(this.resizeTimeout);
+ clearTimeout(this.afterScrolled);
+
+ this.clear();
+
+ this.removeEventListeners();
+
+ this.stage.destroy();
+
+ this.rendered = false;
+
+ /*
+
+ clearTimeout(this.trimTimeout);
+ if(this.settings.hidden) {
+ this.element.removeChild(this.wrapper);
+ } else {
+ this.element.removeChild(this.container);
+ }
+ */
+ }
+
+ onOrientationChange(e) {
+ let {orientation} = window;
+
+ if(this.optsSettings.resizeOnOrientationChange) {
+ this.resize();
+ }
+
+ // Per ampproject:
+ // In IOS 10.3, the measured size of an element is incorrect if the
+ // element size depends on window size directly and the measurement
+ // happens in window.resize event. Adding a timeout for correct
+ // measurement. See https://github.com/ampproject/amphtml/issues/8479
+ clearTimeout(this.orientationTimeout);
+ this.orientationTimeout = setTimeout(function(){
+ this.orientationTimeout = undefined;
+
+ if(this.optsSettings.resizeOnOrientationChange) {
+ this.resize();
+ }
+
+ this.emit(EVENTS.MANAGERS.ORIENTATION_CHANGE, orientation);
+ }.bind(this), 500);
+
+ }
+
+ onResized(e) {
+ this.resize();
+ }
+
+ resize(width, height, epubcfi){
+ let stageSize = this.stage.size(width, height);
+
+ // For Safari, wait for orientation to catch up
+ // if the window is a square
+ this.winBounds = windowBounds();
+ if (this.orientationTimeout &&
+ this.winBounds.width === this.winBounds.height) {
+ // reset the stage size for next resize
+ this._stageSize = undefined;
+ return;
+ }
+
+ if (this._stageSize &&
+ this._stageSize.width === stageSize.width &&
+ this._stageSize.height === stageSize.height ) {
+ // Size is the same, no need to resize
+ return;
+ }
+
+ this._stageSize = stageSize;
+
+ this._bounds = this.bounds();
+
+ // Clear current views
+ this.clear();
+
+ // Update for new views
+ this.viewSettings.width = this._stageSize.width;
+ this.viewSettings.height = this._stageSize.height;
+
+ this.updateLayout();
+
+ this.emit(EVENTS.MANAGERS.RESIZED, {
+ width: this._stageSize.width,
+ height: this._stageSize.height
+ }, epubcfi);
+ }
+
+ createView(section, forceRight) {
+ return new this.View(section, extend(this.viewSettings, { forceRight }) );
+ }
+
+ handleNextPrePaginated(forceRight, section, action) {
+ let next;
+
+ if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) {
+ if (forceRight || section.index === 0) {
+ // First page (cover) should stand alone for pre-paginated books
+ return;
+ }
+ next = section.next();
+ if (next && !next.properties.includes("page-spread-left")) {
+ return action.call(this, next);
+ }
+ }
+ }
+
+ display(section, target){
+
+ var displaying = new defer();
+ var displayed = displaying.promise;
+
+ // Check if moving to target is needed
+ if (target === section.href || isNumber(target)) {
+ target = undefined;
+ }
+
+ // Check to make sure the section we want isn't already shown
+ var visible = this.views.find(section);
+
+ // View is already shown, just move to correct location in view
+ if(visible && section && this.layout.name !== "pre-paginated") {
+ let offset = visible.offset();
+
+ if (this.settings.direction === "ltr") {
+ this.scrollTo(offset.left, offset.top, true);
+ } else {
+ let width = visible.width();
+ this.scrollTo(offset.left + width, offset.top, true);
+ }
+
+ if(target) {
+ let offset = visible.locationOf(target);
+ let width = visible.width();
+ this.moveTo(offset, width);
+ }
+
+ displaying.resolve();
+ return displayed;
+ }
+
+ // Hide all current views
+ this.clear();
+
+ let forceRight = false;
+ if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && section.properties.includes("page-spread-right")) {
+ forceRight = true;
+ }
+
+ this.add(section, forceRight)
+ .then(function(view){
+
+ // Move to correct place within the section, if needed
+ if(target) {
+ let offset = view.locationOf(target);
+ let width = view.width();
+ this.moveTo(offset, width);
+ }
+
+ }.bind(this), (err) => {
+ displaying.reject(err);
+ })
+ .then(function(){
+ return this.handleNextPrePaginated(forceRight, section, this.add);
+ }.bind(this))
+ .then(function(){
+
+ this.views.show();
+
+ displaying.resolve();
+
+ }.bind(this));
+ // .then(function(){
+ // return this.hooks.display.trigger(view);
+ // }.bind(this))
+ // .then(function(){
+ // this.views.show();
+ // }.bind(this));
+ return displayed;
+ }
+
+ afterDisplayed(view){
+ this.emit(EVENTS.MANAGERS.ADDED, view);
+ }
+
+ afterResized(view){
+ this.emit(EVENTS.MANAGERS.RESIZE, view.section);
+ }
+
+ moveTo(offset, width){
+ var distX = 0,
+ distY = 0;
+
+ if(!this.isPaginated) {
+ distY = offset.top;
+ } else {
+ distX = Math.floor(offset.left / this.layout.delta) * this.layout.delta;
+
+ if (distX + this.layout.delta > this.container.scrollWidth) {
+ distX = this.container.scrollWidth - this.layout.delta;
+ }
+
+ distY = Math.floor(offset.top / this.layout.delta) * this.layout.delta;
+
+ if (distY + this.layout.delta > this.container.scrollHeight) {
+ distY = this.container.scrollHeight - this.layout.delta;
+ }
+ }
+ if(this.settings.direction === 'rtl'){
+ /***
+ the `floor` function above (L343) is on positive values, so we should add one `layout.delta`
+ to distX or use `Math.ceil` function, or multiply offset.left by -1
+ before `Math.floor`
+ */
+ distX = distX + this.layout.delta
+ distX = distX - width
+ }
+ this.scrollTo(distX, distY, true);
+ }
+
+ add(section, forceRight){
+ var view = this.createView(section, forceRight);
+
+ this.views.append(view);
+
+ // view.on(EVENTS.VIEWS.SHOWN, this.afterDisplayed.bind(this));
+ view.onDisplayed = this.afterDisplayed.bind(this);
+ view.onResize = this.afterResized.bind(this);
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ return view.display(this.request);
+ }
+
+ append(section, forceRight){
+ var view = this.createView(section, forceRight);
+ this.views.append(view);
+
+ view.onDisplayed = this.afterDisplayed.bind(this);
+ view.onResize = this.afterResized.bind(this);
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ return view.display(this.request);
+ }
+
+ prepend(section, forceRight){
+ var view = this.createView(section, forceRight);
+
+ view.on(EVENTS.VIEWS.RESIZED, (bounds) => {
+ this.counter(bounds);
+ });
+
+ this.views.prepend(view);
+
+ view.onDisplayed = this.afterDisplayed.bind(this);
+ view.onResize = this.afterResized.bind(this);
+
+ view.on(EVENTS.VIEWS.AXIS, (axis) => {
+ this.updateAxis(axis);
+ });
+
+ view.on(EVENTS.VIEWS.WRITING_MODE, (mode) => {
+ this.updateWritingMode(mode);
+ });
+
+ return view.display(this.request);
+ }
+
+ counter(bounds){
+ if(this.settings.axis === "vertical") {
+ this.scrollBy(0, bounds.heightDelta, true);
+ } else {
+ this.scrollBy(bounds.widthDelta, 0, true);
+ }
+
+ }
+
+ // resizeView(view) {
+ //
+ // if(this.settings.globalLayoutProperties.layout === "pre-paginated") {
+ // view.lock("both", this.bounds.width, this.bounds.height);
+ // } else {
+ // view.lock("width", this.bounds.width, this.bounds.height);
+ // }
+ //
+ // };
+
+ next(){
+ var next;
+ var left;
+
+ let dir = this.settings.direction;
+
+ if(!this.views.length) return;
+
+ if(this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) {
+
+ this.scrollLeft = this.container.scrollLeft;
+
+ left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta;
+
+ if(left <= this.container.scrollWidth) {
+ this.scrollBy(this.layout.delta, 0, true);
+ } else {
+ next = this.views.last().section.next();
+ }
+ } else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") {
+
+ this.scrollLeft = this.container.scrollLeft;
+
+ if (this.settings.rtlScrollType === "default"){
+ left = this.container.scrollLeft;
+
+ if (left > 0) {
+ this.scrollBy(this.layout.delta, 0, true);
+ } else {
+ next = this.views.last().section.next();
+ }
+ } else {
+ left = this.container.scrollLeft + ( this.layout.delta * -1 );
+
+ if (left > this.container.scrollWidth * -1){
+ this.scrollBy(this.layout.delta, 0, true);
+ } else {
+ next = this.views.last().section.next();
+ }
+ }
+
+ } else if (this.isPaginated && this.settings.axis === "vertical") {
+
+ this.scrollTop = this.container.scrollTop;
+
+ let top = this.container.scrollTop + this.container.offsetHeight;
+
+ if(top < this.container.scrollHeight) {
+ this.scrollBy(0, this.layout.height, true);
+ } else {
+ next = this.views.last().section.next();
+ }
+
+ } else {
+ next = this.views.last().section.next();
+ }
+
+ if(next) {
+ this.clear();
+ // The new section may have a different writing-mode from the old section. Thus, we need to update layout.
+ this.updateLayout();
+
+ let forceRight = false;
+ if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && next.properties.includes("page-spread-right")) {
+ forceRight = true;
+ }
+
+ return this.append(next, forceRight)
+ .then(function(){
+ return this.handleNextPrePaginated(forceRight, next, this.append);
+ }.bind(this), (err) => {
+ return err;
+ })
+ .then(function(){
+
+ // Reset position to start for scrolled-doc vertical-rl in default mode
+ if (!this.isPaginated &&
+ this.settings.axis === "horizontal" &&
+ this.settings.direction === "rtl" &&
+ this.settings.rtlScrollType === "default") {
+
+ this.scrollTo(this.container.scrollWidth, 0, true);
+ }
+ this.views.show();
+ }.bind(this));
+ }
+
+
+ }
+
+ prev(){
+ var prev;
+ var left;
+ let dir = this.settings.direction;
+
+ if(!this.views.length) return;
+
+ if(this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) {
+
+ this.scrollLeft = this.container.scrollLeft;
+
+ left = this.container.scrollLeft;
+
+ if(left > 0) {
+ this.scrollBy(-this.layout.delta, 0, true);
+ } else {
+ prev = this.views.first().section.prev();
+ }
+
+ } else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") {
+
+ this.scrollLeft = this.container.scrollLeft;
+
+ if (this.settings.rtlScrollType === "default"){
+ left = this.container.scrollLeft + this.container.offsetWidth;
+
+ if (left < this.container.scrollWidth) {
+ this.scrollBy(-this.layout.delta, 0, true);
+ } else {
+ prev = this.views.first().section.prev();
+ }
+ }
+ else{
+ left = this.container.scrollLeft;
+
+ if (left < 0) {
+ this.scrollBy(-this.layout.delta, 0, true);
+ } else {
+ prev = this.views.first().section.prev();
+ }
+ }
+
+ } else if (this.isPaginated && this.settings.axis === "vertical") {
+
+ this.scrollTop = this.container.scrollTop;
+
+ let top = this.container.scrollTop;
+
+ if(top > 0) {
+ this.scrollBy(0, -(this.layout.height), true);
+ } else {
+ prev = this.views.first().section.prev();
+ }
+
+ } else {
+
+ prev = this.views.first().section.prev();
+
+ }
+
+ if(prev) {
+ this.clear();
+ // The new section may have a different writing-mode from the old section. Thus, we need to update layout.
+ this.updateLayout();
+
+ let forceRight = false;
+ if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && typeof prev.prev() !== "object") {
+ forceRight = true;
+ }
+
+ return this.prepend(prev, forceRight)
+ .then(function(){
+ var left;
+ if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) {
+ left = prev.prev();
+ if (left) {
+ return this.prepend(left);
+ }
+ }
+ }.bind(this), (err) => {
+ return err;
+ })
+ .then(function(){
+ if(this.isPaginated && this.settings.axis === "horizontal") {
+ if (this.settings.direction === "rtl") {
+ if (this.settings.rtlScrollType === "default"){
+ this.scrollTo(0, 0, true);
+ }
+ else{
+ this.scrollTo((this.container.scrollWidth * -1) + this.layout.delta, 0, true);
+ }
+ } else {
+ this.scrollTo(this.container.scrollWidth - this.layout.delta, 0, true);
+ }
+ }
+ this.views.show();
+ }.bind(this));
+ }
+ }
+
+ current(){
+ var visible = this.visible();
+ if(visible.length){
+ // Current is the last visible view
+ return visible[visible.length-1];
+ }
+ return null;
+ }
+
+ clear () {
+
+ // this.q.clear();
+
+ if (this.views) {
+ this.views.hide();
+ this.scrollTo(0,0, true);
+ this.views.clear();
+ }
+ }
+
+ currentLocation(){
+ this.updateLayout();
+ if (this.isPaginated && this.settings.axis === "horizontal") {
+ this.location = this.paginatedLocation();
+ } else {
+ this.location = this.scrolledLocation();
+ }
+ return this.location;
+ }
+
+ scrolledLocation() {
+ let visible = this.visible();
+ let container = this.container.getBoundingClientRect();
+ let pageHeight = (container.height < window.innerHeight) ? container.height : window.innerHeight;
+ let pageWidth = (container.width < window.innerWidth) ? container.width : window.innerWidth;
+ let vertical = (this.settings.axis === "vertical");
+ let rtl = (this.settings.direction === "rtl");
+
+ let offset = 0;
+ let used = 0;
+
+ if(this.settings.fullsize) {
+ offset = vertical ? window.scrollY : window.scrollX;
+ }
+
+ let sections = visible.map((view) => {
+ let {index, href} = view.section;
+ let position = view.position();
+ let width = view.width();
+ let height = view.height();
+
+ let startPos;
+ let endPos;
+ let stopPos;
+ let totalPages;
+
+ if (vertical) {
+ startPos = offset + container.top - position.top + used;
+ endPos = startPos + pageHeight - used;
+ totalPages = this.layout.count(height, pageHeight).pages;
+ stopPos = pageHeight;
+ } else {
+ startPos = offset + container.left - position.left + used;
+ endPos = startPos + pageWidth - used;
+ totalPages = this.layout.count(width, pageWidth).pages;
+ stopPos = pageWidth;
+ }
+
+ let currPage = Math.ceil(startPos / stopPos);
+ let pages = [];
+ let endPage = Math.ceil(endPos / stopPos);
+
+ // Reverse page counts for horizontal rtl
+ if (this.settings.direction === "rtl" && !vertical) {
+ let tempStartPage = currPage;
+ currPage = totalPages - endPage;
+ endPage = totalPages - tempStartPage;
+ }
+
+ pages = [];
+ for (var i = currPage; i <= endPage; i++) {
+ let pg = i + 1;
+ pages.push(pg);
+ }
+
+ let mapping = this.mapping.page(view.contents, view.section.cfiBase, startPos, endPos);
+
+ return {
+ index,
+ href,
+ pages,
+ totalPages,
+ mapping
+ };
+ });
+
+ return sections;
+ }
+
+ paginatedLocation(){
+ let visible = this.visible();
+ let container = this.container.getBoundingClientRect();
+
+ let left = 0;
+ let used = 0;
+
+ if(this.settings.fullsize) {
+ left = window.scrollX;
+ }
+
+ let sections = visible.map((view) => {
+ let {index, href} = view.section;
+ let offset;
+ let position = view.position();
+ let width = view.width();
+
+ // Find mapping
+ let start;
+ let end;
+ let pageWidth;
+
+ if (this.settings.direction === "rtl") {
+ offset = container.right - left;
+ pageWidth = Math.min(Math.abs(offset - position.left), this.layout.width) - used;
+ end = position.width - (position.right - offset) - used;
+ start = end - pageWidth;
+ } else {
+ offset = container.left + left;
+ pageWidth = Math.min(position.right - offset, this.layout.width) - used;
+ start = offset - position.left + used;
+ end = start + pageWidth;
+ }
+
+ used += pageWidth;
+
+ let mapping = this.mapping.page(view.contents, view.section.cfiBase, start, end);
+
+ let totalPages = this.layout.count(width).pages;
+ let startPage = Math.floor(start / this.layout.pageWidth);
+ let pages = [];
+ let endPage = Math.floor(end / this.layout.pageWidth);
+
+ // start page should not be negative
+ if (startPage < 0) {
+ startPage = 0;
+ endPage = endPage + 1;
+ }
+
+ // Reverse page counts for rtl
+ if (this.settings.direction === "rtl") {
+ let tempStartPage = startPage;
+ startPage = totalPages - endPage;
+ endPage = totalPages - tempStartPage;
+ }
+
+
+ for (var i = startPage + 1; i <= endPage; i++) {
+ let pg = i;
+ pages.push(pg);
+ }
+
+ return {
+ index,
+ href,
+ pages,
+ totalPages,
+ mapping
+ };
+ });
+
+ return sections;
+ }
+
+ isVisible(view, offsetPrev, offsetNext, _container){
+ var position = view.position();
+ var container = _container || this.bounds();
+
+ if(this.settings.axis === "horizontal" &&
+ position.right > container.left - offsetPrev &&
+ position.left < container.right + offsetNext) {
+
+ return true;
+
+ } else if(this.settings.axis === "vertical" &&
+ position.bottom > container.top - offsetPrev &&
+ position.top < container.bottom + offsetNext) {
+
+ return true;
+ }
+
+ return false;
+
+ }
+
+ visible(){
+ var container = this.bounds();
+ var views = this.views.displayed();
+ var viewsLength = views.length;
+ var visible = [];
+ var isVisible;
+ var view;
+
+ for (var i = 0; i < viewsLength; i++) {
+ view = views[i];
+ isVisible = this.isVisible(view, 0, 0, container);
+
+ if(isVisible === true) {
+ visible.push(view);
+ }
+
+ }
+ return visible;
+ }
+
+ scrollBy(x, y, silent){
+ let dir = this.settings.direction === "rtl" ? -1 : 1;
+
+ if(silent) {
+ this.ignore = true;
+ }
+
+ if(!this.settings.fullsize) {
+ if(x) this.container.scrollLeft += x * dir;
+ if(y) this.container.scrollTop += y;
+ } else {
+ window.scrollBy(x * dir, y * dir);
+ }
+ this.scrolled = true;
+ }
+
+ scrollTo(x, y, silent){
+ if(silent) {
+ this.ignore = true;
+ }
+
+ if(!this.settings.fullsize) {
+ this.container.scrollLeft = x;
+ this.container.scrollTop = y;
+ } else {
+ window.scrollTo(x,y);
+ }
+ this.scrolled = true;
+ }
+
+ onScroll(){
+ let scrollTop;
+ let scrollLeft;
+
+ if(!this.settings.fullsize) {
+ scrollTop = this.container.scrollTop;
+ scrollLeft = this.container.scrollLeft;
+ } else {
+ scrollTop = window.scrollY;
+ scrollLeft = window.scrollX;
+ }
+
+ this.scrollTop = scrollTop;
+ this.scrollLeft = scrollLeft;
+
+ if(!this.ignore) {
+ this.emit(EVENTS.MANAGERS.SCROLL, {
+ top: scrollTop,
+ left: scrollLeft
+ });
+
+ clearTimeout(this.afterScrolled);
+ this.afterScrolled = setTimeout(function () {
+ this.emit(EVENTS.MANAGERS.SCROLLED, {
+ top: this.scrollTop,
+ left: this.scrollLeft
+ });
+ }.bind(this), 20);
+
+
+
+ } else {
+ this.ignore = false;
+ }
+
+ }
+
+ bounds() {
+ var bounds;
+
+ bounds = this.stage.bounds();
+
+ return bounds;
+ }
+
+ applyLayout(layout) {
+
+ this.layout = layout;
+ this.updateLayout();
+ if (this.views && this.views.length > 0 && this.layout.name === "pre-paginated") {
+ this.display(this.views.first().section);
+ }
+ // this.manager.layout(this.layout.format);
+ }
+
+ updateLayout() {
+
+ if (!this.stage) {
+ return;
+ }
+
+ this._stageSize = this.stage.size();
+
+ if(!this.isPaginated) {
+ this.layout.calculate(this._stageSize.width, this._stageSize.height);
+ } else {
+ this.layout.calculate(
+ this._stageSize.width,
+ this._stageSize.height,
+ this.settings.gap
+ );
+
+ // Set the look ahead offset for what is visible
+ this.settings.offset = this.layout.delta / this.layout.divisor;
+
+ // this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]);
+
+ }
+
+ // Set the dimensions for views
+ this.viewSettings.width = this.layout.width;
+ this.viewSettings.height = this.layout.height;
+
+ this.setLayout(this.layout);
+ }
+
+ setLayout(layout){
+
+ this.viewSettings.layout = layout;
+
+ this.mapping = new Mapping(layout.props, this.settings.direction, this.settings.axis);
+
+ if(this.views) {
+
+ this.views.forEach(function(view){
+ if (view) {
+ view.setLayout(layout);
+ }
+ });
+
+ }
+
+ }
+
+ updateWritingMode(mode) {
+ this.writingMode = mode;
+ }
+
+ updateAxis(axis, forceUpdate){
+
+ if (!forceUpdate && axis === this.settings.axis) {
+ return;
+ }
+
+ this.settings.axis = axis;
+
+ this.stage && this.stage.axis(axis);
+
+ this.viewSettings.axis = axis;
+
+ if (this.mapping) {
+ this.mapping = new Mapping(this.layout.props, this.settings.direction, this.settings.axis);
+ }
+
+ if (this.layout) {
+ if (axis === "vertical") {
+ this.layout.spread("none");
+ } else {
+ this.layout.spread(this.layout.settings.spread);
+ }
+ }
+ }
+
+ updateFlow(flow, defaultScrolledOverflow="auto"){
+ let isPaginated = (flow === "paginated" || flow === "auto");
+
+ this.isPaginated = isPaginated;
+
+ if (flow === "scrolled-doc" ||
+ flow === "scrolled-continuous" ||
+ flow === "scrolled") {
+ this.updateAxis("vertical");
+ } else {
+ this.updateAxis("horizontal");
+ }
+
+ this.viewSettings.flow = flow;
+
+ if (!this.settings.overflow) {
+ this.overflow = isPaginated ? "hidden" : defaultScrolledOverflow;
+ } else {
+ this.overflow = this.settings.overflow;
+ }
+
+ this.stage && this.stage.overflow(this.overflow);
+
+ this.updateLayout();
+
+ }
+
+ getContents(){
+ var contents = [];
+ if (!this.views) {
+ return contents;
+ }
+ this.views.forEach(function(view){
+ const viewContents = view && view.contents;
+ if (viewContents) {
+ contents.push(viewContents);
+ }
+ });
+ return contents;
+ }
+
+ direction(dir="ltr") {
+ this.settings.direction = dir;
+
+ this.stage && this.stage.direction(dir);
+
+ this.viewSettings.direction = dir;
+
+ this.updateLayout();
+ }
+
+ isRendered() {
+ return this.rendered;
+ }
+}
+
+//-- Enable binding events to Manager
+EventEmitter(DefaultViewManager.prototype);
+
+export default DefaultViewManager;
diff --git a/lib/epub.js/src/managers/helpers/snap.js b/lib/epub.js/src/managers/helpers/snap.js
new file mode 100644
index 0000000..db0aaff
--- /dev/null
+++ b/lib/epub.js/src/managers/helpers/snap.js
@@ -0,0 +1,338 @@
+import {extend, defer, requestAnimationFrame, prefixed} from "../../utils/core";
+import { EVENTS, DOM_EVENTS } from "../../utils/constants";
+import EventEmitter from "event-emitter";
+
+// easing equations from https://github.com/danro/easing-js/blob/master/easing.js
+const PI_D2 = (Math.PI / 2);
+const EASING_EQUATIONS = {
+ easeOutSine: function (pos) {
+ return Math.sin(pos * PI_D2);
+ },
+ easeInOutSine: function (pos) {
+ return (-0.5 * (Math.cos(Math.PI * pos) - 1));
+ },
+ easeInOutQuint: function (pos) {
+ if ((pos /= 0.5) < 1) {
+ return 0.5 * Math.pow(pos, 5);
+ }
+ return 0.5 * (Math.pow((pos - 2), 5) + 2);
+ },
+ easeInCubic: function(pos) {
+ return Math.pow(pos, 3);
+ }
+};
+
+class Snap {
+ constructor(manager, options) {
+
+ this.settings = extend({
+ duration: 80,
+ minVelocity: 0.2,
+ minDistance: 10,
+ easing: EASING_EQUATIONS['easeInCubic']
+ }, options || {});
+
+ this.supportsTouch = this.supportsTouch();
+
+ if (this.supportsTouch) {
+ this.setup(manager);
+ }
+ }
+
+ setup(manager) {
+ this.manager = manager;
+
+ this.layout = this.manager.layout;
+
+ this.fullsize = this.manager.settings.fullsize;
+ if (this.fullsize) {
+ this.element = this.manager.stage.element;
+ this.scroller = window;
+ this.disableScroll();
+ } else {
+ this.element = this.manager.stage.container;
+ this.scroller = this.element;
+ this.element.style["WebkitOverflowScrolling"] = "touch";
+ }
+
+ // this.overflow = this.manager.overflow;
+
+ // set lookahead offset to page width
+ this.manager.settings.offset = this.layout.width;
+ this.manager.settings.afterScrolledTimeout = this.settings.duration * 2;
+
+ this.isVertical = this.manager.settings.axis === "vertical";
+
+ // disable snapping if not paginated or axis in not horizontal
+ if (!this.manager.isPaginated || this.isVertical) {
+ return;
+ }
+
+ this.touchCanceler = false;
+ this.resizeCanceler = false;
+ this.snapping = false;
+
+
+ this.scrollLeft;
+ this.scrollTop;
+
+ this.startTouchX = undefined;
+ this.startTouchY = undefined;
+ this.startTime = undefined;
+ this.endTouchX = undefined;
+ this.endTouchY = undefined;
+ this.endTime = undefined;
+
+ this.addListeners();
+ }
+
+ supportsTouch() {
+ if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+ return true;
+ }
+
+ return false;
+ }
+
+ disableScroll() {
+ this.element.style.overflow = "hidden";
+ }
+
+ enableScroll() {
+ this.element.style.overflow = "";
+ }
+
+ addListeners() {
+ this._onResize = this.onResize.bind(this);
+ window.addEventListener('resize', this._onResize);
+
+ this._onScroll = this.onScroll.bind(this);
+ this.scroller.addEventListener('scroll', this._onScroll);
+
+ this._onTouchStart = this.onTouchStart.bind(this);
+ this.scroller.addEventListener('touchstart', this._onTouchStart, { passive: true });
+ this.on('touchstart', this._onTouchStart);
+
+ this._onTouchMove = this.onTouchMove.bind(this);
+ this.scroller.addEventListener('touchmove', this._onTouchMove, { passive: true });
+ this.on('touchmove', this._onTouchMove);
+
+ this._onTouchEnd = this.onTouchEnd.bind(this);
+ this.scroller.addEventListener('touchend', this._onTouchEnd, { passive: true });
+ this.on('touchend', this._onTouchEnd);
+
+ this._afterDisplayed = this.afterDisplayed.bind(this);
+ this.manager.on(EVENTS.MANAGERS.ADDED, this._afterDisplayed);
+ }
+
+ removeListeners() {
+ window.removeEventListener('resize', this._onResize);
+ this._onResize = undefined;
+
+ this.scroller.removeEventListener('scroll', this._onScroll);
+ this._onScroll = undefined;
+
+ this.scroller.removeEventListener('touchstart', this._onTouchStart, { passive: true });
+ this.off('touchstart', this._onTouchStart);
+ this._onTouchStart = undefined;
+
+ this.scroller.removeEventListener('touchmove', this._onTouchMove, { passive: true });
+ this.off('touchmove', this._onTouchMove);
+ this._onTouchMove = undefined;
+
+ this.scroller.removeEventListener('touchend', this._onTouchEnd, { passive: true });
+ this.off('touchend', this._onTouchEnd);
+ this._onTouchEnd = undefined;
+
+ this.manager.off(EVENTS.MANAGERS.ADDED, this._afterDisplayed);
+ this._afterDisplayed = undefined;
+ }
+
+ afterDisplayed(view) {
+ let contents = view.contents;
+ ["touchstart", "touchmove", "touchend"].forEach((e) => {
+ contents.on(e, (ev) => this.triggerViewEvent(ev, contents));
+ });
+ }
+
+ triggerViewEvent(e, contents){
+ this.emit(e.type, e, contents);
+ }
+
+ onScroll(e) {
+ this.scrollLeft = this.fullsize ? window.scrollX : this.scroller.scrollLeft;
+ this.scrollTop = this.fullsize ? window.scrollY : this.scroller.scrollTop;
+ }
+
+ onResize(e) {
+ this.resizeCanceler = true;
+ }
+
+ onTouchStart(e) {
+ let { screenX, screenY } = e.touches[0];
+
+ if (this.fullsize) {
+ this.enableScroll();
+ }
+
+ this.touchCanceler = true;
+
+ if (!this.startTouchX) {
+ this.startTouchX = screenX;
+ this.startTouchY = screenY;
+ this.startTime = this.now();
+ }
+
+ this.endTouchX = screenX;
+ this.endTouchY = screenY;
+ this.endTime = this.now();
+ }
+
+ onTouchMove(e) {
+ let { screenX, screenY } = e.touches[0];
+ let deltaY = Math.abs(screenY - this.endTouchY);
+
+ this.touchCanceler = true;
+
+
+ if (!this.fullsize && deltaY < 10) {
+ this.element.scrollLeft -= screenX - this.endTouchX;
+ }
+
+ this.endTouchX = screenX;
+ this.endTouchY = screenY;
+ this.endTime = this.now();
+ }
+
+ onTouchEnd(e) {
+ if (this.fullsize) {
+ this.disableScroll();
+ }
+
+ this.touchCanceler = false;
+
+ let swipped = this.wasSwiped();
+
+ if (swipped !== 0) {
+ this.snap(swipped);
+ } else {
+ this.snap();
+ }
+
+ this.startTouchX = undefined;
+ this.startTouchY = undefined;
+ this.startTime = undefined;
+ this.endTouchX = undefined;
+ this.endTouchY = undefined;
+ this.endTime = undefined;
+ }
+
+ wasSwiped() {
+ let snapWidth = this.layout.pageWidth * this.layout.divisor;
+ let distance = (this.endTouchX - this.startTouchX);
+ let absolute = Math.abs(distance);
+ let time = this.endTime - this.startTime;
+ let velocity = (distance / time);
+ let minVelocity = this.settings.minVelocity;
+
+ if (absolute <= this.settings.minDistance || absolute >= snapWidth) {
+ return 0;
+ }
+
+ if (velocity > minVelocity) {
+ // previous
+ return -1;
+ } else if (velocity < -minVelocity) {
+ // next
+ return 1;
+ }
+ }
+
+ needsSnap() {
+ let left = this.scrollLeft;
+ let snapWidth = this.layout.pageWidth * this.layout.divisor;
+ return (left % snapWidth) !== 0;
+ }
+
+ snap(howMany=0) {
+ let left = this.scrollLeft;
+ let snapWidth = this.layout.pageWidth * this.layout.divisor;
+ let snapTo = Math.round(left / snapWidth) * snapWidth;
+
+ if (howMany) {
+ snapTo += (howMany * snapWidth);
+ }
+
+ return this.smoothScrollTo(snapTo);
+ }
+
+ smoothScrollTo(destination) {
+ const deferred = new defer();
+ const start = this.scrollLeft;
+ const startTime = this.now();
+
+ const duration = this.settings.duration;
+ const easing = this.settings.easing;
+
+ this.snapping = true;
+
+ // add animation loop
+ function tick() {
+ const now = this.now();
+ const time = Math.min(1, ((now - startTime) / duration));
+ const timeFunction = easing(time);
+
+
+ if (this.touchCanceler || this.resizeCanceler) {
+ this.resizeCanceler = false;
+ this.snapping = false;
+ deferred.resolve();
+ return;
+ }
+
+ if (time < 1) {
+ window.requestAnimationFrame(tick.bind(this));
+ this.scrollTo(start + ((destination - start) * time), 0);
+ } else {
+ this.scrollTo(destination, 0);
+ this.snapping = false;
+ deferred.resolve();
+ }
+ }
+
+ tick.call(this);
+
+ return deferred.promise;
+ }
+
+ scrollTo(left=0, top=0) {
+ if (this.fullsize) {
+ window.scroll(left, top);
+ } else {
+ this.scroller.scrollLeft = left;
+ this.scroller.scrollTop = top;
+ }
+ }
+
+ now() {
+ return ('now' in window.performance) ? performance.now() : new Date().getTime();
+ }
+
+ destroy() {
+ if (!this.scroller) {
+ return;
+ }
+
+ if (this.fullsize) {
+ this.enableScroll();
+ }
+
+ this.removeListeners();
+
+ this.scroller = undefined;
+ }
+}
+
+EventEmitter(Snap.prototype);
+
+export default Snap;
diff --git a/lib/epub.js/src/managers/helpers/stage.js b/lib/epub.js/src/managers/helpers/stage.js
new file mode 100644
index 0000000..d0f67e6
--- /dev/null
+++ b/lib/epub.js/src/managers/helpers/stage.js
@@ -0,0 +1,363 @@
+import {uuid, isNumber, isElement, windowBounds, extend} from "../../utils/core";
+import throttle from 'lodash/throttle'
+
+class Stage {
+ constructor(_options) {
+ this.settings = _options || {};
+ this.id = "epubjs-container-" + uuid();
+
+ this.container = this.create(this.settings);
+
+ if(this.settings.hidden) {
+ this.wrapper = this.wrap(this.container);
+ }
+
+ }
+
+ /*
+ * Creates an element to render to.
+ * Resizes to passed width and height or to the elements size
+ */
+ create(options){
+ let height = options.height;// !== false ? options.height : "100%";
+ let width = options.width;// !== false ? options.width : "100%";
+ let overflow = options.overflow || false;
+ let axis = options.axis || "vertical";
+ let direction = options.direction;
+
+ extend(this.settings, options);
+
+ if(options.height && isNumber(options.height)) {
+ height = options.height + "px";
+ }
+
+ if(options.width && isNumber(options.width)) {
+ width = options.width + "px";
+ }
+
+ // Create new container element
+ let container = document.createElement("div");
+
+ container.id = this.id;
+ container.classList.add("epub-container");
+
+ // Style Element
+ // container.style.fontSize = "0";
+ container.style.wordSpacing = "0";
+ container.style.lineHeight = "0";
+ container.style.verticalAlign = "top";
+ container.style.position = "relative";
+
+ if(axis === "horizontal") {
+ // container.style.whiteSpace = "nowrap";
+ container.style.display = "flex";
+ container.style.flexDirection = "row";
+ container.style.flexWrap = "nowrap";
+ }
+
+ if(width){
+ container.style.width = width;
+ }
+
+ if(height){
+ container.style.height = height;
+ }
+
+ if (overflow) {
+ if (overflow === "scroll" && axis === "vertical") {
+ container.style["overflow-y"] = overflow;
+ container.style["overflow-x"] = "hidden";
+ } else if (overflow === "scroll" && axis === "horizontal") {
+ container.style["overflow-y"] = "hidden";
+ container.style["overflow-x"] = overflow;
+ } else {
+ container.style["overflow"] = overflow;
+ }
+ }
+
+ if (direction) {
+ container.dir = direction;
+ container.style["direction"] = direction;
+ }
+
+ if (direction && this.settings.fullsize) {
+ document.body.style["direction"] = direction;
+ }
+
+ return container;
+ }
+
+ wrap(container) {
+ var wrapper = document.createElement("div");
+
+ wrapper.style.visibility = "hidden";
+ wrapper.style.overflow = "hidden";
+ wrapper.style.width = "0";
+ wrapper.style.height = "0";
+
+ wrapper.appendChild(container);
+ return wrapper;
+ }
+
+
+ getElement(_element){
+ var element;
+
+ if(isElement(_element)) {
+ element = _element;
+ } else if (typeof _element === "string") {
+ element = document.getElementById(_element);
+ }
+
+ if(!element){
+ throw new Error("Not an Element");
+ }
+
+ return element;
+ }
+
+ attachTo(what){
+
+ var element = this.getElement(what);
+ var base;
+
+ if(!element){
+ return;
+ }
+
+ if(this.settings.hidden) {
+ base = this.wrapper;
+ } else {
+ base = this.container;
+ }
+
+ element.appendChild(base);
+
+ this.element = element;
+
+ return element;
+
+ }
+
+ getContainer() {
+ return this.container;
+ }
+
+ onResize(func){
+ // Only listen to window for resize event if width and height are not fixed.
+ // This applies if it is set to a percent or auto.
+ if(!isNumber(this.settings.width) ||
+ !isNumber(this.settings.height) ) {
+ this.resizeFunc = throttle(func, 50);
+ window.addEventListener("resize", this.resizeFunc, false);
+ }
+
+ }
+
+ onOrientationChange(func){
+ this.orientationChangeFunc = func;
+ window.addEventListener("orientationchange", this.orientationChangeFunc, false);
+ }
+
+ size(width, height){
+ var bounds;
+ let _width = width || this.settings.width;
+ let _height = height || this.settings.height;
+
+ // If width or height are set to false, inherit them from containing element
+ if(width === null) {
+ bounds = this.element.getBoundingClientRect();
+
+ if(bounds.width) {
+ width = Math.floor(bounds.width);
+ this.container.style.width = width + "px";
+ }
+ } else {
+ if (isNumber(width)) {
+ this.container.style.width = width + "px";
+ } else {
+ this.container.style.width = width;
+ }
+ }
+
+ if(height === null) {
+ bounds = bounds || this.element.getBoundingClientRect();
+
+ if(bounds.height) {
+ height = bounds.height;
+ this.container.style.height = height + "px";
+ }
+
+ } else {
+ if (isNumber(height)) {
+ this.container.style.height = height + "px";
+ } else {
+ this.container.style.height = height;
+ }
+ }
+
+ if(!isNumber(width)) {
+ width = this.container.clientWidth;
+ }
+
+ if(!isNumber(height)) {
+ height = this.container.clientHeight;
+ }
+
+ this.containerStyles = window.getComputedStyle(this.container);
+
+ this.containerPadding = {
+ left: parseFloat(this.containerStyles["padding-left"]) || 0,
+ right: parseFloat(this.containerStyles["padding-right"]) || 0,
+ top: parseFloat(this.containerStyles["padding-top"]) || 0,
+ bottom: parseFloat(this.containerStyles["padding-bottom"]) || 0
+ };
+
+ // Bounds not set, get them from window
+ let _windowBounds = windowBounds();
+ let bodyStyles = window.getComputedStyle(document.body);
+ let bodyPadding = {
+ left: parseFloat(bodyStyles["padding-left"]) || 0,
+ right: parseFloat(bodyStyles["padding-right"]) || 0,
+ top: parseFloat(bodyStyles["padding-top"]) || 0,
+ bottom: parseFloat(bodyStyles["padding-bottom"]) || 0
+ };
+
+ if (!_width) {
+ width = _windowBounds.width -
+ bodyPadding.left -
+ bodyPadding.right;
+ }
+
+ if ((this.settings.fullsize && !_height) || !_height) {
+ height = _windowBounds.height -
+ bodyPadding.top -
+ bodyPadding.bottom;
+ }
+
+ return {
+ width: width -
+ this.containerPadding.left -
+ this.containerPadding.right,
+ height: height -
+ this.containerPadding.top -
+ this.containerPadding.bottom
+ };
+
+ }
+
+ bounds(){
+ let box;
+ if (this.container.style.overflow !== "visible") {
+ box = this.container && this.container.getBoundingClientRect();
+ }
+
+ if(!box || !box.width || !box.height) {
+ return windowBounds();
+ } else {
+ return box;
+ }
+
+ }
+
+ getSheet(){
+ var style = document.createElement("style");
+
+ // WebKit hack --> https://davidwalsh.name/add-rules-stylesheets
+ style.appendChild(document.createTextNode(""));
+
+ document.head.appendChild(style);
+
+ return style.sheet;
+ }
+
+ addStyleRules(selector, rulesArray){
+ var scope = "#" + this.id + " ";
+ var rules = "";
+
+ if(!this.sheet){
+ this.sheet = this.getSheet();
+ }
+
+ rulesArray.forEach(function(set) {
+ for (var prop in set) {
+ if(set.hasOwnProperty(prop)) {
+ rules += prop + ":" + set[prop] + ";";
+ }
+ }
+ });
+
+ this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
+ }
+
+ axis(axis) {
+ if(axis === "horizontal") {
+ this.container.style.display = "flex";
+ this.container.style.flexDirection = "row";
+ this.container.style.flexWrap = "nowrap";
+ } else {
+ this.container.style.display = "block";
+ }
+ this.settings.axis = axis;
+ }
+
+ // orientation(orientation) {
+ // if (orientation === "landscape") {
+ //
+ // } else {
+ //
+ // }
+ //
+ // this.orientation = orientation;
+ // }
+
+ direction(dir) {
+ if (this.container) {
+ this.container.dir = dir;
+ this.container.style["direction"] = dir;
+ }
+
+ if (this.settings.fullsize) {
+ document.body.style["direction"] = dir;
+ }
+ this.settings.dir = dir;
+ }
+
+ overflow(overflow) {
+ if (this.container) {
+ if (overflow === "scroll" && this.settings.axis === "vertical") {
+ this.container.style["overflow-y"] = overflow;
+ this.container.style["overflow-x"] = "hidden";
+ } else if (overflow === "scroll" && this.settings.axis === "horizontal") {
+ this.container.style["overflow-y"] = "hidden";
+ this.container.style["overflow-x"] = overflow;
+ } else {
+ this.container.style["overflow"] = overflow;
+ }
+ }
+ this.settings.overflow = overflow;
+ }
+
+ destroy() {
+ var base;
+
+ if (this.element) {
+
+ if(this.settings.hidden) {
+ base = this.wrapper;
+ } else {
+ base = this.container;
+ }
+
+ if(this.element.contains(this.container)) {
+ this.element.removeChild(this.container);
+ }
+
+ window.removeEventListener("resize", this.resizeFunc);
+ window.removeEventListener("orientationChange", this.orientationChangeFunc);
+
+ }
+ }
+}
+
+export default Stage;
diff --git a/lib/epub.js/src/managers/helpers/views.js b/lib/epub.js/src/managers/helpers/views.js
new file mode 100644
index 0000000..4368da2
--- /dev/null
+++ b/lib/epub.js/src/managers/helpers/views.js
@@ -0,0 +1,167 @@
+class Views {
+ constructor(container) {
+ this.container = container;
+ this._views = [];
+ this.length = 0;
+ this.hidden = false;
+ }
+
+ all() {
+ return this._views;
+ }
+
+ first() {
+ return this._views[0];
+ }
+
+ last() {
+ return this._views[this._views.length-1];
+ }
+
+ indexOf(view) {
+ return this._views.indexOf(view);
+ }
+
+ slice() {
+ return this._views.slice.apply(this._views, arguments);
+ }
+
+ get(i) {
+ return this._views[i];
+ }
+
+ append(view){
+ this._views.push(view);
+ if(this.container){
+ this.container.appendChild(view.element);
+ }
+ this.length++;
+ return view;
+ }
+
+ prepend(view){
+ this._views.unshift(view);
+ if(this.container){
+ this.container.insertBefore(view.element, this.container.firstChild);
+ }
+ this.length++;
+ return view;
+ }
+
+ insert(view, index) {
+ this._views.splice(index, 0, view);
+
+ if(this.container){
+ if(index < this.container.children.length){
+ this.container.insertBefore(view.element, this.container.children[index]);
+ } else {
+ this.container.appendChild(view.element);
+ }
+ }
+
+ this.length++;
+ return view;
+ }
+
+ remove(view) {
+ var index = this._views.indexOf(view);
+
+ if(index > -1) {
+ this._views.splice(index, 1);
+ }
+
+
+ this.destroy(view);
+
+ this.length--;
+ }
+
+ destroy(view) {
+ if(view.displayed){
+ view.destroy();
+ }
+
+ if(this.container){
+ this.container.removeChild(view.element);
+ }
+ view = null;
+ }
+
+ // Iterators
+
+ forEach() {
+ return this._views.forEach.apply(this._views, arguments);
+ }
+
+ clear(){
+ // Remove all views
+ var view;
+ var len = this.length;
+
+ if(!this.length) return;
+
+ for (var i = 0; i < len; i++) {
+ view = this._views[i];
+ this.destroy(view);
+ }
+
+ this._views = [];
+ this.length = 0;
+ }
+
+ find(section){
+
+ var view;
+ var len = this.length;
+
+ for (var i = 0; i < len; i++) {
+ view = this._views[i];
+ if(view.displayed && view.section.index == section.index) {
+ return view;
+ }
+ }
+
+ }
+
+ displayed(){
+ var displayed = [];
+ var view;
+ var len = this.length;
+
+ for (var i = 0; i < len; i++) {
+ view = this._views[i];
+ if(view.displayed){
+ displayed.push(view);
+ }
+ }
+ return displayed;
+ }
+
+ show(){
+ var view;
+ var len = this.length;
+
+ for (var i = 0; i < len; i++) {
+ view = this._views[i];
+ if(view.displayed){
+ view.show();
+ }
+ }
+ this.hidden = false;
+ }
+
+ hide(){
+ var view;
+ var len = this.length;
+
+ for (var i = 0; i < len; i++) {
+ view = this._views[i];
+ if(view.displayed){
+ view.hide();
+ }
+ }
+ this.hidden = true;
+ }
+}
+
+export default Views;
diff --git a/lib/epub.js/src/managers/views/iframe.js b/lib/epub.js/src/managers/views/iframe.js
new file mode 100644
index 0000000..76b2c1d
--- /dev/null
+++ b/lib/epub.js/src/managers/views/iframe.js
@@ -0,0 +1,835 @@
+import EventEmitter from "event-emitter";
+import {extend, borders, uuid, isNumber, bounds, defer, createBlobUrl, revokeBlobUrl} from "../../utils/core";
+import EpubCFI from "../../epubcfi";
+import Contents from "../../contents";
+import { EVENTS } from "../../utils/constants";
+import { Pane, Highlight, Underline } from "marks-pane";
+
+class IframeView {
+ constructor(section, options) {
+ this.settings = extend({
+ ignoreClass : "",
+ axis: undefined, //options.layout && options.layout.props.flow === "scrolled" ? "vertical" : "horizontal",
+ direction: undefined,
+ width: 0,
+ height: 0,
+ layout: undefined,
+ globalLayoutProperties: {},
+ method: undefined,
+ forceRight: false
+ }, options || {});
+
+ this.id = "epubjs-view-" + uuid();
+ this.section = section;
+ this.index = section.index;
+
+ this.element = this.container(this.settings.axis);
+
+ this.added = false;
+ this.displayed = false;
+ this.rendered = false;
+
+ // this.width = this.settings.width;
+ // this.height = this.settings.height;
+
+ this.fixedWidth = 0;
+ this.fixedHeight = 0;
+
+ // Blank Cfi for Parsing
+ this.epubcfi = new EpubCFI();
+
+ this.layout = this.settings.layout;
+ // Dom events to listen for
+ // this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
+
+ this.pane = undefined;
+ this.highlights = {};
+ this.underlines = {};
+ this.marks = {};
+
+ }
+
+ container(axis) {
+ var element = document.createElement("div");
+
+ element.classList.add("epub-view");
+
+ // this.element.style.minHeight = "100px";
+ element.style.height = "0px";
+ element.style.width = "0px";
+ element.style.overflow = "hidden";
+ element.style.position = "relative";
+ element.style.display = "block";
+
+ if(axis && axis == "horizontal"){
+ element.style.flex = "none";
+ } else {
+ element.style.flex = "initial";
+ }
+
+ return element;
+ }
+
+ create() {
+
+ if(this.iframe) {
+ return this.iframe;
+ }
+
+ if(!this.element) {
+ this.element = this.createContainer();
+ }
+
+ this.iframe = document.createElement("iframe");
+ this.iframe.id = this.id;
+ this.iframe.scrolling = "no"; // Might need to be removed: breaks ios width calculations
+ this.iframe.style.overflow = "hidden";
+ this.iframe.seamless = "seamless";
+ // Back up if seamless isn't supported
+ this.iframe.style.border = "none";
+
+ this.iframe.setAttribute("enable-annotation", "true");
+
+ this.resizing = true;
+
+ // this.iframe.style.display = "none";
+ this.element.style.visibility = "hidden";
+ this.iframe.style.visibility = "hidden";
+
+ this.iframe.style.width = "0";
+ this.iframe.style.height = "0";
+ this._width = 0;
+ this._height = 0;
+
+ this.element.setAttribute("ref", this.index);
+
+ this.added = true;
+
+ this.elementBounds = bounds(this.element);
+
+ // if(width || height){
+ // this.resize(width, height);
+ // } else if(this.width && this.height){
+ // this.resize(this.width, this.height);
+ // } else {
+ // this.iframeBounds = bounds(this.iframe);
+ // }
+
+
+ if(("srcdoc" in this.iframe)) {
+ this.supportsSrcdoc = true;
+ } else {
+ this.supportsSrcdoc = false;
+ }
+
+ if (!this.settings.method) {
+ this.settings.method = this.supportsSrcdoc ? "srcdoc" : "write";
+ }
+
+ return this.iframe;
+ }
+
+ render(request, show) {
+
+ // view.onLayout = this.layout.format.bind(this.layout);
+ this.create();
+
+ // Fit to size of the container, apply padding
+ this.size();
+
+ if(!this.sectionRender) {
+ this.sectionRender = this.section.render(request);
+ }
+
+ // Render Chain
+ return this.sectionRender
+ .then(function(contents){
+ return this.load(contents);
+ }.bind(this))
+ .then(function(){
+
+ // find and report the writingMode axis
+ let writingMode = this.contents.writingMode();
+
+ // Set the axis based on the flow and writing mode
+ let axis;
+ if (this.settings.flow === "scrolled") {
+ axis = (writingMode.indexOf("vertical") === 0) ? "horizontal" : "vertical";
+ } else {
+ axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
+ }
+
+ if (writingMode.indexOf("vertical") === 0 && this.settings.flow === "paginated") {
+ this.layout.delta = this.layout.height;
+ }
+
+ this.setAxis(axis);
+ this.emit(EVENTS.VIEWS.AXIS, axis);
+
+ this.setWritingMode(writingMode);
+ this.emit(EVENTS.VIEWS.WRITING_MODE, writingMode);
+
+
+ // apply the layout function to the contents
+ this.layout.format(this.contents, this.section, this.axis);
+
+ // Listen for events that require an expansion of the iframe
+ this.addListeners();
+
+ return new Promise((resolve, reject) => {
+ // Expand the iframe to the full size of the content
+ this.expand();
+
+ if (this.settings.forceRight) {
+ this.element.style.marginLeft = this.width() + "px";
+ }
+ resolve();
+ });
+
+ }.bind(this), function(e){
+ this.emit(EVENTS.VIEWS.LOAD_ERROR, e);
+ return new Promise((resolve, reject) => {
+ reject(e);
+ });
+ }.bind(this))
+ .then(function() {
+ this.emit(EVENTS.VIEWS.RENDERED, this.section);
+ }.bind(this));
+
+ }
+
+ reset () {
+ if (this.iframe) {
+ this.iframe.style.width = "0";
+ this.iframe.style.height = "0";
+ this._width = 0;
+ this._height = 0;
+ this._textWidth = undefined;
+ this._contentWidth = undefined;
+ this._textHeight = undefined;
+ this._contentHeight = undefined;
+ }
+ this._needsReframe = true;
+ }
+
+ // Determine locks base on settings
+ size(_width, _height) {
+ var width = _width || this.settings.width;
+ var height = _height || this.settings.height;
+
+ if(this.layout.name === "pre-paginated") {
+ this.lock("both", width, height);
+ } else if(this.settings.axis === "horizontal") {
+ this.lock("height", width, height);
+ } else {
+ this.lock("width", width, height);
+ }
+
+ this.settings.width = width;
+ this.settings.height = height;
+ }
+
+ // Lock an axis to element dimensions, taking borders into account
+ lock(what, width, height) {
+ var elBorders = borders(this.element);
+ var iframeBorders;
+
+ if(this.iframe) {
+ iframeBorders = borders(this.iframe);
+ } else {
+ iframeBorders = {width: 0, height: 0};
+ }
+
+ if(what == "width" && isNumber(width)){
+ this.lockedWidth = width - elBorders.width - iframeBorders.width;
+ // this.resize(this.lockedWidth, width); // width keeps ratio correct
+ }
+
+ if(what == "height" && isNumber(height)){
+ this.lockedHeight = height - elBorders.height - iframeBorders.height;
+ // this.resize(width, this.lockedHeight);
+ }
+
+ if(what === "both" &&
+ isNumber(width) &&
+ isNumber(height)){
+
+ this.lockedWidth = width - elBorders.width - iframeBorders.width;
+ this.lockedHeight = height - elBorders.height - iframeBorders.height;
+ // this.resize(this.lockedWidth, this.lockedHeight);
+ }
+
+ if(this.displayed && this.iframe) {
+
+ // this.contents.layout();
+ this.expand();
+ }
+
+
+
+ }
+
+ // Resize a single axis based on content dimensions
+ expand(force) {
+ var width = this.lockedWidth;
+ var height = this.lockedHeight;
+ var columns;
+
+ var textWidth, textHeight;
+
+ if(!this.iframe || this._expanding) return;
+
+ this._expanding = true;
+
+ if(this.layout.name === "pre-paginated") {
+ width = this.layout.columnWidth;
+ height = this.layout.height;
+ }
+ // Expand Horizontally
+ else if(this.settings.axis === "horizontal") {
+ // Get the width of the text
+ width = this.contents.textWidth();
+
+ if (width % this.layout.pageWidth > 0) {
+ width = Math.ceil(width / this.layout.pageWidth) * this.layout.pageWidth;
+ }
+
+ if (this.settings.forceEvenPages) {
+ columns = (width / this.layout.pageWidth);
+ if ( this.layout.divisor > 1 &&
+ this.layout.name === "reflowable" &&
+ (columns % 2 > 0)) {
+ // add a blank page
+ width += this.layout.pageWidth;
+ }
+ }
+
+ } // Expand Vertically
+ else if(this.settings.axis === "vertical") {
+ height = this.contents.textHeight();
+ if (this.settings.flow === "paginated" &&
+ height % this.layout.height > 0) {
+ height = Math.ceil(height / this.layout.height) * this.layout.height;
+ }
+ }
+
+ // Only Resize if dimensions have changed or
+ // if Frame is still hidden, so needs reframing
+ if(this._needsReframe || width != this._width || height != this._height){
+ this.reframe(width, height);
+ }
+
+ this._expanding = false;
+ }
+
+ reframe(width, height) {
+ var size;
+
+ if(isNumber(width)){
+ this.element.style.width = width + "px";
+ this.iframe.style.width = width + "px";
+ this._width = width;
+ }
+
+ if(isNumber(height)){
+ this.element.style.height = height + "px";
+ this.iframe.style.height = height + "px";
+ this._height = height;
+ }
+
+ let widthDelta = this.prevBounds ? width - this.prevBounds.width : width;
+ let heightDelta = this.prevBounds ? height - this.prevBounds.height : height;
+
+ size = {
+ width: width,
+ height: height,
+ widthDelta: widthDelta,
+ heightDelta: heightDelta,
+ };
+
+ this.pane && this.pane.render();
+
+ requestAnimationFrame(() => {
+ let mark;
+ for (let m in this.marks) {
+ if (this.marks.hasOwnProperty(m)) {
+ mark = this.marks[m];
+ this.placeMark(mark.element, mark.range);
+ }
+ }
+ });
+
+ this.onResize(this, size);
+
+ this.emit(EVENTS.VIEWS.RESIZED, size);
+
+ this.prevBounds = size;
+
+ this.elementBounds = bounds(this.element);
+
+ }
+
+
+ load(contents) {
+ var loading = new defer();
+ var loaded = loading.promise;
+
+ if(!this.iframe) {
+ loading.reject(new Error("No Iframe Available"));
+ return loaded;
+ }
+
+ this.iframe.onload = function(event) {
+
+ this.onLoad(event, loading);
+
+ }.bind(this);
+
+ if (this.settings.method === "blobUrl") {
+ this.blobUrl = createBlobUrl(contents, "application/xhtml+xml");
+ this.iframe.src = this.blobUrl;
+ this.element.appendChild(this.iframe);
+ } else if(this.settings.method === "srcdoc"){
+ this.iframe.srcdoc = contents;
+ this.element.appendChild(this.iframe);
+ } else {
+
+ this.element.appendChild(this.iframe);
+
+ this.document = this.iframe.contentDocument;
+
+ if(!this.document) {
+ loading.reject(new Error("No Document Available"));
+ return loaded;
+ }
+
+ this.iframe.contentDocument.open();
+ // For Cordova windows platform
+ if(window.MSApp && MSApp.execUnsafeLocalFunction) {
+ var outerThis = this;
+ MSApp.execUnsafeLocalFunction(function () {
+ outerThis.iframe.contentDocument.write(contents);
+ });
+ } else {
+ this.iframe.contentDocument.write(contents);
+ }
+ this.iframe.contentDocument.close();
+
+ }
+
+ return loaded;
+ }
+
+ onLoad(event, promise) {
+
+ this.window = this.iframe.contentWindow;
+ this.document = this.iframe.contentDocument;
+
+ this.contents = new Contents(this.document, this.document.body, this.section.cfiBase, this.section.index);
+
+ this.rendering = false;
+
+ var link = this.document.querySelector("link[rel='canonical']");
+ if (link) {
+ link.setAttribute("href", this.section.canonical);
+ } else {
+ link = this.document.createElement("link");
+ link.setAttribute("rel", "canonical");
+ link.setAttribute("href", this.section.canonical);
+ this.document.querySelector("head").appendChild(link);
+ }
+
+ this.contents.on(EVENTS.CONTENTS.EXPAND, () => {
+ if(this.displayed && this.iframe) {
+ this.expand();
+ if (this.contents) {
+ this.layout.format(this.contents);
+ }
+ }
+ });
+
+ this.contents.on(EVENTS.CONTENTS.RESIZE, (e) => {
+ if(this.displayed && this.iframe) {
+ this.expand();
+ if (this.contents) {
+ this.layout.format(this.contents);
+ }
+ }
+ });
+
+ promise.resolve(this.contents);
+ }
+
+ setLayout(layout) {
+ this.layout = layout;
+
+ if (this.contents) {
+ this.layout.format(this.contents);
+ this.expand();
+ }
+ }
+
+ setAxis(axis) {
+
+ this.settings.axis = axis;
+
+ if(axis == "horizontal"){
+ this.element.style.flex = "none";
+ } else {
+ this.element.style.flex = "initial";
+ }
+
+ this.size();
+
+ }
+
+ setWritingMode(mode) {
+ // this.element.style.writingMode = writingMode;
+ this.writingMode = mode;
+ }
+
+ addListeners() {
+ //TODO: Add content listeners for expanding
+ }
+
+ removeListeners(layoutFunc) {
+ //TODO: remove content listeners for expanding
+ }
+
+ display(request) {
+ var displayed = new defer();
+
+ if (!this.displayed) {
+
+ this.render(request)
+ .then(function () {
+
+ this.emit(EVENTS.VIEWS.DISPLAYED, this);
+ this.onDisplayed(this);
+
+ this.displayed = true;
+ displayed.resolve(this);
+
+ }.bind(this), function (err) {
+ displayed.reject(err, this);
+ });
+
+ } else {
+ displayed.resolve(this);
+ }
+
+
+ return displayed.promise;
+ }
+
+ show() {
+
+ this.element.style.visibility = "visible";
+
+ if(this.iframe){
+ this.iframe.style.visibility = "visible";
+
+ // Remind Safari to redraw the iframe
+ this.iframe.style.transform = "translateZ(0)";
+ this.iframe.offsetWidth;
+ this.iframe.style.transform = null;
+ }
+
+ this.emit(EVENTS.VIEWS.SHOWN, this);
+ }
+
+ hide() {
+ // this.iframe.style.display = "none";
+ this.element.style.visibility = "hidden";
+ this.iframe.style.visibility = "hidden";
+
+ this.stopExpanding = true;
+ this.emit(EVENTS.VIEWS.HIDDEN, this);
+ }
+
+ offset() {
+ return {
+ top: this.element.offsetTop,
+ left: this.element.offsetLeft
+ }
+ }
+
+ width() {
+ return this._width;
+ }
+
+ height() {
+ return this._height;
+ }
+
+ position() {
+ return this.element.getBoundingClientRect();
+ }
+
+ locationOf(target) {
+ var parentPos = this.iframe.getBoundingClientRect();
+ var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
+
+ return {
+ "left": targetPos.left,
+ "top": targetPos.top
+ };
+ }
+
+ onDisplayed(view) {
+ // Stub, override with a custom functions
+ }
+
+ onResize(view, e) {
+ // Stub, override with a custom functions
+ }
+
+ bounds(force) {
+ if(force || !this.elementBounds) {
+ this.elementBounds = bounds(this.element);
+ }
+
+ return this.elementBounds;
+ }
+
+ highlight(cfiRange, data={}, cb, className = "epubjs-hl", styles = {}) {
+ if (!this.contents) {
+ return;
+ }
+ const attributes = Object.assign({"fill": "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply"}, styles);
+ let range = this.contents.range(cfiRange);
+
+ let emitter = () => {
+ this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data);
+ };
+
+ data["epubcfi"] = cfiRange;
+
+ if (!this.pane) {
+ this.pane = new Pane(this.iframe, this.element);
+ }
+
+ let m = new Highlight(range, className, data, attributes);
+ let h = this.pane.addMark(m);
+
+ this.highlights[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] };
+
+ h.element.setAttribute("ref", className);
+ h.element.addEventListener("click", emitter);
+ h.element.addEventListener("touchstart", emitter);
+
+ if (cb) {
+ h.element.addEventListener("click", cb);
+ h.element.addEventListener("touchstart", cb);
+ }
+ return h;
+ }
+
+ underline(cfiRange, data={}, cb, className = "epubjs-ul", styles = {}) {
+ if (!this.contents) {
+ return;
+ }
+ const attributes = Object.assign({"stroke": "black", "stroke-opacity": "0.3", "mix-blend-mode": "multiply"}, styles);
+ let range = this.contents.range(cfiRange);
+ let emitter = () => {
+ this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data);
+ };
+
+ data["epubcfi"] = cfiRange;
+
+ if (!this.pane) {
+ this.pane = new Pane(this.iframe, this.element);
+ }
+
+ let m = new Underline(range, className, data, attributes);
+ let h = this.pane.addMark(m);
+
+ this.underlines[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] };
+
+ h.element.setAttribute("ref", className);
+ h.element.addEventListener("click", emitter);
+ h.element.addEventListener("touchstart", emitter);
+
+ if (cb) {
+ h.element.addEventListener("click", cb);
+ h.element.addEventListener("touchstart", cb);
+ }
+ return h;
+ }
+
+ mark(cfiRange, data={}, cb) {
+ if (!this.contents) {
+ return;
+ }
+
+ if (cfiRange in this.marks) {
+ let item = this.marks[cfiRange];
+ return item;
+ }
+
+ let range = this.contents.range(cfiRange);
+ if (!range) {
+ return;
+ }
+ let container = range.commonAncestorContainer;
+ let parent = (container.nodeType === 1) ? container : container.parentNode;
+
+ let emitter = (e) => {
+ this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data);
+ };
+
+ if (range.collapsed && container.nodeType === 1) {
+ range = new Range();
+ range.selectNodeContents(container);
+ } else if (range.collapsed) { // Webkit doesn't like collapsed ranges
+ range = new Range();
+ range.selectNodeContents(parent);
+ }
+
+ let mark = this.document.createElement("a");
+ mark.setAttribute("ref", "epubjs-mk");
+ mark.style.position = "absolute";
+
+ mark.dataset["epubcfi"] = cfiRange;
+
+ if (data) {
+ Object.keys(data).forEach((key) => {
+ mark.dataset[key] = data[key];
+ });
+ }
+
+ if (cb) {
+ mark.addEventListener("click", cb);
+ mark.addEventListener("touchstart", cb);
+ }
+
+ mark.addEventListener("click", emitter);
+ mark.addEventListener("touchstart", emitter);
+
+ this.placeMark(mark, range);
+
+ this.element.appendChild(mark);
+
+ this.marks[cfiRange] = { "element": mark, "range": range, "listeners": [emitter, cb] };
+
+ return parent;
+ }
+
+ placeMark(element, range) {
+ let top, right, left;
+
+ if(this.layout.name === "pre-paginated" ||
+ this.settings.axis !== "horizontal") {
+ let pos = range.getBoundingClientRect();
+ top = pos.top;
+ right = pos.right;
+ } else {
+ // Element might break columns, so find the left most element
+ let rects = range.getClientRects();
+
+ let rect;
+ for (var i = 0; i != rects.length; i++) {
+ rect = rects[i];
+ if (!left || rect.left < left) {
+ left = rect.left;
+ // right = rect.right;
+ right = Math.ceil(left / this.layout.props.pageWidth) * this.layout.props.pageWidth - (this.layout.gap / 2);
+ top = rect.top;
+ }
+ }
+ }
+
+ element.style.top = `${top}px`;
+ element.style.left = `${right}px`;
+ }
+
+ unhighlight(cfiRange) {
+ let item;
+ if (cfiRange in this.highlights) {
+ item = this.highlights[cfiRange];
+
+ this.pane.removeMark(item.mark);
+ item.listeners.forEach((l) => {
+ if (l) {
+ item.element.removeEventListener("click", l);
+ item.element.removeEventListener("touchstart", l);
+ };
+ });
+ delete this.highlights[cfiRange];
+ }
+ }
+
+ ununderline(cfiRange) {
+ let item;
+ if (cfiRange in this.underlines) {
+ item = this.underlines[cfiRange];
+ this.pane.removeMark(item.mark);
+ item.listeners.forEach((l) => {
+ if (l) {
+ item.element.removeEventListener("click", l);
+ item.element.removeEventListener("touchstart", l);
+ };
+ });
+ delete this.underlines[cfiRange];
+ }
+ }
+
+ unmark(cfiRange) {
+ let item;
+ if (cfiRange in this.marks) {
+ item = this.marks[cfiRange];
+ this.element.removeChild(item.element);
+ item.listeners.forEach((l) => {
+ if (l) {
+ item.element.removeEventListener("click", l);
+ item.element.removeEventListener("touchstart", l);
+ };
+ });
+ delete this.marks[cfiRange];
+ }
+ }
+
+ destroy() {
+
+ for (let cfiRange in this.highlights) {
+ this.unhighlight(cfiRange);
+ }
+
+ for (let cfiRange in this.underlines) {
+ this.ununderline(cfiRange);
+ }
+
+ for (let cfiRange in this.marks) {
+ this.unmark(cfiRange);
+ }
+
+ if (this.blobUrl) {
+ revokeBlobUrl(this.blobUrl);
+ }
+
+ if(this.displayed){
+ this.displayed = false;
+
+ this.removeListeners();
+ this.contents.destroy();
+
+ this.stopExpanding = true;
+ this.element.removeChild(this.iframe);
+
+ this.iframe = undefined;
+ this.contents = undefined;
+
+ this._textWidth = null;
+ this._textHeight = null;
+ this._width = null;
+ this._height = null;
+ }
+
+ // this.element.style.height = "0px";
+ // this.element.style.width = "0px";
+ }
+}
+
+EventEmitter(IframeView.prototype);
+
+export default IframeView;
diff --git a/lib/epub.js/src/managers/views/inline.js b/lib/epub.js/src/managers/views/inline.js
new file mode 100644
index 0000000..072b586
--- /dev/null
+++ b/lib/epub.js/src/managers/views/inline.js
@@ -0,0 +1,432 @@
+import EventEmitter from "event-emitter";
+import {extend, borders, uuid, isNumber, bounds, defer, qs, parse} from "../../utils/core";
+import EpubCFI from "../../epubcfi";
+import Contents from "../../contents";
+import { EVENTS } from "../../utils/constants";
+
+class InlineView {
+ constructor(section, options) {
+ this.settings = extend({
+ ignoreClass : "",
+ axis: "vertical",
+ width: 0,
+ height: 0,
+ layout: undefined,
+ globalLayoutProperties: {},
+ }, options || {});
+
+ this.id = "epubjs-view:" + uuid();
+ this.section = section;
+ this.index = section.index;
+
+ this.element = this.container(this.settings.axis);
+
+ this.added = false;
+ this.displayed = false;
+ this.rendered = false;
+
+ this.width = this.settings.width;
+ this.height = this.settings.height;
+
+ this.fixedWidth = 0;
+ this.fixedHeight = 0;
+
+ // Blank Cfi for Parsing
+ this.epubcfi = new EpubCFI();
+
+ this.layout = this.settings.layout;
+ // Dom events to listen for
+ // this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
+
+ }
+
+ container(axis) {
+ var element = document.createElement("div");
+
+ element.classList.add("epub-view");
+
+ // if(this.settings.axis === "horizontal") {
+ // element.style.width = "auto";
+ // element.style.height = "0";
+ // } else {
+ // element.style.width = "0";
+ // element.style.height = "auto";
+ // }
+
+ element.style.overflow = "hidden";
+
+ if(axis && axis == "horizontal"){
+ element.style.display = "inline-block";
+ } else {
+ element.style.display = "block";
+ }
+
+ return element;
+ }
+
+ create() {
+
+ if(this.frame) {
+ return this.frame;
+ }
+
+ if(!this.element) {
+ this.element = this.createContainer();
+ }
+
+ this.frame = document.createElement("div");
+ this.frame.id = this.id;
+ this.frame.style.overflow = "hidden";
+ this.frame.style.wordSpacing = "initial";
+ this.frame.style.lineHeight = "initial";
+
+ this.resizing = true;
+
+ // this.frame.style.display = "none";
+ this.element.style.visibility = "hidden";
+ this.frame.style.visibility = "hidden";
+
+ if(this.settings.axis === "horizontal") {
+ this.frame.style.width = "auto";
+ this.frame.style.height = "0";
+ } else {
+ this.frame.style.width = "0";
+ this.frame.style.height = "auto";
+ }
+
+ this._width = 0;
+ this._height = 0;
+
+ this.element.appendChild(this.frame);
+ this.added = true;
+
+ this.elementBounds = bounds(this.element);
+
+ return this.frame;
+ }
+
+ render(request, show) {
+
+ // view.onLayout = this.layout.format.bind(this.layout);
+ this.create();
+
+ // Fit to size of the container, apply padding
+ this.size();
+
+ // Render Chain
+ return this.section.render(request)
+ .then(function(contents){
+ return this.load(contents);
+ }.bind(this))
+ // .then(function(doc){
+ // return this.hooks.content.trigger(view, this);
+ // }.bind(this))
+ .then(function(){
+ // this.settings.layout.format(view.contents);
+ // return this.hooks.layout.trigger(view, this);
+ }.bind(this))
+ // .then(function(){
+ // return this.display();
+ // }.bind(this))
+ // .then(function(){
+ // return this.hooks.render.trigger(view, this);
+ // }.bind(this))
+ .then(function(){
+
+ // apply the layout function to the contents
+ this.settings.layout.format(this.contents);
+
+ // Expand the iframe to the full size of the content
+ // this.expand();
+
+ // Listen for events that require an expansion of the iframe
+ this.addListeners();
+
+ if(show !== false) {
+ //this.q.enqueue(function(view){
+ this.show();
+ //}, view);
+ }
+ // this.map = new Map(view, this.layout);
+ //this.hooks.show.trigger(view, this);
+ this.emit(EVENTS.VIEWS.RENDERED, this.section);
+
+ }.bind(this))
+ .catch(function(e){
+ this.emit(EVENTS.VIEWS.LOAD_ERROR, e);
+ }.bind(this));
+
+ }
+
+ // Determine locks base on settings
+ size(_width, _height) {
+ var width = _width || this.settings.width;
+ var height = _height || this.settings.height;
+
+ if(this.layout.name === "pre-paginated") {
+ // TODO: check if these are different than the size set in chapter
+ this.lock("both", width, height);
+ } else if(this.settings.axis === "horizontal") {
+ this.lock("height", width, height);
+ } else {
+ this.lock("width", width, height);
+ }
+
+ }
+
+ // Lock an axis to element dimensions, taking borders into account
+ lock(what, width, height) {
+ var elBorders = borders(this.element);
+ var iframeBorders;
+
+ if(this.frame) {
+ iframeBorders = borders(this.frame);
+ } else {
+ iframeBorders = {width: 0, height: 0};
+ }
+
+ if(what == "width" && isNumber(width)){
+ this.lockedWidth = width - elBorders.width - iframeBorders.width;
+ this.resize(this.lockedWidth, false); // width keeps ratio correct
+ }
+
+ if(what == "height" && isNumber(height)){
+ this.lockedHeight = height - elBorders.height - iframeBorders.height;
+ this.resize(false, this.lockedHeight);
+ }
+
+ if(what === "both" &&
+ isNumber(width) &&
+ isNumber(height)){
+
+ this.lockedWidth = width - elBorders.width - iframeBorders.width;
+ this.lockedHeight = height - elBorders.height - iframeBorders.height;
+
+ this.resize(this.lockedWidth, this.lockedHeight);
+ }
+
+ }
+
+ // Resize a single axis based on content dimensions
+ expand(force) {
+ var width = this.lockedWidth;
+ var height = this.lockedHeight;
+
+ var textWidth, textHeight;
+
+ if(!this.frame || this._expanding) return;
+
+ this._expanding = true;
+
+ // Expand Horizontally
+ if(this.settings.axis === "horizontal") {
+ width = this.contentWidth(textWidth);
+ } // Expand Vertically
+ else if(this.settings.axis === "vertical") {
+ height = this.contentHeight(textHeight);
+ }
+
+ // Only Resize if dimensions have changed or
+ // if Frame is still hidden, so needs reframing
+ if(this._needsReframe || width != this._width || height != this._height){
+ this.resize(width, height);
+ }
+
+ this._expanding = false;
+ }
+
+ contentWidth(min) {
+ return this.frame.scrollWidth;
+ }
+
+ contentHeight(min) {
+ return this.frame.scrollHeight;
+ }
+
+
+ resize(width, height) {
+
+ if(!this.frame) return;
+
+ if(isNumber(width)){
+ this.frame.style.width = width + "px";
+ this._width = width;
+ }
+
+ if(isNumber(height)){
+ this.frame.style.height = height + "px";
+ this._height = height;
+ }
+
+ this.prevBounds = this.elementBounds;
+
+ this.elementBounds = bounds(this.element);
+
+ let size = {
+ width: this.elementBounds.width,
+ height: this.elementBounds.height,
+ widthDelta: this.elementBounds.width - this.prevBounds.width,
+ heightDelta: this.elementBounds.height - this.prevBounds.height,
+ };
+
+ this.onResize(this, size);
+
+ this.emit(EVENTS.VIEWS.RESIZED, size);
+
+ }
+
+
+ load(contents) {
+ var loading = new defer();
+ var loaded = loading.promise;
+ var doc = parse(contents, "text/html");
+ var body = qs(doc, "body");
+
+ /*
+ var srcs = doc.querySelectorAll("[src]");
+
+ Array.prototype.slice.call(srcs)
+ .forEach(function(item) {
+ var src = item.getAttribute("src");
+ var assetUri = URI(src);
+ var origin = assetUri.origin();
+ var absoluteUri;
+
+ if (!origin) {
+ absoluteUri = assetUri.absoluteTo(this.section.url);
+ item.src = absoluteUri;
+ }
+ }.bind(this));
+ */
+ this.frame.innerHTML = body.innerHTML;
+
+ this.document = this.frame.ownerDocument;
+ this.window = this.document.defaultView;
+
+ this.contents = new Contents(this.document, this.frame);
+
+ this.rendering = false;
+
+ loading.resolve(this.contents);
+
+
+ return loaded;
+ }
+
+ setLayout(layout) {
+ this.layout = layout;
+ }
+
+
+ resizeListenters() {
+ // Test size again
+ // clearTimeout(this.expanding);
+ // this.expanding = setTimeout(this.expand.bind(this), 350);
+ }
+
+ addListeners() {
+ //TODO: Add content listeners for expanding
+ }
+
+ removeListeners(layoutFunc) {
+ //TODO: remove content listeners for expanding
+ }
+
+ display(request) {
+ var displayed = new defer();
+
+ if (!this.displayed) {
+
+ this.render(request).then(function () {
+
+ this.emit(EVENTS.VIEWS.DISPLAYED, this);
+ this.onDisplayed(this);
+
+ this.displayed = true;
+
+ displayed.resolve(this);
+
+ }.bind(this));
+
+ } else {
+ displayed.resolve(this);
+ }
+
+
+ return displayed.promise;
+ }
+
+ show() {
+
+ this.element.style.visibility = "visible";
+
+ if(this.frame){
+ this.frame.style.visibility = "visible";
+ }
+
+ this.emit(EVENTS.VIEWS.SHOWN, this);
+ }
+
+ hide() {
+ // this.frame.style.display = "none";
+ this.element.style.visibility = "hidden";
+ this.frame.style.visibility = "hidden";
+
+ this.stopExpanding = true;
+ this.emit(EVENTS.VIEWS.HIDDEN, this);
+ }
+
+ position() {
+ return this.element.getBoundingClientRect();
+ }
+
+ locationOf(target) {
+ var parentPos = this.frame.getBoundingClientRect();
+ var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
+
+ return {
+ "left": window.scrollX + parentPos.left + targetPos.left,
+ "top": window.scrollY + parentPos.top + targetPos.top
+ };
+ }
+
+ onDisplayed(view) {
+ // Stub, override with a custom functions
+ }
+
+ onResize(view, e) {
+ // Stub, override with a custom functions
+ }
+
+ bounds() {
+ if(!this.elementBounds) {
+ this.elementBounds = bounds(this.element);
+ }
+ return this.elementBounds;
+ }
+
+ destroy() {
+
+ if(this.displayed){
+ this.displayed = false;
+
+ this.removeListeners();
+
+ this.stopExpanding = true;
+ this.element.removeChild(this.frame);
+ this.displayed = false;
+ this.frame = null;
+
+ this._textWidth = null;
+ this._textHeight = null;
+ this._width = null;
+ this._height = null;
+ }
+ // this.element.style.height = "0px";
+ // this.element.style.width = "0px";
+ }
+}
+
+EventEmitter(InlineView.prototype);
+
+export default InlineView;
diff --git a/lib/epub.js/src/mapping.js b/lib/epub.js/src/mapping.js
new file mode 100644
index 0000000..4216204
--- /dev/null
+++ b/lib/epub.js/src/mapping.js
@@ -0,0 +1,511 @@
+import EpubCFI from "./epubcfi";
+import { nodeBounds } from "./utils/core";
+
+/**
+ * Map text locations to CFI ranges
+ * @class
+ * @param {Layout} layout Layout to apply
+ * @param {string} [direction="ltr"] Text direction
+ * @param {string} [axis="horizontal"] vertical or horizontal axis
+ * @param {boolean} [dev] toggle developer highlighting
+ */
+class Mapping {
+ constructor(layout, direction, axis, dev=false) {
+ this.layout = layout;
+ this.horizontal = (axis === "horizontal") ? true : false;
+ this.direction = direction || "ltr";
+ this._dev = dev;
+ }
+
+ /**
+ * Find CFI pairs for entire section at once
+ */
+ section(view) {
+ var ranges = this.findRanges(view);
+ var map = this.rangeListToCfiList(view.section.cfiBase, ranges);
+
+ return map;
+ }
+
+ /**
+ * Find CFI pairs for a page
+ * @param {Contents} contents Contents from view
+ * @param {string} cfiBase string of the base for a cfi
+ * @param {number} start position to start at
+ * @param {number} end position to end at
+ */
+ page(contents, cfiBase, start, end) {
+ var root = contents && contents.document ? contents.document.body : false;
+ var result;
+
+ if (!root) {
+ return;
+ }
+
+ result = this.rangePairToCfiPair(cfiBase, {
+ start: this.findStart(root, start, end),
+ end: this.findEnd(root, start, end)
+ });
+
+ if (this._dev === true) {
+ let doc = contents.document;
+ let startRange = new EpubCFI(result.start).toRange(doc);
+ let endRange = new EpubCFI(result.end).toRange(doc);
+
+ let selection = doc.defaultView.getSelection();
+ let r = doc.createRange();
+ selection.removeAllRanges();
+ r.setStart(startRange.startContainer, startRange.startOffset);
+ r.setEnd(endRange.endContainer, endRange.endOffset);
+ selection.addRange(r);
+ }
+
+ return result;
+ }
+
+ /**
+ * Walk a node, preforming a function on each node it finds
+ * @private
+ * @param {Node} root Node to walkToNode
+ * @param {function} func walk function
+ * @return {*} returns the result of the walk function
+ */
+ walk(root, func) {
+ // IE11 has strange issue, if root is text node IE throws exception on
+ // calling treeWalker.nextNode(), saying
+ // Unexpected call to method or property access instead of returing null value
+ if(root && root.nodeType === Node.TEXT_NODE) {
+ return;
+ }
+ // safeFilter is required so that it can work in IE as filter is a function for IE
+ // and for other browser filter is an object.
+ var filter = {
+ acceptNode: function(node) {
+ if (node.data.trim().length > 0) {
+ return NodeFilter.FILTER_ACCEPT;
+ } else {
+ return NodeFilter.FILTER_REJECT;
+ }
+ }
+ };
+ var safeFilter = filter.acceptNode;
+ safeFilter.acceptNode = filter.acceptNode;
+
+ var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, safeFilter, false);
+ var node;
+ var result;
+ while ((node = treeWalker.nextNode())) {
+ result = func(node);
+ if(result) break;
+ }
+
+ return result;
+ }
+
+ findRanges(view){
+ var columns = [];
+ var scrollWidth = view.contents.scrollWidth();
+ var spreads = Math.ceil( scrollWidth / this.layout.spreadWidth);
+ var count = spreads * this.layout.divisor;
+ var columnWidth = this.layout.columnWidth;
+ var gap = this.layout.gap;
+ var start, end;
+
+ for (var i = 0; i < count.pages; i++) {
+ start = (columnWidth + gap) * i;
+ end = (columnWidth * (i+1)) + (gap * i);
+ columns.push({
+ start: this.findStart(view.document.body, start, end),
+ end: this.findEnd(view.document.body, start, end)
+ });
+ }
+
+ return columns;
+ }
+
+ /**
+ * Find Start Range
+ * @private
+ * @param {Node} root root node
+ * @param {number} start position to start at
+ * @param {number} end position to end at
+ * @return {Range}
+ */
+ findStart(root, start, end){
+ var stack = [root];
+ var $el;
+ var found;
+ var $prev = root;
+
+ while (stack.length) {
+
+ $el = stack.shift();
+
+ found = this.walk($el, (node) => {
+ var left, right, top, bottom;
+ var elPos;
+ var elRange;
+
+
+ elPos = nodeBounds(node);
+
+ if (this.horizontal && this.direction === "ltr") {
+
+ left = this.horizontal ? elPos.left : elPos.top;
+ right = this.horizontal ? elPos.right : elPos.bottom;
+
+ if( left >= start && left <= end ) {
+ return node;
+ } else if (right > start) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ } else if (this.horizontal && this.direction === "rtl") {
+
+ left = elPos.left;
+ right = elPos.right;
+
+ if( right <= end && right >= start ) {
+ return node;
+ } else if (left < end) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ } else {
+
+ top = elPos.top;
+ bottom = elPos.bottom;
+
+ if( top >= start && top <= end ) {
+ return node;
+ } else if (bottom > start) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ }
+
+
+ });
+
+ if(found) {
+ return this.findTextStartRange(found, start, end);
+ }
+
+ }
+
+ // Return last element
+ return this.findTextStartRange($prev, start, end);
+ }
+
+ /**
+ * Find End Range
+ * @private
+ * @param {Node} root root node
+ * @param {number} start position to start at
+ * @param {number} end position to end at
+ * @return {Range}
+ */
+ findEnd(root, start, end){
+ var stack = [root];
+ var $el;
+ var $prev = root;
+ var found;
+
+ while (stack.length) {
+
+ $el = stack.shift();
+
+ found = this.walk($el, (node) => {
+
+ var left, right, top, bottom;
+ var elPos;
+ var elRange;
+
+ elPos = nodeBounds(node);
+
+ if (this.horizontal && this.direction === "ltr") {
+
+ left = Math.round(elPos.left);
+ right = Math.round(elPos.right);
+
+ if(left > end && $prev) {
+ return $prev;
+ } else if(right > end) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ } else if (this.horizontal && this.direction === "rtl") {
+
+ left = Math.round(this.horizontal ? elPos.left : elPos.top);
+ right = Math.round(this.horizontal ? elPos.right : elPos.bottom);
+
+ if(right < start && $prev) {
+ return $prev;
+ } else if(left < start) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ } else {
+
+ top = Math.round(elPos.top);
+ bottom = Math.round(elPos.bottom);
+
+ if(top > end && $prev) {
+ return $prev;
+ } else if(bottom > end) {
+ return node;
+ } else {
+ $prev = node;
+ stack.push(node);
+ }
+
+ }
+
+ });
+
+
+ if(found){
+ return this.findTextEndRange(found, start, end);
+ }
+
+ }
+
+ // end of chapter
+ return this.findTextEndRange($prev, start, end);
+ }
+
+ /**
+ * Find Text Start Range
+ * @private
+ * @param {Node} root root node
+ * @param {number} start position to start at
+ * @param {number} end position to end at
+ * @return {Range}
+ */
+ findTextStartRange(node, start, end){
+ var ranges = this.splitTextNodeIntoRanges(node);
+ var range;
+ var pos;
+ var left, top, right;
+
+ for (var i = 0; i < ranges.length; i++) {
+ range = ranges[i];
+
+ pos = range.getBoundingClientRect();
+
+ if (this.horizontal && this.direction === "ltr") {
+
+ left = pos.left;
+ if( left >= start ) {
+ return range;
+ }
+
+ } else if (this.horizontal && this.direction === "rtl") {
+
+ right = pos.right;
+ if( right <= end ) {
+ return range;
+ }
+
+ } else {
+
+ top = pos.top;
+ if( top >= start ) {
+ return range;
+ }
+
+ }
+
+ // prev = range;
+
+ }
+
+ return ranges[0];
+ }
+
+ /**
+ * Find Text End Range
+ * @private
+ * @param {Node} root root node
+ * @param {number} start position to start at
+ * @param {number} end position to end at
+ * @return {Range}
+ */
+ findTextEndRange(node, start, end){
+ var ranges = this.splitTextNodeIntoRanges(node);
+ var prev;
+ var range;
+ var pos;
+ var left, right, top, bottom;
+
+ for (var i = 0; i < ranges.length; i++) {
+ range = ranges[i];
+
+ pos = range.getBoundingClientRect();
+
+ if (this.horizontal && this.direction === "ltr") {
+
+ left = pos.left;
+ right = pos.right;
+
+ if(left > end && prev) {
+ return prev;
+ } else if(right > end) {
+ return range;
+ }
+
+ } else if (this.horizontal && this.direction === "rtl") {
+
+ left = pos.left
+ right = pos.right;
+
+ if(right < start && prev) {
+ return prev;
+ } else if(left < start) {
+ return range;
+ }
+
+ } else {
+
+ top = pos.top;
+ bottom = pos.bottom;
+
+ if(top > end && prev) {
+ return prev;
+ } else if(bottom > end) {
+ return range;
+ }
+
+ }
+
+
+ prev = range;
+
+ }
+
+ // Ends before limit
+ return ranges[ranges.length-1];
+
+ }
+
+ /**
+ * Split up a text node into ranges for each word
+ * @private
+ * @param {Node} root root node
+ * @param {string} [_splitter] what to split on
+ * @return {Range[]}
+ */
+ splitTextNodeIntoRanges(node, _splitter){
+ var ranges = [];
+ var textContent = node.textContent || "";
+ var text = textContent.trim();
+ var range;
+ var doc = node.ownerDocument;
+ var splitter = _splitter || " ";
+
+ var pos = text.indexOf(splitter);
+
+ if(pos === -1 || node.nodeType != Node.TEXT_NODE) {
+ range = doc.createRange();
+ range.selectNodeContents(node);
+ return [range];
+ }
+
+ range = doc.createRange();
+ range.setStart(node, 0);
+ range.setEnd(node, pos);
+ ranges.push(range);
+ range = false;
+
+ while ( pos != -1 ) {
+
+ pos = text.indexOf(splitter, pos + 1);
+ if(pos > 0) {
+
+ if(range) {
+ range.setEnd(node, pos);
+ ranges.push(range);
+ }
+
+ range = doc.createRange();
+ range.setStart(node, pos+1);
+ }
+ }
+
+ if(range) {
+ range.setEnd(node, text.length);
+ ranges.push(range);
+ }
+
+ return ranges;
+ }
+
+
+ /**
+ * Turn a pair of ranges into a pair of CFIs
+ * @private
+ * @param {string} cfiBase base string for an EpubCFI
+ * @param {object} rangePair { start: Range, end: Range }
+ * @return {object} { start: "epubcfi(...)", end: "epubcfi(...)" }
+ */
+ rangePairToCfiPair(cfiBase, rangePair){
+
+ var startRange = rangePair.start;
+ var endRange = rangePair.end;
+
+ startRange.collapse(true);
+ endRange.collapse(false);
+
+ let startCfi = new EpubCFI(startRange, cfiBase).toString();
+ let endCfi = new EpubCFI(endRange, cfiBase).toString();
+
+ return {
+ start: startCfi,
+ end: endCfi
+ };
+
+ }
+
+ rangeListToCfiList(cfiBase, columns){
+ var map = [];
+ var cifPair;
+
+ for (var i = 0; i < columns.length; i++) {
+ cifPair = this.rangePairToCfiPair(cfiBase, columns[i]);
+
+ map.push(cifPair);
+
+ }
+
+ return map;
+ }
+
+ /**
+ * Set the axis for mapping
+ * @param {string} axis horizontal | vertical
+ * @return {boolean} is it horizontal?
+ */
+ axis(axis) {
+ if (axis) {
+ this.horizontal = (axis === "horizontal") ? true : false;
+ }
+ return this.horizontal;
+ }
+}
+
+export default Mapping;
diff --git a/lib/epub.js/src/navigation.js b/lib/epub.js/src/navigation.js
new file mode 100644
index 0000000..8d593a8
--- /dev/null
+++ b/lib/epub.js/src/navigation.js
@@ -0,0 +1,356 @@
+import {qs, qsa, querySelectorByType, filterChildren, getParentByTagName} from "./utils/core";
+
+/**
+ * Navigation Parser
+ * @param {document} xml navigation html / xhtml / ncx
+ */
+class Navigation {
+ constructor(xml) {
+ this.toc = [];
+ this.tocByHref = {};
+ this.tocById = {};
+
+ this.landmarks = [];
+ this.landmarksByType = {};
+
+ this.length = 0;
+ if (xml) {
+ this.parse(xml);
+ }
+ }
+
+ /**
+ * Parse out the navigation items
+ * @param {document} xml navigation html / xhtml / ncx
+ */
+ parse(xml) {
+ let isXml = xml.nodeType;
+ let html;
+ let ncx;
+
+ if (isXml) {
+ html = qs(xml, "html");
+ ncx = qs(xml, "ncx");
+ }
+
+ if (!isXml) {
+ this.toc = this.load(xml);
+ } else if(html) {
+ this.toc = this.parseNav(xml);
+ this.landmarks = this.parseLandmarks(xml);
+ } else if(ncx){
+ this.toc = this.parseNcx(xml);
+ }
+
+ this.length = 0;
+
+ this.unpack(this.toc);
+ }
+
+ /**
+ * Unpack navigation items
+ * @private
+ * @param {array} toc
+ */
+ unpack(toc) {
+ var item;
+
+ for (var i = 0; i < toc.length; i++) {
+ item = toc[i];
+
+ if (item.href) {
+ this.tocByHref[item.href] = i;
+ }
+
+ if (item.id) {
+ this.tocById[item.id] = i;
+ }
+
+ this.length++;
+
+ if (item.subitems.length) {
+ this.unpack(item.subitems);
+ }
+ }
+
+ }
+
+ /**
+ * Get an item from the navigation
+ * @param {string} target
+ * @return {object} navItem
+ */
+ get(target) {
+ var index;
+
+ if(!target) {
+ return this.toc;
+ }
+
+ if(target.indexOf("#") === 0) {
+ index = this.tocById[target.substring(1)];
+ } else if(target in this.tocByHref){
+ index = this.tocByHref[target];
+ }
+
+ return this.getByIndex(target, index, this.toc);
+ }
+
+ /**
+ * Get an item from navigation subitems recursively by index
+ * @param {string} target
+ * @param {number} index
+ * @param {array} navItems
+ * @return {object} navItem
+ */
+ getByIndex(target, index, navItems) {
+ if (navItems.length === 0) {
+ return;
+ }
+
+ const item = navItems[index];
+ if (item && (target === item.id || target === item.href)) {
+ return item;
+ } else {
+ let result;
+ for (let i = 0; i < navItems.length; ++i) {
+ result = this.getByIndex(target, index, navItems[i].subitems);
+ if (result) {
+ break;
+ }
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Get a landmark by type
+ * List of types: https://idpf.github.io/epub-vocabs/structure/
+ * @param {string} type
+ * @return {object} landmarkItem
+ */
+ landmark(type) {
+ var index;
+
+ if(!type) {
+ return this.landmarks;
+ }
+
+ index = this.landmarksByType[type];
+
+ return this.landmarks[index];
+ }
+
+ /**
+ * Parse toc from a Epub > 3.0 Nav
+ * @private
+ * @param {document} navHtml
+ * @return {array} navigation list
+ */
+ parseNav(navHtml){
+ var navElement = querySelectorByType(navHtml, "nav", "toc");
+ var list = [];
+
+ if (!navElement) return list;
+
+ let navList = filterChildren(navElement, "ol", true);
+ if (!navList) return list;
+
+ list = this.parseNavList(navList);
+ return list;
+ }
+
+ /**
+ * Parses lists in the toc
+ * @param {document} navListHtml
+ * @param {string} parent id
+ * @return {array} navigation list
+ */
+ parseNavList(navListHtml, parent) {
+ const result = [];
+
+ if (!navListHtml) return result;
+ if (!navListHtml.children) return result;
+
+ for (let i = 0; i < navListHtml.children.length; i++) {
+ const item = this.navItem(navListHtml.children[i], parent);
+
+ if (item) {
+ result.push(item);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Create a navItem
+ * @private
+ * @param {element} item
+ * @return {object} navItem
+ */
+ navItem(item, parent) {
+ let id = item.getAttribute("id") || undefined;
+ let content = filterChildren(item, "a", true);
+
+ if (!content) {
+ return;
+ }
+
+ let src = content.getAttribute("href") || "";
+
+ if (!id) {
+ id = src;
+ }
+ let text = content.textContent || "";
+
+ let subitems = [];
+ let nested = filterChildren(item, "ol", true);
+ if (nested) {
+ subitems = this.parseNavList(nested, id);
+ }
+
+ return {
+ "id": id,
+ "href": src,
+ "label": text,
+ "subitems" : subitems,
+ "parent" : parent
+ };
+ }
+
+ /**
+ * Parse landmarks from a Epub > 3.0 Nav
+ * @private
+ * @param {document} navHtml
+ * @return {array} landmarks list
+ */
+ parseLandmarks(navHtml){
+ var navElement = querySelectorByType(navHtml, "nav", "landmarks");
+ var navItems = navElement ? qsa(navElement, "li") : [];
+ var length = navItems.length;
+ var i;
+ var list = [];
+ var item;
+
+ if(!navItems || length === 0) return list;
+
+ for (i = 0; i < length; ++i) {
+ item = this.landmarkItem(navItems[i]);
+ if (item) {
+ list.push(item);
+ this.landmarksByType[item.type] = i;
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * Create a landmarkItem
+ * @private
+ * @param {element} item
+ * @return {object} landmarkItem
+ */
+ landmarkItem(item){
+ let content = filterChildren(item, "a", true);
+
+ if (!content) {
+ return;
+ }
+
+ let type = content.getAttributeNS("http://www.idpf.org/2007/ops", "type") || undefined;
+ let href = content.getAttribute("href") || "";
+ let text = content.textContent || "";
+
+ return {
+ "href": href,
+ "label": text,
+ "type" : type
+ };
+ }
+
+ /**
+ * Parse from a Epub > 3.0 NC
+ * @private
+ * @param {document} navHtml
+ * @return {array} navigation list
+ */
+ parseNcx(tocXml){
+ var navPoints = qsa(tocXml, "navPoint");
+ var length = navPoints.length;
+ var i;
+ var toc = {};
+ var list = [];
+ var item, parent;
+
+ if(!navPoints || length === 0) return list;
+
+ for (i = 0; i < length; ++i) {
+ item = this.ncxItem(navPoints[i]);
+ toc[item.id] = item;
+ if(!item.parent) {
+ list.push(item);
+ } else {
+ parent = toc[item.parent];
+ parent.subitems.push(item);
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * Create a ncxItem
+ * @private
+ * @param {element} item
+ * @return {object} ncxItem
+ */
+ ncxItem(item){
+ var id = item.getAttribute("id") || false,
+ content = qs(item, "content"),
+ src = content.getAttribute("src"),
+ navLabel = qs(item, "navLabel"),
+ text = navLabel.textContent ? navLabel.textContent : "",
+ subitems = [],
+ parentNode = item.parentNode,
+ parent;
+
+ if(parentNode && (parentNode.nodeName === "navPoint" || parentNode.nodeName.split(':').slice(-1)[0] === "navPoint")) {
+ parent = parentNode.getAttribute("id");
+ }
+
+
+ return {
+ "id": id,
+ "href": src,
+ "label": text,
+ "subitems" : subitems,
+ "parent" : parent
+ };
+ }
+
+ /**
+ * Load Spine Items
+ * @param {object} json the items to be loaded
+ * @return {Array} navItems
+ */
+ load(json) {
+ return json.map(item => {
+ item.label = item.title;
+ item.subitems = item.children ? this.load(item.children) : [];
+ return item;
+ });
+ }
+
+ /**
+ * forEach pass through
+ * @param {Function} fn function to run on each item
+ * @return {method} forEach loop
+ */
+ forEach(fn) {
+ return this.toc.forEach(fn);
+ }
+}
+
+export default Navigation;
diff --git a/lib/epub.js/src/packaging.js b/lib/epub.js/src/packaging.js
new file mode 100644
index 0000000..396b5d4
--- /dev/null
+++ b/lib/epub.js/src/packaging.js
@@ -0,0 +1,372 @@
+import {qs, qsa, qsp, indexOfElementNode} from "./utils/core";
+
+/**
+ * Open Packaging Format Parser
+ * @class
+ * @param {document} packageDocument OPF XML
+ */
+class Packaging {
+ constructor(packageDocument) {
+ this.manifest = {};
+ this.navPath = '';
+ this.ncxPath = '';
+ this.coverPath = '';
+ this.spineNodeIndex = 0;
+ this.spine = [];
+ this.metadata = {};
+
+ if (packageDocument) {
+ this.parse(packageDocument);
+ }
+ }
+
+ /**
+ * Parse OPF XML
+ * @param {document} packageDocument OPF XML
+ * @return {object} parsed package parts
+ */
+ parse(packageDocument){
+ var metadataNode, manifestNode, spineNode;
+
+ if(!packageDocument) {
+ throw new Error("Package File Not Found");
+ }
+
+ metadataNode = qs(packageDocument, "metadata");
+ if(!metadataNode) {
+ throw new Error("No Metadata Found");
+ }
+
+ manifestNode = qs(packageDocument, "manifest");
+ if(!manifestNode) {
+ throw new Error("No Manifest Found");
+ }
+
+ spineNode = qs(packageDocument, "spine");
+ if(!spineNode) {
+ throw new Error("No Spine Found");
+ }
+
+ this.manifest = this.parseManifest(manifestNode);
+ this.navPath = this.findNavPath(manifestNode);
+ this.ncxPath = this.findNcxPath(manifestNode, spineNode);
+ this.coverPath = this.findCoverPath(packageDocument);
+
+ this.spineNodeIndex = indexOfElementNode(spineNode);
+
+ this.spine = this.parseSpine(spineNode, this.manifest);
+
+ this.uniqueIdentifier = this.findUniqueIdentifier(packageDocument);
+ this.metadata = this.parseMetadata(metadataNode);
+
+ this.metadata.direction = spineNode.getAttribute("page-progression-direction");
+
+ return {
+ "metadata" : this.metadata,
+ "spine" : this.spine,
+ "manifest" : this.manifest,
+ "navPath" : this.navPath,
+ "ncxPath" : this.ncxPath,
+ "coverPath": this.coverPath,
+ "spineNodeIndex" : this.spineNodeIndex
+ };
+ }
+
+ /**
+ * Parse Metadata
+ * @private
+ * @param {node} xml
+ * @return {object} metadata
+ */
+ parseMetadata(xml){
+ var metadata = {};
+
+ metadata.title = this.getElementText(xml, "title");
+ metadata.creator = this.getElementText(xml, "creator");
+ metadata.description = this.getElementText(xml, "description");
+
+ metadata.pubdate = this.getElementText(xml, "date");
+
+ metadata.publisher = this.getElementText(xml, "publisher");
+
+ metadata.identifier = this.getElementText(xml, "identifier");
+ metadata.language = this.getElementText(xml, "language");
+ metadata.rights = this.getElementText(xml, "rights");
+
+ metadata.modified_date = this.getPropertyText(xml, "dcterms:modified");
+
+ metadata.layout = this.getPropertyText(xml, "rendition:layout");
+ metadata.orientation = this.getPropertyText(xml, "rendition:orientation");
+ metadata.flow = this.getPropertyText(xml, "rendition:flow");
+ metadata.viewport = this.getPropertyText(xml, "rendition:viewport");
+ metadata.media_active_class = this.getPropertyText(xml, "media:active-class");
+ metadata.spread = this.getPropertyText(xml, "rendition:spread");
+ // metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
+
+ return metadata;
+ }
+
+ /**
+ * Parse Manifest
+ * @private
+ * @param {node} manifestXml
+ * @return {object} manifest
+ */
+ parseManifest(manifestXml){
+ var manifest = {};
+
+ //-- Turn items into an array
+ // var selected = manifestXml.querySelectorAll("item");
+ var selected = qsa(manifestXml, "item");
+ var 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") || "",
+ overlay = item.getAttribute("media-overlay") || "",
+ properties = item.getAttribute("properties") || "";
+
+ manifest[id] = {
+ "href" : href,
+ // "url" : href,
+ "type" : type,
+ "overlay" : overlay,
+ "properties" : properties.length ? properties.split(" ") : []
+ };
+
+ });
+
+ return manifest;
+
+ }
+
+ /**
+ * Parse Spine
+ * @private
+ * @param {node} spineXml
+ * @param {Packaging.manifest} manifest
+ * @return {object} spine
+ */
+ parseSpine(spineXml, manifest){
+ var spine = [];
+
+ var selected = qsa(spineXml, "itemref");
+ var items = Array.prototype.slice.call(selected);
+
+ // var epubcfi = new EpubCFI();
+
+ //-- Add to array to mantain ordering and cross reference with manifest
+ items.forEach(function(item, index){
+ var idref = 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 itemref = {
+ "idref" : idref,
+ "linear" : item.getAttribute("linear") || "yes",
+ "properties" : propArray,
+ // "href" : manifest[Id].href,
+ // "url" : manifest[Id].url,
+ "index" : index
+ // "cfiBase" : cfiBase
+ };
+ spine.push(itemref);
+ });
+
+ return spine;
+ }
+
+ /**
+ * Find Unique Identifier
+ * @private
+ * @param {node} packageXml
+ * @return {string} Unique Identifier text
+ */
+ findUniqueIdentifier(packageXml){
+ var uniqueIdentifierId = packageXml.documentElement.getAttribute("unique-identifier");
+ if (! uniqueIdentifierId) {
+ return "";
+ }
+ var identifier = packageXml.getElementById(uniqueIdentifierId);
+ if (! identifier) {
+ return "";
+ }
+
+ if (identifier.localName === "identifier" && identifier.namespaceURI === "http://purl.org/dc/elements/1.1/") {
+ return identifier.childNodes.length > 0 ? identifier.childNodes[0].nodeValue.trim() : "";
+ }
+
+ return "";
+ }
+
+ /**
+ * Find TOC NAV
+ * @private
+ * @param {element} manifestNode
+ * @return {string}
+ */
+ findNavPath(manifestNode){
+ // Find item with property "nav"
+ // Should catch nav irregardless of order
+ // var node = manifestNode.querySelector("item[properties$='nav'], item[properties^='nav '], item[properties*=' nav ']");
+ var node = qsp(manifestNode, "item", {"properties":"nav"});
+ return node ? node.getAttribute("href") : false;
+ }
+
+ /**
+ * Find TOC NCX
+ * media-type="application/x-dtbncx+xml" href="toc.ncx"
+ * @private
+ * @param {element} manifestNode
+ * @param {element} spineNode
+ * @return {string}
+ */
+ findNcxPath(manifestNode, spineNode){
+ // var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
+ var node = qsp(manifestNode, "item", {"media-type":"application/x-dtbncx+xml"});
+ var tocId;
+
+ // If we can't find the toc by media-type then try to look for id of the item in the spine attributes as
+ // according to http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4.1.2,
+ // "The item that describes the NCX must be referenced by the spine toc attribute."
+ if (!node) {
+ tocId = spineNode.getAttribute("toc");
+ if(tocId) {
+ // node = manifestNode.querySelector("item[id='" + tocId + "']");
+ node = manifestNode.querySelector(`#${tocId}`);
+ }
+ }
+
+ return node ? node.getAttribute("href") : false;
+ }
+
+ /**
+ * Find the Cover Path
+ * <item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />
+ * Fallback for Epub 2.0
+ * @private
+ * @param {node} packageXml
+ * @return {string} href
+ */
+ findCoverPath(packageXml){
+ var pkg = qs(packageXml, "package");
+ var epubVersion = pkg.getAttribute("version");
+
+ // Try parsing cover with epub 3.
+ // var node = packageXml.querySelector("item[properties='cover-image']");
+ var node = qsp(packageXml, "item", {"properties":"cover-image"});
+ if (node) return node.getAttribute("href");
+
+ // Fallback to epub 2.
+ var metaCover = qsp(packageXml, "meta", {"name":"cover"});
+
+ if (metaCover) {
+ var coverId = metaCover.getAttribute("content");
+ // var cover = packageXml.querySelector("item[id='" + coverId + "']");
+ var cover = packageXml.getElementById(coverId);
+ return cover ? cover.getAttribute("href") : "";
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Get text of a namespaced element
+ * @private
+ * @param {node} xml
+ * @param {string} tag
+ * @return {string} text
+ */
+ getElementText(xml, tag){
+ var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag);
+ var el;
+
+ if(!found || found.length === 0) return "";
+
+ el = found[0];
+
+ if(el.childNodes.length){
+ return el.childNodes[0].nodeValue;
+ }
+
+ return "";
+
+ }
+
+ /**
+ * Get text by property
+ * @private
+ * @param {node} xml
+ * @param {string} property
+ * @return {string} text
+ */
+ getPropertyText(xml, property){
+ var el = qsp(xml, "meta", {"property":property});
+
+ if(el && el.childNodes.length){
+ return el.childNodes[0].nodeValue;
+ }
+
+ return "";
+ }
+
+ /**
+ * Load JSON Manifest
+ * @param {document} packageDocument OPF XML
+ * @return {object} parsed package parts
+ */
+ load(json) {
+ this.metadata = json.metadata;
+
+ let spine = json.readingOrder || json.spine;
+ this.spine = spine.map((item, index) =>{
+ item.index = index;
+ item.linear = item.linear || "yes";
+ return item;
+ });
+
+ json.resources.forEach((item, index) => {
+ this.manifest[index] = item;
+
+ if (item.rel && item.rel[0] === "cover") {
+ this.coverPath = item.href;
+ }
+ });
+
+ this.spineNodeIndex = 0;
+
+ this.toc = json.toc.map((item, index) =>{
+ item.label = item.title;
+ return item;
+ });
+
+ return {
+ "metadata" : this.metadata,
+ "spine" : this.spine,
+ "manifest" : this.manifest,
+ "navPath" : this.navPath,
+ "ncxPath" : this.ncxPath,
+ "coverPath": this.coverPath,
+ "spineNodeIndex" : this.spineNodeIndex,
+ "toc" : this.toc
+ };
+ }
+
+ destroy() {
+ this.manifest = undefined;
+ this.navPath = undefined;
+ this.ncxPath = undefined;
+ this.coverPath = undefined;
+ this.spineNodeIndex = undefined;
+ this.spine = undefined;
+ this.metadata = undefined;
+ }
+}
+
+export default Packaging;
diff --git a/lib/epub.js/src/pagelist.js b/lib/epub.js/src/pagelist.js
new file mode 100644
index 0000000..6de82f6
--- /dev/null
+++ b/lib/epub.js/src/pagelist.js
@@ -0,0 +1,274 @@
+import EpubCFI from "./epubcfi";
+import {
+ qs,
+ qsa,
+ querySelectorByType,
+ indexOfSorted,
+ locationOf
+} from "./utils/core";
+
+/**
+ * Page List Parser
+ * @param {document} [xml]
+ */
+class PageList {
+ constructor(xml) {
+ this.pages = [];
+ this.locations = [];
+ this.epubcfi = new EpubCFI();
+
+ this.firstPage = 0;
+ this.lastPage = 0;
+ this.totalPages = 0;
+
+ this.toc = undefined;
+ this.ncx = undefined;
+
+ if (xml) {
+ this.pageList = this.parse(xml);
+ }
+
+ if(this.pageList && this.pageList.length) {
+ this.process(this.pageList);
+ }
+ }
+
+ /**
+ * Parse PageList Xml
+ * @param {document} xml
+ */
+ parse(xml) {
+ var html = qs(xml, "html");
+ var ncx = qs(xml, "ncx");
+
+ if(html) {
+ return this.parseNav(xml);
+ } else if(ncx){
+ return this.parseNcx(xml);
+ }
+
+ }
+
+ /**
+ * Parse a Nav PageList
+ * @private
+ * @param {node} navHtml
+ * @return {PageList.item[]} list
+ */
+ parseNav(navHtml){
+ var navElement = querySelectorByType(navHtml, "nav", "page-list");
+ var navItems = navElement ? qsa(navElement, "li") : [];
+ var length = navItems.length;
+ var i;
+ var list = [];
+ var item;
+
+ if(!navItems || length === 0) return list;
+
+ for (i = 0; i < length; ++i) {
+ item = this.item(navItems[i]);
+ list.push(item);
+ }
+
+ return list;
+ }
+
+ parseNcx(navXml) {
+ var list = [];
+ var i = 0;
+ var item;
+ var pageList;
+ var pageTargets;
+ var length = 0;
+
+ pageList = qs(navXml, "pageList");
+ if (!pageList) return list;
+
+ pageTargets = qsa(pageList, "pageTarget");
+ length = pageTargets.length;
+
+ if (!pageTargets || pageTargets.length === 0) {
+ return list;
+ }
+
+ for (i = 0; i < length; ++i) {
+ item = this.ncxItem(pageTargets[i]);
+ list.push(item);
+ }
+
+ return list;
+ }
+
+ ncxItem(item) {
+ var navLabel = qs(item, "navLabel");
+ var navLabelText = qs(navLabel, "text");
+ var pageText = navLabelText.textContent;
+ var content = qs(item, "content");
+
+ var href = content.getAttribute("src");
+ var page = parseInt(pageText, 10);
+
+ return {
+ "href": href,
+ "page": page,
+ };
+ }
+
+ /**
+ * Page List Item
+ * @private
+ * @param {node} item
+ * @return {object} pageListItem
+ */
+ item(item){
+ var content = qs(item, "a"),
+ 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;
+ return {
+ "cfi" : cfi,
+ "href" : href,
+ "packageUrl" : packageUrl,
+ "page" : page
+ };
+ } else {
+ return {
+ "href" : href,
+ "page" : page
+ };
+ }
+ }
+
+ /**
+ * Process pageList items
+ * @private
+ * @param {array} pageList
+ */
+ process(pageList){
+ pageList.forEach(function(item){
+ this.pages.push(item.page);
+ if (item.cfi) {
+ this.locations.push(item.cfi);
+ }
+ }, this);
+ this.firstPage = parseInt(this.pages[0]);
+ this.lastPage = parseInt(this.pages[this.pages.length-1]);
+ this.totalPages = this.lastPage - this.firstPage;
+ }
+
+ /**
+ * Get a PageList result from a EpubCFI
+ * @param {string} cfi EpubCFI String
+ * @return {number} page
+ */
+ pageFromCfi(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 = indexOfSorted(cfi, this.locations, this.epubcfi.compare);
+ if(index != -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 = 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;
+ }
+
+ /**
+ * Get an EpubCFI from a Page List Item
+ * @param {string | number} pg
+ * @return {string} cfi
+ */
+ cfiFromPage(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;
+ }
+
+ /**
+ * Get a Page from Book percentage
+ * @param {number} percent
+ * @return {number} page
+ */
+ pageFromPercentage(percent){
+ var pg = Math.round(this.totalPages * percent);
+ return pg;
+ }
+
+ /**
+ * Returns a value between 0 - 1 corresponding to the location of a page
+ * @param {number} pg the page
+ * @return {number} percentage
+ */
+ percentageFromPage(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
+ * @param {string} cfi EpubCFI String
+ * @return {number} percentage
+ */
+ percentageFromCfi(cfi){
+ var pg = this.pageFromCfi(cfi);
+ var percentage = this.percentageFromPage(pg);
+ return percentage;
+ }
+
+ /**
+ * Destroy
+ */
+ destroy() {
+ this.pages = undefined;
+ this.locations = undefined;
+ this.epubcfi = undefined;
+
+ this.pageList = undefined;
+
+ this.toc = undefined;
+ this.ncx = undefined;
+ }
+}
+
+export default PageList;
diff --git a/lib/epub.js/src/rendition.js b/lib/epub.js/src/rendition.js
new file mode 100644
index 0000000..f9ba53d
--- /dev/null
+++ b/lib/epub.js/src/rendition.js
@@ -0,0 +1,1064 @@
+import EventEmitter from "event-emitter";
+import { extend, defer, isFloat } from "./utils/core";
+import Hook from "./utils/hook";
+import EpubCFI from "./epubcfi";
+import Queue from "./utils/queue";
+import Layout from "./layout";
+// import Mapping from "./mapping";
+import Themes from "./themes";
+import Contents from "./contents";
+import Annotations from "./annotations";
+import { EVENTS, DOM_EVENTS } from "./utils/constants";
+
+// Default Views
+import IframeView from "./managers/views/iframe";
+
+// Default View Managers
+import DefaultViewManager from "./managers/default/index";
+import ContinuousViewManager from "./managers/continuous/index";
+
+/**
+ * Displays an Epub as a series of Views for each Section.
+ * Requires Manager and View class to handle specifics of rendering
+ * the section content.
+ * @class
+ * @param {Book} book
+ * @param {object} [options]
+ * @param {number} [options.width]
+ * @param {number} [options.height]
+ * @param {string} [options.ignoreClass] class for the cfi parser to ignore
+ * @param {string | function | object} [options.manager='default']
+ * @param {string | function} [options.view='iframe']
+ * @param {string} [options.layout] layout to force
+ * @param {string} [options.spread] force spread value
+ * @param {number} [options.minSpreadWidth] overridden by spread: none (never) / both (always)
+ * @param {string} [options.stylesheet] url of stylesheet to be injected
+ * @param {boolean} [options.resizeOnOrientationChange] false to disable orientation events
+ * @param {string} [options.script] url of script to be injected
+ * @param {boolean | object} [options.snap=false] use snap scrolling
+ */
+class Rendition {
+ constructor(book, options) {
+
+ this.settings = extend(this.settings || {}, {
+ width: null,
+ height: null,
+ ignoreClass: "",
+ manager: "default",
+ view: "iframe",
+ flow: null,
+ layout: null,
+ spread: null,
+ minSpreadWidth: 800,
+ stylesheet: null,
+ resizeOnOrientationChange: true,
+ script: null,
+ snap: false,
+ defaultDirection: "ltr"
+ });
+
+ extend(this.settings, options);
+
+ if (typeof(this.settings.manager) === "object") {
+ this.manager = this.settings.manager;
+ }
+
+ this.book = book;
+
+ /**
+ * Adds Hook methods to the Rendition prototype
+ * @member {object} hooks
+ * @property {Hook} hooks.content
+ * @memberof Rendition
+ */
+ this.hooks = {};
+ this.hooks.display = new Hook(this);
+ this.hooks.serialize = new Hook(this);
+ this.hooks.content = new Hook(this);
+ this.hooks.unloaded = new Hook(this);
+ this.hooks.layout = new Hook(this);
+ this.hooks.render = new Hook(this);
+ this.hooks.show = new Hook(this);
+
+ this.hooks.content.register(this.handleLinks.bind(this));
+ this.hooks.content.register(this.passEvents.bind(this));
+ this.hooks.content.register(this.adjustImages.bind(this));
+
+ this.book.spine.hooks.content.register(this.injectIdentifier.bind(this));
+
+ if (this.settings.stylesheet) {
+ this.book.spine.hooks.content.register(this.injectStylesheet.bind(this));
+ }
+
+ if (this.settings.script) {
+ this.book.spine.hooks.content.register(this.injectScript.bind(this));
+ }
+
+ /**
+ * @member {Themes} themes
+ * @memberof Rendition
+ */
+ this.themes = new Themes(this);
+
+ /**
+ * @member {Annotations} annotations
+ * @memberof Rendition
+ */
+ this.annotations = new Annotations(this);
+
+ this.epubcfi = new EpubCFI();
+
+ this.q = new Queue(this);
+
+ /**
+ * A Rendered Location Range
+ * @typedef location
+ * @type {Object}
+ * @property {object} start
+ * @property {string} start.index
+ * @property {string} start.href
+ * @property {object} start.displayed
+ * @property {EpubCFI} start.cfi
+ * @property {number} start.location
+ * @property {number} start.percentage
+ * @property {number} start.displayed.page
+ * @property {number} start.displayed.total
+ * @property {object} end
+ * @property {string} end.index
+ * @property {string} end.href
+ * @property {object} end.displayed
+ * @property {EpubCFI} end.cfi
+ * @property {number} end.location
+ * @property {number} end.percentage
+ * @property {number} end.displayed.page
+ * @property {number} end.displayed.total
+ * @property {boolean} atStart
+ * @property {boolean} atEnd
+ * @memberof Rendition
+ */
+ this.location = undefined;
+
+ // Hold queue until book is opened
+ this.q.enqueue(this.book.opened);
+
+ this.starting = new defer();
+ /**
+ * @member {promise} started returns after the rendition has started
+ * @memberof Rendition
+ */
+ this.started = this.starting.promise;
+
+ // Block the queue until rendering is started
+ this.q.enqueue(this.start);
+ }
+
+ /**
+ * Set the manager function
+ * @param {function} manager
+ */
+ setManager(manager) {
+ this.manager = manager;
+ }
+
+ /**
+ * Require the manager from passed string, or as a class function
+ * @param {string|object} manager [description]
+ * @return {method}
+ */
+ requireManager(manager) {
+ var viewManager;
+
+ // If manager is a string, try to load from imported managers
+ if (typeof manager === "string" && manager === "default") {
+ viewManager = DefaultViewManager;
+ } else if (typeof manager === "string" && manager === "continuous") {
+ viewManager = ContinuousViewManager;
+ } else {
+ // otherwise, assume we were passed a class function
+ viewManager = manager;
+ }
+
+ return viewManager;
+ }
+
+ /**
+ * Require the view from passed string, or as a class function
+ * @param {string|object} view
+ * @return {view}
+ */
+ requireView(view) {
+ var View;
+
+ // If view is a string, try to load from imported views,
+ if (typeof view == "string" && view === "iframe") {
+ View = IframeView;
+ } else {
+ // otherwise, assume we were passed a class function
+ View = view;
+ }
+
+ return View;
+ }
+
+ /**
+ * Start the rendering
+ * @return {Promise} rendering has started
+ */
+ start(){
+ if (!this.settings.layout && (this.book.package.metadata.layout === "pre-paginated" || this.book.displayOptions.fixedLayout === "true")) {
+ this.settings.layout = "pre-paginated";
+ }
+ switch(this.book.package.metadata.spread) {
+ case 'none':
+ this.settings.spread = 'none';
+ break;
+ case 'both':
+ this.settings.spread = true;
+ break;
+ }
+
+ if(!this.manager) {
+ this.ViewManager = this.requireManager(this.settings.manager);
+ this.View = this.requireView(this.settings.view);
+
+ this.manager = new this.ViewManager({
+ view: this.View,
+ queue: this.q,
+ request: this.book.load.bind(this.book),
+ settings: this.settings
+ });
+ }
+
+ this.direction(this.book.package.metadata.direction || this.settings.defaultDirection);
+
+ // Parse metadata to get layout props
+ this.settings.globalLayoutProperties = this.determineLayoutProperties(this.book.package.metadata);
+
+ this.flow(this.settings.globalLayoutProperties.flow);
+
+ this.layout(this.settings.globalLayoutProperties);
+
+ // Listen for displayed views
+ this.manager.on(EVENTS.MANAGERS.ADDED, this.afterDisplayed.bind(this));
+ this.manager.on(EVENTS.MANAGERS.REMOVED, this.afterRemoved.bind(this));
+
+ // Listen for resizing
+ this.manager.on(EVENTS.MANAGERS.RESIZED, this.onResized.bind(this));
+
+ // Listen for rotation
+ this.manager.on(EVENTS.MANAGERS.ORIENTATION_CHANGE, this.onOrientationChange.bind(this));
+
+ // Listen for scroll changes
+ this.manager.on(EVENTS.MANAGERS.SCROLLED, this.reportLocation.bind(this));
+
+ /**
+ * Emit that rendering has started
+ * @event started
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.STARTED);
+
+ // Start processing queue
+ this.starting.resolve();
+ }
+
+ /**
+ * Call to attach the container to an element in the dom
+ * Container must be attached before rendering can begin
+ * @param {element} element to attach to
+ * @return {Promise}
+ */
+ attachTo(element){
+
+ return this.q.enqueue(function () {
+
+ // Start rendering
+ this.manager.render(element, {
+ "width" : this.settings.width,
+ "height" : this.settings.height
+ });
+
+ /**
+ * Emit that rendering has attached to an element
+ * @event attached
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.ATTACHED);
+
+ }.bind(this));
+
+ }
+
+ /**
+ * Display a point in the book
+ * The request will be added to the rendering Queue,
+ * so it will wait until book is opened, rendering started
+ * and all other rendering tasks have finished to be called.
+ * @param {string} target Url or EpubCFI
+ * @return {Promise}
+ */
+ display(target){
+ if (this.displaying) {
+ this.displaying.resolve();
+ }
+ return this.q.enqueue(this._display, target);
+ }
+
+ /**
+ * Tells the manager what to display immediately
+ * @private
+ * @param {string} target Url or EpubCFI
+ * @return {Promise}
+ */
+ _display(target){
+ if (!this.book) {
+ return;
+ }
+ var isCfiString = this.epubcfi.isCfiString(target);
+ var displaying = new defer();
+ var displayed = displaying.promise;
+ var section;
+ var moveTo;
+
+ this.displaying = displaying;
+
+ // Check if this is a book percentage
+ if (this.book.locations.length() && isFloat(target)) {
+ target = this.book.locations.cfiFromPercentage(parseFloat(target));
+ }
+
+ section = this.book.spine.get(target);
+
+ if(!section){
+ displaying.reject(new Error("No Section Found"));
+ return displayed;
+ }
+
+ this.manager.display(section, target)
+ .then(() => {
+ displaying.resolve(section);
+ this.displaying = undefined;
+
+ /**
+ * Emit that a section has been displayed
+ * @event displayed
+ * @param {Section} section
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.DISPLAYED, section);
+ this.reportLocation();
+ }, (err) => {
+ /**
+ * Emit that has been an error displaying
+ * @event displayError
+ * @param {Section} section
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.DISPLAY_ERROR, err);
+ });
+
+ return displayed;
+ }
+
+ /*
+ render(view, show) {
+
+ // view.onLayout = this.layout.format.bind(this.layout);
+ view.create();
+
+ // Fit to size of the container, apply padding
+ this.manager.resizeView(view);
+
+ // Render Chain
+ return view.section.render(this.book.request)
+ .then(function(contents){
+ return view.load(contents);
+ }.bind(this))
+ .then(function(doc){
+ return this.hooks.content.trigger(view, this);
+ }.bind(this))
+ .then(function(){
+ this.layout.format(view.contents);
+ return this.hooks.layout.trigger(view, this);
+ }.bind(this))
+ .then(function(){
+ return view.display();
+ }.bind(this))
+ .then(function(){
+ return this.hooks.render.trigger(view, this);
+ }.bind(this))
+ .then(function(){
+ if(show !== false) {
+ this.q.enqueue(function(view){
+ view.show();
+ }, view);
+ }
+ // this.map = new Map(view, this.layout);
+ this.hooks.show.trigger(view, this);
+ this.trigger("rendered", view.section);
+
+ }.bind(this))
+ .catch(function(e){
+ this.trigger("loaderror", e);
+ }.bind(this));
+
+ }
+ */
+
+ /**
+ * Report what section has been displayed
+ * @private
+ * @param {*} view
+ */
+ afterDisplayed(view){
+
+ view.on(EVENTS.VIEWS.MARK_CLICKED, (cfiRange, data) => this.triggerMarkEvent(cfiRange, data, view.contents));
+
+ this.hooks.render.trigger(view, this)
+ .then(() => {
+ if (view.contents) {
+ this.hooks.content.trigger(view.contents, this).then(() => {
+ /**
+ * Emit that a section has been rendered
+ * @event rendered
+ * @param {Section} section
+ * @param {View} view
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.RENDERED, view.section, view);
+ });
+ } else {
+ this.emit(EVENTS.RENDITION.RENDERED, view.section, view);
+ }
+ });
+
+ }
+
+ /**
+ * Report what has been removed
+ * @private
+ * @param {*} view
+ */
+ afterRemoved(view){
+ this.hooks.unloaded.trigger(view, this).then(() => {
+ /**
+ * Emit that a section has been removed
+ * @event removed
+ * @param {Section} section
+ * @param {View} view
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.REMOVED, view.section, view);
+ });
+ }
+
+ /**
+ * Report resize events and display the last seen location
+ * @private
+ */
+ onResized(size, epubcfi){
+
+ /**
+ * Emit that the rendition has been resized
+ * @event resized
+ * @param {number} width
+ * @param {height} height
+ * @param {string} epubcfi (optional)
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.RESIZED, {
+ width: size.width,
+ height: size.height
+ }, epubcfi);
+
+ if (this.location && this.location.start) {
+ this.display(epubcfi || this.location.start.cfi);
+ }
+
+ }
+
+ /**
+ * Report orientation events and display the last seen location
+ * @private
+ */
+ onOrientationChange(orientation){
+ /**
+ * Emit that the rendition has been rotated
+ * @event orientationchange
+ * @param {string} orientation
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.ORIENTATION_CHANGE, orientation);
+ }
+
+ /**
+ * Move the Rendition to a specific offset
+ * Usually you would be better off calling display()
+ * @param {object} offset
+ */
+ moveTo(offset){
+ this.manager.moveTo(offset);
+ }
+
+ /**
+ * Trigger a resize of the views
+ * @param {number} [width]
+ * @param {number} [height]
+ * @param {string} [epubcfi] (optional)
+ */
+ resize(width, height, epubcfi){
+ if (width) {
+ this.settings.width = width;
+ }
+ if (height) {
+ this.settings.height = height;
+ }
+ this.manager.resize(width, height, epubcfi);
+ }
+
+ /**
+ * Clear all rendered views
+ */
+ clear(){
+ this.manager.clear();
+ }
+
+ /**
+ * Go to the next "page" in the rendition
+ * @return {Promise}
+ */
+ next(){
+ return this.q.enqueue(this.manager.next.bind(this.manager))
+ .then(this.reportLocation.bind(this));
+ }
+
+ /**
+ * Go to the previous "page" in the rendition
+ * @return {Promise}
+ */
+ prev(){
+ return this.q.enqueue(this.manager.prev.bind(this.manager))
+ .then(this.reportLocation.bind(this));
+ }
+
+ //-- http://www.idpf.org/epub/301/spec/epub-publications.html#meta-properties-rendering
+ /**
+ * Determine the Layout properties from metadata and settings
+ * @private
+ * @param {object} metadata
+ * @return {object} properties
+ */
+ determineLayoutProperties(metadata){
+ var properties;
+ var layout = this.settings.layout || metadata.layout || "reflowable";
+ var spread = this.settings.spread || metadata.spread || "auto";
+ var orientation = this.settings.orientation || metadata.orientation || "auto";
+ var flow = this.settings.flow || metadata.flow || "auto";
+ var viewport = metadata.viewport || "";
+ var minSpreadWidth = this.settings.minSpreadWidth || metadata.minSpreadWidth || 800;
+ var direction = this.settings.direction || metadata.direction || "ltr";
+
+ if ((this.settings.width === 0 || this.settings.width > 0) &&
+ (this.settings.height === 0 || this.settings.height > 0)) {
+ // viewport = "width="+this.settings.width+", height="+this.settings.height+"";
+ }
+
+ properties = {
+ layout : layout,
+ spread : spread,
+ orientation : orientation,
+ flow : flow,
+ viewport : viewport,
+ minSpreadWidth : minSpreadWidth,
+ direction: direction
+ };
+
+ return properties;
+ }
+
+ /**
+ * Adjust the flow of the rendition to paginated or scrolled
+ * (scrolled-continuous vs scrolled-doc are handled by different view managers)
+ * @param {string} flow
+ */
+ flow(flow){
+ var _flow = flow;
+ if (flow === "scrolled" ||
+ flow === "scrolled-doc" ||
+ flow === "scrolled-continuous") {
+ _flow = "scrolled";
+ }
+
+ if (flow === "auto" || flow === "paginated") {
+ _flow = "paginated";
+ }
+
+ this.settings.flow = flow;
+
+ if (this._layout) {
+ this._layout.flow(_flow);
+ }
+
+ if (this.manager && this._layout) {
+ this.manager.applyLayout(this._layout);
+ }
+
+ if (this.manager) {
+ this.manager.updateFlow(_flow);
+ }
+
+ if (this.manager && this.manager.isRendered() && this.location) {
+ this.manager.clear();
+ this.display(this.location.start.cfi);
+ }
+ }
+
+ /**
+ * Adjust the layout of the rendition to reflowable or pre-paginated
+ * @param {object} settings
+ */
+ layout(settings){
+ if (settings) {
+ this._layout = new Layout(settings);
+ this._layout.spread(settings.spread, this.settings.minSpreadWidth);
+
+ // this.mapping = new Mapping(this._layout.props);
+
+ this._layout.on(EVENTS.LAYOUT.UPDATED, (props, changed) => {
+ this.emit(EVENTS.RENDITION.LAYOUT, props, changed);
+ })
+ }
+
+ if (this.manager && this._layout) {
+ this.manager.applyLayout(this._layout);
+ }
+
+ return this._layout;
+ }
+
+ /**
+ * Adjust if the rendition uses spreads
+ * @param {string} spread none | auto (TODO: implement landscape, portrait, both)
+ * @param {int} [min] min width to use spreads at
+ */
+ spread(spread, min){
+
+ this.settings.spread = spread;
+
+ if (min) {
+ this.settings.minSpreadWidth = min;
+ }
+
+ if (this._layout) {
+ this._layout.spread(spread, min);
+ }
+
+ if (this.manager && this.manager.isRendered()) {
+ this.manager.updateLayout();
+ }
+ }
+
+ /**
+ * Adjust the direction of the rendition
+ * @param {string} dir
+ */
+ direction(dir){
+
+ this.settings.direction = dir || "ltr";
+
+ if (this.manager) {
+ this.manager.direction(this.settings.direction);
+ }
+
+ if (this.manager && this.manager.isRendered() && this.location) {
+ this.manager.clear();
+ this.display(this.location.start.cfi);
+ }
+ }
+
+ /**
+ * Report the current location
+ * @fires relocated
+ * @fires locationChanged
+ */
+ reportLocation(){
+ return this.q.enqueue(function reportedLocation(){
+ requestAnimationFrame(function reportedLocationAfterRAF() {
+ var location = this.manager.currentLocation();
+ if (location && location.then && typeof location.then === "function") {
+ location.then(function(result) {
+ let located = this.located(result);
+
+ if (!located || !located.start || !located.end) {
+ return;
+ }
+
+ this.location = located;
+
+ this.emit(EVENTS.RENDITION.LOCATION_CHANGED, {
+ index: this.location.start.index,
+ href: this.location.start.href,
+ start: this.location.start.cfi,
+ end: this.location.end.cfi,
+ percentage: this.location.start.percentage
+ });
+
+ this.emit(EVENTS.RENDITION.RELOCATED, this.location);
+ }.bind(this));
+ } else if (location) {
+ let located = this.located(location);
+
+ if (!located || !located.start || !located.end) {
+ return;
+ }
+
+ this.location = located;
+
+ /**
+ * @event locationChanged
+ * @deprecated
+ * @type {object}
+ * @property {number} index
+ * @property {string} href
+ * @property {EpubCFI} start
+ * @property {EpubCFI} end
+ * @property {number} percentage
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.LOCATION_CHANGED, {
+ index: this.location.start.index,
+ href: this.location.start.href,
+ start: this.location.start.cfi,
+ end: this.location.end.cfi,
+ percentage: this.location.start.percentage
+ });
+
+ /**
+ * @event relocated
+ * @type {displayedLocation}
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.RELOCATED, this.location);
+ }
+ }.bind(this));
+ }.bind(this));
+ }
+
+ /**
+ * Get the Current Location object
+ * @return {displayedLocation | promise} location (may be a promise)
+ */
+ currentLocation(){
+ var location = this.manager.currentLocation();
+ if (location && location.then && typeof location.then === "function") {
+ location.then(function(result) {
+ let located = this.located(result);
+ return located;
+ }.bind(this));
+ } else if (location) {
+ let located = this.located(location);
+ return located;
+ }
+ }
+
+ /**
+ * Creates a Rendition#locationRange from location
+ * passed by the Manager
+ * @returns {displayedLocation}
+ * @private
+ */
+ located(location){
+ if (!location.length) {
+ return {};
+ }
+ let start = location[0];
+ let end = location[location.length-1];
+
+ let located = {
+ start: {
+ index: start.index,
+ href: start.href,
+ cfi: start.mapping.start,
+ displayed: {
+ page: start.pages[0] || 1,
+ total: start.totalPages
+ }
+ },
+ end: {
+ index: end.index,
+ href: end.href,
+ cfi: end.mapping.end,
+ displayed: {
+ page: end.pages[end.pages.length-1] || 1,
+ total: end.totalPages
+ }
+ }
+ };
+
+ let locationStart = this.book.locations.locationFromCfi(start.mapping.start);
+ let locationEnd = this.book.locations.locationFromCfi(end.mapping.end);
+
+ if (locationStart != null) {
+ located.start.location = locationStart;
+ located.start.percentage = this.book.locations.percentageFromLocation(locationStart);
+ }
+ if (locationEnd != null) {
+ located.end.location = locationEnd;
+ located.end.percentage = this.book.locations.percentageFromLocation(locationEnd);
+ }
+
+ let pageStart = this.book.pageList.pageFromCfi(start.mapping.start);
+ let pageEnd = this.book.pageList.pageFromCfi(end.mapping.end);
+
+ if (pageStart != -1) {
+ located.start.page = pageStart;
+ }
+ if (pageEnd != -1) {
+ located.end.page = pageEnd;
+ }
+
+ if (end.index === this.book.spine.last().index &&
+ located.end.displayed.page >= located.end.displayed.total) {
+ located.atEnd = true;
+ }
+
+ if (start.index === this.book.spine.first().index &&
+ located.start.displayed.page === 1) {
+ located.atStart = true;
+ }
+
+ return located;
+ }
+
+ /**
+ * Remove and Clean Up the Rendition
+ */
+ destroy(){
+ // Clear the queue
+ // this.q.clear();
+ // this.q = undefined;
+
+ this.manager && this.manager.destroy();
+
+ this.book = undefined;
+
+ // this.views = null;
+
+ // this.hooks.display.clear();
+ // this.hooks.serialize.clear();
+ // this.hooks.content.clear();
+ // this.hooks.layout.clear();
+ // this.hooks.render.clear();
+ // this.hooks.show.clear();
+ // this.hooks = {};
+
+ // this.themes.destroy();
+ // this.themes = undefined;
+
+ // this.epubcfi = undefined;
+
+ // this.starting = undefined;
+ // this.started = undefined;
+
+
+ }
+
+ /**
+ * Pass the events from a view's Contents
+ * @private
+ * @param {Contents} view contents
+ */
+ passEvents(contents){
+ DOM_EVENTS.forEach((e) => {
+ contents.on(e, (ev) => this.triggerViewEvent(ev, contents));
+ });
+
+ contents.on(EVENTS.CONTENTS.SELECTED, (e) => this.triggerSelectedEvent(e, contents));
+ }
+
+ /**
+ * Emit events passed by a view
+ * @private
+ * @param {event} e
+ */
+ triggerViewEvent(e, contents){
+ this.emit(e.type, e, contents);
+ }
+
+ /**
+ * Emit a selection event's CFI Range passed from a a view
+ * @private
+ * @param {string} cfirange
+ */
+ triggerSelectedEvent(cfirange, contents){
+ /**
+ * Emit that a text selection has occured
+ * @event selected
+ * @param {string} cfirange
+ * @param {Contents} contents
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.SELECTED, cfirange, contents);
+ }
+
+ /**
+ * Emit a markClicked event with the cfiRange and data from a mark
+ * @private
+ * @param {EpubCFI} cfirange
+ */
+ triggerMarkEvent(cfiRange, data, contents){
+ /**
+ * Emit that a mark was clicked
+ * @event markClicked
+ * @param {EpubCFI} cfirange
+ * @param {object} data
+ * @param {Contents} contents
+ * @memberof Rendition
+ */
+ this.emit(EVENTS.RENDITION.MARK_CLICKED, cfiRange, data, contents);
+ }
+
+ /**
+ * Get a Range from a Visible CFI
+ * @param {string} cfi EpubCfi String
+ * @param {string} ignoreClass
+ * @return {range}
+ */
+ getRange(cfi, ignoreClass){
+ var _cfi = new EpubCFI(cfi);
+ var found = this.manager.visible().filter(function (view) {
+ if(_cfi.spinePos === view.index) return true;
+ });
+
+ // Should only every return 1 item
+ if (found.length) {
+ return found[0].contents.range(_cfi, ignoreClass);
+ }
+ }
+
+ /**
+ * Hook to adjust images to fit in columns
+ * @param {Contents} contents
+ * @private
+ */
+ adjustImages(contents) {
+
+ if (this._layout.name === "pre-paginated") {
+ return new Promise(function(resolve){
+ resolve();
+ });
+ }
+
+ let computed = contents.window.getComputedStyle(contents.content, null);
+ let height = (contents.content.offsetHeight - (parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom))) * .95;
+ let horizontalPadding = parseFloat(computed.paddingLeft) + parseFloat(computed.paddingRight);
+
+ contents.addStylesheetRules({
+ "img" : {
+ "max-width": (this._layout.columnWidth ? (this._layout.columnWidth - horizontalPadding) + "px" : "100%") + "!important",
+ "max-height": height + "px" + "!important",
+ "object-fit": "contain",
+ "page-break-inside": "avoid",
+ "break-inside": "avoid",
+ "box-sizing": "border-box"
+ },
+ "svg" : {
+ "max-width": (this._layout.columnWidth ? (this._layout.columnWidth - horizontalPadding) + "px" : "100%") + "!important",
+ "max-height": height + "px" + "!important",
+ "page-break-inside": "avoid",
+ "break-inside": "avoid"
+ }
+ });
+
+ return new Promise(function(resolve, reject){
+ // Wait to apply
+ setTimeout(function() {
+ resolve();
+ }, 1);
+ });
+ }
+
+ /**
+ * Get the Contents object of each rendered view
+ * @returns {Contents[]}
+ */
+ getContents () {
+ return this.manager ? this.manager.getContents() : [];
+ }
+
+ /**
+ * Get the views member from the manager
+ * @returns {Views}
+ */
+ views () {
+ let views = this.manager ? this.manager.views : undefined;
+ return views || [];
+ }
+
+ /**
+ * Hook to handle link clicks in rendered content
+ * @param {Contents} contents
+ * @private
+ */
+ handleLinks(contents) {
+ if (contents) {
+ contents.on(EVENTS.CONTENTS.LINK_CLICKED, (href) => {
+ let relative = this.book.path.relative(href);
+ this.display(relative);
+ });
+ }
+ }
+
+ /**
+ * Hook to handle injecting stylesheet before
+ * a Section is serialized
+ * @param {document} doc
+ * @param {Section} section
+ * @private
+ */
+ injectStylesheet(doc, section) {
+ let style = doc.createElement("link");
+ style.setAttribute("type", "text/css");
+ style.setAttribute("rel", "stylesheet");
+ style.setAttribute("href", this.settings.stylesheet);
+ doc.getElementsByTagName("head")[0].appendChild(style);
+ }
+
+ /**
+ * Hook to handle injecting scripts before
+ * a Section is serialized
+ * @param {document} doc
+ * @param {Section} section
+ * @private
+ */
+ injectScript(doc, section) {
+ let script = doc.createElement("script");
+ script.setAttribute("type", "text/javascript");
+ script.setAttribute("src", this.settings.script);
+ script.textContent = " "; // Needed to prevent self closing tag
+ doc.getElementsByTagName("head")[0].appendChild(script);
+ }
+
+ /**
+ * Hook to handle the document identifier before
+ * a Section is serialized
+ * @param {document} doc
+ * @param {Section} section
+ * @private
+ */
+ injectIdentifier(doc, section) {
+ let ident = this.book.packaging.metadata.identifier;
+ let meta = doc.createElement("meta");
+ meta.setAttribute("name", "dc.relation.ispartof");
+ if (ident) {
+ meta.setAttribute("content", ident);
+ }
+ doc.getElementsByTagName("head")[0].appendChild(meta);
+ }
+
+}
+
+//-- Enable binding events to Renderer
+EventEmitter(Rendition.prototype);
+
+export default Rendition;
diff --git a/lib/epub.js/src/resources.js b/lib/epub.js/src/resources.js
new file mode 100644
index 0000000..b5d77f8
--- /dev/null
+++ b/lib/epub.js/src/resources.js
@@ -0,0 +1,320 @@
+import {substitute} from "./utils/replacements";
+import {createBase64Url, createBlobUrl, blob2base64} from "./utils/core";
+import Url from "./utils/url";
+import mime from "./utils/mime";
+import Path from "./utils/path";
+import path from "path-webpack";
+
+/**
+ * Handle Package Resources
+ * @class
+ * @param {Manifest} manifest
+ * @param {object} [options]
+ * @param {string} [options.replacements="base64"]
+ * @param {Archive} [options.archive]
+ * @param {method} [options.resolver]
+ */
+class Resources {
+ constructor(manifest, options) {
+ this.settings = {
+ replacements: (options && options.replacements) || "base64",
+ archive: (options && options.archive),
+ resolver: (options && options.resolver),
+ request: (options && options.request)
+ };
+
+ this.process(manifest);
+ }
+
+ /**
+ * Process resources
+ * @param {Manifest} manifest
+ */
+ process(manifest){
+ this.manifest = manifest;
+ this.resources = Object.keys(manifest).
+ map(function (key){
+ return manifest[key];
+ });
+
+ this.replacementUrls = [];
+
+ this.html = [];
+ this.assets = [];
+ this.css = [];
+
+ this.urls = [];
+ this.cssUrls = [];
+
+ this.split();
+ this.splitUrls();
+ }
+
+ /**
+ * Split resources by type
+ * @private
+ */
+ split(){
+
+ // HTML
+ this.html = this.resources.
+ filter(function (item){
+ if (item.type === "application/xhtml+xml" ||
+ item.type === "text/html") {
+ return true;
+ }
+ });
+
+ // Exclude HTML
+ this.assets = this.resources.
+ filter(function (item){
+ if (item.type !== "application/xhtml+xml" &&
+ item.type !== "text/html") {
+ return true;
+ }
+ });
+
+ // Only CSS
+ this.css = this.resources.
+ filter(function (item){
+ if (item.type === "text/css") {
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Convert split resources into Urls
+ * @private
+ */
+ splitUrls(){
+
+ // All Assets Urls
+ this.urls = this.assets.
+ map(function(item) {
+ return item.href;
+ }.bind(this));
+
+ // Css Urls
+ this.cssUrls = this.css.map(function(item) {
+ return item.href;
+ });
+
+ }
+
+ /**
+ * Create a url to a resource
+ * @param {string} url
+ * @return {Promise<string>} Promise resolves with url string
+ */
+ createUrl (url) {
+ var parsedUrl = new Url(url);
+ var mimeType = mime.lookup(parsedUrl.filename);
+
+ if (this.settings.archive) {
+ return this.settings.archive.createUrl(url, {"base64": (this.settings.replacements === "base64")});
+ } else {
+ if (this.settings.replacements === "base64") {
+ return this.settings.request(url, 'blob')
+ .then((blob) => {
+ return blob2base64(blob);
+ })
+ .then((blob) => {
+ return createBase64Url(blob, mimeType);
+ });
+ } else {
+ return this.settings.request(url, 'blob').then((blob) => {
+ return createBlobUrl(blob, mimeType);
+ })
+ }
+ }
+ }
+
+ /**
+ * Create blob urls for all the assets
+ * @return {Promise} returns replacement urls
+ */
+ replacements(){
+ if (this.settings.replacements === "none") {
+ return new Promise(function(resolve) {
+ resolve(this.urls);
+ }.bind(this));
+ }
+
+ var replacements = this.urls.map( (url) => {
+ var absolute = this.settings.resolver(url);
+
+ return this.createUrl(absolute).
+ catch((err) => {
+ console.error(err);
+ return null;
+ });
+ });
+
+ return Promise.all(replacements)
+ .then( (replacementUrls) => {
+ this.replacementUrls = replacementUrls.filter((url) => {
+ return (typeof(url) === "string");
+ });
+ return replacementUrls;
+ });
+ }
+
+ /**
+ * Replace URLs in CSS resources
+ * @private
+ * @param {Archive} [archive]
+ * @param {method} [resolver]
+ * @return {Promise}
+ */
+ replaceCss(archive, resolver){
+ var replaced = [];
+ archive = archive || this.settings.archive;
+ resolver = resolver || this.settings.resolver;
+ this.cssUrls.forEach(function(href) {
+ var replacement = this.createCssFile(href, archive, resolver)
+ .then(function (replacementUrl) {
+ // switch the url in the replacementUrls
+ var indexInUrls = this.urls.indexOf(href);
+ if (indexInUrls > -1) {
+ this.replacementUrls[indexInUrls] = replacementUrl;
+ }
+ }.bind(this))
+
+
+ replaced.push(replacement);
+ }.bind(this));
+ return Promise.all(replaced);
+ }
+
+ /**
+ * Create a new CSS file with the replaced URLs
+ * @private
+ * @param {string} href the original css file
+ * @return {Promise} returns a BlobUrl to the new CSS file or a data url
+ */
+ createCssFile(href){
+ var newUrl;
+
+ if (path.isAbsolute(href)) {
+ return new Promise(function(resolve){
+ resolve();
+ });
+ }
+
+ var absolute = this.settings.resolver(href);
+
+ // Get the text of the css file from the archive
+ var textResponse;
+
+ if (this.settings.archive) {
+ textResponse = this.settings.archive.getText(absolute);
+ } else {
+ textResponse = this.settings.request(absolute, "text");
+ }
+
+ // Get asset links relative to css file
+ var relUrls = this.urls.map( (assetHref) => {
+ var resolved = this.settings.resolver(assetHref);
+ var relative = new Path(absolute).relative(resolved);
+
+ return relative;
+ });
+
+ if (!textResponse) {
+ // file not found, don't replace
+ return new Promise(function(resolve){
+ resolve();
+ });
+ }
+
+ return textResponse.then( (text) => {
+ // Replacements in the css text
+ text = substitute(text, relUrls, this.replacementUrls);
+
+ // Get the new url
+ if (this.settings.replacements === "base64") {
+ newUrl = createBase64Url(text, "text/css");
+ } else {
+ newUrl = createBlobUrl(text, "text/css");
+ }
+
+ return newUrl;
+ }, (err) => {
+ // handle response errors
+ return new Promise(function(resolve){
+ resolve();
+ });
+ });
+
+ }
+
+ /**
+ * Resolve all resources URLs relative to an absolute URL
+ * @param {string} absolute to be resolved to
+ * @param {resolver} [resolver]
+ * @return {string[]} array with relative Urls
+ */
+ relativeTo(absolute, resolver){
+ resolver = resolver || this.settings.resolver;
+
+ // Get Urls relative to current sections
+ return this.urls.
+ map(function(href) {
+ var resolved = resolver(href);
+ var relative = new Path(absolute).relative(resolved);
+ return relative;
+ }.bind(this));
+ }
+
+ /**
+ * Get a URL for a resource
+ * @param {string} path
+ * @return {string} url
+ */
+ get(path) {
+ var indexInUrls = this.urls.indexOf(path);
+ if (indexInUrls === -1) {
+ return;
+ }
+ if (this.replacementUrls.length) {
+ return new Promise(function(resolve, reject) {
+ resolve(this.replacementUrls[indexInUrls]);
+ }.bind(this));
+ } else {
+ return this.createUrl(path);
+ }
+ }
+
+ /**
+ * Substitute urls in content, with replacements,
+ * relative to a url if provided
+ * @param {string} content
+ * @param {string} [url] url to resolve to
+ * @return {string} content with urls substituted
+ */
+ substitute(content, url) {
+ var relUrls;
+ if (url) {
+ relUrls = this.relativeTo(url);
+ } else {
+ relUrls = this.urls;
+ }
+ return substitute(content, relUrls, this.replacementUrls);
+ }
+
+ destroy() {
+ this.settings = undefined;
+ this.manifest = undefined;
+ this.resources = undefined;
+ this.replacementUrls = undefined;
+ this.html = undefined;
+ this.assets = undefined;
+ this.css = undefined;
+
+ this.urls = undefined;
+ this.cssUrls = undefined;
+ }
+}
+
+export default Resources;
diff --git a/lib/epub.js/src/section.js b/lib/epub.js/src/section.js
new file mode 100644
index 0000000..89912d7
--- /dev/null
+++ b/lib/epub.js/src/section.js
@@ -0,0 +1,323 @@
+import { defer } from "./utils/core";
+import EpubCFI from "./epubcfi";
+import Hook from "./utils/hook";
+import { sprint } from "./utils/core";
+import { replaceBase } from "./utils/replacements";
+import Request from "./utils/request";
+import { XMLDOMParser as XMLDOMSerializer } from "xmldom";
+
+/**
+ * Represents a Section of the Book
+ *
+ * In most books this is equivelent to a Chapter
+ * @param {object} item The spine item representing the section
+ * @param {object} hooks hooks for serialize and content
+ */
+class Section {
+ constructor(item, hooks){
+ this.idref = item.idref;
+ this.linear = item.linear === "yes";
+ this.properties = item.properties;
+ this.index = item.index;
+ this.href = item.href;
+ this.url = item.url;
+ this.canonical = item.canonical;
+ this.next = item.next;
+ this.prev = item.prev;
+
+ this.cfiBase = item.cfiBase;
+
+ if (hooks) {
+ this.hooks = hooks;
+ } else {
+ this.hooks = {};
+ this.hooks.serialize = new Hook(this);
+ this.hooks.content = new Hook(this);
+ }
+
+ this.document = undefined;
+ this.contents = undefined;
+ this.output = undefined;
+ }
+
+ /**
+ * Load the section from its url
+ * @param {method} [_request] a request method to use for loading
+ * @return {document} a promise with the xml document
+ */
+ load(_request){
+ var request = _request || this.request || Request;
+ var loading = new defer();
+ var loaded = loading.promise;
+
+ if(this.contents) {
+ loading.resolve(this.contents);
+ } else {
+ request(this.url)
+ .then(function(xml){
+ // var directory = new Url(this.url).directory;
+
+ this.document = xml;
+ this.contents = xml.documentElement;
+
+ return this.hooks.content.trigger(this.document, this);
+ }.bind(this))
+ .then(function(){
+ loading.resolve(this.contents);
+ }.bind(this))
+ .catch(function(error){
+ loading.reject(error);
+ });
+ }
+
+ return loaded;
+ }
+
+ /**
+ * Adds a base tag for resolving urls in the section
+ * @private
+ */
+ base(){
+ return replaceBase(this.document, this);
+ }
+
+ /**
+ * Render the contents of a section
+ * @param {method} [_request] a request method to use for loading
+ * @return {string} output a serialized XML Document
+ */
+ render(_request){
+ var rendering = new defer();
+ var rendered = rendering.promise;
+ this.output; // TODO: better way to return this from hooks?
+
+ this.load(_request).
+ then(function(contents){
+ var userAgent = (typeof navigator !== 'undefined' && navigator.userAgent) || '';
+ var isIE = userAgent.indexOf('Trident') >= 0;
+ var Serializer;
+ if (typeof XMLSerializer === "undefined" || isIE) {
+ Serializer = XMLDOMSerializer;
+ } else {
+ Serializer = XMLSerializer;
+ }
+ var serializer = new Serializer();
+ this.output = serializer.serializeToString(contents);
+ return this.output;
+ }.bind(this)).
+ then(function(){
+ return this.hooks.serialize.trigger(this.output, this);
+ }.bind(this)).
+ then(function(){
+ rendering.resolve(this.output);
+ }.bind(this))
+ .catch(function(error){
+ rendering.reject(error);
+ });
+
+ return rendered;
+ }
+
+ /**
+ * Find a string in a section
+ * @param {string} _query The query string to find
+ * @return {object[]} A list of matches, with form {cfi, excerpt}
+ */
+ find(_query){
+ var section = this;
+ var matches = [];
+ var query = _query.toLowerCase();
+ var find = function(node){
+ var text = node.textContent.toLowerCase();
+ var range = section.document.createRange();
+ var cfi;
+ var pos;
+ var last = -1;
+ var excerpt;
+ var limit = 150;
+
+ while (pos != -1) {
+ // Search for the query
+ pos = text.indexOf(query, last + 1);
+
+ if (pos != -1) {
+ // We found it! Generate a CFI
+ range = section.document.createRange();
+ range.setStart(node, pos);
+ range.setEnd(node, pos + query.length);
+
+ cfi = section.cfiFromRange(range);
+
+ // Generate the excerpt
+ if (node.textContent.length < limit) {
+ excerpt = node.textContent;
+ }
+ else {
+ excerpt = node.textContent.substring(pos - limit/2, pos + limit/2);
+ excerpt = "..." + excerpt + "...";
+ }
+
+ // Add the CFI to the matches list
+ matches.push({
+ cfi: cfi,
+ excerpt: excerpt
+ });
+ }
+
+ last = pos;
+ }
+ };
+
+ sprint(section.document, function(node) {
+ find(node);
+ });
+
+ return matches;
+ };
+
+
+ /**
+ * Search a string in multiple sequential Element of the section. If the document.createTreeWalker api is missed(eg: IE8), use `find` as a fallback.
+ * @param {string} _query The query string to search
+ * @param {int} maxSeqEle The maximum number of Element that are combined for search, defualt value is 5.
+ * @return {object[]} A list of matches, with form {cfi, excerpt}
+ */
+ search(_query , maxSeqEle = 5){
+ if (typeof(document.createTreeWalker) == "undefined") {
+ return this.find(_query);
+ }
+ let matches = [];
+ const excerptLimit = 150;
+ const section = this;
+ const query = _query.toLowerCase();
+ const search = function(nodeList){
+ const textWithCase = nodeList.reduce((acc ,current)=>{
+ return acc + current.textContent;
+ },"");
+ const text = textWithCase.toLowerCase();
+ const pos = text.indexOf(query);
+ if (pos != -1){
+ const startNodeIndex = 0 , endPos = pos + query.length;
+ let endNodeIndex = 0 , l = 0;
+ if (pos < nodeList[startNodeIndex].length){
+ let cfi;
+ while( endNodeIndex < nodeList.length - 1 ){
+ l += nodeList[endNodeIndex].length;
+ if ( endPos <= l){
+ break;
+ }
+ endNodeIndex += 1;
+ }
+
+ let startNode = nodeList[startNodeIndex] , endNode = nodeList[endNodeIndex];
+ let range = section.document.createRange();
+ range.setStart(startNode,pos);
+ let beforeEndLengthCount = nodeList.slice(0, endNodeIndex).reduce((acc,current)=>{return acc+current.textContent.length;},0) ;
+ range.setEnd(endNode, beforeEndLengthCount > endPos ? endPos : endPos - beforeEndLengthCount );
+ cfi = section.cfiFromRange(range);
+
+ let excerpt = nodeList.slice(0, endNodeIndex+1).reduce((acc,current)=>{return acc+current.textContent ;},"");
+ if (excerpt.length > excerptLimit){
+ excerpt = excerpt.substring(pos - excerptLimit/2, pos + excerptLimit/2);
+ excerpt = "..." + excerpt + "...";
+ }
+ matches.push({
+ cfi: cfi,
+ excerpt: excerpt
+ });
+ }
+ }
+ }
+
+ const treeWalker = document.createTreeWalker(section.document, NodeFilter.SHOW_TEXT, null, false);
+ let node , nodeList = [];
+ while (node = treeWalker.nextNode()) {
+ nodeList.push(node);
+ if (nodeList.length == maxSeqEle){
+ search(nodeList.slice(0 , maxSeqEle));
+ nodeList = nodeList.slice(1, maxSeqEle);
+ }
+ }
+ if (nodeList.length > 0){
+ search(nodeList);
+ }
+ return matches;
+ }
+
+ /**
+ * Reconciles the current chapters layout properies with
+ * the global layout properities.
+ * @param {object} globalLayout The global layout settings object, chapter properties string
+ * @return {object} layoutProperties Object with layout properties
+ */
+ reconcileLayoutSettings(globalLayout){
+ //-- Get the global defaults
+ var settings = {
+ layout : globalLayout.layout,
+ spread : globalLayout.spread,
+ orientation : globalLayout.orientation
+ };
+
+ //-- Get the chapter's display type
+ this.properties.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;
+ }
+
+ /**
+ * Get a CFI from a Range in the Section
+ * @param {range} _range
+ * @return {string} cfi an EpubCFI string
+ */
+ cfiFromRange(_range) {
+ return new EpubCFI(_range, this.cfiBase).toString();
+ }
+
+ /**
+ * Get a CFI from an Element in the Section
+ * @param {element} el
+ * @return {string} cfi an EpubCFI string
+ */
+ cfiFromElement(el) {
+ return new EpubCFI(el, this.cfiBase).toString();
+ }
+
+ /**
+ * Unload the section document
+ */
+ unload() {
+ this.document = undefined;
+ this.contents = undefined;
+ this.output = undefined;
+ }
+
+ destroy() {
+ this.unload();
+ this.hooks.serialize.clear();
+ this.hooks.content.clear();
+
+ this.hooks = undefined;
+ this.idref = undefined;
+ this.linear = undefined;
+ this.properties = undefined;
+ this.index = undefined;
+ this.href = undefined;
+ this.url = undefined;
+ this.next = undefined;
+ this.prev = undefined;
+
+ this.cfiBase = undefined;
+ }
+}
+
+export default Section;
diff --git a/lib/epub.js/src/spine.js b/lib/epub.js/src/spine.js
new file mode 100644
index 0000000..519b67c
--- /dev/null
+++ b/lib/epub.js/src/spine.js
@@ -0,0 +1,274 @@
+import EpubCFI from "./epubcfi";
+import Hook from "./utils/hook";
+import Section from "./section";
+import {replaceBase, replaceCanonical, replaceMeta} from "./utils/replacements";
+
+/**
+ * A collection of Spine Items
+ */
+class Spine {
+ constructor() {
+ this.spineItems = [];
+ this.spineByHref = {};
+ this.spineById = {};
+
+ this.hooks = {};
+ this.hooks.serialize = new Hook();
+ this.hooks.content = new Hook();
+
+ // Register replacements
+ this.hooks.content.register(replaceBase);
+ this.hooks.content.register(replaceCanonical);
+ this.hooks.content.register(replaceMeta);
+
+ this.epubcfi = new EpubCFI();
+
+ this.loaded = false;
+
+ this.items = undefined;
+ this.manifest = undefined;
+ this.spineNodeIndex = undefined;
+ this.baseUrl = undefined;
+ this.length = undefined;
+ }
+
+ /**
+ * Unpack items from a opf into spine items
+ * @param {Packaging} _package
+ * @param {method} resolver URL resolver
+ * @param {method} canonical Resolve canonical url
+ */
+ unpack(_package, resolver, canonical) {
+
+ this.items = _package.spine;
+ this.manifest = _package.manifest;
+ this.spineNodeIndex = _package.spineNodeIndex;
+ this.baseUrl = _package.baseUrl || _package.basePath || "";
+ this.length = this.items.length;
+
+ this.items.forEach( (item, index) => {
+ var manifestItem = this.manifest[item.idref];
+ var spineItem;
+
+ item.index = index;
+ item.cfiBase = this.epubcfi.generateChapterComponent(this.spineNodeIndex, item.index, item.idref);
+
+ if (item.href) {
+ item.url = resolver(item.href, true);
+ item.canonical = canonical(item.href);
+ }
+
+ if(manifestItem) {
+ item.href = manifestItem.href;
+ item.url = resolver(item.href, true);
+ item.canonical = canonical(item.href);
+
+ if(manifestItem.properties.length){
+ item.properties.push.apply(item.properties, manifestItem.properties);
+ }
+ }
+
+ if (item.linear === "yes") {
+ item.prev = function() {
+ let prevIndex = item.index;
+ while (prevIndex > 0) {
+ let prev = this.get(prevIndex-1);
+ if (prev && prev.linear) {
+ return prev;
+ }
+ prevIndex -= 1;
+ }
+ return;
+ }.bind(this);
+ item.next = function() {
+ let nextIndex = item.index;
+ while (nextIndex < this.spineItems.length-1) {
+ let next = this.get(nextIndex+1);
+ if (next && next.linear) {
+ return next;
+ }
+ nextIndex += 1;
+ }
+ return;
+ }.bind(this);
+ } else {
+ item.prev = function() {
+ return;
+ }
+ item.next = function() {
+ return;
+ }
+ }
+
+
+ spineItem = new Section(item, this.hooks);
+
+ this.append(spineItem);
+
+
+ });
+
+ this.loaded = true;
+ }
+
+ /**
+ * Get an item from the spine
+ * @param {string|number} [target]
+ * @return {Section} section
+ * @example spine.get();
+ * @example spine.get(1);
+ * @example spine.get("chap1.html");
+ * @example spine.get("#id1234");
+ */
+ get(target) {
+ var index = 0;
+
+ if (typeof target === "undefined") {
+ while (index < this.spineItems.length) {
+ let next = this.spineItems[index];
+ if (next && next.linear) {
+ break;
+ }
+ index += 1;
+ }
+ } else if(this.epubcfi.isCfiString(target)) {
+ let cfi = new EpubCFI(target);
+ index = cfi.spinePos;
+ } else if(typeof target === "number" || isNaN(target) === false){
+ index = target;
+ } else if(typeof target === "string" && target.indexOf("#") === 0) {
+ index = this.spineById[target.substring(1)];
+ } else if(typeof target === "string") {
+ // Remove fragments
+ target = target.split("#")[0];
+ index = this.spineByHref[target] || this.spineByHref[encodeURI(target)];
+ }
+
+ return this.spineItems[index] || null;
+ }
+
+ /**
+ * Append a Section to the Spine
+ * @private
+ * @param {Section} section
+ */
+ append(section) {
+ var index = this.spineItems.length;
+ section.index = index;
+
+ this.spineItems.push(section);
+
+ // Encode and Decode href lookups
+ // see pr for details: https://github.com/futurepress/epub.js/pull/358
+ this.spineByHref[decodeURI(section.href)] = index;
+ this.spineByHref[encodeURI(section.href)] = index;
+ this.spineByHref[section.href] = index;
+
+ this.spineById[section.idref] = index;
+
+ return index;
+ }
+
+ /**
+ * Prepend a Section to the Spine
+ * @private
+ * @param {Section} section
+ */
+ prepend(section) {
+ // var index = this.spineItems.unshift(section);
+ this.spineByHref[section.href] = 0;
+ this.spineById[section.idref] = 0;
+
+ // Re-index
+ this.spineItems.forEach(function(item, index){
+ item.index = index;
+ });
+
+ return 0;
+ }
+
+ // insert(section, index) {
+ //
+ // };
+
+ /**
+ * Remove a Section from the Spine
+ * @private
+ * @param {Section} section
+ */
+ remove(section) {
+ var index = this.spineItems.indexOf(section);
+
+ if(index > -1) {
+ delete this.spineByHref[section.href];
+ delete this.spineById[section.idref];
+
+ return this.spineItems.splice(index, 1);
+ }
+ }
+
+ /**
+ * Loop over the Sections in the Spine
+ * @return {method} forEach
+ */
+ each() {
+ return this.spineItems.forEach.apply(this.spineItems, arguments);
+ }
+
+ /**
+ * Find the first Section in the Spine
+ * @return {Section} first section
+ */
+ first() {
+ let index = 0;
+
+ do {
+ let next = this.get(index);
+
+ if (next && next.linear) {
+ return next;
+ }
+ index += 1;
+ } while (index < this.spineItems.length) ;
+ }
+
+ /**
+ * Find the last Section in the Spine
+ * @return {Section} last section
+ */
+ last() {
+ let index = this.spineItems.length-1;
+
+ do {
+ let prev = this.get(index);
+ if (prev && prev.linear) {
+ return prev;
+ }
+ index -= 1;
+ } while (index >= 0);
+ }
+
+ destroy() {
+ this.each((section) => section.destroy());
+
+ this.spineItems = undefined
+ this.spineByHref = undefined
+ this.spineById = undefined
+
+ this.hooks.serialize.clear();
+ this.hooks.content.clear();
+ this.hooks = undefined;
+
+ this.epubcfi = undefined;
+
+ this.loaded = false;
+
+ this.items = undefined;
+ this.manifest = undefined;
+ this.spineNodeIndex = undefined;
+ this.baseUrl = undefined;
+ this.length = undefined;
+ }
+}
+
+export default Spine;
diff --git a/lib/epub.js/src/store.js b/lib/epub.js/src/store.js
new file mode 100644
index 0000000..0d12103
--- /dev/null
+++ b/lib/epub.js/src/store.js
@@ -0,0 +1,384 @@
+import {defer, isXml, parse} from "./utils/core";
+import httpRequest from "./utils/request";
+import mime from "./utils/mime";
+import Path from "./utils/path";
+import EventEmitter from "event-emitter";
+import localforage from "localforage";
+
+/**
+ * Handles saving and requesting files from local storage
+ * @class
+ * @param {string} name This should be the name of the application for modals
+ * @param {function} [requester]
+ * @param {function} [resolver]
+ */
+class Store {
+
+ constructor(name, requester, resolver) {
+ this.urlCache = {};
+
+ this.storage = undefined;
+
+ this.name = name;
+ this.requester = requester || httpRequest;
+ this.resolver = resolver;
+
+ this.online = true;
+
+ this.checkRequirements();
+
+ this.addListeners();
+ }
+
+ /**
+ * Checks to see if localForage exists in global namspace,
+ * Requires localForage if it isn't there
+ * @private
+ */
+ checkRequirements(){
+ try {
+ let store;
+ if (typeof localforage === "undefined") {
+ store = localforage;
+ }
+ this.storage = store.createInstance({
+ name: this.name
+ });
+ } catch (e) {
+ throw new Error("localForage lib not loaded");
+ }
+ }
+
+ /**
+ * Add online and offline event listeners
+ * @private
+ */
+ addListeners() {
+ this._status = this.status.bind(this);
+ window.addEventListener('online', this._status);
+ window.addEventListener('offline', this._status);
+ }
+
+ /**
+ * Remove online and offline event listeners
+ * @private
+ */
+ removeListeners() {
+ window.removeEventListener('online', this._status);
+ window.removeEventListener('offline', this._status);
+ this._status = undefined;
+ }
+
+ /**
+ * Update the online / offline status
+ * @private
+ */
+ status(event) {
+ let online = navigator.onLine;
+ this.online = online;
+ if (online) {
+ this.emit("online", this);
+ } else {
+ this.emit("offline", this);
+ }
+ }
+
+ /**
+ * Add all of a book resources to the store
+ * @param {Resources} resources book resources
+ * @param {boolean} [force] force resaving resources
+ * @return {Promise<object>} store objects
+ */
+ add(resources, force) {
+ let mapped = resources.resources.map((item) => {
+ let { href } = item;
+ let url = this.resolver(href);
+ let encodedUrl = window.encodeURIComponent(url);
+
+ return this.storage.getItem(encodedUrl).then((item) => {
+ if (!item || force) {
+ return this.requester(url, "binary")
+ .then((data) => {
+ return this.storage.setItem(encodedUrl, data);
+ });
+ } else {
+ return item;
+ }
+ });
+
+ });
+ return Promise.all(mapped);
+ }
+
+ /**
+ * Put binary data from a url to storage
+ * @param {string} url a url to request from storage
+ * @param {boolean} [withCredentials]
+ * @param {object} [headers]
+ * @return {Promise<Blob>}
+ */
+ put(url, withCredentials, headers) {
+ let encodedUrl = window.encodeURIComponent(url);
+
+ return this.storage.getItem(encodedUrl).then((result) => {
+ if (!result) {
+ return this.requester(url, "binary", withCredentials, headers).then((data) => {
+ return this.storage.setItem(encodedUrl, data);
+ });
+ }
+ return result;
+ });
+ }
+
+ /**
+ * Request a url
+ * @param {string} url a url to request from storage
+ * @param {string} [type] specify the type of the returned result
+ * @param {boolean} [withCredentials]
+ * @param {object} [headers]
+ * @return {Promise<Blob | string | JSON | Document | XMLDocument>}
+ */
+ request(url, type, withCredentials, headers){
+ if (this.online) {
+ // From network
+ return this.requester(url, type, withCredentials, headers).then((data) => {
+ // save to store if not present
+ this.put(url);
+ return data;
+ })
+ } else {
+ // From store
+ return this.retrieve(url, type);
+ }
+
+ }
+
+ /**
+ * Request a url from storage
+ * @param {string} url a url to request from storage
+ * @param {string} [type] specify the type of the returned result
+ * @return {Promise<Blob | string | JSON | Document | XMLDocument>}
+ */
+ retrieve(url, type) {
+ var deferred = new defer();
+ var response;
+ var path = new Path(url);
+
+ // If type isn't set, determine it from the file extension
+ if(!type) {
+ type = path.extension;
+ }
+
+ if(type == "blob"){
+ response = this.getBlob(url);
+ } else {
+ response = this.getText(url);
+ }
+
+
+ return response.then((r) => {
+ var deferred = new defer();
+ var result;
+ if (r) {
+ result = this.handleResponse(r, type);
+ deferred.resolve(result);
+ } else {
+ deferred.reject({
+ message : "File not found in storage: " + url,
+ stack : new Error().stack
+ });
+ }
+ return deferred.promise;
+ });
+ }
+
+ /**
+ * Handle the response from request
+ * @private
+ * @param {any} response
+ * @param {string} [type]
+ * @return {any} the parsed result
+ */
+ handleResponse(response, type){
+ var r;
+
+ if(type == "json") {
+ r = JSON.parse(response);
+ }
+ else
+ if(isXml(type)) {
+ r = parse(response, "text/xml");
+ }
+ else
+ if(type == "xhtml") {
+ r = parse(response, "application/xhtml+xml");
+ }
+ else
+ if(type == "html" || type == "htm") {
+ r = parse(response, "text/html");
+ } else {
+ r = response;
+ }
+
+ return r;
+ }
+
+ /**
+ * Get a Blob from Storage by Url
+ * @param {string} url
+ * @param {string} [mimeType]
+ * @return {Blob}
+ */
+ getBlob(url, mimeType){
+ let encodedUrl = window.encodeURIComponent(url);
+
+ return this.storage.getItem(encodedUrl).then(function(uint8array) {
+ if(!uint8array) return;
+
+ mimeType = mimeType || mime.lookup(url);
+
+ return new Blob([uint8array], {type : mimeType});
+ });
+
+ }
+
+ /**
+ * Get Text from Storage by Url
+ * @param {string} url
+ * @param {string} [mimeType]
+ * @return {string}
+ */
+ getText(url, mimeType){
+ let encodedUrl = window.encodeURIComponent(url);
+
+ mimeType = mimeType || mime.lookup(url);
+
+ return this.storage.getItem(encodedUrl).then(function(uint8array) {
+ var deferred = new defer();
+ var reader = new FileReader();
+ var blob;
+
+ if(!uint8array) return;
+
+ blob = new Blob([uint8array], {type : mimeType});
+
+ reader.addEventListener("loadend", () => {
+ deferred.resolve(reader.result);
+ });
+
+ reader.readAsText(blob, mimeType);
+
+ return deferred.promise;
+ });
+ }
+
+ /**
+ * Get a base64 encoded result from Storage by Url
+ * @param {string} url
+ * @param {string} [mimeType]
+ * @return {string} base64 encoded
+ */
+ getBase64(url, mimeType){
+ let encodedUrl = window.encodeURIComponent(url);
+
+ mimeType = mimeType || mime.lookup(url);
+
+ return this.storage.getItem(encodedUrl).then((uint8array) => {
+ var deferred = new defer();
+ var reader = new FileReader();
+ var blob;
+
+ if(!uint8array) return;
+
+ blob = new Blob([uint8array], {type : mimeType});
+
+ reader.addEventListener("loadend", () => {
+ deferred.resolve(reader.result);
+ });
+ reader.readAsDataURL(blob, mimeType);
+
+ return deferred.promise;
+ });
+ }
+
+ /**
+ * Create a Url from a stored item
+ * @param {string} url
+ * @param {object} [options.base64] use base64 encoding or blob url
+ * @return {Promise} url promise with Url string
+ */
+ createUrl(url, options){
+ var deferred = new defer();
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ var tempUrl;
+ var response;
+ var useBase64 = options && options.base64;
+
+ if(url in this.urlCache) {
+ deferred.resolve(this.urlCache[url]);
+ return deferred.promise;
+ }
+
+ if (useBase64) {
+ response = this.getBase64(url);
+
+ if (response) {
+ response.then(function(tempUrl) {
+
+ this.urlCache[url] = tempUrl;
+ deferred.resolve(tempUrl);
+
+ }.bind(this));
+
+ }
+
+ } else {
+
+ response = this.getBlob(url);
+
+ if (response) {
+ response.then(function(blob) {
+
+ tempUrl = _URL.createObjectURL(blob);
+ this.urlCache[url] = tempUrl;
+ deferred.resolve(tempUrl);
+
+ }.bind(this));
+
+ }
+ }
+
+
+ if (!response) {
+ deferred.reject({
+ message : "File not found in storage: " + url,
+ stack : new Error().stack
+ });
+ }
+
+ return deferred.promise;
+ }
+
+ /**
+ * Revoke Temp Url for a achive item
+ * @param {string} url url of the item in the store
+ */
+ revokeUrl(url){
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ var fromCache = this.urlCache[url];
+ if(fromCache) _URL.revokeObjectURL(fromCache);
+ }
+
+ destroy() {
+ var _URL = window.URL || window.webkitURL || window.mozURL;
+ for (let fromCache in this.urlCache) {
+ _URL.revokeObjectURL(fromCache);
+ }
+ this.urlCache = {};
+ this.removeListeners();
+ }
+}
+
+EventEmitter(Store.prototype);
+
+export default Store;
diff --git a/lib/epub.js/src/themes.js b/lib/epub.js/src/themes.js
new file mode 100644
index 0000000..6e37f1d
--- /dev/null
+++ b/lib/epub.js/src/themes.js
@@ -0,0 +1,268 @@
+import Url from "./utils/url";
+
+/**
+ * Themes to apply to displayed content
+ * @class
+ * @param {Rendition} rendition
+ */
+class Themes {
+ constructor(rendition) {
+ this.rendition = rendition;
+ this._themes = {
+ "default" : {
+ "rules" : {},
+ "url" : "",
+ "serialized" : ""
+ }
+ };
+ this._overrides = {};
+ this._current = "default";
+ this._injected = [];
+ this.rendition.hooks.content.register(this.inject.bind(this));
+ this.rendition.hooks.content.register(this.overrides.bind(this));
+
+ }
+
+ /**
+ * Add themes to be used by a rendition
+ * @param {object | Array<object> | string}
+ * @example themes.register("light", "http://example.com/light.css")
+ * @example themes.register("light", { "body": { "color": "purple"}})
+ * @example themes.register({ "light" : {...}, "dark" : {...}})
+ */
+ register () {
+ if (arguments.length === 0) {
+ return;
+ }
+ if (arguments.length === 1 && typeof(arguments[0]) === "object") {
+ return this.registerThemes(arguments[0]);
+ }
+ if (arguments.length === 1 && typeof(arguments[0]) === "string") {
+ return this.default(arguments[0]);
+ }
+ if (arguments.length === 2 && typeof(arguments[1]) === "string") {
+ return this.registerUrl(arguments[0], arguments[1]);
+ }
+ if (arguments.length === 2 && typeof(arguments[1]) === "object") {
+ return this.registerRules(arguments[0], arguments[1]);
+ }
+ }
+
+ /**
+ * Add a default theme to be used by a rendition
+ * @param {object | string} theme
+ * @example themes.register("http://example.com/default.css")
+ * @example themes.register({ "body": { "color": "purple"}})
+ */
+ default (theme) {
+ if (!theme) {
+ return;
+ }
+ if (typeof(theme) === "string") {
+ return this.registerUrl("default", theme);
+ }
+ if (typeof(theme) === "object") {
+ return this.registerRules("default", theme);
+ }
+ }
+
+ /**
+ * Register themes object
+ * @param {object} themes
+ */
+ registerThemes (themes) {
+ for (var theme in themes) {
+ if (themes.hasOwnProperty(theme)) {
+ if (typeof(themes[theme]) === "string") {
+ this.registerUrl(theme, themes[theme]);
+ } else {
+ this.registerRules(theme, themes[theme]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Register a theme by passing its css as string
+ * @param {string} name
+ * @param {string} css
+ */
+ registerCss (name, css) {
+ this._themes[name] = { "serialized" : css };
+ if (this._injected[name] || name == 'default') {
+ this.update(name);
+ }
+ }
+
+ /**
+ * Register a url
+ * @param {string} name
+ * @param {string} input
+ */
+ registerUrl (name, input) {
+ var url = new Url(input);
+ this._themes[name] = { "url": url.toString() };
+ if (this._injected[name] || name == 'default') {
+ this.update(name);
+ }
+ }
+
+ /**
+ * Register rule
+ * @param {string} name
+ * @param {object} rules
+ */
+ registerRules (name, rules) {
+ this._themes[name] = { "rules": rules };
+ // TODO: serialize css rules
+ if (this._injected[name] || name == 'default') {
+ this.update(name);
+ }
+ }
+
+ /**
+ * Select a theme
+ * @param {string} name
+ */
+ select (name) {
+ var prev = this._current;
+ var contents;
+
+ this._current = name;
+ this.update(name);
+
+ contents = this.rendition.getContents();
+ contents.forEach( (content) => {
+ content.removeClass(prev);
+ content.addClass(name);
+ });
+ }
+
+ /**
+ * Update a theme
+ * @param {string} name
+ */
+ update (name) {
+ var contents = this.rendition.getContents();
+ contents.forEach( (content) => {
+ this.add(name, content);
+ });
+ }
+
+ /**
+ * Inject all themes into contents
+ * @param {Contents} contents
+ */
+ inject (contents) {
+ var links = [];
+ var themes = this._themes;
+ var theme;
+
+ for (var name in themes) {
+ if (themes.hasOwnProperty(name) && (name === this._current || name === "default")) {
+ theme = themes[name];
+ if((theme.rules && Object.keys(theme.rules).length > 0) || (theme.url && links.indexOf(theme.url) === -1)) {
+ this.add(name, contents);
+ }
+ this._injected.push(name);
+ }
+ }
+
+ if(this._current != "default") {
+ contents.addClass(this._current);
+ }
+ }
+
+ /**
+ * Add Theme to contents
+ * @param {string} name
+ * @param {Contents} contents
+ */
+ add (name, contents) {
+ var theme = this._themes[name];
+
+ if (!theme || !contents) {
+ return;
+ }
+
+ if (theme.url) {
+ contents.addStylesheet(theme.url);
+ } else if (theme.serialized) {
+ contents.addStylesheetCss(theme.serialized, name);
+ theme.injected = true;
+ } else if (theme.rules) {
+ contents.addStylesheetRules(theme.rules, name);
+ theme.injected = true;
+ }
+ }
+
+ /**
+ * Add override
+ * @param {string} name
+ * @param {string} value
+ * @param {boolean} priority
+ */
+ override (name, value, priority) {
+ var contents = this.rendition.getContents();
+
+ this._overrides[name] = {
+ value: value,
+ priority: priority === true
+ };
+
+ contents.forEach( (content) => {
+ content.css(name, this._overrides[name].value, this._overrides[name].priority);
+ });
+ }
+
+ removeOverride (name) {
+ var contents = this.rendition.getContents();
+
+ delete this._overrides[name];
+
+ contents.forEach( (content) => {
+ content.css(name);
+ });
+ }
+
+ /**
+ * Add all overrides
+ * @param {Content} content
+ */
+ overrides (contents) {
+ var overrides = this._overrides;
+
+ for (var rule in overrides) {
+ if (overrides.hasOwnProperty(rule)) {
+ contents.css(rule, overrides[rule].value, overrides[rule].priority);
+ }
+ }
+ }
+
+ /**
+ * Adjust the font size of a rendition
+ * @param {number} size
+ */
+ fontSize (size) {
+ this.override("font-size", size);
+ }
+
+ /**
+ * Adjust the font-family of a rendition
+ * @param {string} f
+ */
+ font (f) {
+ this.override("font-family", f, true);
+ }
+
+ destroy() {
+ this.rendition = undefined;
+ this._themes = undefined;
+ this._overrides = undefined;
+ this._current = undefined;
+ this._injected = undefined;
+ }
+
+}
+
+export default Themes;
diff --git a/lib/epub.js/src/utils/constants.js b/lib/epub.js/src/utils/constants.js
new file mode 100644
index 0000000..ac0a268
--- /dev/null
+++ b/lib/epub.js/src/utils/constants.js
@@ -0,0 +1,62 @@
+export const EPUBJS_VERSION = "0.3";
+
+// Dom events to listen for
+export const DOM_EVENTS = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "mousemove", "click", "touchend", "touchstart", "touchmove"];
+
+export const EVENTS = {
+ BOOK : {
+ OPEN_FAILED : "openFailed"
+ },
+ CONTENTS : {
+ EXPAND : "expand",
+ RESIZE : "resize",
+ SELECTED : "selected",
+ SELECTED_RANGE : "selectedRange",
+ LINK_CLICKED : "linkClicked"
+ },
+ LOCATIONS : {
+ CHANGED : "changed"
+ },
+ MANAGERS : {
+ RESIZE : "resize",
+ RESIZED : "resized",
+ ORIENTATION_CHANGE : "orientationchange",
+ ADDED : "added",
+ SCROLL : "scroll",
+ SCROLLED : "scrolled",
+ REMOVED : "removed",
+ },
+ VIEWS : {
+ AXIS: "axis",
+ WRITING_MODE: "writingMode",
+ LOAD_ERROR : "loaderror",
+ RENDERED : "rendered",
+ RESIZED : "resized",
+ DISPLAYED : "displayed",
+ SHOWN : "shown",
+ HIDDEN : "hidden",
+ MARK_CLICKED : "markClicked"
+ },
+ RENDITION : {
+ STARTED : "started",
+ ATTACHED : "attached",
+ DISPLAYED : "displayed",
+ DISPLAY_ERROR : "displayerror",
+ RENDERED : "rendered",
+ REMOVED : "removed",
+ RESIZED : "resized",
+ ORIENTATION_CHANGE : "orientationchange",
+ LOCATION_CHANGED : "locationChanged",
+ RELOCATED : "relocated",
+ MARK_CLICKED : "markClicked",
+ SELECTED : "selected",
+ LAYOUT: "layout"
+ },
+ LAYOUT : {
+ UPDATED : "updated"
+ },
+ ANNOTATION : {
+ ATTACH : "attach",
+ DETACH : "detach"
+ }
+}
diff --git a/lib/epub.js/src/utils/core.js b/lib/epub.js/src/utils/core.js
new file mode 100644
index 0000000..5c83944
--- /dev/null
+++ b/lib/epub.js/src/utils/core.js
@@ -0,0 +1,876 @@
+/**
+ * Core Utilities and Helpers
+ * @module Core
+*/
+import { DOMParser as XMLDOMParser } from "xmldom";
+
+/**
+ * Vendor prefixed requestAnimationFrame
+ * @returns {function} requestAnimationFrame
+ * @memberof Core
+ */
+export const requestAnimationFrame = (typeof window != "undefined") ? (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame) : false;
+const ELEMENT_NODE = 1;
+const TEXT_NODE = 3;
+const COMMENT_NODE = 8;
+const DOCUMENT_NODE = 9;
+const _URL = typeof URL != "undefined" ? URL : (typeof window != "undefined" ? (window.URL || window.webkitURL || window.mozURL) : undefined);
+
+/**
+ * Generates a UUID
+ * based on: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
+ * @returns {string} uuid
+ * @memberof Core
+ */
+export function uuid() {
+ 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;
+}
+
+/**
+ * Gets the height of a document
+ * @returns {number} height
+ * @memberof Core
+ */
+export function documentHeight() {
+ return Math.max(
+ document.documentElement.clientHeight,
+ document.body.scrollHeight,
+ document.documentElement.scrollHeight,
+ document.body.offsetHeight,
+ document.documentElement.offsetHeight
+ );
+}
+
+/**
+ * Checks if a node is an element
+ * @param {object} obj
+ * @returns {boolean}
+ * @memberof Core
+ */
+export function isElement(obj) {
+ return !!(obj && obj.nodeType == 1);
+}
+
+/**
+ * @param {any} n
+ * @returns {boolean}
+ * @memberof Core
+ */
+export function isNumber(n) {
+ return !isNaN(parseFloat(n)) && isFinite(n);
+}
+
+/**
+ * @param {any} n
+ * @returns {boolean}
+ * @memberof Core
+ */
+export function isFloat(n) {
+ let f = parseFloat(n);
+
+ if (isNumber(n) === false) {
+ return false;
+ }
+
+ if (typeof n === "string" && n.indexOf(".") > -1) {
+ return true;
+ }
+
+ return Math.floor(f) !== f;
+}
+
+/**
+ * Get a prefixed css property
+ * @param {string} unprefixed
+ * @returns {string}
+ * @memberof Core
+ */
+export function prefixed(unprefixed) {
+ var vendors = ["Webkit", "webkit", "Moz", "O", "ms" ];
+ var prefixes = ["-webkit-", "-webkit-", "-moz-", "-o-", "-ms-"];
+ var lower = unprefixed.toLowerCase();
+ var length = vendors.length;
+
+ if (typeof(document) === "undefined" || typeof(document.body.style[lower]) != "undefined") {
+ return unprefixed;
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (typeof(document.body.style[prefixes[i] + lower]) != "undefined") {
+ return prefixes[i] + lower;
+ }
+ }
+
+ return unprefixed;
+}
+
+/**
+ * Apply defaults to an object
+ * @param {object} obj
+ * @returns {object}
+ * @memberof Core
+ */
+export function defaults(obj) {
+ for (var i = 1, length = arguments.length; i < length; i++) {
+ var source = arguments[i];
+ for (var prop in source) {
+ if (obj[prop] === void 0) obj[prop] = source[prop];
+ }
+ }
+ return obj;
+}
+
+/**
+ * Extend properties of an object
+ * @param {object} target
+ * @returns {object}
+ * @memberof Core
+ */
+export function extend(target) {
+ var sources = [].slice.call(arguments, 1);
+ sources.forEach(function (source) {
+ if(!source) return;
+ Object.getOwnPropertyNames(source).forEach(function(propName) {
+ Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
+ });
+ });
+ return target;
+}
+
+/**
+ * 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
+ * @param {any} item
+ * @param {array} array
+ * @param {function} [compareFunction]
+ * @returns {number} location (in array)
+ * @memberof Core
+ */
+export function insert(item, array, compareFunction) {
+ var location = locationOf(item, array, compareFunction);
+ array.splice(location, 0, item);
+
+ return location;
+}
+
+/**
+ * Finds where something would fit into a sorted array
+ * @param {any} item
+ * @param {array} array
+ * @param {function} [compareFunction]
+ * @param {function} [_start]
+ * @param {function} [_end]
+ * @returns {number} location (in array)
+ * @memberof Core
+ */
+export function locationOf(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 locationOf(item, array, compareFunction, pivot, end);
+ } else{
+ return locationOf(item, array, compareFunction, start, pivot);
+ }
+}
+
+/**
+ * Finds index of something in a sorted array
+ * Returns -1 if not found
+ * @param {any} item
+ * @param {array} array
+ * @param {function} [compareFunction]
+ * @param {function} [_start]
+ * @param {function} [_end]
+ * @returns {number} index (in array) or -1
+ * @memberof Core
+ */
+export function indexOfSorted(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 indexOfSorted(item, array, compareFunction, pivot, end);
+ } else{
+ return indexOfSorted(item, array, compareFunction, start, pivot);
+ }
+}
+/**
+ * Find the bounds of an element
+ * taking padding and margin into account
+ * @param {element} el
+ * @returns {{ width: Number, height: Number}}
+ * @memberof Core
+ */
+export function bounds(el) {
+
+ var style = window.getComputedStyle(el);
+ var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
+ var heightProps = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
+
+ var width = 0;
+ var height = 0;
+
+ widthProps.forEach(function(prop){
+ width += parseFloat(style[prop]) || 0;
+ });
+
+ heightProps.forEach(function(prop){
+ height += parseFloat(style[prop]) || 0;
+ });
+
+ return {
+ height: height,
+ width: width
+ };
+
+}
+
+/**
+ * Find the bounds of an element
+ * taking padding, margin and borders into account
+ * @param {element} el
+ * @returns {{ width: Number, height: Number}}
+ * @memberof Core
+ */
+export function borders(el) {
+
+ var style = window.getComputedStyle(el);
+ var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
+ var heightProps = ["paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
+
+ var width = 0;
+ var height = 0;
+
+ widthProps.forEach(function(prop){
+ width += parseFloat(style[prop]) || 0;
+ });
+
+ heightProps.forEach(function(prop){
+ height += parseFloat(style[prop]) || 0;
+ });
+
+ return {
+ height: height,
+ width: width
+ };
+
+}
+
+/**
+ * Find the bounds of any node
+ * allows for getting bounds of text nodes by wrapping them in a range
+ * @param {node} node
+ * @returns {BoundingClientRect}
+ * @memberof Core
+ */
+export function nodeBounds(node) {
+ let elPos;
+ let doc = node.ownerDocument;
+ if(node.nodeType == Node.TEXT_NODE){
+ let elRange = doc.createRange();
+ elRange.selectNodeContents(node);
+ elPos = elRange.getBoundingClientRect();
+ } else {
+ elPos = node.getBoundingClientRect();
+ }
+ return elPos;
+}
+
+/**
+ * Find the equivelent of getBoundingClientRect of a browser window
+ * @returns {{ width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number }}
+ * @memberof Core
+ */
+export function windowBounds() {
+
+ var width = window.innerWidth;
+ var height = window.innerHeight;
+
+ return {
+ top: 0,
+ left: 0,
+ right: width,
+ bottom: height,
+ width: width,
+ height: height
+ };
+
+}
+
+/**
+ * Gets the index of a node in its parent
+ * @param {Node} node
+ * @param {string} typeId
+ * @return {number} index
+ * @memberof Core
+ */
+export function indexOfNode(node, typeId) {
+ var parent = node.parentNode;
+ var children = parent.childNodes;
+ var sib;
+ var index = -1;
+ for (var i = 0; i < children.length; i++) {
+ sib = children[i];
+ if (sib.nodeType === typeId) {
+ index++;
+ }
+ if (sib == node) break;
+ }
+
+ return index;
+}
+
+/**
+ * Gets the index of a text node in its parent
+ * @param {node} textNode
+ * @returns {number} index
+ * @memberof Core
+ */
+export function indexOfTextNode(textNode) {
+ return indexOfNode(textNode, TEXT_NODE);
+}
+
+/**
+ * Gets the index of an element node in its parent
+ * @param {element} elementNode
+ * @returns {number} index
+ * @memberof Core
+ */
+export function indexOfElementNode(elementNode) {
+ return indexOfNode(elementNode, ELEMENT_NODE);
+}
+
+/**
+ * Check if extension is xml
+ * @param {string} ext
+ * @returns {boolean}
+ * @memberof Core
+ */
+export function isXml(ext) {
+ return ["xml", "opf", "ncx"].indexOf(ext) > -1;
+}
+
+/**
+ * Create a new blob
+ * @param {any} content
+ * @param {string} mime
+ * @returns {Blob}
+ * @memberof Core
+ */
+export function createBlob(content, mime){
+ return new Blob([content], {type : mime });
+}
+
+/**
+ * Create a new blob url
+ * @param {any} content
+ * @param {string} mime
+ * @returns {string} url
+ * @memberof Core
+ */
+export function createBlobUrl(content, mime){
+ var tempUrl;
+ var blob = createBlob(content, mime);
+
+ tempUrl = _URL.createObjectURL(blob);
+
+ return tempUrl;
+}
+
+/**
+ * Remove a blob url
+ * @param {string} url
+ * @memberof Core
+ */
+export function revokeBlobUrl(url){
+ return _URL.revokeObjectURL(url);
+}
+
+/**
+ * Create a new base64 encoded url
+ * @param {any} content
+ * @param {string} mime
+ * @returns {string} url
+ * @memberof Core
+ */
+export function createBase64Url(content, mime){
+ var data;
+ var datauri;
+
+ if (typeof(content) !== "string") {
+ // Only handles strings
+ return;
+ }
+
+ data = btoa(encodeURIComponent(content));
+
+ datauri = "data:" + mime + ";base64," + data;
+
+ return datauri;
+}
+
+/**
+ * Get type of an object
+ * @param {object} obj
+ * @returns {string} type
+ * @memberof Core
+ */
+export function type(obj){
+ return Object.prototype.toString.call(obj).slice(8, -1);
+}
+
+/**
+ * Parse xml (or html) markup
+ * @param {string} markup
+ * @param {string} mime
+ * @param {boolean} forceXMLDom force using xmlDom to parse instead of native parser
+ * @returns {document} document
+ * @memberof Core
+ */
+export function parse(markup, mime, forceXMLDom) {
+ var doc;
+ var Parser;
+
+ if (typeof DOMParser === "undefined" || forceXMLDom) {
+ Parser = XMLDOMParser;
+ } else {
+ Parser = DOMParser;
+ }
+
+ // Remove byte order mark before parsing
+ // https://www.w3.org/International/questions/qa-byte-order-mark
+ if(markup.charCodeAt(0) === 0xFEFF) {
+ markup = markup.slice(1);
+ }
+
+ doc = new Parser().parseFromString(markup, mime);
+
+ return doc;
+}
+
+/**
+ * querySelector polyfill
+ * @param {element} el
+ * @param {string} sel selector string
+ * @returns {element} element
+ * @memberof Core
+ */
+export function qs(el, sel) {
+ var elements;
+ if (!el) {
+ throw new Error("No Element Provided");
+ }
+
+ if (typeof el.querySelector != "undefined") {
+ return el.querySelector(sel);
+ } else {
+ elements = el.getElementsByTagName(sel);
+ if (elements.length) {
+ return elements[0];
+ }
+ }
+}
+
+/**
+ * querySelectorAll polyfill
+ * @param {element} el
+ * @param {string} sel selector string
+ * @returns {element[]} elements
+ * @memberof Core
+ */
+export function qsa(el, sel) {
+
+ if (typeof el.querySelector != "undefined") {
+ return el.querySelectorAll(sel);
+ } else {
+ return el.getElementsByTagName(sel);
+ }
+}
+
+/**
+ * querySelector by property
+ * @param {element} el
+ * @param {string} sel selector string
+ * @param {object[]} props
+ * @returns {element[]} elements
+ * @memberof Core
+ */
+export function qsp(el, sel, props) {
+ var q, filtered;
+ if (typeof el.querySelector != "undefined") {
+ sel += "[";
+ for (var prop in props) {
+ sel += prop + "~='" + props[prop] + "'";
+ }
+ sel += "]";
+ return el.querySelector(sel);
+ } else {
+ q = el.getElementsByTagName(sel);
+ filtered = Array.prototype.slice.call(q, 0).filter(function(el) {
+ for (var prop in props) {
+ if(el.getAttribute(prop) === props[prop]){
+ return true;
+ }
+ }
+ return false;
+ });
+
+ if (filtered) {
+ return filtered[0];
+ }
+ }
+}
+
+/**
+ * Sprint through all text nodes in a document
+ * @memberof Core
+ * @param {element} root element to start with
+ * @param {function} func function to run on each element
+ */
+export function sprint(root, func) {
+ var doc = root.ownerDocument || root;
+ if (typeof(doc.createTreeWalker) !== "undefined") {
+ treeWalker(root, func, NodeFilter.SHOW_TEXT);
+ } else {
+ walk(root, function(node) {
+ if (node && node.nodeType === 3) { // Node.TEXT_NODE
+ func(node);
+ }
+ }, true);
+ }
+}
+
+/**
+ * Create a treeWalker
+ * @memberof Core
+ * @param {element} root element to start with
+ * @param {function} func function to run on each element
+ * @param {function | object} filter funtion or object to filter with
+ */
+export function treeWalker(root, func, filter) {
+ var treeWalker = document.createTreeWalker(root, filter, null, false);
+ let node;
+ while ((node = treeWalker.nextNode())) {
+ func(node);
+ }
+}
+
+/**
+ * @memberof Core
+ * @param {node} node
+ * @param {callback} return false for continue,true for break inside callback
+ */
+export function walk(node,callback){
+ if(callback(node)){
+ return true;
+ }
+ node = node.firstChild;
+ if(node){
+ do{
+ let walked = walk(node,callback);
+ if(walked){
+ return true;
+ }
+ node = node.nextSibling;
+ } while(node);
+ }
+}
+
+/**
+ * Convert a blob to a base64 encoded string
+ * @param {Blog} blob
+ * @returns {string}
+ * @memberof Core
+ */
+export function blob2base64(blob) {
+ return new Promise(function(resolve, reject) {
+ var reader = new FileReader();
+ reader.readAsDataURL(blob);
+ reader.onloadend = function() {
+ resolve(reader.result);
+ };
+ });
+}
+
+
+/**
+ * Creates a new pending promise and provides methods to resolve or reject it.
+ * From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
+ * @memberof Core
+ */
+export function defer() {
+ /* A method to resolve the associated Promise with the value passed.
+ * If the promise is already settled it does nothing.
+ *
+ * @param {anything} value : This value is used to resolve the promise
+ * If the value is a Promise then the associated promise assumes the state
+ * of Promise passed as value.
+ */
+ this.resolve = null;
+
+ /* A method to reject the assocaited Promise with the value passed.
+ * If the promise is already settled it does nothing.
+ *
+ * @param {anything} reason: The reason for the rejection of the Promise.
+ * Generally its an Error object. If however a Promise is passed, then the Promise
+ * itself will be the reason for rejection no matter the state of the Promise.
+ */
+ this.reject = null;
+
+ this.id = uuid();
+
+ /* A newly created Pomise object.
+ * Initially in pending state.
+ */
+ this.promise = new Promise((resolve, reject) => {
+ this.resolve = resolve;
+ this.reject = reject;
+ });
+ Object.freeze(this);
+}
+
+/**
+ * querySelector with filter by epub type
+ * @param {element} html
+ * @param {string} element element type to find
+ * @param {string} type epub type to find
+ * @returns {element[]} elements
+ * @memberof Core
+ */
+export function querySelectorByType(html, element, type){
+ var query;
+ if (typeof html.querySelector != "undefined") {
+ query = html.querySelector(`${element}[*|type="${type}"]`);
+ }
+ // Handle IE not supporting namespaced epub:type in querySelector
+ if(!query || query.length === 0) {
+ query = qsa(html, element);
+ for (var i = 0; i < query.length; i++) {
+ if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type ||
+ query[i].getAttribute("epub:type") === type) {
+ return query[i];
+ }
+ }
+ } else {
+ return query;
+ }
+}
+
+/**
+ * Find direct decendents of an element
+ * @param {element} el
+ * @returns {element[]} children
+ * @memberof Core
+ */
+export function findChildren(el) {
+ var result = [];
+ var childNodes = el.childNodes;
+ for (var i = 0; i < childNodes.length; i++) {
+ let node = childNodes[i];
+ if (node.nodeType === 1) {
+ result.push(node);
+ }
+ }
+ return result;
+}
+
+/**
+ * Find all parents (ancestors) of an element
+ * @param {element} node
+ * @returns {element[]} parents
+ * @memberof Core
+ */
+export function parents(node) {
+ var nodes = [node];
+ for (; node; node = node.parentNode) {
+ nodes.unshift(node);
+ }
+ return nodes
+}
+
+/**
+ * Find all direct decendents of a specific type
+ * @param {element} el
+ * @param {string} nodeName
+ * @param {boolean} [single]
+ * @returns {element[]} children
+ * @memberof Core
+ */
+export function filterChildren(el, nodeName, single) {
+ var result = [];
+ var childNodes = el.childNodes;
+ for (var i = 0; i < childNodes.length; i++) {
+ let node = childNodes[i];
+ if (node.nodeType === 1 && node.nodeName.toLowerCase() === nodeName) {
+ if (single) {
+ return node;
+ } else {
+ result.push(node);
+ }
+ }
+ }
+ if (!single) {
+ return result;
+ }
+}
+
+/**
+ * Filter all parents (ancestors) with tag name
+ * @param {element} node
+ * @param {string} tagname
+ * @returns {element[]} parents
+ * @memberof Core
+ */
+export function getParentByTagName(node, tagname) {
+ let parent;
+ if (node === null || tagname === '') return;
+ parent = node.parentNode;
+ while (parent.nodeType === 1) {
+ if (parent.tagName.toLowerCase() === tagname) {
+ return parent;
+ }
+ parent = parent.parentNode;
+ }
+}
+
+/**
+ * Lightweight Polyfill for DOM Range
+ * @class
+ * @memberof Core
+ */
+export class RangeObject {
+ constructor() {
+ this.collapsed = false;
+ this.commonAncestorContainer = undefined;
+ this.endContainer = undefined;
+ this.endOffset = undefined;
+ this.startContainer = undefined;
+ this.startOffset = undefined;
+ }
+
+ setStart(startNode, startOffset) {
+ this.startContainer = startNode;
+ this.startOffset = startOffset;
+
+ if (!this.endContainer) {
+ this.collapse(true);
+ } else {
+ this.commonAncestorContainer = this._commonAncestorContainer();
+ }
+
+ this._checkCollapsed();
+ }
+
+ setEnd(endNode, endOffset) {
+ this.endContainer = endNode;
+ this.endOffset = endOffset;
+
+ if (!this.startContainer) {
+ this.collapse(false);
+ } else {
+ this.collapsed = false;
+ this.commonAncestorContainer = this._commonAncestorContainer();
+ }
+
+ this._checkCollapsed();
+ }
+
+ collapse(toStart) {
+ this.collapsed = true;
+ if (toStart) {
+ this.endContainer = this.startContainer;
+ this.endOffset = this.startOffset;
+ this.commonAncestorContainer = this.startContainer.parentNode;
+ } else {
+ this.startContainer = this.endContainer;
+ this.startOffset = this.endOffset;
+ this.commonAncestorContainer = this.endOffset.parentNode;
+ }
+ }
+
+ selectNode(referenceNode) {
+ let parent = referenceNode.parentNode;
+ let index = Array.prototype.indexOf.call(parent.childNodes, referenceNode);
+ this.setStart(parent, index);
+ this.setEnd(parent, index + 1);
+ }
+
+ selectNodeContents(referenceNode) {
+ let end = referenceNode.childNodes[referenceNode.childNodes - 1];
+ let endIndex = (referenceNode.nodeType === 3) ?
+ referenceNode.textContent.length : parent.childNodes.length;
+ this.setStart(referenceNode, 0);
+ this.setEnd(referenceNode, endIndex);
+ }
+
+ _commonAncestorContainer(startContainer, endContainer) {
+ var startParents = parents(startContainer || this.startContainer);
+ var endParents = parents(endContainer || this.endContainer);
+
+ if (startParents[0] != endParents[0]) return undefined;
+
+ for (var i = 0; i < startParents.length; i++) {
+ if (startParents[i] != endParents[i]) {
+ return startParents[i - 1];
+ }
+ }
+ }
+
+ _checkCollapsed() {
+ if (this.startContainer === this.endContainer &&
+ this.startOffset === this.endOffset) {
+ this.collapsed = true;
+ } else {
+ this.collapsed = false;
+ }
+ }
+
+ toString() {
+ // TODO: implement walking between start and end to find text
+ }
+}
diff --git a/lib/epub.js/src/utils/hook.js b/lib/epub.js/src/utils/hook.js
new file mode 100644
index 0000000..ea1b901
--- /dev/null
+++ b/lib/epub.js/src/utils/hook.js
@@ -0,0 +1,82 @@
+/**
+ * Hooks allow for injecting functions that must all complete in order before finishing
+ * They will execute in parallel but all must finish before continuing
+ * Functions may return a promise if they are asycn.
+ * @param {any} context scope of this
+ * @example this.content = new EPUBJS.Hook(this);
+ */
+class Hook {
+ constructor(context){
+ this.context = context || this;
+ this.hooks = [];
+ }
+
+ /**
+ * Adds a function to be run before a hook completes
+ * @example this.content.register(function(){...});
+ */
+ register(){
+ for(var i = 0; i < arguments.length; ++i) {
+ if (typeof arguments[i] === "function") {
+ this.hooks.push(arguments[i]);
+ } else {
+ // unpack array
+ for(var j = 0; j < arguments[i].length; ++j) {
+ this.hooks.push(arguments[i][j]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes a function
+ * @example this.content.deregister(function(){...});
+ */
+ deregister(func){
+ let hook;
+ for (let i = 0; i < this.hooks.length; i++) {
+ hook = this.hooks[i];
+ if (hook === func) {
+ this.hooks.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Triggers a hook to run all functions
+ * @example this.content.trigger(args).then(function(){...});
+ */
+ trigger(){
+ var args = arguments;
+ var context = this.context;
+ var promises = [];
+
+ this.hooks.forEach(function(task) {
+ try {
+ var executing = task.apply(context, args);
+ } catch (err) {
+ console.log(err);
+ }
+
+ if(executing && typeof executing["then"] === "function") {
+ // Task is a function that returns a promise
+ promises.push(executing);
+ }
+ // Otherwise Task resolves immediately, continue
+ });
+
+
+ return Promise.all(promises);
+ }
+
+ // Adds a function to be run before a hook completes
+ list(){
+ return this.hooks;
+ }
+
+ clear(){
+ return this.hooks = [];
+ }
+}
+export default Hook;
diff --git a/lib/epub.js/src/utils/mime.js b/lib/epub.js/src/utils/mime.js
new file mode 100644
index 0000000..8f4cca3
--- /dev/null
+++ b/lib/epub.js/src/utils/mime.js
@@ -0,0 +1,169 @@
+/*
+ From Zip.js, by Gildas Lormeau
+edited down
+ */
+
+var table = {
+ "application" : {
+ "ecmascript" : [ "es", "ecma" ],
+ "javascript" : "js",
+ "ogg" : "ogx",
+ "pdf" : "pdf",
+ "postscript" : [ "ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3" ],
+ "rdf+xml" : "rdf",
+ "smil" : [ "smi", "smil" ],
+ "xhtml+xml" : [ "xhtml", "xht" ],
+ "xml" : [ "xml", "xsl", "xsd", "opf", "ncx" ],
+ "zip" : "zip",
+ "x-httpd-eruby" : "rhtml",
+ "x-latex" : "latex",
+ "x-maker" : [ "frm", "maker", "frame", "fm", "fb", "book", "fbdoc" ],
+ "x-object" : "o",
+ "x-shockwave-flash" : [ "swf", "swfl" ],
+ "x-silverlight" : "scr",
+ "epub+zip" : "epub",
+ "font-tdpfr" : "pfr",
+ "inkml+xml" : [ "ink", "inkml" ],
+ "json" : "json",
+ "jsonml+json" : "jsonml",
+ "mathml+xml" : "mathml",
+ "metalink+xml" : "metalink",
+ "mp4" : "mp4s",
+ // "oebps-package+xml" : "opf",
+ "omdoc+xml" : "omdoc",
+ "oxps" : "oxps",
+ "vnd.amazon.ebook" : "azw",
+ "widget" : "wgt",
+ // "x-dtbncx+xml" : "ncx",
+ "x-dtbook+xml" : "dtb",
+ "x-dtbresource+xml" : "res",
+ "x-font-bdf" : "bdf",
+ "x-font-ghostscript" : "gsf",
+ "x-font-linux-psf" : "psf",
+ "x-font-otf" : "otf",
+ "x-font-pcf" : "pcf",
+ "x-font-snf" : "snf",
+ "x-font-ttf" : [ "ttf", "ttc" ],
+ "x-font-type1" : [ "pfa", "pfb", "pfm", "afm" ],
+ "x-font-woff" : "woff",
+ "x-mobipocket-ebook" : [ "prc", "mobi" ],
+ "x-mspublisher" : "pub",
+ "x-nzb" : "nzb",
+ "x-tgif" : "obj",
+ "xaml+xml" : "xaml",
+ "xml-dtd" : "dtd",
+ "xproc+xml" : "xpl",
+ "xslt+xml" : "xslt",
+ "internet-property-stream" : "acx",
+ "x-compress" : "z",
+ "x-compressed" : "tgz",
+ "x-gzip" : "gz",
+ },
+ "audio" : {
+ "flac" : "flac",
+ "midi" : [ "mid", "midi", "kar", "rmi" ],
+ "mpeg" : [ "mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a" ],
+ "mpegurl" : "m3u",
+ "ogg" : [ "oga", "ogg", "spx" ],
+ "x-aiff" : [ "aif", "aiff", "aifc" ],
+ "x-ms-wma" : "wma",
+ "x-wav" : "wav",
+ "adpcm" : "adp",
+ "mp4" : "mp4a",
+ "webm" : "weba",
+ "x-aac" : "aac",
+ "x-caf" : "caf",
+ "x-matroska" : "mka",
+ "x-pn-realaudio-plugin" : "rmp",
+ "xm" : "xm",
+ "mid" : [ "mid", "rmi" ]
+ },
+ "image" : {
+ "gif" : "gif",
+ "ief" : "ief",
+ "jpeg" : [ "jpeg", "jpg", "jpe" ],
+ "pcx" : "pcx",
+ "png" : "png",
+ "svg+xml" : [ "svg", "svgz" ],
+ "tiff" : [ "tiff", "tif" ],
+ "x-icon" : "ico",
+ "bmp" : "bmp",
+ "webp" : "webp",
+ "x-pict" : [ "pic", "pct" ],
+ "x-tga" : "tga",
+ "cis-cod" : "cod"
+ },
+ "text" : {
+ "cache-manifest" : [ "manifest", "appcache" ],
+ "css" : "css",
+ "csv" : "csv",
+ "html" : [ "html", "htm", "shtml", "stm" ],
+ "mathml" : "mml",
+ "plain" : [ "txt", "text", "brf", "conf", "def", "list", "log", "in", "bas" ],
+ "richtext" : "rtx",
+ "tab-separated-values" : "tsv",
+ "x-bibtex" : "bib"
+ },
+ "video" : {
+ "mpeg" : [ "mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2" ],
+ "mp4" : [ "mp4", "mp4v", "mpg4" ],
+ "quicktime" : [ "qt", "mov" ],
+ "ogg" : "ogv",
+ "vnd.mpegurl" : [ "mxu", "m4u" ],
+ "x-flv" : "flv",
+ "x-la-asf" : [ "lsf", "lsx" ],
+ "x-mng" : "mng",
+ "x-ms-asf" : [ "asf", "asx", "asr" ],
+ "x-ms-wm" : "wm",
+ "x-ms-wmv" : "wmv",
+ "x-ms-wmx" : "wmx",
+ "x-ms-wvx" : "wvx",
+ "x-msvideo" : "avi",
+ "x-sgi-movie" : "movie",
+ "x-matroska" : [ "mpv", "mkv", "mk3d", "mks" ],
+ "3gpp2" : "3g2",
+ "h261" : "h261",
+ "h263" : "h263",
+ "h264" : "h264",
+ "jpeg" : "jpgv",
+ "jpm" : [ "jpm", "jpgm" ],
+ "mj2" : [ "mj2", "mjp2" ],
+ "vnd.ms-playready.media.pyv" : "pyv",
+ "vnd.uvvu.mp4" : [ "uvu", "uvvu" ],
+ "vnd.vivo" : "viv",
+ "webm" : "webm",
+ "x-f4v" : "f4v",
+ "x-m4v" : "m4v",
+ "x-ms-vob" : "vob",
+ "x-smv" : "smv"
+ }
+};
+
+var mimeTypes = (function() {
+ var type, subtype, val, index, mimeTypes = {};
+ for (type in table) {
+ if (table.hasOwnProperty(type)) {
+ for (subtype in table[type]) {
+ if (table[type].hasOwnProperty(subtype)) {
+ val = table[type][subtype];
+ if (typeof val == "string") {
+ mimeTypes[val] = type + "/" + subtype;
+ } else {
+ for (index = 0; index < val.length; index++) {
+ mimeTypes[val[index]] = type + "/" + subtype;
+ }
+ }
+ }
+ }
+ }
+ }
+ return mimeTypes;
+})();
+
+var defaultValue = "text/plain";//"application/octet-stream";
+
+function lookup(filename) {
+ return filename && mimeTypes[filename.split(".").pop().toLowerCase()] || defaultValue;
+};
+
+export default { lookup };
diff --git a/lib/epub.js/src/utils/path.js b/lib/epub.js/src/utils/path.js
new file mode 100644
index 0000000..6a060cb
--- /dev/null
+++ b/lib/epub.js/src/utils/path.js
@@ -0,0 +1,102 @@
+import path from "path-webpack";
+
+/**
+ * Creates a Path object for parsing and manipulation of a path strings
+ *
+ * Uses a polyfill for Nodejs path: https://nodejs.org/api/path.html
+ * @param {string} pathString a url string (relative or absolute)
+ * @class
+ */
+class Path {
+ constructor(pathString) {
+ var protocol;
+ var parsed;
+
+ protocol = pathString.indexOf("://");
+ if (protocol > -1) {
+ pathString = new URL(pathString).pathname;
+ }
+
+ parsed = this.parse(pathString);
+
+ this.path = pathString;
+
+ if (this.isDirectory(pathString)) {
+ this.directory = pathString;
+ } else {
+ this.directory = parsed.dir + "/";
+ }
+
+ this.filename = parsed.base;
+ this.extension = parsed.ext.slice(1);
+
+ }
+
+ /**
+ * Parse the path: https://nodejs.org/api/path.html#path_path_parse_path
+ * @param {string} what
+ * @returns {object}
+ */
+ parse (what) {
+ return path.parse(what);
+ }
+
+ /**
+ * @param {string} what
+ * @returns {boolean}
+ */
+ isAbsolute (what) {
+ return path.isAbsolute(what || this.path);
+ }
+
+ /**
+ * Check if path ends with a directory
+ * @param {string} what
+ * @returns {boolean}
+ */
+ isDirectory (what) {
+ return (what.charAt(what.length-1) === "/");
+ }
+
+ /**
+ * Resolve a path against the directory of the Path
+ *
+ * https://nodejs.org/api/path.html#path_path_resolve_paths
+ * @param {string} what
+ * @returns {string} resolved
+ */
+ resolve (what) {
+ return path.resolve(this.directory, what);
+ }
+
+ /**
+ * Resolve a path relative to the directory of the Path
+ *
+ * https://nodejs.org/api/path.html#path_path_relative_from_to
+ * @param {string} what
+ * @returns {string} relative
+ */
+ relative (what) {
+ var isAbsolute = what && (what.indexOf("://") > -1);
+
+ if (isAbsolute) {
+ return what;
+ }
+
+ return path.relative(this.directory, what);
+ }
+
+ splitPath(filename) {
+ return this.splitPathRe.exec(filename).slice(1);
+ }
+
+ /**
+ * Return the path string
+ * @returns {string} path
+ */
+ toString () {
+ return this.path;
+ }
+}
+
+export default Path;
diff --git a/lib/epub.js/src/utils/queue.js b/lib/epub.js/src/utils/queue.js
new file mode 100644
index 0000000..1f8a18a
--- /dev/null
+++ b/lib/epub.js/src/utils/queue.js
@@ -0,0 +1,246 @@
+import {defer, requestAnimationFrame} from "./core";
+
+/**
+ * Queue for handling tasks one at a time
+ * @class
+ * @param {scope} context what this will resolve to in the tasks
+ */
+class Queue {
+ constructor(context){
+ this._q = [];
+ this.context = context;
+ this.tick = requestAnimationFrame;
+ this.running = false;
+ this.paused = false;
+ }
+
+ /**
+ * Add an item to the queue
+ * @return {Promise}
+ */
+ enqueue() {
+ var deferred, promise;
+ var queued;
+ var task = [].shift.call(arguments);
+ var args = arguments;
+
+ // Handle single args without context
+ // if(args && !Array.isArray(args)) {
+ // args = [args];
+ // }
+ if(!task) {
+ throw new Error("No Task Provided");
+ }
+
+ if(typeof task === "function"){
+
+ deferred = new defer();
+ promise = deferred.promise;
+
+ queued = {
+ "task" : task,
+ "args" : args,
+ //"context" : context,
+ "deferred" : deferred,
+ "promise" : promise
+ };
+
+ } else {
+ // Task is a promise
+ queued = {
+ "promise" : task
+ };
+
+ }
+
+ this._q.push(queued);
+
+ // Wait to start queue flush
+ if (this.paused == false && !this.running) {
+ // setTimeout(this.flush.bind(this), 0);
+ // this.tick.call(window, this.run.bind(this));
+ this.run();
+ }
+
+ return queued.promise;
+ }
+
+ /**
+ * Run one item
+ * @return {Promise}
+ */
+ dequeue(){
+ var inwait, task, result;
+
+ if(this._q.length && !this.paused) {
+ inwait = this._q.shift();
+ task = inwait.task;
+ if(task){
+ // console.log(task)
+
+ result = task.apply(this.context, inwait.args);
+
+ if(result && typeof result["then"] === "function") {
+ // Task is a function that returns a promise
+ return result.then(function(){
+ inwait.deferred.resolve.apply(this.context, arguments);
+ }.bind(this), function() {
+ inwait.deferred.reject.apply(this.context, arguments);
+ }.bind(this));
+ } else {
+ // Task resolves immediately
+ inwait.deferred.resolve.apply(this.context, result);
+ return inwait.promise;
+ }
+
+
+
+ } else if(inwait.promise) {
+ // Task is a promise
+ return inwait.promise;
+ }
+
+ } else {
+ inwait = new defer();
+ inwait.deferred.resolve();
+ return inwait.promise;
+ }
+
+ }
+
+ // Run All Immediately
+ dump(){
+ while(this._q.length) {
+ this.dequeue();
+ }
+ }
+
+ /**
+ * Run all tasks sequentially, at convince
+ * @return {Promise}
+ */
+ run(){
+
+ if(!this.running){
+ this.running = true;
+ this.defered = new defer();
+ }
+
+ this.tick.call(window, () => {
+
+ if(this._q.length) {
+
+ this.dequeue()
+ .then(function(){
+ this.run();
+ }.bind(this));
+
+ } else {
+ this.defered.resolve();
+ this.running = undefined;
+ }
+
+ });
+
+ // Unpause
+ if(this.paused == true) {
+ this.paused = false;
+ }
+
+ return this.defered.promise;
+ }
+
+ /**
+ * Flush all, as quickly as possible
+ * @return {Promise}
+ */
+ flush(){
+
+ if(this.running){
+ return this.running;
+ }
+
+ if(this._q.length) {
+ this.running = this.dequeue()
+ .then(function(){
+ this.running = undefined;
+ return this.flush();
+ }.bind(this));
+
+ return this.running;
+ }
+
+ }
+
+ /**
+ * Clear all items in wait
+ */
+ clear(){
+ this._q = [];
+ }
+
+ /**
+ * Get the number of tasks in the queue
+ * @return {number} tasks
+ */
+ length(){
+ return this._q.length;
+ }
+
+ /**
+ * Pause a running queue
+ */
+ pause(){
+ this.paused = true;
+ }
+
+ /**
+ * End the queue
+ */
+ stop(){
+ this._q = [];
+ this.running = false;
+ this.paused = true;
+ }
+}
+
+
+/**
+ * Create a new task from a callback
+ * @class
+ * @private
+ * @param {function} task
+ * @param {array} args
+ * @param {scope} context
+ * @return {function} task
+ */
+class Task {
+ constructor(task, args, context){
+
+ return function(){
+ var toApply = arguments || [];
+
+ return new Promise( (resolve, reject) => {
+ var callback = function(value, err){
+ if (!value && err) {
+ reject(err);
+ } else {
+ resolve(value);
+ }
+ };
+ // Add the callback to the arguments list
+ toApply.push(callback);
+
+ // Apply all arguments to the functions
+ task.apply(context || this, toApply);
+
+ });
+
+ };
+
+ }
+}
+
+
+export default Queue;
+export { Task };
diff --git a/lib/epub.js/src/utils/replacements.js b/lib/epub.js/src/utils/replacements.js
new file mode 100644
index 0000000..a271088
--- /dev/null
+++ b/lib/epub.js/src/utils/replacements.js
@@ -0,0 +1,138 @@
+import { qs, qsa } from "./core";
+import Url from "./url";
+import Path from "./path";
+
+export function replaceBase(doc, section){
+ var base;
+ var head;
+ var url = section.url;
+ var absolute = (url.indexOf("://") > -1);
+
+ if(!doc){
+ return;
+ }
+
+ head = qs(doc, "head");
+ base = qs(head, "base");
+
+ if(!base) {
+ base = doc.createElement("base");
+ head.insertBefore(base, head.firstChild);
+ }
+
+ // Fix for Safari crashing if the url doesn't have an origin
+ if (!absolute && window && window.location) {
+ url = window.location.origin + url;
+ }
+
+ base.setAttribute("href", url);
+}
+
+export function replaceCanonical(doc, section){
+ var head;
+ var link;
+ var url = section.canonical;
+
+ if(!doc){
+ return;
+ }
+
+ head = qs(doc, "head");
+ link = qs(head, "link[rel='canonical']");
+
+ if (link) {
+ link.setAttribute("href", url);
+ } else {
+ link = doc.createElement("link");
+ link.setAttribute("rel", "canonical");
+ link.setAttribute("href", url);
+ head.appendChild(link);
+ }
+}
+
+export function replaceMeta(doc, section){
+ var head;
+ var meta;
+ var id = section.idref;
+ if(!doc){
+ return;
+ }
+
+ head = qs(doc, "head");
+ meta = qs(head, "link[property='dc.identifier']");
+
+ if (meta) {
+ meta.setAttribute("content", id);
+ } else {
+ meta = doc.createElement("meta");
+ meta.setAttribute("name", "dc.identifier");
+ meta.setAttribute("content", id);
+ head.appendChild(meta);
+ }
+}
+
+// TODO: move me to Contents
+export function replaceLinks(contents, fn) {
+
+ var links = contents.querySelectorAll("a[href]");
+
+ if (!links.length) {
+ return;
+ }
+
+ var base = qs(contents.ownerDocument, "base");
+ var location = base ? base.getAttribute("href") : undefined;
+ var replaceLink = function(link){
+ var href = link.getAttribute("href");
+
+ if(href.indexOf("mailto:") === 0){
+ return;
+ }
+
+ var absolute = (href.indexOf("://") > -1);
+
+ if(absolute){
+
+ link.setAttribute("target", "_blank");
+
+ }else{
+ var linkUrl;
+ try {
+ linkUrl = new Url(href, location);
+ } catch(error) {
+ // NOOP
+ }
+
+ link.onclick = function(){
+
+ if(linkUrl && linkUrl.hash) {
+ fn(linkUrl.Path.path + linkUrl.hash);
+ } else if(linkUrl){
+ fn(linkUrl.Path.path);
+ } else {
+ fn(href);
+ }
+
+ return false;
+ };
+ }
+ }.bind(this);
+
+ for (var i = 0; i < links.length; i++) {
+ replaceLink(links[i]);
+ }
+
+
+}
+
+export function substitute(content, urls, replacements) {
+ urls.forEach(function(url, i){
+ if (url && replacements[i]) {
+ // Account for special characters in the file name.
+ // See https://stackoverflow.com/a/6318729.
+ url = url.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ content = content.replace(new RegExp(url, "g"), replacements[i]);
+ }
+ });
+ return content;
+}
diff --git a/lib/epub.js/src/utils/request.js b/lib/epub.js/src/utils/request.js
new file mode 100644
index 0000000..0de3b86
--- /dev/null
+++ b/lib/epub.js/src/utils/request.js
@@ -0,0 +1,150 @@
+import {defer, isXml, parse} from "./core";
+import Path from "./path";
+
+function request(url, type, withCredentials, headers) {
+ var supportsURL = (typeof window != "undefined") ? window.URL : false; // TODO: fallback for url if window isn't defined
+ var BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer";
+
+ var deferred = new defer();
+
+ var xhr = new XMLHttpRequest();
+
+ //-- Check from PDF.js:
+ // https://github.com/mozilla/pdf.js/blob/master/web/compatibility.js
+ var xhrPrototype = XMLHttpRequest.prototype;
+
+ var header;
+
+ if (!("overrideMimeType" in xhrPrototype)) {
+ // IE10 might have response, but not overrideMimeType
+ Object.defineProperty(xhrPrototype, "overrideMimeType", {
+ value: function xmlHttpRequestOverrideMimeType() {}
+ });
+ }
+
+ if(withCredentials) {
+ xhr.withCredentials = true;
+ }
+
+ xhr.onreadystatechange = handler;
+ xhr.onerror = err;
+
+ xhr.open("GET", url, true);
+
+ for(header in headers) {
+ xhr.setRequestHeader(header, headers[header]);
+ }
+
+ if(type == "json") {
+ xhr.setRequestHeader("Accept", "application/json");
+ }
+
+ // If type isn"t set, determine it from the file extension
+ if(!type) {
+ type = new Path(url).extension;
+ }
+
+ if(type == "blob"){
+ xhr.responseType = BLOB_RESPONSE;
+ }
+
+
+ if(isXml(type)) {
+ // xhr.responseType = "document";
+ xhr.overrideMimeType("text/xml"); // for OPF parsing
+ }
+
+ if(type == "xhtml") {
+ // xhr.responseType = "document";
+ }
+
+ if(type == "html" || type == "htm") {
+ // xhr.responseType = "document";
+ }
+
+ if(type == "binary") {
+ xhr.responseType = "arraybuffer";
+ }
+
+ xhr.send();
+
+ function err(e) {
+ deferred.reject(e);
+ }
+
+ function handler() {
+ if (this.readyState === XMLHttpRequest.DONE) {
+ var responseXML = false;
+
+ if(this.responseType === "" || this.responseType === "document") {
+ responseXML = this.responseXML;
+ }
+
+ if (this.status === 200 || this.status === 0 || responseXML) { //-- Firefox is reporting 0 for blob urls
+ var r;
+
+ if (!this.response && !responseXML) {
+ deferred.reject({
+ status: this.status,
+ message : "Empty Response",
+ stack : new Error().stack
+ });
+ return deferred.promise;
+ }
+
+ if (this.status === 403) {
+ deferred.reject({
+ status: this.status,
+ response: this.response,
+ message : "Forbidden",
+ stack : new Error().stack
+ });
+ return deferred.promise;
+ }
+ if(responseXML){
+ r = this.responseXML;
+ } else
+ if(isXml(type)){
+ // xhr.overrideMimeType("text/xml"); // for OPF parsing
+ // If this.responseXML wasn't set, try to parse using a DOMParser from text
+ r = parse(this.response, "text/xml");
+ }else
+ if(type == "xhtml"){
+ r = parse(this.response, "application/xhtml+xml");
+ }else
+ if(type == "html" || type == "htm"){
+ r = parse(this.response, "text/html");
+ }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({
+ status: this.status,
+ message : this.response,
+ stack : new Error().stack
+ });
+
+ }
+ }
+ }
+
+ return deferred.promise;
+}
+
+export default request;
diff --git a/lib/epub.js/src/utils/scrolltype.js b/lib/epub.js/src/utils/scrolltype.js
new file mode 100644
index 0000000..7d2e47b
--- /dev/null
+++ b/lib/epub.js/src/utils/scrolltype.js
@@ -0,0 +1,55 @@
+// Detect RTL scroll type
+// Based on https://github.com/othree/jquery.rtl-scroll-type/blob/master/src/jquery.rtl-scroll.js
+export default function scrollType() {
+ var type = "reverse";
+ var definer = createDefiner();
+ document.body.appendChild(definer);
+
+ if (definer.scrollLeft > 0) {
+ type = "default";
+ } else {
+ if (typeof Element !== 'undefined' && Element.prototype.scrollIntoView) {
+ definer.children[0].children[1].scrollIntoView();
+ if (definer.scrollLeft < 0) {
+ type = "negative";
+ }
+ } else {
+ definer.scrollLeft = 1;
+ if (definer.scrollLeft === 0) {
+ type = "negative";
+ }
+ }
+ }
+
+ document.body.removeChild(definer);
+ return type;
+}
+
+export function createDefiner() {
+ var definer = document.createElement('div');
+ definer.dir="rtl";
+
+ definer.style.position = "fixed";
+ definer.style.width = "1px";
+ definer.style.height = "1px";
+ definer.style.top = "0px";
+ definer.style.left = "0px";
+ definer.style.overflow = "hidden";
+
+ var innerDiv = document.createElement('div');
+ innerDiv.style.width = "2px";
+
+ var spanA = document.createElement('span');
+ spanA.style.width = "1px";
+ spanA.style.display = "inline-block";
+
+ var spanB = document.createElement('span');
+ spanB.style.width = "1px";
+ spanB.style.display = "inline-block";
+
+ innerDiv.appendChild(spanA);
+ innerDiv.appendChild(spanB);
+ definer.appendChild(innerDiv);
+
+ return definer;
+}
diff --git a/lib/epub.js/src/utils/url.js b/lib/epub.js/src/utils/url.js
new file mode 100644
index 0000000..3cc8c04
--- /dev/null
+++ b/lib/epub.js/src/utils/url.js
@@ -0,0 +1,108 @@
+import Path from "./path";
+import path from "path-webpack";
+
+/**
+ * creates a Url object for parsing and manipulation of a url string
+ * @param {string} urlString a url string (relative or absolute)
+ * @param {string} [baseString] optional base for the url,
+ * default to window.location.href
+ */
+class Url {
+ constructor(urlString, baseString) {
+ var absolute = (urlString.indexOf("://") > -1);
+ var pathname = urlString;
+ var basePath;
+
+ this.Url = undefined;
+ this.href = urlString;
+ this.protocol = "";
+ this.origin = "";
+ this.hash = "";
+ this.hash = "";
+ this.search = "";
+ this.base = baseString;
+
+ if (!absolute &&
+ baseString !== false &&
+ typeof(baseString) !== "string" &&
+ window && window.location) {
+ this.base = window.location.href;
+ }
+
+ // URL Polyfill doesn't throw an error if base is empty
+ if (absolute || this.base) {
+ try {
+ if (this.base) { // Safari doesn't like an undefined base
+ this.Url = new URL(urlString, this.base);
+ } else {
+ this.Url = new URL(urlString);
+ }
+ this.href = this.Url.href;
+
+ this.protocol = this.Url.protocol;
+ this.origin = this.Url.origin;
+ this.hash = this.Url.hash;
+ this.search = this.Url.search;
+
+ pathname = this.Url.pathname + (this.Url.search ? this.Url.search : '');
+ } catch (e) {
+ // Skip URL parsing
+ this.Url = undefined;
+ // resolve the pathname from the base
+ if (this.base) {
+ basePath = new Path(this.base);
+ pathname = basePath.resolve(pathname);
+ }
+ }
+ }
+
+ this.Path = new Path(pathname);
+
+ this.directory = this.Path.directory;
+ this.filename = this.Path.filename;
+ this.extension = this.Path.extension;
+
+ }
+
+ /**
+ * @returns {Path}
+ */
+ path () {
+ return this.Path;
+ }
+
+ /**
+ * Resolves a relative path to a absolute url
+ * @param {string} what
+ * @returns {string} url
+ */
+ resolve (what) {
+ var isAbsolute = (what.indexOf("://") > -1);
+ var fullpath;
+
+ if (isAbsolute) {
+ return what;
+ }
+
+ fullpath = path.resolve(this.directory, what);
+ return this.origin + fullpath;
+ }
+
+ /**
+ * Resolve a path relative to the url
+ * @param {string} what
+ * @returns {string} path
+ */
+ relative (what) {
+ return path.relative(what, this.directory);
+ }
+
+ /**
+ * @returns {string}
+ */
+ toString () {
+ return this.href;
+ }
+}
+
+export default Url;
diff --git a/lib/epub.js/test/book.js b/lib/epub.js/test/book.js
new file mode 100644
index 0000000..4575fb2
--- /dev/null
+++ b/lib/epub.js/test/book.js
@@ -0,0 +1,66 @@
+import Book from '../src/book';
+import assert from 'assert';
+
+describe('Book', function() {
+
+ describe('Unarchived', function() {
+ var book = new Book("/fixtures/alice/OPS/package.opf");
+ it('should open a epub', async function() {
+ await book.opened
+ assert.equal(book.isOpen, true, "book is opened");
+ assert.equal( book.url.toString(), "http://localhost:9876/fixtures/alice/OPS/package.opf", "book url is passed to new Book" );
+ });
+ it('should have a local coverUrl', async function() {
+ assert.equal( await book.coverUrl(), "http://localhost:9876/fixtures/alice/OPS/images/cover_th.jpg", "cover url is available" );
+ });
+ });
+
+ describe('Archived epub', function() {
+ var book = new Book("/fixtures/alice.epub");
+
+ it('should open a archived epub', async function() {
+ await book.opened
+ assert.equal(book.isOpen, true, "book is opened");
+ assert(book.archive, "book is unarchived");
+ });
+ it('should have a blob coverUrl', async function() {
+ let coverUrl = await book.coverUrl()
+ assert( /^blob:http:\/\/localhost:9876\/[^\/]+$/.test(coverUrl), "cover url is available and a blob: url" );
+ });
+ });
+
+ describe('Archived epub in array buffer without options', function() {
+ let book;
+
+ before(async function() {
+ const response = await fetch("/fixtures/alice.epub");
+ const buffer = await response.arrayBuffer()
+ book = new Book(buffer)
+ })
+
+ it('should open a archived epub', async function() {
+ await book.opened
+ assert.equal(book.isOpen, true, "book is opened");
+ assert(book.archive, "book is unarchived");
+ });
+
+ it('should have a blob coverUrl', async function() {
+ let coverUrl = await book.coverUrl()
+ assert( /^blob:http:\/\/localhost:9876\/[^\/]+$/.test(coverUrl), "cover url is available and a blob: url" );
+ });
+ });
+
+ describe('Archived epub without cover', function() {
+ var book = new Book("/fixtures/alice_without_cover.epub");
+
+ it('should open a archived epub', async function() {
+ await book.opened
+ assert.equal(book.isOpen, true, "book is opened");
+ assert(book.archive, "book is unarchived");
+ });
+ it('should have a empty coverUrl', async function() {
+ let coverUrl = await book.coverUrl()
+ assert.equal(coverUrl, null, "cover url should be null" );
+ });
+ });
+});
diff --git a/lib/epub.js/test/core.js b/lib/epub.js/test/core.js
new file mode 100644
index 0000000..5f0839b
--- /dev/null
+++ b/lib/epub.js/test/core.js
@@ -0,0 +1,199 @@
+import assert from 'assert';
+import Url from '../src/utils/url';
+import Path from '../src/utils/path';
+
+describe('Core', function() {
+
+
+ before(function(){
+
+ });
+
+
+ describe('Url', function () {
+
+ it("Url()", function() {
+ var url = new Url("http://example.com/fred/chasen/derf.html");
+
+ assert.equal( url.href, "http://example.com/fred/chasen/derf.html" );
+ assert.equal( url.directory, "/fred/chasen/" );
+ assert.equal( url.extension, "html" );
+ assert.equal( url.filename, "derf.html" );
+ assert.equal( url.origin, "http://example.com" );
+ assert.equal( url.protocol, "http:" );
+ assert.equal( url.search, "" );
+ });
+
+ describe('#resolve()', function () {
+ it("should join subfolders", function() {
+ var a = "http://example.com/fred/chasen/";
+ var b = "ops/derf.html";
+
+ var resolved = new Url(a).resolve(b);
+ assert.equal( resolved, "http://example.com/fred/chasen/ops/derf.html" );
+ });
+
+ it("should resolve up a level", function() {
+ var a = "http://example.com/fred/chasen/index.html";
+ var b = "../derf.html";
+
+ var resolved = new Url(a).resolve(b);
+ assert.equal( resolved, "http://example.com/fred/derf.html" );
+ });
+
+ it("should resolve absolute", function() {
+ var a = "http://example.com/fred/chasen/index.html";
+ var b = "/derf.html";
+
+ var resolved = new Url(a).resolve(b);
+ assert.equal( resolved, "http://example.com/derf.html" );
+ });
+
+ it("should resolve with search strings", function() {
+ var a = "http://example.com/fred/chasen/index.html?debug=true";
+ var b = "/derf.html";
+
+ var resolved = new Url(a).resolve(b);
+ assert.equal( resolved, "http://example.com/derf.html" );
+ });
+
+ // Doesn't work with path.parse
+ xit("should handle directory with a dot", function() {
+ var a = "http://example.com/fred/chasen/index.epub/";
+
+ var url = new Url(a);
+ assert.equal( url.directory, "/fred/chasen/index.epub/" );
+ assert.equal( url.extension, "" );
+ });
+
+ it("should handle file urls", function() {
+ var url = new Url("file:///var/mobile/Containers/Data/Application/F47E4434-9B98-4654-93F1-702336B08EE6/Documents/books/moby-dick/derf.html");
+
+ assert.equal( url.href, "file:///var/mobile/Containers/Data/Application/F47E4434-9B98-4654-93F1-702336B08EE6/Documents/books/moby-dick/derf.html" );
+ assert.equal( url.directory, "/var/mobile/Containers/Data/Application/F47E4434-9B98-4654-93F1-702336B08EE6/Documents/books/moby-dick/" );
+ assert.equal( url.extension, "html" );
+ assert.equal( url.filename, "derf.html" );
+ assert.equal( url.origin, "file://" ); // origin should be blank
+ assert.equal( url.protocol, "file:" );
+ assert.equal( url.search, "" );
+ });
+
+ it("should resolve with file urls", function() {
+ var a = "file:///var/mobile/Containers/Data/Application/books/";
+ var b = "derf.html";
+
+ var resolved = new Url(a).resolve(b);
+ assert.equal( resolved, "file:///var/mobile/Containers/Data/Application/books/derf.html" );
+ });
+
+ });
+ });
+
+ describe('Path', function () {
+
+ it("Path()", function() {
+ var path = new Path("/fred/chasen/derf.html");
+
+ assert.equal( path.path, "/fred/chasen/derf.html" );
+ assert.equal( path.directory, "/fred/chasen/" );
+ assert.equal( path.extension, "html" );
+ assert.equal( path.filename, "derf.html" );
+ });
+
+ it("Strip out url", function() {
+ var path = new Path("http://example.com/fred/chasen/derf.html");
+
+ assert.equal( path.path, "/fred/chasen/derf.html" );
+ assert.equal( path.directory, "/fred/chasen/" );
+ assert.equal( path.extension, "html" );
+ assert.equal( path.filename, "derf.html" );
+ });
+
+ describe('#parse()', function () {
+ it("should parse a path", function() {
+ var path = Path.prototype.parse("/fred/chasen/derf.html");
+
+ assert.equal( path.dir, "/fred/chasen" );
+ assert.equal( path.base, "derf.html" );
+ assert.equal( path.ext, ".html" );
+ });
+
+ it("should parse a relative path", function() {
+ var path = Path.prototype.parse("fred/chasen/derf.html");
+
+ assert.equal( path.dir, "fred/chasen" );
+ assert.equal( path.base, "derf.html" );
+ assert.equal( path.ext, ".html" );
+ });
+ });
+
+ describe('#isDirectory()', function () {
+ it("should recognize a directory", function() {
+ var directory = Path.prototype.isDirectory("/fred/chasen/");
+ var notDirectory = Path.prototype.isDirectory("/fred/chasen/derf.html");
+
+ assert(directory, "/fred/chasen/ is a directory" );
+ assert(!notDirectory, "/fred/chasen/derf.html is not directory" );
+ });
+ });
+
+ describe('#resolve()', function () {
+
+ it("should resolve a path", function() {
+ var a = "/fred/chasen/index.html";
+ var b = "derf.html";
+
+ var resolved = new Path(a).resolve(b);
+ assert.equal(resolved, "/fred/chasen/derf.html" );
+ });
+
+ it("should resolve a relative path", function() {
+ var a = "fred/chasen/index.html";
+ var b = "derf.html";
+
+ var resolved = new Path(a).resolve(b);
+ assert.equal(resolved, "/fred/chasen/derf.html" );
+ });
+
+ it("should resolve a level up", function() {
+ var a = "/fred/chasen/index.html";
+ var b = "../derf.html";
+
+ var resolved = new Path(a).resolve(b);
+ assert.equal(resolved, "/fred/derf.html" );
+ });
+
+ });
+
+ describe('#relative()', function () {
+
+ it("should find a relative path at the same level", function() {
+ var a = "/fred/chasen/index.html";
+ var b = "/fred/chasen/derf.html";
+
+ var relative = new Path(a).relative(b);
+ assert.equal(relative, "derf.html" );
+ });
+
+ it("should find a relative path down a level", function() {
+ var a = "/fred/chasen/index.html";
+ var b = "/fred/chasen/ops/derf.html";
+
+ var relative = new Path(a).relative(b);
+ assert.equal(relative, "ops/derf.html" );
+ });
+
+ it("should resolve a level up", function() {
+ var a = "/fred/chasen/index.html";
+ var b = "/fred/derf.html";
+
+ var relative = new Path(a).relative(b);
+ assert.equal(relative, "../derf.html" );
+ });
+
+ });
+
+
+ });
+
+});
diff --git a/lib/epub.js/test/epub.js b/lib/epub.js/test/epub.js
new file mode 100644
index 0000000..d5d2516
--- /dev/null
+++ b/lib/epub.js/test/epub.js
@@ -0,0 +1,52 @@
+import assert from 'assert';
+import ePub from '../src/epub';
+// var sinon = require('sinon');
+
+
+describe('ePub', function() {
+ var server;
+ before(function(){
+ /*
+ // var packageContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/package.opf', 'utf8');
+ // var tocContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/toc.xhtml', 'utf8');
+ var packageContents = require('./fixtures/moby-dick/OPS/package.opf');
+ var tocContents = require('./fixtures/moby-dick/OPS/toc.xhtml');
+
+ server = sinon.fakeServer.create();
+ server.autoRespond = true;
+
+ server.respondWith("moby-dick/OPS/package.opf", [200, {
+ "Content-Type": "text/xml"
+ }, packageContents]);
+
+ server.respondWith("moby-dick/OPS/toc.xhtml", [200, {
+ "Content-Type": "application/xhtml+xml"
+ }, tocContents]);
+ */
+
+ });
+ after(function(){
+ // server.restore();
+ });
+
+ it('should open a epub', function() {
+ var book = ePub("/fixtures/alice/OPS/package.opf");
+
+ return book.opened.then(function(){
+ assert.equal( book.isOpen, true, "book is opened" );
+ assert.equal( book.url.toString(), "http://localhost:9876/fixtures/alice/OPS/package.opf", "book url is passed to new Book" );
+ });
+ });
+
+ it('should open a archived epub', function() {
+ var book = ePub("/fixtures/alice.epub");
+
+ // assert(typeof (JSZip) !== "undefined", "JSZip is present" );
+
+ return book.opened.then(function(){
+ assert.equal( book.isOpen, true, "book is opened" );
+ assert( book.archive, "book is unarchived" );
+ });
+ });
+
+});
diff --git a/lib/epub.js/test/epubcfi.js b/lib/epub.js/test/epubcfi.js
new file mode 100644
index 0000000..232f9ab
--- /dev/null
+++ b/lib/epub.js/test/epubcfi.js
@@ -0,0 +1,425 @@
+import assert from 'assert';
+import EpubCFI from '../src/epubcfi.js';
+// var fs = require('fs');
+if (typeof DOMParser === "undefined") {
+ global.DOMParser = require('xmldom').DOMParser;
+}
+
+describe('EpubCFI', function() {
+
+ it('parse a cfi on init', function() {
+ var cfi = new EpubCFI("epubcfi(/6/2[cover]!/6)");
+
+ assert.equal( cfi.spinePos, 0, "spinePos is parsed as the first item" );
+ });
+
+ it('parse a cfi and ignore the base if present', function() {
+ var cfi = new EpubCFI("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
+
+ assert.equal( cfi.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
+ });
+
+ describe('#parse()', function() {
+ var cfi = new EpubCFI();
+
+ it('parse a cfi on init', function() {
+ var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)");
+
+ assert.equal( parsed.spinePos, 0, "spinePos is parsed as the first item" );
+ });
+
+ it('parse a cfi and ignore the base if present', function() {
+ var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
+
+ assert.equal( parsed.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
+ });
+
+ it('parse a cfi with a charecter offset', function() {
+ var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
+
+ assert.equal( parsed.path.terminal.offset, 3, "Path has a terminal offset of 3" );
+ });
+
+ it('parse a cfi with a range', function() {
+ var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)");
+
+ assert.equal( parsed.range, true, "Range is true" );
+ assert.equal( parsed.start.steps.length, 2, "Start steps are present" );
+ assert.equal( parsed.end.steps.length, 1, "End steps are present" );
+ assert.equal( parsed.start.terminal.offset, 1, "Start has a terminal offset of 1" );
+ assert.equal( parsed.end.terminal.offset, 4, "End has a terminal offset of 4" );
+
+ });
+
+ });
+
+ describe('#toString()', function() {
+ it('parse a cfi and write it back', function() {
+
+ assert.equal(new EpubCFI("epubcfi(/6/2[cover]!/6)").toString(), "epubcfi(/6/2[cover]!/6)", "output cfi string is same as input" );
+ assert.equal(new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)", "output cfi string is same as input" );
+ assert.equal(new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)", "output cfi string is same as input" );
+
+ });
+ });
+
+ describe('#checkType()', function() {
+ it('determine the type of a cfi string', function() {
+ var cfi = new EpubCFI();
+
+ assert.equal( cfi.checkType('epubcfi(/6/2[cover]!/6)'), 'string' );
+ assert.equal( cfi.checkType('/6/2[cover]!/6'), false );
+
+ });
+
+ it('determine the type of a cfi', function() {
+ var ogcfi = new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
+ var cfi = new EpubCFI();
+
+ assert.equal( cfi.checkType(ogcfi), 'EpubCFI' );
+
+ });
+
+ it('determine the type of a node', function() {
+ var cfi = new EpubCFI();
+ var el = document.createElement('div');
+
+ assert.equal( cfi.checkType(el), 'node' );
+
+ });
+
+ it('determine the type of a range', function() {
+ var cfi = new EpubCFI();
+ var range = document.createRange();
+
+ assert.equal( cfi.checkType(range), 'range' );
+
+ });
+
+ });
+
+ describe('#compare()', function() {
+ it('compare CFIs', function() {
+ var epubcfi = new EpubCFI();
+
+ // Spines
+ assert.equal(epubcfi.compare("epubcfi(/6/4[cover]!/4)", "epubcfi(/6/2[cover]!/4)"), 1, "First spine is greater");
+ assert.equal(epubcfi.compare("epubcfi(/6/4[cover]!/4)", "epubcfi(/6/6[cover]!/4)"), -1, "Second spine is greater");
+
+ // First is deeper
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/8/2)", "epubcfi(/6/2[cover]!/6)"), 1, "First Element is after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/2)", "epubcfi(/6/2[cover]!/6)"), -1, "First Element is before Second");
+
+ // Second is deeper
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/8/2)", "epubcfi(/6/2[cover]!/6/4/2/2)"), 1, "First Element is after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/4)", "epubcfi(/6/2[cover]!/6/4/2/2)"), -1, "First Element is before Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/6)", "epubcfi(/6/2[cover]!/4/6/8/1:0)"), -1, "First is less specific, so is before Second");
+
+ // Same Depth
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/6/8)", "epubcfi(/6/2[cover]!/6/2)"), 1, "First Element is after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/20)", "epubcfi(/6/2[cover]!/6/10)"), -1, "First Element is before Second");
+
+ // Text nodes
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5)", "epubcfi(/6/2[cover]!/4/3)"), 1, "First TextNode is after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/7)", "epubcfi(/6/2[cover]!/4/13)"), -1, "First TextNode is before Second");
+
+ // Char offset
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5:1)", "epubcfi(/6/2[cover]!/4/5:0)"), 1, "First Char Offset after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5:2)", "epubcfi(/6/2[cover]!/4/5:30)"), -1, "Second Char Offset before Second");
+
+ // Normal example
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/5:1)", "epubcfi(/6/2[cover]!/4/6/15:2)"), 1, "First Element after Second");
+ assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/1:0)", "epubcfi(/6/2[cover]!/4/8/1:0)"), 0, "All Equal");
+
+ // Different Lengths
+ assert.equal(epubcfi.compare(
+ 'epubcfi(/6/16[id42]!/4[5N3C0-8c483216e03a4ff49927fc1a97dc7b2c]/10/1:317)',
+ 'epubcfi(/6/16[id42]!/4[5N3C0-8c483216e03a4ff49927fc1a97dc7b2c]/10/2[page18]/1:0)'
+ ), -1, "First CFI is before Second");
+ assert.equal(epubcfi.compare(
+ 'epubcfi(/6/16[id42]!/4[5N3C0-8c483216e03a4ff49927fc1a97dc7b2c]/12/1:0)',
+ 'epubcfi(/6/16[id42]!/4[5N3C0-8c483216e03a4ff49927fc1a97dc7b2c]/12/2/1:9)'
+ ), -1, "First CFI is before Second");
+ assert.equal(epubcfi.compare(
+ 'epubcfi(/6/16!/4/12/1:0)',
+ 'epubcfi(/6/16!/4/12/2/1:9)'
+ ), -1, "First CFI is before Second");
+
+
+ });
+ });
+
+ describe('#fromNode()', function() {
+ var base = "/6/4[chap01ref]";
+ // var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
+ var contents = require('./fixtures/chapter1-highlights.xhtml').default;
+
+ // var serializer = new XMLSerializer();
+ // var doc = serializer.serializeToString(contents);
+ var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
+
+ it('get a cfi from a p node', function() {
+ var span = doc.getElementById('c001p0004');
+ var cfi = new EpubCFI(span, base);
+
+ assert.equal(span.nodeType, Node.ELEMENT_NODE, "provided a element node");
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004])" );
+
+ });
+
+ it('get a cfi from a text node', function() {
+ var t = doc.getElementById('c001p0004').childNodes[0];
+ var cfi = new EpubCFI(t, base);
+
+ assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1)" );
+
+
+ });
+
+ it('get a cfi from a text node inside a highlight', function() {
+ var t = doc.getElementById('highlight-1').childNodes[0];
+ var cfi = new EpubCFI(t, base, 'annotator-hl');
+
+ assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1)" );
+
+ });
+
+ it('get a cfi from a highlight node', function() {
+ var t = doc.getElementById('highlight-1');
+ var cfi = new EpubCFI(t, base, 'annotator-hl');
+
+ assert.equal(t.nodeType, Node.ELEMENT_NODE, "provided a highlight node");
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017])" );
+
+ });
+
+ });
+
+ describe('#fromRange()', function() {
+ var base = "/6/4[chap01ref]";
+
+ // var contentsClean = fs.readFileSync(__dirname + '/fixtures/chapter1.xhtml', 'utf8');
+ var contentsClean = require('./fixtures/chapter1.xhtml').default;
+
+ var doc = new DOMParser().parseFromString(contentsClean, "application/xhtml+xml");
+
+ // var contentsHighlights = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
+ var contentsHighlights = require('./fixtures/chapter1-highlights.xhtml').default;
+ var docHighlights = new DOMParser().parseFromString(contentsHighlights, "application/xhtml+xml");
+
+ // var highlightContents = fs.readFileSync(__dirname + '/fixtures/highlight.xhtml', 'utf8');
+ var highlightContents = require('./fixtures/highlight.xhtml').default;
+ var docHighlightsAlice = new DOMParser().parseFromString(highlightContents, "application/xhtml+xml");
+
+ it('get a cfi from a collapsed range', function() {
+ var t1 = doc.getElementById('c001p0004').childNodes[0];
+ var t2 = doc.getElementById('c001p0007').childNodes[0];
+ var range = doc.createRange();
+ var cfi;
+
+ range.setStart(t1, 6);
+
+ cfi = new EpubCFI(range, base);
+
+ assert.equal( cfi.range, false);
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
+
+ });
+
+ it('get a cfi from a range', function() {
+ var t1 = doc.getElementById('c001p0004').childNodes[0];
+ var t2 = doc.getElementById('c001p0007').childNodes[0];
+ var range = doc.createRange();
+ var cfi;
+
+ range.setStart(t1, 6);
+ range.setEnd(t2, 27);
+
+ cfi = new EpubCFI(range, base);
+
+ assert.equal( cfi.range, true);
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
+
+ });
+
+ it('get a cfi from a range with offset 0', function() {
+ var t1 = doc.getElementById('c001p0004').childNodes[0];
+ var range = doc.createRange();
+ var cfi;
+
+ range.setStart(t1, 0);
+ range.setEnd(t1, 1);
+
+ cfi = new EpubCFI(range, base);
+
+ assert.equal( cfi.range, true);
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004],/1:0,/1:1)" );
+
+ });
+
+ it('get a cfi from a range inside a highlight', function() {
+ var t1 = docHighlights.getElementById('highlight-1').childNodes[0];
+ var range = docHighlights.createRange();
+ var cfi;
+
+ range.setStart(t1, 6);
+
+ cfi = new EpubCFI(range, base, 'annotator-hl');
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
+
+ });
+ // TODO: might need to have double ranges in front
+ it('get a cfi from a range past a highlight', function() {
+ var t1 = docHighlights.getElementById('c001s0001').childNodes[1];
+ var range = docHighlights.createRange();
+ var cfi;
+
+ range.setStart(t1, 25);
+
+ cfi = new EpubCFI(range, base, 'annotator-hl');
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001]/1:41)" );
+
+ });
+
+ it('get a cfi from a range inbetween two highlights', function() {
+ var t1 = docHighlightsAlice.getElementById('p2').childNodes[1];
+ var range = docHighlightsAlice.createRange();
+ var cfi;
+
+ range.setStart(t1, 4);
+
+ cfi = new EpubCFI(range, base, 'annotator-hl');
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/4[p2]/1:123)" );
+
+ });
+
+ it('correctly count text nodes, independent of any elements present inbetween', function() {
+ var t1 = docHighlightsAlice.getElementById('p3').childNodes[2];
+ var range = docHighlightsAlice.createRange();
+ var cfi;
+
+ range.setStart(t1, 4);
+
+ cfi = new EpubCFI(range, base);
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/6[p3]/3:4)" );
+
+ });
+
+ });
+
+
+ describe('#toRange()', function() {
+ var base = "/6/4[chap01ref]";
+ // var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
+ var contents = require('./fixtures/chapter1-highlights.xhtml').default;
+
+ var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
+
+ // var serializer = new XMLSerializer();
+ // console.log(serializer.serializeToString(doc));
+
+ it('get a range from a cfi', function() {
+ var t1 = doc.getElementById('c001p0004').childNodes[0];
+ var t2 = doc.getElementById('c001p0007').childNodes[0];
+ var ogRange = doc.createRange();
+ var cfi;
+ var newRange;
+
+ ogRange.setStart(t1, 6);
+
+ cfi = new EpubCFI(ogRange, base);
+
+ // Check it was parse correctly
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
+
+ // Check the range
+ newRange = cfi.toRange(doc);
+
+ assert.equal( newRange.startContainer, t1);
+ assert.equal( newRange.startOffset, 6);
+ assert.equal( newRange.collapsed, true);
+
+ });
+
+ it('get a range from a cfi with a range', function() {
+ var t1 = doc.getElementById('c001p0004').childNodes[0];
+ var t2 = doc.getElementById('c001p0007').childNodes[0];
+ var ogRange = doc.createRange();
+ var cfi;
+ var newRange;
+
+ ogRange.setStart(t1, 6);
+ ogRange.setEnd(t2, 27);
+
+ cfi = new EpubCFI(ogRange, base);
+
+ // Check it was parse correctly
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
+
+ // Check the range
+ newRange = cfi.toRange(doc);
+
+ assert.equal( newRange.startContainer, t1);
+ assert.equal( newRange.startOffset, 6);
+
+ assert.equal( newRange.endContainer, t2);
+ assert.equal( newRange.endOffset, 27);
+
+ assert.equal( newRange.collapsed, false);
+
+ });
+
+ it('get a cfi from a range inside a highlight', function() {
+ var t1 = doc.getElementById('highlight-1').childNodes[0];
+ var ogRange = doc.createRange();
+ var cfi;
+ var newRange;
+
+ ogRange.setStart(t1, 6);
+
+ cfi = new EpubCFI(ogRange, base, 'annotator-hl');
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
+
+ // Check the range
+ newRange = cfi.toRange(doc, 'annotator-hl');
+
+ assert.ok(newRange.startContainer);
+
+ assert.equal( newRange.startContainer, t1);
+ assert.equal( newRange.startOffset, 6);
+
+ });
+
+ it('get a cfi from a range inside a highlight range', function() {
+ var t1 = doc.getElementById('highlight-2').childNodes[0];
+ var t2 = doc.getElementById('c001s0001').childNodes[1];
+ var ogRange = doc.createRange();
+ var cfi;
+ var newRange;
+
+ ogRange.setStart(t1, 5);
+ ogRange.setEnd(t2, 25);
+
+ cfi = new EpubCFI(ogRange, base, 'annotator-hl');
+
+ assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001],/1:5,/1:41)" );
+
+ // Check the range
+ newRange = cfi.toRange(doc, 'annotator-hl');
+
+ assert.strictEqual( newRange.startContainer.textContent, t1.textContent);
+ // assert.strictEqual( newRange.startContainer, t1);
+ // assert.equal( newRange.startOffset, 5);
+
+ });
+
+ });
+
+});
diff --git a/lib/epub.js/test/fixtures/alice.epub b/lib/epub.js/test/fixtures/alice.epub
new file mode 100644
index 0000000..9ac6ba3
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice.epub
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/META-INF/container.xml b/lib/epub.js/test/fixtures/alice/META-INF/container.xml
new file mode 100644
index 0000000..f9a37a7
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/META-INF/container.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
+<rootfiles>
+<rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
+</rootfiles>
+</container> \ No newline at end of file
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_001.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_001.xhtml
new file mode 100644
index 0000000..26ac098
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_001.xhtml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00004"><a id="I_DOWN_THE_RABBIT-HOLE"></a>Down The Rabbit-Hole</h2>
+
+ <figure class="small">
+ <img src= "images/i001_th.jpg" alt="Illo1" />
+ </figure>
+
+ <p>Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do. Once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?"</p>
+
+ <p>So she was considering in her own mind (as well as she could, for the day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.</p>
+
+ <figure class="small">
+ <img src="images/i002_th.jpg" alt="Illo2" />
+ </figure>
+
+ <p>There was nothing so very remarkable in that, nor did Alice think it so
+ <a id="Page_4" class="pageno" title="[Pg 4]"></a>very much out of the way to hear the Rabbit
+ say to itself, "Oh dear! Oh dear! I shall be too late!" But when the Rabbit actually
+ took a watch out of its waistcoat-pocket and looked at it and then hurried on, Alice
+ started to her feet, for it flashed across her mind that she had never before seen a
+ rabbit with either a waistcoat-pocket, or a watch to take out of it, and, burning with
+ curiosity, she ran across the field after it and was just in time to see it pop down a
+ large rabbit-hole, under the hedge. In another moment, down went Alice after it!</p>
+
+ <p>The rabbit-hole went straight on like a tunnel for some way and then dipped suddenly
+ down, so suddenly that Alice had not a moment to think about stopping herself before
+ she found herself falling down what seemed to be a very deep well.</p>
+
+ <p>Either the well was very deep, or she fell very slowly, for she had plenty of time,
+ as she went down, to look about her. First, she tried to make out what she was coming
+ to, but it was too dark to see anything; then she looked at the sides of the well and
+ noticed that they were filled with cupboards and book-shelves; here and there she saw
+ maps and <a id="Page_5" class="pageno" title="[Pg 5]"></a>pictures hung upon pegs. She
+ took down a jar from one of the shelves as she passed. It was labeled "ORANGE
+ MARMALADE," but, to her great disappointment, it was empty; she did not like to drop
+ the jar, so managed to put it into one of the cupboards as she fell past it.</p>
+
+ <p>Down, down, down! Would the fall never come to an end? There was nothing else to do,
+ so Alice soon began talking to herself. "Dinah'll miss me very much to-night, I should
+ think!" (Dinah was the cat.) "I hope they'll remember her saucer of milk at tea-time.
+ Dinah, my dear, I wish you were down here with me!" Alice felt that she was dozing off,
+ when suddenly, thump! thump! down she came upon a heap of sticks and dry leaves, and
+ the fall was over.</p>
+
+ <p>Alice was not a bit hurt, and she jumped up in a moment. She looked up, but it was
+ all dark overhead; before her was another long passage and the White Rabbit was still
+ in sight, hurrying down it. There was not a moment to be lost. Away went Alice like the
+ wind and was just in time to hear it say, as it turned a corner, "Oh, my ears and
+ whiskers, how late it's getting!" She was close behind it when she turned the corner,
+ but the Rabbit was no longer to be seen.</p>
+
+ <p>She found herself in a long, low hall, which was lit up by a row of lamps hanging
+ from the roof. There were doors all 'round the hall, but they were all locked; and when
+ Alice had been all the way down one side and up the other, trying every door, she
+ walked sadly down the middle, <a id="Page_6" class="pageno" title=
+ "[Pg 6]"></a>wondering how she was ever to get out again.</p>
+
+ <figure class="small">
+ <img src="images/i003_th.jpg" alt="Illo3" />
+ </figure>
+
+ <p>Suddenly she came upon a little table, all made of solid glass. There was nothing on
+ it but a tiny golden key, and Alice's first idea was that this might belong to one of
+ the doors of the hall; but, alas! either the locks were too large, or the key was too
+ small, but, at any rate, it would not open any of them. However, on the second time
+ 'round, she came upon a low curtain she had not noticed before, and behind it was a
+ little door about fifteen inches high. She tried the little golden key in the lock, and
+ to her great delight, it fitted!</p>
+
+ <p>Alice opened the door and found that it led into a small passage, not much larger
+ than a rat-hole; she knelt down and looked along the passage into the loveliest garden
+ you ever saw. How she longed to get out of that dark hall and wander about among those
+ beds of bright flowers and those cool fountains, but she could not even get her head
+ through the doorway. "Oh," said Alice, "how I wish I could shut up like a telescope! I
+ think I could, if I only knew how to begin."</p>
+
+ <p>Alice went back to the table, half hoping she might find another key on it, or at
+ any rate, a book of rules for shutting people up like telescopes. This time she<a id=
+ "Page_7" class="pageno" title="[Pg 7]"></a> found a little bottle on it ("which
+ certainly was not here before," said Alice), and tied 'round the neck of the bottle was
+ a paper label, with the words "DRINK ME" beautifully printed on it in large
+ letters.</p>
+
+ <p>"No, I'll look first," she said, "and see whether it's marked '<i>poison</i>' or
+ not," for she had never forgotten that, if you drink from a bottle marked "poison," it
+ is almost certain to disagree with you, sooner or later. However, this bottle was
+ <i>not</i> marked "poison," so Alice ventured to taste it, and, finding it very nice
+ (it had a sort of mixed flavor of cherry-tart, custard, pineapple, roast turkey, toffy
+ and hot buttered toast), she very soon finished it off.</p>
+
+ <p>"What a curious feeling!" said Alice. "I must be shutting up like a telescope!"</p>
+
+ <p>And so it was indeed! She was now only ten inches high, and her face brightened up
+ at the thought that she was now the right size for going through the little door into
+ that lovely garden.</p>
+
+ <p>After awhile, finding that nothing more happened, she decided on going into the
+ garden at once; but, alas for poor Alice! When she got to the door, she found she had
+ forgotten the little golden key, and when she went back to the table for it, she found
+ she could not possibly reach it: she could see it quite plainly through the glass and
+ she tried her best to climb up one of the legs of the table, but it was too slippery,
+ and when she had tired herself out with trying, the poor little thing sat down and
+ cried.</p>
+
+ <p>"Come, there's no use in crying like that!" said Alice to herself rather sharply. "I
+ advise you to<a id="Page_8" class="pageno" title="[Pg 8]"></a> leave off this minute!"
+ She generally gave herself very good advice (though she very seldom followed it), and
+ sometimes she scolded herself so severely as to bring tears into her eyes.</p>
+
+ <p>Soon her eye fell on a little glass box that was lying under the table: she opened
+ it and found in it a very small cake, on which the words "EAT ME" were beautifully
+ marked in currants. "Well, I'll eat it," said Alice, "and if it makes me grow larger, I
+ can reach the key; and if it makes me grow smaller, I can creep under the door: so
+ either way I'll get into the garden, and I don't care which happens!"</p>
+
+ <p>She ate a little bit and said anxiously to herself, "Which way? Which way?" holding
+ her hand on the top of her head to feel which way she was growing; and she was quite
+ surprised to find that she remained the same size. So she set to work and very soon
+ finished off the cake.</p>
+
+ <figure class="small">
+ <img src="images/i004_th.jpg" alt="Illo4" />
+ </figure>
+
+ <p><a id="Page_9" class="pageno" title="[Pg 9]"></a></p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_002.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_002.xhtml
new file mode 100644
index 0000000..3babe69
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_002.xhtml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00005"><a id="II_THE_POOL_OF_TEARS"></a>The Pool Of Tears</h2>
+
+ <p>Curiouser and curiouser!" cried Alice (she was so much
+ surprised that for the moment she quite forgot how to speak good English). "Now I'm
+ opening out like the largest telescope that ever was! Good-by, feet! Oh, my poor little
+ feet, I wonder who will put on your shoes and stockings for you now, dears? I shall be
+ a great deal too far off to trouble myself about you."</p>
+
+ <p>Just at this moment her head struck against the roof of the hall; in fact, she was
+ now rather more than nine feet high, and she at once took up the little golden key and
+ hurried off to the garden door.</p>
+
+ <p>Poor Alice! It was as much as she could do, lying down on one side, to look through
+ into the garden with one eye; but to get through was more hopeless than ever. She sat
+ down and began to cry again.</p>
+
+ <p>She went on shedding gallons of tears, until there was a large pool all 'round her
+ and reaching half down the hall.</p>
+
+ <p>After a time, she heard a little pattering of feet in the distance and she hastily
+ dried her eyes to see what was coming. It was the White Rabbit returning, splendidly
+ dressed, with a pair of white kid-gloves in one hand and a large fan in the other.
+ He<a id="Page_10" class="pageno" title="[Pg 10]"></a> came trotting along in a great
+ hurry, muttering to himself, "Oh! the Duchess, the Duchess! Oh! <i>won't</i> she be
+ savage if I've kept her waiting!"</p>
+
+ <figure class="small">
+ <img src="images/i005_th.jpg" alt="Illo5" />
+ </figure>
+
+ <p>When the Rabbit came near her, Alice began, in a low, timid voice, "If you please,
+ sir&#8212;" The Rabbit started violently, dropped the white kid-gloves and the fan and
+ skurried away into the darkness as hard as he could go.</p>
+
+ <p>Alice took up the fan and gloves and she kept fanning herself all the time she went
+ on talking. "Dear, dear! How queer everything is to-day! And yesterday things went on
+ just as usual. <i>Was</i> I the same when I got up this morning? But if I'm not the
+ same, the next question is, 'Who in the world am I?' Ah, <i>that's</i> the great
+ puzzle!"</p>
+
+ <p>As she said this, she looked down at her hands and was surprised to see that she had
+ put on one of the Rabbit's little white kid-gloves while she was talking. "How
+ <i>can</i> I have done that?" she thought. "I must be growing small again." She got up
+ and went to the table to measure herself by it and found that she was now about two
+ feet high and was going on<a id="Page_11" class="pageno" title="[Pg 11]"></a> shrinking
+ rapidly. She soon found out that the cause of this was the fan she was holding and she
+ dropped it hastily, just in time to save herself from shrinking away altogether.</p>
+
+ <p>"That <i>was</i> a narrow escape!" said Alice, a good deal frightened at the sudden
+ change, but very glad to find herself still in existence. "And now for the garden!" And
+ she ran with all speed back to the little door; but, alas! the little door was shut
+ again and the little golden key was lying on the glass table as before. "Things are
+ worse than ever," thought the poor child, "for I never was so small as this before,
+ never!"</p>
+
+ <p>As she said these words, her foot slipped, and in another moment, splash! she was up
+ to her chin in salt-water. Her first idea was that she had somehow fallen into the sea.
+ However, she soon made out that she was in the pool of tears which she had wept when
+ she was nine feet high.</p>
+
+ <figure class="small">
+ <img src="images/i006_th.jpg" alt="Illo6" />
+ </figure>
+
+ <p>Just then she heard something splashing about in the pool a little way off, and she
+ swam nearer to see what it was: she soon made out that it was only a mouse that had
+ slipped in like herself.<a id="Page_12" class="pageno" title="[Pg 12]"></a></p>
+
+ <p>"Would it be of any use, now," thought Alice, "to speak to this mouse? Everything is
+ so out-of-the-way down here that I should think very likely it can talk; at any rate,
+ there's no harm in trying." So she began, "O Mouse, do you know the way out of this
+ pool? I am very tired of swimming about here, O Mouse!" The Mouse looked at her rather
+ inquisitively and seemed to her to wink with one of its little eyes, but it said
+ nothing.</p>
+
+ <p>"Perhaps it doesn't understand English," thought Alice. "I dare say it's a French
+ mouse, come over with William the Conqueror." So she began again: "O&#249; est ma
+ chatte?" which was the first sentence in her French lesson-book. The Mouse gave a
+ sudden leap out of the water and seemed to quiver all over with fright. "Oh, I beg your
+ pardon!" cried Alice hastily, afraid that she had hurt the poor animal's feelings. "I
+ quite forgot you didn't like cats."</p>
+
+ <p>"Not like cats!" cried the Mouse in a shrill, passionate voice. "Would <i>you</i>
+ like cats, if you were me?"</p>
+
+ <p>"Well, perhaps not," said Alice in a soothing tone; "don't be angry about it. And
+ yet I wish I could show you our cat Dinah. I think you'd take a fancy to cats, if you
+ could only see her. She is such a dear, quiet thing." The Mouse was bristling all over
+ and she felt certain it must be really offended. "We won't talk about her any more, if
+ you'd rather not."</p>
+
+ <p>"We, indeed!" cried the Mouse, who was trembling down to the end of its tail. "As if
+ <i>I</i> would talk on such a subject! Our family always <i>hated</i> cats<a id=
+ "Page_13" class="pageno" title="[Pg 13]"></a>&#8212;nasty, low, vulgar things! Don't
+ let me hear the name again!"</p>
+
+ <figure class="full">
+ <img src= "images/plate02_th.jpg" alt="Alice at the Mad Tea Party." title="Alice at the Mad Tea Party." />
+ <figcaption>
+ <p>Alice at the Mad Tea Party.</p>
+ </figcaption>
+ </figure>
+
+ <p>"I won't indeed!" said Alice, in a great hurry to change the subject of
+ conversation. "Are you&#8212;are you fond&#8212;of&#8212;of dogs? There is such a nice
+ little dog near our house, I should like to show you! It kills all the rats
+ and&#8212;oh, dear!" cried Alice in a sorrowful tone. "I'm afraid I've offended it
+ again!" For the Mouse was swimming away from her as hard as it could go, and making
+ quite a commotion in the pool as it went.</p>
+
+ <p>So she called softly after it, "Mouse dear! Do come back again, and we won't talk
+ about cats, or dogs either, if you don't like them!" When the Mouse heard this, it
+ turned 'round and swam slowly back to her; its face was quite pale, and it said, in a
+ low, trembling voice, "Let us get to the shore and then I'll tell you my history and
+ you'll understand why it is I hate cats and dogs."</p>
+
+ <p>It was high time to go, for the pool was getting quite crowded with the birds and
+ animals that had fallen into it; there were a Duck and a Dodo, a Lory and an Eaglet,
+ and several other curious creatures. Alice led the way and the whole party swam to the
+ shore.</p>
+
+ <figure class="small">
+ <img src="images/i007_th.jpg" alt="Illo7" />
+ </figure>
+
+ <p><a id="Page_14" class="pageno" title="[Pg 14]"></a></p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_003.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_003.xhtml
new file mode 100644
index 0000000..6b80493
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_003.xhtml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00006">
+ <a id="III_A_CAUCUS-RACE_AND_A_LONG_TALE"></a>
+ A Caucus-Race And A Long Tale
+ </h2>
+
+ <p>They were indeed a queer-looking party that assembled on the
+ bank&#8212;the birds with draggled feathers, the animals with their fur clinging close
+ to them, and all dripping wet, cross and uncomfortable.</p>
+
+ <figure class="small">
+ <img src="images/i008_th.jpg" alt="Illo8" />
+ </figure>
+
+ <p>The first question, of course, was how to get dry again. They had a consultation
+ about this and after a few minutes, it seemed quite natural to Alice to find herself
+ talking familiarly with them, as if she had known them all her life.</p>
+
+ <p>At last the Mouse, who seemed to be a person of<a id="Page_15" class="pageno" title=
+ "[Pg 15]"></a> some authority among them, called out, "Sit down, all of you, and listen
+ to me! <i>I'll</i> soon make you dry enough!" They all sat down at once, in a large
+ ring, with the Mouse in the middle.</p>
+
+ <p>"Ahem!" said the Mouse with an important air. "Are you all ready? This is the driest
+ thing I know. Silence all 'round, if you please! 'William the Conqueror, whose cause
+ was favored by the pope, was soon submitted to by the English, who wanted leaders, and
+ had been of late much accustomed to usurpation and conquest. Edwin and Morcar, the
+ Earls of Mercia and Northumbria'&#8212;"</p>
+
+ <p>"Ugh!" said the Lory, with a shiver.</p>
+
+ <p>"&#8212;'And even Stigand, the patriotic archbishop of Canterbury, found it
+ advisable'&#8212;"</p>
+
+ <p>"Found <i>what</i>?" said the Duck.</p>
+
+ <p>"Found <i>it</i>," the Mouse replied rather crossly; "of course, you know what 'it'
+ means."</p>
+
+ <p>"I know what 'it' means well enough, when <i>I</i> find a thing," said the Duck;
+ "it's generally a frog or a worm. The question is, what did the archbishop find?"</p>
+
+ <p>The Mouse did not notice this question, but hurriedly went on, "'&#8212;found it
+ advisable to go with Edgar Atheling to meet William and offer him the crown.'&#8212;How
+ are you getting on now, my dear?" it continued, turning to Alice as it spoke.</p>
+
+ <p>"As wet as ever," said Alice in a melancholy tone; "it doesn't seem to dry me at
+ all."</p>
+
+ <p>"In that case," said the Dodo solemnly, rising to its feet, "I move that the meeting
+ adjourn, for the immediate adoption of more energetic remedies&#8212;"<a id="Page_16"
+ class="pageno" title="[Pg 16]"></a></p>
+
+ <p>"Speak English!" said the Eaglet. "I don't know the meaning of half those long
+ words, and, what's more, I don't believe you do either!"</p>
+
+ <p>"What I was going to say," said the Dodo in an offended tone, "is that the best
+ thing to get us dry would be a Caucus-race."</p>
+
+ <p>"What <i>is</i> a Caucus-race?" said Alice.</p>
+
+ <figure class="small">
+ <img src="images/i009_th.jpg" alt="Illo9" />
+ </figure>
+
+ <p>"Why," said the Dodo, "the best way to explain it is to do it." First it marked out
+ a race-course, in a sort of circle, and then all the party were placed along the
+ course, here and there. There was no "One, two, three and away!" but they began running
+ when they liked and left off when they liked, so that it was not easy to know when the
+ race was over. However, when they had been running half an hour or so and were quite
+ dry again, the Dodo suddenly called out, "The race is over!" and they all crowded
+ 'round it, panting and asking, "But who has won?"<a id="Page_17" class="pageno" title=
+ "[Pg 17]"></a></p>
+
+ <p>This question the Dodo could not answer without a great deal of thought. At last it
+ said, "<i>Everybody</i> has won, and <i>all</i> must have prizes."</p>
+
+ <p>"But who is to give the prizes?" quite a chorus of voices asked.</p>
+
+ <p>"Why, <i>she</i>, of course," said the Dodo, pointing to Alice with one finger; and
+ the whole party at once crowded 'round her, calling out, in a confused way, "Prizes!
+ Prizes!"</p>
+
+ <p>Alice had no idea what to do, and in despair she put her hand into her pocket and
+ pulled out a box of comfits (luckily the salt-water had not got into it) and handed
+ them 'round as prizes. There was exactly one a-piece, all 'round.</p>
+
+ <p>The next thing was to eat the comfits; this caused some noise and confusion, as the
+ large birds complained that they could not taste theirs, and the small ones choked and
+ had to be patted on the back. However, it was over at last and they sat down again in a
+ ring and begged the Mouse to tell them something more.</p>
+
+ <p>"You promised to tell me your history, you know," said Alice, "and why it is you
+ hate&#8212;C and D," she added in a whisper, half afraid that it would be offended
+ again.</p>
+
+ <p>"Mine is a long and a sad tale!" said the Mouse, turning to Alice and sighing.</p>
+
+ <p>"It <i>is</i> a long tail, certainly," said Alice, looking down with wonder at the
+ Mouse's tail, "but why do you call it sad?" And she kept on puzzling about it while the
+ Mouse was speaking, so that her idea of the tale was something like this:<a id=
+ "Page_18" class="pageno" title="[Pg 18]"></a>&#8212;</p>
+
+ <div class="poem stanza">
+ <span class="i1">"Fury said to<br /></span> <span class="i2">a mouse,
+ That<br /></span> <span class="i3">he met in the<br /></span> <span class="i4">house,
+ 'Let<br /></span> <span class="i5">us both go<br /></span> <span class="i6">to law:
+ <i>I</i><br /></span> <span class="i6 c9">will prosecute<br /></span> <span class=
+ "i6 c9"><i>you</i>.&#8212;<br /></span> <span class="i6 c9">Come, I'll<br /></span>
+ <span class="i5 c9">take no denial:<br /></span> <span class="c20"><span class=
+ "i4 c9">We must have<br /></span> <span class="i3 c10">the trial;<br /></span>
+ <span class="i2 c10">For really<br /></span> <span class="i1 c10">this
+ morning<br /></span> <span class="i0 c10">I've<br /></span> <span class=
+ "i0 c10">nothing<br /></span> <span class="i0 c11">to do.'<br /></span> <span class=
+ "i1 c11">Said the<br /></span> <span class="i2 c11">mouse to<br /></span>
+ <span class="c19"><span class="i3 c11">the cur,<br /></span> <span class=
+ "i4 c11">'Such a<br /></span> <span class="i5 c12">trial, dear<br /></span>
+ <span class="i6 c12">sir, With<br /></span> <span class="i8 c12">no jury<br /></span>
+ <span class="i9 c12">or judge,<br /></span> <span class="i9 c12">would<br /></span>
+ <span class="i8 c13">be wasting<br /></span> <span class="i7 c13">our<br /></span>
+ <span class="c18"><span class="i5 c13">breath.'<br /></span> <span class=
+ "i4 c13">'I'll be<br /></span> <span class="i3 c13">judge,<br /></span> <span class=
+ "i2 c14">I'll be<br /></span> <span class="i1 c14">jury,'<br /></span> <span class=
+ "i0 c14">said<br /></span> <span class="i0 c14">cunning<br /></span> <span class=
+ "i1 c14">old<br /></span> <span class="i2 c15">Fury;<br /></span> <span class=
+ "c17"><span class="i3 c15">'I'll<br /></span> <span class="i4 c15">try<br /></span>
+ <span class="i5 c15">the<br /></span> <span class="i6 c15">whole<br /></span>
+ <span class="i7 c16">cause,<br /></span> <span class="i7 c16">and<br /></span>
+ <span class="i6 c16">condemn<br /></span> <span class="i5 c16">you to<br /></span>
+ <span class="i3 c16">death.'"<br /></span></span></span></span></span>
+ </div>
+
+ <p><a id="Page_19" class="pageno" title="[Pg 19]"></a>"You are not attending!" said the
+ Mouse to Alice, severely. "What are you thinking of?"</p>
+
+ <p>"I beg your pardon," said Alice very humbly, "you had got to the fifth bend, I
+ think?"</p>
+
+ <p>"You insult me by talking such nonsense!" said the Mouse, getting up and walking
+ away.</p>
+
+ <p>"Please come back and finish your story!" Alice called after it. And the others all
+ joined in chorus, "Yes, please do!" But the Mouse only shook its head impatiently and
+ walked a little quicker.</p>
+
+ <p>"I wish I had Dinah, our cat, here!" said Alice. This caused a remarkable sensation
+ among the party. Some of the birds hurried off at once, and a Canary called out in a
+ trembling voice, to its children, "Come away, my dears! It's high time you were all in
+ bed!" On various pretexts they all moved off and Alice was soon left alone.</p>
+
+ <p>"I wish I hadn't mentioned Dinah! Nobody seems to like her down here and I'm sure
+ she's the best cat in the world!" Poor Alice began to cry again, for she felt very
+ lonely and low-spirited. In a little while, however, she again heard a little pattering
+ of footsteps in the distance and she looked up eagerly.</p>
+
+ <figure class="small">
+ <img src="images/i010_th.jpg" alt="Illo10" />
+ </figure>
+ <p><a id="Page_20" class="pageno" title="[Pg 20]"></a></p>
+
+ <figure class="small">
+ <img src="images/i011_th.jpg" alt="Illo11" />
+ </figure>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_004.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_004.xhtml
new file mode 100644
index 0000000..babbb4e
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_004.xhtml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00007"><a id="IV_THE_RABBIT_SENDS_IN_A_LITTLE_BILL"></a>
+ The Rabbit Sends In A Little Bill</h2>
+
+ <p>It was the White Rabbit, trotting slowly back again and
+ looking anxiously about as it went, as if it had lost something; Alice heard it
+ muttering to itself, "The Duchess! The Duchess! Oh, my dear paws! Oh, my fur and
+ whiskers! She'll get me executed, as sure as ferrets are ferrets! Where <i>can</i> I
+ have dropped them, I wonder?" Alice guessed in a moment that it was looking for the fan
+ and the pair of white kid-gloves and she very good-naturedly began hunting about for
+ them, but they were nowhere to be seen&#8212;everything seemed to have changed since
+ her swim in the pool, and the great hall, with the glass table and the little door, had
+ vanished completely.<a id="Page_21" class="pageno" title="[Pg 21]"></a></p>
+
+ <p>Very soon the Rabbit noticed Alice, and called to her, in an angry tone, "Why, Mary
+ Ann, what <i>are</i> you doing out here? Run home this moment and fetch me a pair of
+ gloves and a fan! Quick, now!"</p>
+
+ <p>"He took me for his housemaid!" said Alice, as she ran off. "How surprised he'll be
+ when he finds out who I am!" As she said this, she came upon a neat little house, on
+ the door of which was a bright brass plate with the name "W. RABBIT" engraved upon it.
+ She went in without knocking and hurried upstairs, in great fear lest she should meet
+ the real Mary Ann and be turned out of the house before she had found the fan and
+ gloves.</p>
+
+ <p>By this time, Alice had found her way into a tidy little room with a table in the
+ window, and on it a fan and two or three pairs of tiny white kid-gloves; she took up
+ the fan and a pair of the gloves and was just going to leave the room, when her eyes
+ fell upon a little bottle that stood near the looking-glass. She uncorked it and put it
+ to her lips, saying to herself, "I do hope it'll make me grow large again, for, really,
+ I'm quite tired of being such a tiny little thing!"</p>
+
+ <p>Before she had drunk half the bottle, she found her head pressing against the
+ ceiling, and had to stoop to save her neck from being broken. She hastily put down the
+ bottle, remarking, "That's quite enough&#8212;I hope I sha'n't grow any more."</p>
+
+ <p>Alas! It was too late to wish that! She went on growing and growing and very soon
+ she had to kneel down on the floor. Still she went on growing, and, as a last resource,
+ she put one arm out of the window and one foot up the chimney, and said to
+ herself,<a id="Page_22" class="pageno" title="[Pg 22]"></a> "Now I can do no more,
+ wha tev er happens. What <i>will</i> become of me?"</p>
+
+ <figure class="small">
+ <img src="images/i012_th.jpg" alt="Illo12" />
+ </figure>
+
+ <p>Luckily for Alice, the little mag ic b ottle had now had its full effect and she grew
+ no larger. After a few minutes she hear d a voice outside and stopped to listen.</p>
+
+ <p>"Mary Ann! Mary Ann!" said the voice . "Fetch me my gloves this moment!" Thencame a
+ little pattering of feet on the stairs. Alice knew it was the Rabbit coming to look for
+ her and she trembled till she shoo k th e house, quite forgetting that she was now about
+ a thousand times as large as the Rabbit and had no reason to be afraid of it.</p>
+
+ <p>Presently the Rabbit came up to the door and tried to open it; but as the door
+ opened inwards and Alice's elbow was press ed h ard against it, that attempt proved a
+ failure. Alice heard it sayto itself, "Then I'll g o 'round and get in at the
+ window."</p>
+
+ <p>"<i>That</i> you won't!" thought Ali ce; and after waiting till she fancied she heard
+ the Rabbit just under the window, sh e suddenly spread out her hand and<a id="Page_23"
+ class="pageno" title="[Pg 23]"></a > made asnatch in the air. She did not get hold of
+ anything, but she heard a little s hriek and a fall and a crash of bro ken glass, from
+ which she concluded that it was just possible it had fallen into a c ucumber-frame or
+ something of that sort.</p>
+
+ <p>Next came an angry voice&#8212;the Rabbit's&#8212;" Pat!Pat! Where are you?" And
+ then a voice she had never heard before, "Sure t hen, I'm here! D iggi ng for apples, yer
+ honor!"</p>
+
+ <p>"Here! Come and help me out of this! Now tell me, Pat, what's that in the
+ windo w?"</p>
+
+ <p>"Sure, it's an arm, yer honor!"</p>
+
+ <p>"Well, it's got no business the re, at any rate; go and take it away!"</p>
+
+ <p>There was a long silence after this an d Alice could only hear whispers now and then,
+ and at last she spread out her hand ag ain and made another snatch in the air. This time
+ there were <i>two</i> little shrieks a nd more sounds of brok en g lass. "I wonder what
+ they'll do next!" thought Alice. "As for pulling me out of the wi ndow, I only wish they
+ <i>could</i>!"</p>
+
+ <p>She waited for some time without h earing anything more. At last came a rumbling of
+ little cart-wheels and the sound of a good many voices all talking together. She made
+ out the words: "Where's the other lad der? Bill's got the other&#8212;Bill! Here, Bill!
+ Will the roof bear?&#8212;Who's to g o do wn the chimney?&#8212;Nay, <i>I</i> sha'n't!
+ <i>You</i> do it! Here, Bill! The master s ays you've got to go down the chimney!"</p>
+
+ <p>Alice drew her foot as far down the c himney as she couldand waited till she heard a
+ little animal scratching and scrambling a bout in the chimney close above
+ <a id="Page_24" class="pageno" title="[Pg 24]"></a> her; then she gave one sharp kick and waited to see
+ what would happen next.</p>
+
+ <p>The first thing she heard was a general chorus of "There goes Bill!" then the
+ Rabbit's voice alone&#8212;"Catc h him, you by the hedge!" Then silence a nd t hen another
+ confusion of voices&#8212;"Hold up his head&#8212;Brandy now&#8212;Don 't choke
+ him&#8212;What happened to you?"</p>
+
+ <p>Lastcame a little f eeble, squeaking voice, "Well, I hardly know&#8212;No mor e,
+ thank ye. I'm better now&#8212;all I know is, something comes at me like a
+ Jack-in-the -box and up I goes like a sky-rocket!"</p>
+
+ <p>Afte r a minute or two of silence, they began moving about again, and Alice heard the
+ Rabbit say , "A barrowful will do, to begin with."</p>
+
+ <p>"A barrowful of <i>what</i>?" though t Alice. But she had not long to doubt, for the
+ next moment a shower of little pe bbles came rattling in at the window and some of them
+ hither in the face. Alice no ticed, with some surprise, that the pebbles were all
+ turning into little cakes as they lay on the floor and abr ight idea came into her
+ head. "If Ieat one of these cakes," she thought, "it's sure to m ake <i>some</i> change
+ in my size."</p>
+
+ <p>So she swallowed one of the cakes an d was delighted to find that she began shrinking
+ directly. As soon as she was small enough to get through the door, she ran out of the
+ house and found quite a crowd of lit tle animals and birds waiting outside. They all
+ m ade a rush at Alice the moment she ap peared, but she ran off as hard as she could and
+ soon found herself safe in a thick wood.</p>
+
+ <figure class="full">
+ <img src="images/plate03_th.jpg" alt="The Duchess tucked her arm affectionately into Alice's." title=
+ "The Duchess tucked her arm affectionately into Alice's." />
+ <figcaption>
+ <p>"The Duchess tucked her arm affectionately into Alice's."</p>
+ </figcaption>
+ </figure>
+
+ <p>"The first thing I've got to do," said Alice to herself, <a id="Page_25" class=
+ "pageno" title="[Pg 25]"></a>as she wande red about in the wood, "is to grow to my right
+ size again; and the second thing i s to find my way into that lovely garden. I suppose I
+ ought to eat or drink something or other, but the great question is 'What?'"</p>
+
+ <p>Alice looked all arou nd her at the flowers and the blades of grass, but she could
+ notsee anything that loo kedlike the right thing to eat or drink under the
+ circumstances. There was a large mushroom growing near her, about the same height as
+ herself. She stretched herself u p on tiptoe and peeped over the edge and her eyes
+ immediately met those of a large blue caterpillar, that was sitting on the top, with
+ its armsfolded, quietly smoking a long hookah a nd taking not the smallest notice of
+ her or of anything else.</p>
+
+ <figure class="small">
+ <img src="images/i013_th.jpg" alt="Illo13" />
+ </figure>
+
+ <p><a id="Page_26" class="pageno" title="[Pg 26]"></a></p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_005.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_005.xhtml
new file mode 100644
index 0000000..25d3522
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_005.xhtml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00008"><a id="V_ADVICE_FROM_A_CATERPILLAR"></a>
+ Advice From A Caterpillar</h2>
+
+ <p>At last the Caterpillar took the hookah out of its mouth and
+ addressed Alice in alanguid, sleepy voice.</p>
+
+ <p>"Who are <i>you</i>?" said the Caterpillar.</p>
+
+ <figure class="small">
+ <img src="images/i014_th.jpg" alt="Illo14" />
+ </figure>
+
+ <p>Alice replied, rather shyly, "I&#8212;I hardly know, sir, just at present&#8212;at
+ least I know who I <i>was</i> when I got up this morning, but I think I must have
+ changed several times since then."</p>
+
+ <p> "Wha t do you mean by that?" said the Caterpillar, sternly. "Explain yourself!"<a id=
+ "Page_27" class="pageno" title="[Pg 27]"></a></p>
+
+ <p>"I can't explain<i>myself</i>, I'm afraid, sir," said Alice,"because I'm not
+ myself, you see&#8212;being so ma nydifferent sizes in a day is very confusing." She
+ drew hers elf up and said very gravely, "I think you ought to tell me who <i>you</i>
+ are, first."</p>
+
+ <p>"Why?" said the Caterpillar.</p>
+
+ <p>As Alice could not think of any good reason and the Caterpillar seemed to be in a
+ <i>very</i> u npleasant state of mind, she turned away.</p>
+
+ <p>"Come back!" the Caterpillar called after her. "I've something important to say!"
+ Alice turned and came back again.</p>
+
+ <p>"Keep your temper," said the Caterpillar.</p>
+
+ <p>"Is that all?" said Alice, swallowing down her anger as well as she could.</p>
+
+ <p>"No," said the Caterpillar.</p>
+
+ <p>It unfolded its arms, took the hookah out of its mouth again, and said, " So you
+ think you're changed, do you?"</p>
+
+ <p>"I'm afr aid, I am, sir," said Alice. "I can't remember things as I used&#8212;and I
+ don't keep the same size for ten minutes together!"</p>
+
+ <p>"What size d o you want to be?" asked the Caterpillar.</p>
+
+ <p>"Oh, I'mnot particular as to si ze," Alice hastily replied, "only one doesn't like
+ changing sooften, you know. I should like to be a <i>little</i> larger, sir, if you
+ wouldn't mind," said Alice. "Three inches is such a wretched height to be."</p>
+
+ <p>"It is a very good height indeed!" said the Caterpillar an grily, rearing itself
+ upright as it spoke (it was exactly three inches high).<a id="Page_28" class="pageno"
+ title="[Pg 28]"></a></p>
+
+ <p>In a minute or two, the Caterpillar got down off the mushroom and crawled away in to
+ the grass,merely remarking, as it went, "One side will make you grow taller, and the
+ other side will make you grow shorter."</p>
+
+ <p>"One side of <i>what</i>? The other side of <i >what</i>?" thought Alice to
+ herself.</p>
+
+ <p>"Of the mushroom," said the Caterpillar, just as if she had asked it aloud; and in
+ another moment, it was out of sight.</p>
+
+ <p>Alice remained looking thoughtfully at the mushroom for a minute, trying to make out
+ whichwere the two sides of it. At last she stretched her arms 'round it as far as they
+ would go, and broke off a bit of the edge with each hand.</p>
+
+ <p>"And now which is which?" she said to herself, and nibbled a little of the
+ right-hand bit to trythe effect. The next moment she felt a violent blow underneath
+ her chin&#8212;it had struck her foot!</p>
+
+ <p>She was a gooddeal frightened b y this very sudden change, as she was shrinking
+ rapidly; so she set to work at once to eat some of the other bit. Her chin was pressed
+ so closely against her foo tthat there was hardly room to open her mouth; but she did
+ it at last and managed to s wallow a morsel of the left-hand bit....</p>
+
+ <p>"Come, my head's free at last!" said Alice; but all she could see, when she loo ked
+ down, was an immense length of neck, which seemed to rise like a stalk out of a sea of
+ green leaves that lay far below her.</p>
+
+ <p>"Where <i>have</i> my shoulders got to? And oh, mypoor hands, how is it I can't see
+ you?"Shewas de<a id="Page_29" class="pageno" title="[Pg 29]"></a>lighted to find that
+ her neck would bend about easily in any direction, like a serpent. She had just
+ succeeded in curving it down into a gr aceful zigzag and was going to dive inamong the
+ leaves, when a s harp hiss made her draw back in a hurry &#8212;a large pigeon had flo wn
+ into her face and was beating her violently with its wings.</p>
+
+ <figure class="small">
+ <img src="images/i015_th.jpg" alt="Illo15" />
+ </figure>
+
+ <p>"Serpent!" cried the Pigeon.</p>
+
+ <p>"I'm <i>not</i> a serpent!" said Alice indignantly. "Let me alone!"</p>
+
+ <p>"I've tried the roo ts of trees, and I've tried banks, and I've tri ed hedges," the
+ Pigeon went on, "but those serpents! There's no pleasing them!"</p>
+
+ <p>Alice was more and more puzzled.</p>
+
+ <p>"As if it wasn't trouble enough hatching the eggs," said the Pigeon, "but I must be
+ on the look-out for serpents, night and day! And just as I'd taken the highest tree in
+ the wood," continued the Pigeon, raising its voice to a shriek, "and just as I was
+ thinkingI should be free of them at last, they must needs come wriggling down from the
+ sky! Ugh, Serpent!"</p>
+
+ <p>"But I'm <i>not</i> a serpent, I tell you!" said Alice. "I'm a&#8212;I'm a&#8212;I'm
+ a little girl," she added rather<a id="Page_30" class="pageno" title="[Pg 30]"></a>
+ doubtfully, as she remembered the numbe r of changes she had gone through that day.</p>
+
+ <p>"You're looking for eggs, I know <i>that</i> well enough," said the Pigeon; "and
+ what does it matter to me whether you're a little girl or a serpent?"</p>
+
+ <p>"It matters a good deal to <i>me</i>," said Alice h astily; "but I'm not looking for
+ eggs, as it happens, and if I was, I shouldn't want <i>yours</i>&#8212;I don't like
+ them raw."</p>
+
+ <p>"Well, be off, then!" said the Pige on in a sulky tone, as it settled down again into
+ its nest. Alice crouched down a mong the trees as well as she could, for her neck kept
+ getting entangled among the bra nches, and every now and then she had to stop and
+ untwist it. After awhile she rememb ered that she still held the pieces of mushroom in
+ her hands, and she set to work very carefully, nibbling first at one and then at the
+ other, and growing sometimes taller and sometimes shorter, until she had succeeded in
+ bringing herself down to her usual height.</p>
+
+ <p>It was so long since she had been anything near the right size that it felt quite
+ strange at first. "The next thing is to get into that beautiful garden&#8212;how
+ <i>is</i> that to be done, I wonder?" As she said this, she came suddenly upon an open
+ place, with a little house in it about four feet high. "Whoever lives there," thought
+ Alice, "it'll never do to come upon them <i>this</i> size;why, I should frighten them
+ out of their wits!" She did not venture to go near the house till she had brought
+ herself down to nine inches high.</p>
+
+ <p><a id="Page_31" class="pageno" title="[Pg 31]"></a></p>
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_006.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_006.xhtml
new file mode 100644
index 0000000..b36f41e
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_006.xhtml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00009"><a id="VI_PIG_AND_PEPPER"></a>Pig And Pepper</h2>
+
+ <p>For a minute or twoshe stood looking at the house, when
+ suddenly a footman in livery came running out of the wood (judging by his face only,
+ she would have called him a fish)&#8212;and rapped loudly at the door with his
+ knuckles. It was opened by another footman in livery,with a round face and large eyes
+ like a frog.</p>
+
+ <figure class="small">
+ <img src="images/i015_th.jpg" alt="Illo15" />
+ </figure>
+
+ <p>The Fish-Footman began by producing from under his arm a great letter, and this he
+ handed over to the other, saying, in a solemn tone, "For the Duchess.<a id="Page_32"
+ class="pageno" title="[Pg 32]"></a> An invitation from the Queen to play croquet." The
+ Frog-Footman repeated, in the same solemn tone, "From the Queen. An invitation for the
+ Duchess to play croquet." Then they both bowed low and their curls got entangled
+ together.</p>
+
+ <p>When Alice next peeped out, the Fish-Footman was gone, and the other was sitting on
+ the ground near the door, staring stupidly up into the sky. Alice went timidly up to
+ the door and knocked.</p>
+
+ <p>"There's no sortof use in knocking," said the Footman, "and that for two reasons.
+ First, because I'm on the same side of the door as you are; secondly, because they're
+ making such a noise inside, no one could possibly hear you." And certainly there
+ <i>was</i> a most extraordinary noise going on within&#8212;a constant howling and
+ sneezing, and every now and then a great crash, as if a dish or kettle had been broken
+ to pieces.</p>
+
+ <p>"How am I to get in?" asked Alice.</p>
+
+ <p>"<i>Are</i> you to get in at all?" said the Footman. "That's the first question, you
+ know."</p>
+
+ <p>Alice opened the door and went in. The door led right into a large kitchen, which
+ was full of smoke from one end to the other; the Duchess was sitting on a three-legged
+ stool in the middle, nursing a baby; the cook was leaning over the fire, stirring a
+ large caldron which seemed to be full of soup.</p>
+
+ <p>"There's certainly too much pepper in that soup!" Alice said to herself, as well as
+ she could for sneezing. Even the Duchess sneezed occasionally; and asforthe baby, it
+ was sneezing and howling alternately without a moment'spause. The only two
+ creatures<a id="Page_33" class="pageno" title="[Pg 33]"></a> in the kitchen that did
+ <i>not</i> sneeze were the cook and a large cat, which was grinning from ear to
+ ear.</p>
+
+ <p>"Please would you tell me," said Alice, a little timidly, "why your cat grins like
+ that?"</p>
+
+ <p>"It's a Cheshire-Cat," said the Duchess,"and that's why."</p>
+
+ <p>"I didn't know that Cheshire-Cats always grinned; in fact, I didn't know that cats
+ <i>could</i> grin," said Alice.</p>
+
+ <p>"You don't know much," said the Duchess, "and that's a fact."</p>
+
+ <p>Just then the cook took the caldron of soupoff the fire, and at once set to work
+ throwing everything within her reach at the Duchess and the baby&#8212;the fire-irons
+ came first; then followed a shower of saucepans, plates and dishes. The Duchess took no
+ notice of them, even when they hit her, and the baby was howling so much already that
+ itwas quite impossible to say whether the blows hurt it or not.</p>
+
+ <p>"Oh, <i>please</i> mind what you're doing!" cried Alice, jumping up and down in an
+ agony of terror.</p>
+
+ <p>"Here! You may nurse it a bit, if you like!" the Duchess said to Alice, flinging the
+ baby at her as she spoke. "I must go and get ready to play croquet with the Queen," and
+ she hurried out of the room.</p>
+
+ <p>Alice caught the baby with some difficulty, as it was a queer-shaped little creature
+ and held out its arms and legs in all directions. "If I don't take this child away with
+ me," thought Alice, "they're sure to kill it in a day or two. Wouldn't it be murder to
+ leave it behind?" She said the last words out loud and the little thing grunted in
+ reply.<a id="Page_34" class="pageno" title="[Pg 34]"></a></p>
+
+ <p>"If you're going to turn into a pig, my dear," said Alice, "I'll have nothing more
+ to do with you. Mind now!"</p>
+
+ <p>Alice was just beginning to think to herself, "Now, what am I to do with this
+ creature, when I get it home?" when it grunted again so violently that Alice looked
+ down into its face in some alarm. This time there could be <i>no</i> mistake about
+ it&#8212;it was neither more nor less than a pig; so she set the little creature down
+ and felt quite relieved to see it trot awayquietly into the wood.</p>
+
+ <p>Alice was a little startled by seeing the Cheshire-Catsitting on a bough of a tree
+ a few yards off. The Cat only grinned when it saw her. "Cheshire-Puss," began Alice,
+ rather timidly, "would you please tell me which way I ought to gofrom here?"</p>
+
+ <p>"In <i>that</i> direction," the Cat said, waving the right paw 'round, "lives a
+ Hatter; and in <i>that</i> direction," waving the other paw, "lives a March Hare. Visit
+ either you like; they're both mad."</p>
+
+ <p>"But I don't want to go among mad people," Alice remarked.</p>
+
+ <p>"Oh, you can't help that," said the Cat; "we're all mad here. Do you play croquet
+ with the Queen to-day?"</p>
+
+ <p>"I should like it very much," said Alice, "but I haven't been invited yet."</p>
+
+ <p>"You'll see me there," said the Cat, and vanished.</p>
+
+ <p>Alice had not gone much farther before she came in sight of the house of the March
+ Hare; it was so large a house that she did not like to go near till she had nibbled
+ some more of the left-hand bit of mushroom.</p>
+
+ <p><a id="Page_35" class="pageno" title="[Pg 35]"></a></p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_007.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_007.xhtml
new file mode 100644
index 0000000..5a79bca
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_007.xhtml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00010"><a id="VII_A_MAD_TEA-PARTY"></a>A Mad Tea-Party</h2>
+
+ <p>There was a table set out under a tree in front of the
+ house, and the March Hare and the Hatter were having tea at it; a Dormouse was sitting
+ between them, fast asleep.</p>
+
+ <p>The table was a large one, but the three were all crowded together at one corner of
+ it. "No room! No room!" they cried out when they saw Alice coming. "There's
+ <i>plenty</i> of room!" said Alice indignantly, and she sat down in a large arm-chair
+ at one end of the table.</p>
+
+ <p>The Hatter opened his eyes very wide on hearing this, but all he said was "Why is a
+ raven like a writing-desk?"</p>
+
+ <p>"I'm glad they've begun asking riddles&#8212;I believe I can guess that," she added
+ aloud.</p>
+
+ <p>"Do you mean that you think you can find out the answer to it?" said the March
+ Hare.</p>
+
+ <p>"Exactly so," said Alice.</p>
+
+ <p>"Then you should say what you mean," the March Hare went on.</p>
+
+ <p>"I do," Alice hastily replied; "at least&#8212;at least I mean what I
+ say&#8212;that's the same thing, you know."</p>
+
+ <p>"You might just as well say," added the Dormouse, which seemed to be talking in its
+ sleep, "that 'I breathe when I sleep' is the same thing as 'I sleep when I
+ breathe!'"<a id="Page_36" class="pageno" title="[Pg36]"></a></p>
+
+ <p>"It <i>is</i> the same thing with you," said the Hatter, and he poured a little hot
+ tea upon its nose. The Dormouse shook its head impatiently and said, without opening
+ its eyes,"Ofcourse, of course; just what I was going to remark myself."</p>
+
+ <figure class="small">
+ <img src="images/i017_th.jpg" alt="Illo17" />
+ </figure>
+
+ <p>"Have you guessed the riddle yet?" the Hatter said, turning to Alice again.</p>
+
+ <p>"No, I give it up," Alice replied. "What's theanswer?"</p>
+
+ <p>"I haven't the slightest idea," said the Hatter.</p>
+
+ <p>"Nor I,"said the March Hare.</p>
+
+ <p>Alice gave a weary sigh. "I think you might do something better with the time," she
+ said, "than wasting it in asking riddles that have no answers."</p>
+
+ <p>"Take some more tea," the March Hare said to Alice, very earnestly.</p>
+
+ <p>"I've had nothing yet," Alice replied in an offended tone, "so I can't take
+ more."</p>
+
+ <p>"You mean you can't take <i>less</i>," said the Hatter; "it's very easy to take
+ <i>more</i> than nothing."</p>
+
+ <p>At this, Alice got up and walked off. The Dormouse fell asleep instantly and neither
+ of the others took the least notice of her going, thoughshe looked <a id="Page_37"
+ class="pageno" title="[Pg 37]"></a>back once or twice; the last time she saw them, they
+ were trying to put the Dormouse into the tea-pot.</p>
+
+
+ <figure class="full">
+ <img src="images/plate04_th.jpg" alt="The Trial of the Knave of Hearts." title="The Trial of the Knave of Hearts." />
+ <figcaption>
+ <p>The Trial of the Knave of Hearts.</p>
+ </figcaption>
+ </figure>
+
+ <p>"At any rate, I'll never go <i>there</i> again!" said Alice, as she picked her way
+ through the wood. "It's the stupidest tea-party I ever was at in all my life!" Just as
+ she said this, she noticed that one of the trees had a door leading right into it.
+ "That's very curious!" she thought. "I think I may as well go in at once." And in she
+ went.</p>
+
+ <p>Once more she foundherself in the long hall and close to the little glass table.
+ Taking the little golden key, she unlocked the door that led into the garden. Then she
+ set to work nibbling at the mushroom (she had kept a piece of it in her pocket) till
+ she was about a foot high; then she walked down the little passage; and
+ <i>then</i>&#8212;she found herself at last in the beautiful garden, among the bright
+ flower-beds and the cool fountains.</p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_008.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_008.xhtml
new file mode 100644
index 0000000..06f0522
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_008.xhtml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00011"><a id="VIII_THE_QUEENS_CROQUET_GROUND"></a>
+ The Queen's Croquet Ground</h2>
+
+ <p>A large rose-tree stood near the entrance of the garden; the
+ roses growing on it were white, but there were threegardeners at it, busily painting
+ them red. Suddenly their eyes chanced to fall upon Alice, as she stood watching them.
+ "Would you tell me, please," said Alice, a little timidly, "why you are painting those
+ roses?"</p>
+
+ <p>Five and Seven said nothing, butlooked at Two.<a id="Page_38" class="pageno" title=
+ "[Pg 38]"></a> Twobegan, in a low voice, "Why, the fact is, you see, Miss, this here
+ ought to have been a <i>red</i> rose-tree, and we put a white one in by mistake; and,
+ if the Queen was to find it out, we should all have our heads cut off, you know. So you
+ see, Miss, we're doing our best, afore she comes, to&#8212;" At this moment, Five, who
+ had been anxiously looking across the garden, called out, "The Queen! The Queen!" and
+ the three gardeners instantly threw themselves flat upon their faces. There was a sound
+ of many footstepsand Alice looked 'round, eager to see the Queen.</p>
+
+ <p>First came ten soldiers carrying clubs, with their hands and feet at the corners:
+ next the ten courtiers; these were ornamented all over with diamonds. After these came
+ the royal children; there were ten of them, all ornamented with hearts. Next came the
+ guests, mostly Kings and Queens, and among them Alice recognized the White Rabbit. Then
+ followed the Knave of Hearts, carrying the King's crown on a crimson velvet cushion;
+ and last of all this grand procession came THE KING AND THE QUEEN OF HEARTS.</p>
+
+ <p>When the procession came opposite to Alice, they all stopped and looked at her, and
+ the Queen said severely, "Who is this?" She said it to the Knave of Hearts, who only
+ bowed and smiled in reply.</p>
+
+ <p>"My name is Alice, so please Your Majesty," said Alice very politely; but she added
+ to herself, "Why, they're only a pack of cards, after all!"</p>
+
+ <p>"Can you play croquet?" shouted the Queen. The question was evidently meant for
+ Alice.<a id="Page_39" class="pageno" title="[Pg 39]"></a></p>
+
+ <p>"Yes!" said Alice loudly.</p>
+
+ <p>"Come on, then!" roared the Queen.</p>
+
+ <p>"It's&#8212;it's a very fine day!" said a timid voice to Alice. She was walking by
+ the White Rabbit, who was peeping anxiously into her face.</p>
+
+ <p>"Very," said Alice. "Where's the Duchess?"</p>
+
+ <p>"Hush! Hush!" said the Rabbit. "She's under sentence of execution."</p>
+
+ <p>"What for?" said Alice.</p>
+
+ <p>"She boxed the Queen's ears&#8212;" the Rabbit began.</p>
+
+ <p>"Get to your places!" shouted the Queen in a voice of thunder, and people began
+ running about in all directions, tumbling up against each other. However, they got
+ settled down in a minute or two, and the game began.</p>
+
+ <p>Alice thought she had never seen such a curious croquet-ground in her life; it was
+ all ridges and furrows. The croquet balls were live hedgehogs, and the mallets live
+ flamingos and the soldiers had to double themselves up and stand on their hands and
+ feet, to make the arches.</p>
+
+ <p>The players all played at once, without waiting for turns, quarrelling all the while
+ and fighting for the hedgehogs; and in a very short time, the Queen was in a furious
+ passion and went stamping about and shouting, "Off with his head!" or "Off with her
+ head!" about once in a minute.</p>
+
+ <p>"They're dreadfully fond of beheading people here," thought Alice; "the great wonder
+ is that there's anyone left alive!"</p>
+
+ <p>She was looking about for some way of escape, when she noticed a curious appearance
+ in the air.<a id="Page_40" class="pageno" title="[Pg 40]"></a> "It's the Cheshire-Cat,"
+ she said to herself; "now I shall have somebody to talk to."</p>
+
+ <p>"How are you getting on?" said the Cat.</p>
+
+ <p>"I don't think they play at all fairly," Alice said, in a rather complaining tone;
+ "and they all quarrel so dreadfully one can't hear oneself speak&#8212;and they don't
+ seem to have any rules in particular."</p>
+
+ <p>"How do you like the Queen?" said the Cat in a low voice.</p>
+
+ <p>"Not at all," said Alice.</p>
+
+ <figure class="small">
+ <img src="images/i018_th.jpg" alt="Illo18" />
+ </figure>
+
+ <p>Alice thought she might as well go back and see how the game was going on. So she
+ went off in search of her hedgehog. The hedgehog was engaged in a fight with another
+ hedgehog, which seemed to Alice an excellent opportunity for croqueting one of them
+ with the other; the only difficulty was that her flamingo was gone across to the other
+ side of the garden, where Alice could see it trying, in a helpless sort of way, to fly
+ up into a tree. She caught the flamingo and tucked it away under her arm, that it might
+ not escape again.<a id="Page_41" class="pageno" title="[Pg 41]"></a></p>
+
+ <p>Just then Alice ran across the Duchess (who was now out of prison). She tucked her
+ arm affectionately into Alice's and they walked off together. Alice was very glad to
+ find her in such a pleasant temper. She was a little startled, however, when she heard
+ the voice of the Duchess close to her ear. "You're thinking about something, my dear,
+ and that makes you forget to talk."</p>
+
+ <p>"The game's going on rather better now," Alice said, by way of keeping up the
+ conversation a little.</p>
+
+ <p>"'Tis so," said the Duchess; "and the moral of that is&#8212;'Oh, 'tis love, 'tis
+ love that makes the world go 'round!'"</p>
+
+ <p>"Somebody said," Alice whispered, "that it's done by everybody minding his own
+ business!"</p>
+
+ <p>"Ah, well! It means much the same thing," said the Duchess, digging her sharp little
+ chin into Alice's shoulder, as she added "and the moral of <i>that</i> is&#8212;'Take
+ care of the sense and the sounds will take care of themselves.'"</p>
+
+ <p>To Alice's great surprise, the Duchess's arm that was linked into hers began to
+ tremble. Alice looked up and there stood the Queen in front of them, with her arms
+ folded, frowning like a thunderstorm!</p>
+
+ <p>"Now, I give you fair warning," shouted the Queen, stamping on the ground as she
+ spoke, "either you or your head must be off, and that in about half no time. Take your
+ choice!" The Duchess took her choice, and was gone in a moment.</p>
+
+ <p>"Let's go on with the game," the Queen said to Alice; and Alice was too much
+ frightened to say a<a id="Page_42" class="pageno" title="[Pg 42]"></a> word, but slowly
+ followed her back to the croquet-ground.</p>
+
+ <p>All the time they were playing, the Queen never left off quarreling with the other
+ players and shouting, "Off with his head!" or "Off with her head!" By the end of half
+ an hour or so, all the players, except the King, the Queen and Alice, were in custody
+ of the soldiers and under sentence of execution.</p>
+
+ <p>Then the Queen left off, quite out of breath, and walked away with Alice.</p>
+
+ <p>Alice heard the King say in a low voice to the company generally, "You are all
+ pardoned."</p>
+
+ <p>Suddenly the cry "The Trial's beginning!" was heard in the distance, and Alice ran
+ along with the others.</p>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_009.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_009.xhtml
new file mode 100644
index 0000000..57653ae
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_009.xhtml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00012"><a id="IX_WHO_STOLE_THE_TARTS"></a>Who Stole The Tarts?</h2>
+
+ <p>The King and Queen of Hearts were seated on their throne
+ when they arrived, with a great crowd assembled about them&#8212;all sorts of little
+ birds and beasts, as well as the whole pack of cards: the Knave was standing before
+ them, in chains, with a soldier on each side to guard him; and near the King was the
+ White Rabbit, with a trumpet in one hand and a scroll of parchment in the other. In the
+ very middle of the court<a id="Page_43" class="pageno" title="[Pg 43]"></a> was a
+ table, with a large dish of tarts upon it. "I wish they'd get the trial done," Alice
+ thought, "and hand 'round the refreshments!"</p>
+
+ <figure class="small">
+ <img src="images/i019_th.jpg" alt="Illo19" />
+ </figure>
+
+ <p>The judge, by the way, was the King and he wore his crown over his great wig.
+ "That's the jury-box," thought Alice; "and those twelve creatures (some were animals
+ and some were birds) I suppose they are the jurors."</p>
+
+ <p>Just then the White Rabbit cried out "Silence in the court!"</p>
+
+ <p>"Herald, read the accusation!" said the King.</p>
+
+ <p>On this, the White Rabbit blew three blasts on the trumpet, then unrolled the
+ parchment-scroll and read as follows:</p>
+
+ <div class="poem stanza">
+ <span class="i0">"The Queen of Hearts, she made some tarts,<br /></span> <span class=
+ "i2">All on a summer day;<br /></span> <span class="i0">The Knave of Hearts, he stole
+ those tarts<br /></span> <span class="i2">And took them quite away!"<br /></span>
+ </div>
+
+ <p>"Call the first witness," said the King; and the White Rabbit blew three blasts on
+ the trumpet and called out, "First witness!"</p>
+
+ <p>The first witness was the Hatter. He came in with<a id="Page_44" class="pageno"
+ title="[Pg 44]"></a> a teacup in one hand and a piece of bread and butter in the
+ other.</p>
+
+ <p>"You ought to have finished," said the King. "When did you begin?"</p>
+
+ <p>The Hatter looked at the March Hare, who had followed him into the court, arm in arm
+ with the Dormouse. "Fourteenth of March, I <i>think</i> it was," he said.</p>
+
+ <p>"Give your evidence," said the King, "and don't be nervous, or I'll have you
+ executed on the spot."</p>
+
+ <p>This did not seem to encourage the witness at all; he kept shifting from one foot to
+ the other, looking uneasily at the Queen, and, in his confusion, he bit a large piece
+ out of his teacup instead of the bread and butter.</p>
+
+ <p>Just at this moment Alice felt a very curious sensation&#8212;she was beginning to
+ grow larger again.</p>
+
+ <p>The miserable Hatter dropped his teacup and bread and butter and went down on one
+ knee. "I'm a poor man, Your Majesty," he began.</p>
+
+ <p>"You're a <i>very</i> poor <i>speaker</i>," said the King.</p>
+
+ <p>"You may go," said the King, and the Hatter hurriedly left the court.</p>
+
+ <p>"Call the next witness!" said the King.</p>
+
+ <p>The next witness was the Duchess's cook. She carried the pepper-box in her hand and
+ the people near the door began sneezing all at once.</p>
+
+ <p>"Give your evidence," said the King.</p>
+
+ <p>"Sha'n't," said the cook.</p>
+
+ <p>The King looked anxiously at the White Rabbit, who said, in a low voice, "Your
+ Majesty must cross-examine <i>this</i> witness."<a id="Page_45" class="pageno" title=
+ "[Pg 45]"></a></p>
+
+ <p>"Well, if I must, I must," the King said. "What are tarts made of?"</p>
+
+ <p>"Pepper, mostly," said the cook.</p>
+
+ <p>For some minutes the whole court was in confusion and by the time they had settled
+ down again, the cook had disappeared.</p>
+
+ <p>"Never mind!" said the King, "call the next witness."</p>
+
+ <p>Alice watched the White Rabbit as he fumbled over the list. Imagine her surprise
+ when he read out, at the top of his shrill little voice, the name "Alice!"</p>
+
+ </section>
+</body>
+</html> \ No newline at end of file
diff --git a/lib/epub.js/test/fixtures/alice/OPS/chapter_010.xhtml b/lib/epub.js/test/fixtures/alice/OPS/chapter_010.xhtml
new file mode 100644
index 0000000..4dc46c5
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/chapter_010.xhtml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="chapter">
+
+ <h2 id="pgepubid00013"><a id="X_ALICES_EVIDENCE"></a>Alice's Evidence</h2>
+
+ <p>"Here!" cried Alice. She jumped up in such a hurry that she
+ tipped over the jury-box, upsetting all the jurymen on to the heads of the crowd
+ below.</p>
+
+ <p>"Oh, I <i>beg</i> your pardon!" she exclaimed in a tone of great dismay.</p>
+
+ <p>"The trial cannot proceed," said the King, "until all the jurymen are back in their
+ proper places&#8212;<i>all</i>," he repeated with great emphasis, looking hard at
+ Alice.</p>
+
+ <p>"What do you know about this business?" the King said to Alice.</p>
+
+ <p>"Nothing whatever," said Alice.</p>
+
+ <p>The King then read from his book: "Rule forty-<a id="Page_46" class="pageno" title=
+ "[Pg 46]"></a>two. <i>All persons more than a mile high to leave the court</i>."</p>
+
+ <p>"<i>I'm</i> not a mile high," said Alice.</p>
+
+ <p>"Nearly two miles high," said the Queen.</p>
+
+ <figure>
+ <img src="images/i020_th.jpg" alt="Illo20" />
+ </figure>
+
+ <p>"Well, I sha'n't go, at any rate," said Alice.</p>
+
+ <p>The King turned pale and shut his note-book hastily. "Consider your verdict," he
+ said to the jury, in a low, trembling voice.</p>
+
+ <p>"There's more evidence to come yet, please Your Majesty," said the White Rabbit,
+ jumping up in a great hurry. "This paper has just been picked up. It seems to be a
+ letter written by the prisoner to&#8212;to somebody." He unfolded the paper as he spoke
+ and added, "It isn't a letter, after all; it's a set of verses."</p>
+
+ <p>"Please, Your Majesty," said the Knave, "I didn't write it and they can't prove that
+ I did; there's no name signed at the end."</p>
+
+ <p>"You <i>must</i> have meant some mischief, or else you'd have signed your name like
+ an honest man," said the King. There was a general clapping of hands at this.<a id=
+ "Page_47" class="pageno" title="[Pg 47]"></a></p>
+
+ <p>"Read them," he added, turning to the White Rabbit.</p>
+
+ <p>There was dead silence in the court whilst the White Rabbit read out the verses.</p>
+
+ <p>"That's the most important piece of evidence we've heard yet," said the King.</p>
+
+ <p>"<i>I</i> don't believe there's an atom of meaning in it," ventured Alice.</p>
+
+ <p>"If there's no meaning in it," said the King, "that saves a world of trouble, you
+ know, as we needn't try to find any. Let the jury consider their verdict."</p>
+
+ <p>"No, no!" said the Queen. "Sentence first&#8212;verdict afterwards."</p>
+
+ <p>"Stuff and nonsense!" said Alice loudly. "The idea of having the sentence
+ first!"</p>
+
+ <figure class="small">
+ <img src="images/ii021_th.jpg" alt="Illo21" />
+ </figure>
+
+ <p>"Hold your tongue!" said the Queen, turning purple.</p>
+
+ <p>"I won't!" said Alice.</p>
+
+ <p>"Off with her head!" the Queen shouted at the top of her voice. Nobody moved.</p>
+
+ <p>"Who cares for <i>you</i>?" said Alice (she had grown to her full size by this
+ time). "You're nothing but a pack of cards!"</p>
+
+ <p>At this, the whole pack rose up in the air and came flying down upon her; she<a id=
+ "Page_48" class="pageno" title="[Pg 48]"></a> gave a little scream, half of fright and
+ half of anger, and tried to beat them off, and found herself lying on the bank, with
+ her head in the lap of her sister, who was gently brushing away some dead leaves that
+ had fluttered down from the trees upon her face.</p>
+
+ <p>"Wake up, Alice dear!" said her sister. "Why, what a long sleep you've had!"</p>
+
+ <p>"Oh, I've had such a curious dream!" said Alice. And she told her sister, as well as
+ she could remember them, all these strange adventures of hers that you have just been
+ reading about. Alice got up and ran off, thinking while she ran, as well she might,
+ what a wonderful dream it had been.</p>
+
+ <figure class="small">
+ <img src="images/i022_th.jpg" alt="Illo22" />
+ </figure>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/cover.xhtml b/lib/epub.js/test/fixtures/alice/OPS/cover.xhtml
new file mode 100644
index 0000000..ac72347
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/cover.xhtml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Cover</title>
+ <link rel="stylesheet" type="text/css" href="css/stylesheet.css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <img src="images/cover_th.jpg" alt="Cover Image" title="Cover Image"/>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/css/stylesheet.css b/lib/epub.js/test/fixtures/alice/OPS/css/stylesheet.css
new file mode 100644
index 0000000..57531fe
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/css/stylesheet.css
@@ -0,0 +1,105 @@
+body {
+ font-family: Georgia, serif;
+ font-size: 1em;
+ line-height: 1.33em;
+}
+
+/* Book Title */
+h1 {
+ font-size: 1.5em;
+ line-height: 1.33em;
+}
+
+/* Chapter Title */
+h2 {
+ font-size: 1.33em;
+ line-height: 1.2em;
+}
+
+/* Subtitle */
+h3 {
+ font-size: 1.25em;
+ line-height: 1.12em;
+}
+
+/* Meta Info */
+h4 {
+ font-size: 1.1em;
+ line-height: 1.05em;
+}
+
+/* Chapter Container */
+section {
+
+}
+
+section > p {
+
+}
+
+/* Drop Cap */
+section > p:first-of-type:first-letter {
+ float: left;
+ font-size: 4em;
+ line-height: .8;
+ padding: 0 .2em;
+ font-family: Georgia;
+}
+
+figure.small {
+
+}
+
+figure.full {
+
+}
+
+figure > img {
+
+}
+
+figcaption {
+
+}
+
+figcaption > p {
+
+}
+
+/* More specific Kindle Eink queries at: http://epubsecrets.com/media-queries-for-kindle-devices.php */
+
+/* Amazon Kindle */
+@media amzn-kf8 {
+
+}
+
+/* Many device available at: https://css-tricks.com/snippets/css/media-queries-for-standard-devices/ */
+
+/* Smartphone - Portrait */
+@media only screen
+ and (min-device-width: 320px)
+ and (max-device-width: 667px)
+ and (orientation: portrait) {
+
+}
+
+/* Smartphone - Landscape */
+@media only screen
+ and (min-device-width: 320px)
+ and (max-device-width: 667px)
+ and (orientation: landscape) {
+
+}
+
+/* Tablet - Portrait and Landscape */
+@media only screen
+ and (min-device-width: 768px)
+ and (max-device-width: 1024px) {
+
+}
+
+/* Laptop & Desktops */
+@media only screen
+ and (min-device-width: 1025px) {
+
+} \ No newline at end of file
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/cover_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/cover_th.jpg
new file mode 100644
index 0000000..b9cc3b3
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/cover_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i001_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i001_th.jpg
new file mode 100644
index 0000000..ab6a9c5
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i001_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i002_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i002_th.jpg
new file mode 100644
index 0000000..df12dc5
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i002_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i003_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i003_th.jpg
new file mode 100644
index 0000000..2005bd2
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i003_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i004_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i004_th.jpg
new file mode 100644
index 0000000..7ad8456
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i004_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i005_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i005_th.jpg
new file mode 100644
index 0000000..3d8cd6a
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i005_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i006_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i006_th.jpg
new file mode 100644
index 0000000..786b173
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i006_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i007_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i007_th.jpg
new file mode 100644
index 0000000..ef2cd70
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i007_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i008_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i008_th.jpg
new file mode 100644
index 0000000..7999df7
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i008_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i009_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i009_th.jpg
new file mode 100644
index 0000000..c89542b
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i009_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i010_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i010_th.jpg
new file mode 100644
index 0000000..73b480c
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i010_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i011_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i011_th.jpg
new file mode 100644
index 0000000..75d7162
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i011_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i012_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i012_th.jpg
new file mode 100644
index 0000000..a95a783
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i012_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i013_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i013_th.jpg
new file mode 100644
index 0000000..b0e5620
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i013_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i014_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i014_th.jpg
new file mode 100644
index 0000000..492169f
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i014_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i015_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i015_th.jpg
new file mode 100644
index 0000000..cba87ed
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i015_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i016_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i016_th.jpg
new file mode 100644
index 0000000..6e38f32
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i016_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i017_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i017_th.jpg
new file mode 100644
index 0000000..bc22737
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i017_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i018_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i018_th.jpg
new file mode 100644
index 0000000..b0e5de0
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i018_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i019_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i019_th.jpg
new file mode 100644
index 0000000..779d5aa
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i019_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i020_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i020_th.jpg
new file mode 100644
index 0000000..3db3517
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i020_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/i022_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/i022_th.jpg
new file mode 100644
index 0000000..f8a0b96
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/i022_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/ii021_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/ii021_th.jpg
new file mode 100644
index 0000000..2f83b7d
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/ii021_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/plate01_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/plate01_th.jpg
new file mode 100644
index 0000000..b8798cc
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/plate01_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/plate02_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/plate02_th.jpg
new file mode 100644
index 0000000..010d94c
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/plate02_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/plate03_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/plate03_th.jpg
new file mode 100644
index 0000000..e96ff78
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/plate03_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/plate04_th.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/plate04_th.jpg
new file mode 100644
index 0000000..a8184ea
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/plate04_th.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/images/title.jpg b/lib/epub.js/test/fixtures/alice/OPS/images/title.jpg
new file mode 100644
index 0000000..34a4fb2
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/images/title.jpg
Binary files differ
diff --git a/lib/epub.js/test/fixtures/alice/OPS/package.opf b/lib/epub.js/test/fixtures/alice/OPS/package.opf
new file mode 100644
index 0000000..da1f41e
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/package.opf
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="pub-id">
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
+ <dc:language>en-US</dc:language>
+ <meta property="dcterms:modified">2012-01-18T12:47:00Z</meta>
+ <!-- Id, referenced above - in Reverse domain name notation -->
+ <dc:identifier id="pub-id">edu.nyu.itp.future-of-publishing.alice-in-wonderland</dc:identifier>
+ <!-- Basic Metadata -->
+ <dc:rights>Public domain in the USA.</dc:rights>
+ <dc:creator>Lewis Carroll</dc:creator>
+ <dc:contributor>Gordon Robinson</dc:contributor>
+ <dc:title>Alice's Adventures in Wonderland</dc:title>
+ <dc:subject>Fantasy</dc:subject>
+ <dc:source>http://www.gutenberg.org/files/19033/19033-h/19033-h.htm</dc:source>
+
+ <meta content="coverpage" name="cover"/>
+
+ </metadata>
+ <manifest>
+ <!-- Frontmater -->
+ <item id="toc" properties="nav" href="toc.xhtml" media-type="application/xhtml+xml"/>
+ <item id="cover" href="cover.xhtml" media-type="application/xhtml+xml"/>
+ <!-- Stylesheets -->
+ <item id="style" href="css/stylesheet.css" media-type="text/css"/>
+ <!-- Images -->
+ <item id="cover-image" properties="cover-image" href="images/cover_th.jpg" media-type="image/jpeg"/>
+ <item id="i001_th" href="images/i001_th.jpg" media-type="image/jpeg"/>
+ <item id="i002_th" href="images/i002_th.jpg" media-type="image/jpeg"/>
+ <item id="i003_th" href="images/i003_th.jpg" media-type="image/jpeg"/>
+ <item id="i004_th" href="images/i004_th.jpg" media-type="image/jpeg"/>
+ <item id="i005_th" href="images/i005_th.jpg" media-type="image/jpeg"/>
+ <item id="i006_th" href="images/i006_th.jpg" media-type="image/jpeg"/>
+ <item id="i007_th" href="images/i007_th.jpg" media-type="image/jpeg"/>
+ <item id="i008_th" href="images/i008_th.jpg" media-type="image/jpeg"/>
+ <item id="i009_th" href="images/i009_th.jpg" media-type="image/jpeg"/>
+ <item id="i010_th" href="images/i010_th.jpg" media-type="image/jpeg"/>
+ <item id="i011_th" href="images/i011_th.jpg" media-type="image/jpeg"/>
+ <item id="i012_th" href="images/i012_th.jpg" media-type="image/jpeg"/>
+ <item id="i013_th" href="images/i013_th.jpg" media-type="image/jpeg"/>
+ <item id="i014_th" href="images/i014_th.jpg" media-type="image/jpeg"/>
+ <item id="i015_th" href="images/i015_th.jpg" media-type="image/jpeg"/>
+ <item id="i016_th" href="images/i016_th.jpg" media-type="image/jpeg"/>
+ <item id="i017_th" href="images/i017_th.jpg" media-type="image/jpeg"/>
+ <item id="i018_th" href="images/i018_th.jpg" media-type="image/jpeg"/>
+ <item id="i019_th" href="images/i019_th.jpg" media-type="image/jpeg"/>
+ <item id="i020_th" href="images/i020_th.jpg" media-type="image/jpeg"/>
+ <item id="i022_th" href="images/i022_th.jpg" media-type="image/jpeg"/>
+ <item id="ii021_th" href="images/ii021_th.jpg" media-type="image/jpeg"/>
+ <item id="plate01_th" href="images/plate01_th.jpg" media-type="image/jpeg"/>
+ <item id="plate02_th" href="images/plate02_th.jpg" media-type="image/jpeg"/>
+ <item id="plate03_th" href="images/plate03_th.jpg" media-type="image/jpeg"/>
+ <item id="plate04_th" href="images/plate04_th.jpg" media-type="image/jpeg"/>
+ <item id="title-img" href="images/title.jpg" media-type="image/jpeg"/>
+ <!-- Chapters -->
+ <item id="titlepage" href="titlepage.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_001" href="chapter_001.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_002" href="chapter_002.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_003" href="chapter_003.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_004" href="chapter_004.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_005" href="chapter_005.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_006" href="chapter_006.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_007" href="chapter_007.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_008" href="chapter_008.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_009" href="chapter_009.xhtml" media-type="application/xhtml+xml"/>
+ <item id="chapter_010" href="chapter_010.xhtml" media-type="application/xhtml+xml"/>
+ </manifest>
+ <spine>
+ <!-- Frontmater -->
+ <itemref idref="cover" linear="no"/>
+ <itemref idref="toc" linear="no"/>
+ <!-- Chapters -->
+ <itemref linear="yes" idref="titlepage"/>
+ <itemref linear="yes" idref="chapter_001"/>
+ <itemref linear="yes" idref="chapter_002"/>
+ <itemref linear="yes" idref="chapter_003"/>
+ <itemref linear="yes" idref="chapter_004"/>
+ <itemref linear="yes" idref="chapter_005"/>
+ <itemref linear="yes" idref="chapter_006"/>
+ <itemref linear="yes" idref="chapter_007"/>
+ <itemref linear="yes" idref="chapter_008"/>
+ <itemref linear="yes" idref="chapter_009"/>
+ <itemref linear="yes" idref="chapter_010"/>
+ </spine>
+</package>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/titlepage.xhtml b/lib/epub.js/test/fixtures/alice/OPS/titlepage.xhtml
new file mode 100644
index 0000000..f7da637
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/titlepage.xhtml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+</head>
+<body>
+ <section epub:type="titlepage">
+
+ <p><a id="Page_1" class="pageno" title="[Pg 1]"></a></p>
+
+ <h1 id="pgepubid00001">
+ Alice's Adventures In Wonderland
+ </h1>
+
+ <p><a id="Page_2" class="pageno" title="[Pg 2]"></a></p>
+
+ <figure class="full titlepage">
+ <img src= "images/title.jpg" alt="title" />
+ </figure>
+
+
+ <p><a id="Page_3" class="pageno" title="[Pg 3]"></a></p>
+
+ <h4 id="pgepubid00003">
+ Copyright, 1916,<br />
+ By Sam'l Gabriel Sons &#38; Company<br />
+ New York
+ </h4>
+
+ <figure class="full">
+ <img src= "images/plate01_th.jpg" alt= "Alice in the Room of the Duchess." title= "Alice in the Room of the Duchess." />
+ <figcaption>
+ <p>Alice in the Room of the Duchess.</p>
+ </figcaption>
+ </figure>
+
+ </section>
+</body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/OPS/toc.xhtml b/lib/epub.js/test/fixtures/alice/OPS/toc.xhtml
new file mode 100644
index 0000000..eff8c48
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/OPS/toc.xhtml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+ <head>
+ <title>Alice's Adventures in Wonderland</title>
+ <link rel="stylesheet" href="css/stylesheet.css" type="text/css"/>
+ <meta charset="utf-8"/>
+ </head>
+ <body>
+ <section epub:type="frontmatter toc">
+ <header>
+ <h1>Contents</h1>
+ </header>
+
+ <nav xmlns:epub="http://www.idpf.org/2007/ops" epub:type="toc">
+ <ol>
+ <li><a href="titlepage.xhtml">Title Page</a></li>
+ <li><a href="chapter_001.xhtml">Down The Rabbit-Hole</a></li>
+ <li><a href="chapter_002.xhtml">The Pool Of Tears</a></li>
+ <li><a href="chapter_003.xhtml">A Caucus-Race And A Long Tale</a></li>
+ <li><a href="chapter_004.xhtml">The Rabbit Sends In A Little Bill</a></li>
+ <li><a href="chapter_005.xhtml">Advice From A Caterpillar</a></li>
+ <li><a href="chapter_006.xhtml">Pig And Pepper</a></li>
+ <li><a href="chapter_007.xhtml">A Mad Tea-Party</a></li>
+ <li><a href="chapter_008.xhtml">The Queen's Croquet Ground</a></li>
+ <li><a href="chapter_009.xhtml">Who Stole The Tarts?</a></li>
+ <li><a href="chapter_010.xhtml">Alice's Evidence</a></li>
+ </ol>
+ </nav>
+
+ </section>
+ </body>
+</html>
diff --git a/lib/epub.js/test/fixtures/alice/mimetype b/lib/epub.js/test/fixtures/alice/mimetype
new file mode 100644
index 0000000..57ef03f
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice/mimetype
@@ -0,0 +1 @@
+application/epub+zip \ No newline at end of file
diff --git a/lib/epub.js/test/fixtures/alice_without_cover.epub b/lib/epub.js/test/fixtures/alice_without_cover.epub
new file mode 100644
index 0000000..b215b2a
--- /dev/null
+++ b/lib/epub.js/test/fixtures/alice_without_cover.epub
Binary files differ
diff --git a/lib/epub.js/test/fixtures/chapter1-highlights.xhtml b/lib/epub.js/test/fixtures/chapter1-highlights.xhtml
new file mode 100644
index 0000000..200cd00
--- /dev/null
+++ b/lib/epub.js/test/fixtures/chapter1-highlights.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+<title>
+Moby-Dick</title>
+<link rel="stylesheet" href="css/stylesheet.css" type="text/css"></link>
+<meta charset="utf-8"/>
+</head>
+<body>
+<section class="body-rw Chapter-rw" epub:type="bodymatter chapter">
+<header>
+<h1><span class="audio" id="c001s0000">Chapter 1. Loomings.</span></h1></header>
+
+
+
+<p><span class="audio" id="c001s0001"><span id="highlight-2" class='annotator-hl'>Call me Ishmael.</span> Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.</span> <span class="audio" id="c001s0003">It is a way I have of driving off the spleen and regulating the circulation.</span> <span class="audio" id="c001s0004">Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people’s hats off—then, I account it high time to get to sea as soon as I can.</span> <span class="audio" id="c001s0005">This is my substitute for pistol and ball.</span> <span class="audio" id="c001s0006">With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship.</span> <span class="audio" id="c001s0007">There is nothing surprising in this.</span> <span class="audio" id="c001s0008">If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.</span></p>
+<p><span class="audio" id="c001p0002">There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs—commerce surrounds it with her surf. Right and left, the streets take you waterward. Its extreme downtown is the battery, where that noble mole is washed by waves, and cooled by breezes, which a few hours previous were out of sight of land. Look at the crowds of water-gazers there.</span></p>
+<p><span class="audio" id="c001p0003">Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook to Coenties Slip, and from thence, by Whitehall, northward. What do you see?—Posted like silent sentinels all around the town, stand thousands upon thousands of mortal men fixed in ocean reveries. Some leaning against the spiles; some seated upon the pier-heads; some looking over the bulwarks of ships from China; some high aloft in the rigging, as if striving to get a still better seaward peep. But these are all landsmen; of week days pent up in lath and plaster—tied to counters, nailed to benches, clinched to desks. How then is this? Are the green fields gone? What do they here?</span>
+</p>
+<p><span class="audio" id="c001p0004">But look! here come more crowds, pacing straight for the water, and seemingly bound for a dive. Strange! Nothing will content them but the extremest limit of the land; loitering under the shady lee of yonder warehouses will not suffice. No. They must get just as nigh the water as they possibly can without falling in. And there they stand—miles of them—leagues. Inlanders all, they come from lanes and alleys, streets and avenues—north, east, south, and west. Yet here they all unite. Tell me, does the magnetic virtue of the needles of the compasses of all those ships attract them thither?</span></p>
+<p><span class="audio" id="c001p0005">Once more. Say you are in the country; in some high land of lakes. Take almost any path you please, and ten to one it carries you down in a dale, and leaves you there by a pool in the stream. There is magic in it. Let the most absent-minded of men be plunged in his deepest reveries—stand that man on his legs, set his feet a-going, and he will infallibly lead you to water, if water there be in all that region. Should you ever be athirst in the great American desert, try this experiment, if your caravan happen to be supplied with a metaphysical professor. Yes, as every one knows, meditation and water are wedded for ever.</span></p>
+<p><span class="audio" id="c001p0006">But here is an artist. He desires to paint you the dreamiest, shadiest, quietest, most enchanting bit of romantic landscape in all the valley of the Saco. What is the chief element he employs? There stand his trees, each with a hollow trunk, as if a hermit and a crucifix were within; and here sleeps his meadow, and there sleep his cattle; and up from yonder cottage goes a sleepy smoke. Deep into distant woodlands winds a mazy way, reaching to overlapping spurs of mountains bathed in their hill-side blue. But though the picture lies thus tranced, and though this pine-tree shakes down its sighs like leaves upon this shepherd’s head, yet all were vain, unless the shepherd’s eye were fixed upon the magic stream before him. Go visit the Prairies in June, when for scores on scores of miles you wade knee-deep among Tiger-lilies—what is the one charm wanting?—Water—there is not a drop of water there! Were Niagara but a cataract of sand, would you travel your thousand miles to see it? Why did the poor poet of Tennessee, upon suddenly receiving two handfuls of silver, deliberate whether to buy him a coat, which he sadly needed, or invest his money in a pedestrian trip to Rockaway Beach? Why is almost every robust healthy boy with a robust healthy soul in him, at some time or other crazy to go to sea? Why upon your first voyage as a passenger, did you yourself feel such a mystical vibration, when first told that you and your ship were now out of sight of land? Why did the old Persians hold the sea holy? Why did the Greeks give it a separate deity, and own brother of Jove? Surely all this is not without meaning. And still deeper the meaning of that story of Narcissus, who because he could not grasp the tormenting, mild image he saw in the fountain, plunged into it and was drowned. But that same image, we ourselves see in all rivers and oceans. It is the image of the ungraspable phantom of life; and this is the key to it all.</span></p>
+<p><span class="audio" id="c001p0007">Now, when I say that I am in the habit of going to sea whenever I begin to grow hazy about the eyes, and begin to be over conscious of my lungs, I do not mean to have it inferred that I ever go to sea as a passenger. For to go as a passenger you must needs have a purse, and a purse is but a rag unless you have something in it. Besides, passengers get sea-sick—grow quarrelsome—don’t sleep of nights—do not enjoy themselves much, as a general thing;—no, I never go as a passenger; nor, though I am something of a salt, do I ever go to sea as a Commodore, or a Captain, or a Cook. I abandon the glory and distinction of such offices to those who like them. For my part, I abominate all honourable respectable toils, trials, and tribulations of every kind whatsoever. It is quite as much as I can do to take care of myself, without taking care of ships, barques, brigs, schooners, and what not. And as for going as cook,—though I confess there is considerable glory in that, a cook being a sort of officer on ship-board—yet, somehow, I never fancied broiling fowls;—though once broiled, judiciously buttered, and judgmatically salted and peppered, there is no one who will speak more respectfully, not to say reverentially, of a broiled fowl than I will. It is out of the idolatrous dotings of the old Egyptians upon broiled ibis and roasted river horse, that you see the mummies of those creatures in their huge bake-houses the pyramids.</span></p>
+<p><span class="audio" id="c001p0008">No, when I go to sea, I go as a simple sailor, right before the mast, plumb down into the forecastle, aloft there to the royal mast-head. True, they rather order me about some, and make me jump from spar to spar, like a grasshopper in a May meadow. And at first, this sort of thing is unpleasant enough. It touches one’s sense of honour, particularly if you come of an old established family in the land, the Van Rensselaers, or Randolphs, or Hardicanutes. And more than all, if just previous to putting your hand into the tar-pot, you have been lording it as a country schoolmaster, making the tallest boys stand in awe of you. The transition is a keen one, I assure you, from a schoolmaster to a sailor, and requires a strong decoction of Seneca and the Stoics to enable you to grin and bear it. But even this wears off in time.</span></p>
+<p><span class="audio" id="c001p0009">What of it, if some old hunks of a sea-captain orders me to get a broom and sweep down the decks? What does that indignity amount to, weighed, I mean, in the scales of the New Testament? Do you think the archangel Gabriel thinks anything the less of me, because I promptly and respectfully obey that old hunks in that particular instance? Who ain’t a slave? Tell me that. Well, then, however the old sea-captains may order me about—however they may thump and punch me about, I have the satisfaction of knowing that it is all right; that everybody else is one way or other served in much the same way—either in a physical or metaphysical point of view, that is; and so the universal thump is passed round, and all hands should rub each other’s shoulder-blades, and be content.</span></p>
+<p><span class="audio" id="c001p0010">Again, I always go to sea as a sailor, because they make a point of paying me for my trouble, whereas they never pay passengers a single penny that I ever heard of. On the contrary, passengers themselves must pay. And there is all the difference in the world between paying and being paid. The act of paying is perhaps the most uncomfortable infliction that the two orchard thieves entailed upon us. But BEING PAID,—what will compare with it? The urbane activity with which a man receives money is really marvellous, considering that we so earnestly believe money to be the root of all earthly ills, and that on no account can a monied man enter heaven. Ah! how cheerfully we consign ourselves to perdition!</span></p>
+<p><span class="audio" id="c001p0011">Finally, I always go to sea as a sailor, because of the wholesome exercise and pure air of the fore-castle deck. For as in this world, head winds are far more prevalent than winds from astern (that is, if you never violate the Pythagorean maxim), so for the most part the Commodore on the quarter-deck gets his atmosphere at second hand from the sailors on the forecastle. He thinks he breathes it first; but not so. In much the same way do the commonalty lead their leaders in many other things, at the same time that the leaders little suspect it. But wherefore it was that after having repeatedly smelt the sea as a merchant sailor, I should now take it into my head to go on a whaling voyage; this the invisible police officer of the Fates, who has the constant surveillance of me, and secretly dogs me, and influences me in some unaccountable way—he can better answer than any one else. And, doubtless, my going on this whaling voyage, formed part of the grand programme of Providence that was drawn up a long time ago. It came in as a sort of brief interlude and solo between more extensive performances. I take it that this part of the bill must have run something like this:</span></p>
+
+<div class="block-rw extract-rw headline-rw">
+<p><span class="audio" id="c001p0012">“GRAND CONTESTED ELECTION FOR THE PRESIDENCY OF THE UNITED STATES.</span></p>
+<p><span class="audio" id="c001p0013">“WHALING VOYAGE BY ONE ISHMAEL.</span></p>
+<p><span class="audio" id="c001p0014">“BLOODY BATTLE IN AFFGHANISTAN.”</span></p></div>
+<p><span class="audio" id="c001p0015">Though I cannot tell why it was exactly that those stage managers, the Fates, put me down for this shabby part of a whaling voyage, when others were set down for magnificent parts in high tragedies, and short and easy parts in genteel comedies, and jolly parts in farces—though I cannot tell why this was exactly; yet, now that I recall all the circumstances, I think I can see a little into the springs and motives which being cunningly presented to me under various disguises, induced me to set about performing the part I did, besides cajoling me into the delusion that it was a choice resulting from my own unbiased freewill and discriminating judgment.</span></p>
+<p><span class="audio" id="c001p0016">Chief among these motives was the overwhelming idea of the great whale himself. Such a portentous and mysterious monster roused all my curiosity. Then the wild and distant seas where he rolled his island bulk; the undeliverable, nameless perils of the whale; these, with all the attending marvels of a thousand Patagonian sights and sounds, helped to sway me to my wish. With other men, perhaps, such things would not have been inducements; but as for me, I am tormented with an everlasting itch for things remote. I love to sail forbidden seas, and land on barbarous coasts. Not ignoring what is good, I am quick to perceive a horror, and could still be social with it—would they let me—since it is but well to be on friendly terms with all the inmates of the place one lodges in.</span></p>
+<p><span class="audio" id="c001p0017">By reason of these things, then, the <span id="highlight-1" class='annotator-hl'>whaling voyage</span> was welcome; the great flood-gates of the wonder-world swung open, and in the wild conceits that swayed me to my purpose, two and two there floated into my inmost soul, endless processions of the whale, and, mid most of them all, one grand hooded phantom, like a snow hill in the air.</span></p>
+</section></body></html>
diff --git a/lib/epub.js/test/fixtures/chapter1.xhtml b/lib/epub.js/test/fixtures/chapter1.xhtml
new file mode 100644
index 0000000..1875a7e
--- /dev/null
+++ b/lib/epub.js/test/fixtures/chapter1.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+<title>
+Moby-Dick</title>
+<link rel="stylesheet" href="css/stylesheet.css" type="text/css"></link>
+<meta charset="utf-8"/>
+</head>
+<body>
+<section class="body-rw Chapter-rw" epub:type="bodymatter chapter">
+<header>
+<h1><span class="audio" id="c001s0000">Chapter 1. Loomings.</span></h1></header>
+
+
+
+<p><span class="audio" id="c001s0001">Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.</span> <span class="audio" id="c001s0003">It is a way I have of driving off the spleen and regulating the circulation.</span> <span class="audio" id="c001s0004">Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people’s hats off—then, I account it high time to get to sea as soon as I can.</span> <span class="audio" id="c001s0005">This is my substitute for pistol and ball.</span> <span class="audio" id="c001s0006">With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship.</span> <span class="audio" id="c001s0007">There is nothing surprising in this.</span> <span class="audio" id="c001s0008">If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.</span></p>
+<p><span class="audio" id="c001p0002">There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs—commerce surrounds it with her surf. Right and left, the streets take you waterward. Its extreme downtown is the battery, where that noble mole is washed by waves, and cooled by breezes, which a few hours previous were out of sight of land. Look at the crowds of water-gazers there.</span></p>
+<p><span class="audio" id="c001p0003">Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook to Coenties Slip, and from thence, by Whitehall, northward. What do you see?—Posted like silent sentinels all around the town, stand thousands upon thousands of mortal men fixed in ocean reveries. Some leaning against the spiles; some seated upon the pier-heads; some looking over the bulwarks of ships from China; some high aloft in the rigging, as if striving to get a still better seaward peep. But these are all landsmen; of week days pent up in lath and plaster—tied to counters, nailed to benches, clinched to desks. How then is this? Are the green fields gone? What do they here?</span>
+</p>
+<p><span class="audio" id="c001p0004">But look! here come more crowds, pacing straight for the water, and seemingly bound for a dive. Strange! Nothing will content them but the extremest limit of the land; loitering under the shady lee of yonder warehouses will not suffice. No. They must get just as nigh the water as they possibly can without falling in. And there they stand—miles of them—leagues. Inlanders all, they come from lanes and alleys, streets and avenues—north, east, south, and west. Yet here they all unite. Tell me, does the magnetic virtue of the needles of the compasses of all those ships attract them thither?</span></p>
+<p><span class="audio" id="c001p0005">Once more. Say you are in the country; in some high land of lakes. Take almost any path you please, and ten to one it carries you down in a dale, and leaves you there by a pool in the stream. There is magic in it. Let the most absent-minded of men be plunged in his deepest reveries—stand that man on his legs, set his feet a-going, and he will infallibly lead you to water, if water there be in all that region. Should you ever be athirst in the great American desert, try this experiment, if your caravan happen to be supplied with a metaphysical professor. Yes, as every one knows, meditation and water are wedded for ever.</span></p>
+<p><span class="audio" id="c001p0006">But here is an artist. He desires to paint you the dreamiest, shadiest, quietest, most enchanting bit of romantic landscape in all the valley of the Saco. What is the chief element he employs? There stand his trees, each with a hollow trunk, as if a hermit and a crucifix were within; and here sleeps his meadow, and there sleep his cattle; and up from yonder cottage goes a sleepy smoke. Deep into distant woodlands winds a mazy way, reaching to overlapping spurs of mountains bathed in their hill-side blue. But though the picture lies thus tranced, and though this pine-tree shakes down its sighs like leaves upon this shepherd’s head, yet all were vain, unless the shepherd’s eye were fixed upon the magic stream before him. Go visit the Prairies in June, when for scores on scores of miles you wade knee-deep among Tiger-lilies—what is the one charm wanting?—Water—there is not a drop of water there! Were Niagara but a cataract of sand, would you travel your thousand miles to see it? Why did the poor poet of Tennessee, upon suddenly receiving two handfuls of silver, deliberate whether to buy him a coat, which he sadly needed, or invest his money in a pedestrian trip to Rockaway Beach? Why is almost every robust healthy boy with a robust healthy soul in him, at some time or other crazy to go to sea? Why upon your first voyage as a passenger, did you yourself feel such a mystical vibration, when first told that you and your ship were now out of sight of land? Why did the old Persians hold the sea holy? Why did the Greeks give it a separate deity, and own brother of Jove? Surely all this is not without meaning. And still deeper the meaning of that story of Narcissus, who because he could not grasp the tormenting, mild image he saw in the fountain, plunged into it and was drowned. But that same image, we ourselves see in all rivers and oceans. It is the image of the ungraspable phantom of life; and this is the key to it all.</span></p>
+<p><span class="audio" id="c001p0007">Now, when I say that I am in the habit of going to sea whenever I begin to grow hazy about the eyes, and begin to be over conscious of my lungs, I do not mean to have it inferred that I ever go to sea as a passenger. For to go as a passenger you must needs have a purse, and a purse is but a rag unless you have something in it. Besides, passengers get sea-sick—grow quarrelsome—don’t sleep of nights—do not enjoy themselves much, as a general thing;—no, I never go as a passenger; nor, though I am something of a salt, do I ever go to sea as a Commodore, or a Captain, or a Cook. I abandon the glory and distinction of such offices to those who like them. For my part, I abominate all honourable respectable toils, trials, and tribulations of every kind whatsoever. It is quite as much as I can do to take care of myself, without taking care of ships, barques, brigs, schooners, and what not. And as for going as cook,—though I confess there is considerable glory in that, a cook being a sort of officer on ship-board—yet, somehow, I never fancied broiling fowls;—though once broiled, judiciously buttered, and judgmatically salted and peppered, there is no one who will speak more respectfully, not to say reverentially, of a broiled fowl than I will. It is out of the idolatrous dotings of the old Egyptians upon broiled ibis and roasted river horse, that you see the mummies of those creatures in their huge bake-houses the pyramids.</span></p>
+<p><span class="audio" id="c001p0008">No, when I go to sea, I go as a simple sailor, right before the mast, plumb down into the forecastle, aloft there to the royal mast-head. True, they rather order me about some, and make me jump from spar to spar, like a grasshopper in a May meadow. And at first, this sort of thing is unpleasant enough. It touches one’s sense of honour, particularly if you come of an old established family in the land, the Van Rensselaers, or Randolphs, or Hardicanutes. And more than all, if just previous to putting your hand into the tar-pot, you have been lording it as a country schoolmaster, making the tallest boys stand in awe of you. The transition is a keen one, I assure you, from a schoolmaster to a sailor, and requires a strong decoction of Seneca and the Stoics to enable you to grin and bear it. But even this wears off in time.</span></p>
+<p><span class="audio" id="c001p0009">What of it, if some old hunks of a sea-captain orders me to get a broom and sweep down the decks? What does that indignity amount to, weighed, I mean, in the scales of the New Testament? Do you think the archangel Gabriel thinks anything the less of me, because I promptly and respectfully obey that old hunks in that particular instance? Who ain’t a slave? Tell me that. Well, then, however the old sea-captains may order me about—however they may thump and punch me about, I have the satisfaction of knowing that it is all right; that everybody else is one way or other served in much the same way—either in a physical or metaphysical point of view, that is; and so the universal thump is passed round, and all hands should rub each other’s shoulder-blades, and be content.</span></p>
+<p><span class="audio" id="c001p0010">Again, I always go to sea as a sailor, because they make a point of paying me for my trouble, whereas they never pay passengers a single penny that I ever heard of. On the contrary, passengers themselves must pay. And there is all the difference in the world between paying and being paid. The act of paying is perhaps the most uncomfortable infliction that the two orchard thieves entailed upon us. But BEING PAID,—what will compare with it? The urbane activity with which a man receives money is really marvellous, considering that we so earnestly believe money to be the root of all earthly ills, and that on no account can a monied man enter heaven. Ah! how cheerfully we consign ourselves to perdition!</span></p>
+<p><span class="audio" id="c001p0011">Finally, I always go to sea as a sailor, because of the wholesome exercise and pure air of the fore-castle deck. For as in this world, head winds are far more prevalent than winds from astern (that is, if you never violate the Pythagorean maxim), so for the most part the Commodore on the quarter-deck gets his atmosphere at second hand from the sailors on the forecastle. He thinks he breathes it first; but not so. In much the same way do the commonalty lead their leaders in many other things, at the same time that the leaders little suspect it. But wherefore it was that after having repeatedly smelt the sea as a merchant sailor, I should now take it into my head to go on a whaling voyage; this the invisible police officer of the Fates, who has the constant surveillance of me, and secretly dogs me, and influences me in some unaccountable way—he can better answer than any one else. And, doubtless, my going on this whaling voyage, formed part of the grand programme of Providence that was drawn up a long time ago. It came in as a sort of brief interlude and solo between more extensive performances. I take it that this part of the bill must have run something like this:</span></p>
+
+<div class="block-rw extract-rw headline-rw">
+<p><span class="audio" id="c001p0012">“GRAND CONTESTED ELECTION FOR THE PRESIDENCY OF THE UNITED STATES.</span></p>
+<p><span class="audio" id="c001p0013">“WHALING VOYAGE BY ONE ISHMAEL.</span></p>
+<p><span class="audio" id="c001p0014">“BLOODY BATTLE IN AFFGHANISTAN.”</span></p></div>
+<p><span class="audio" id="c001p0015">Though I cannot tell why it was exactly that those stage managers, the Fates, put me down for this shabby part of a whaling voyage, when others were set down for magnificent parts in high tragedies, and short and easy parts in genteel comedies, and jolly parts in farces—though I cannot tell why this was exactly; yet, now that I recall all the circumstances, I think I can see a little into the springs and motives which being cunningly presented to me under various disguises, induced me to set about performing the part I did, besides cajoling me into the delusion that it was a choice resulting from my own unbiased freewill and discriminating judgment.</span></p>
+<p><span class="audio" id="c001p0016">Chief among these motives was the overwhelming idea of the great whale himself. Such a portentous and mysterious monster roused all my curiosity. Then the wild and distant seas where he rolled his island bulk; the undeliverable, nameless perils of the whale; these, with all the attending marvels of a thousand Patagonian sights and sounds, helped to sway me to my wish. With other men, perhaps, such things would not have been inducements; but as for me, I am tormented with an everlasting itch for things remote. I love to sail forbidden seas, and land on barbarous coasts. Not ignoring what is good, I am quick to perceive a horror, and could still be social with it—would they let me—since it is but well to be on friendly terms with all the inmates of the place one lodges in.</span></p>
+<p><span class="audio" id="c001p0017">By reason of these things, then, the whaling voyage was welcome; the great flood-gates of the wonder-world swung open, and in the wild conceits that swayed me to my purpose, two and two there floated into my inmost soul, endless processions of the whale, and, mid most of them all, one grand hooded phantom, like a snow hill in the air.</span></p>
+</section></body></html>
diff --git a/lib/epub.js/test/fixtures/highlight.xhtml b/lib/epub.js/test/fixtures/highlight.xhtml
new file mode 100644
index 0000000..9fdc98c
--- /dev/null
+++ b/lib/epub.js/test/fixtures/highlight.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta charset="utf-8"/>
+ <title>Highlight Test</title>
+ </head>
+ <body>
+ <p id="p1">Alice was beginning to get very tired of sitting by her
+ sister on the bank, and of having nothing to do. Once or twice she had peeped into the
+ book her sister was reading, but it had no pictures or conversations in it, "and what
+ is the use of a book," thought Alice, "without pictures or conversations?"</p>
+
+ <p id="p2"><span class="annotator-hl" id="a1">So she was considering in her own mind (as well as she could, for the day made her
+ feel very sleepy and stupid)</span>, whether the <span class="annotator-hl" id="a2">pleasure of making a daisy-chain</span> would be
+ worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit
+ with pink eyes ran close by her.</p>
+
+ <p id="p3">There was nothing so very remarkable in that, nor did Alice think it so
+ <a id="Page_4" class="pageno" title="[Pg 4]"></a>very much out of the way to hear the Rabbit
+ say to itself, "Oh dear! Oh dear! I shall be too late!" But when the Rabbit actually
+ took a watch out of its waistcoat-pocket and looked at it and then hurried on, Alice
+ started to her feet, for it flashed across her mind that she had never before seen a
+ rabbit with either a waistcoat-pocket, or a watch to take out of it, and, burning with
+ curiosity, she ran across the field after it and was just in time to see it pop down a
+ large rabbit-hole, under the hedge. In another moment, down went Alice after it!</p>
+ </body>
+</html>
diff --git a/lib/epub.js/test/fixtures/locations.xhtml b/lib/epub.js/test/fixtures/locations.xhtml
new file mode 100644
index 0000000..7f97adf
--- /dev/null
+++ b/lib/epub.js/test/fixtures/locations.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
+<head>
+<title>
+Moby-Dick</title>
+<link rel="stylesheet" href="css/stylesheet.css" type="text/css"></link>
+<meta charset="utf-8"/>
+</head>
+<body>
+<section class="body-rw Chapter-rw" epub:type="bodymatter chapter">
+<header>
+<!-- 20 -->
+<h1>Chapter 1. Loomings.</h1>
+</header>
+
+<!-- 1107 -->
+<p>Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.
+It is a way I have of driving off the spleen and regulating the circulation.
+Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people’s hats off—then, I account it high time to get to sea as soon as I can.
+This is my substitute for pistol and ball.
+With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship.
+There is nothing surprising in this.
+If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.</p>
+
+<!-- 387 -->
+<p>There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs—commerce surrounds it with her surf. Right and left, the streets take you waterward. Its extreme downtown is the battery, where that noble mole is washed by waves, and cooled by breezes, which a few hours previous were out of sight of land. Look at the crowds of water-gazers there.</p>
+
+</section></body></html>
diff --git a/lib/epub.js/test/index.html b/lib/epub.js/test/index.html
new file mode 100644
index 0000000..b2a5495
--- /dev/null
+++ b/lib/epub.js/test/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Mocha</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="./node_modules/mocha/mocha.css" />
+ <script src="/test/test.build.js"></script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/lib/epub.js/test/locations.js b/lib/epub.js/test/locations.js
new file mode 100644
index 0000000..64288eb
--- /dev/null
+++ b/lib/epub.js/test/locations.js
@@ -0,0 +1,31 @@
+import assert from 'assert';
+import Locations from '../src/locations';
+import * as core from '../src/utils/core';
+
+describe('Locations', function() {
+
+ describe('#parse', function() {
+ var chapter = require('./fixtures/locations.xhtml').default;
+
+ it('parse locations from a document', function() {
+ var doc = core.parse(chapter, "application/xhtml+xml");
+ var contents = doc.documentElement;
+ var locations = new Locations();
+ var result = locations.parse(contents, "/6/4[chap01ref]", 100);
+ assert.equal(result.length, 15);
+
+ });
+
+ it('parse locations from xmldom', function() {
+ var doc = core.parse(chapter, "application/xhtml+xml", true);
+ var contents = doc.documentElement;
+
+ var locations = new Locations();
+ var result = locations.parse(contents, "/6/4[chap01ref]", 100);
+ assert.equal(result.length, 15);
+
+ });
+
+ });
+
+});
diff --git a/lib/epub.js/test/old/epub.js b/lib/epub.js/test/old/epub.js
new file mode 100644
index 0000000..8723114
--- /dev/null
+++ b/lib/epub.js/test/old/epub.js
@@ -0,0 +1,371 @@
+var domain = window.location.origin;
+
+module('Core');
+
+test("EPUBJS.core.resolveUrl", 1, function() {
+ var a = "http://example.com/fred/chasen/";
+ var b = "/chasen/derf.html";
+
+ var resolved = EPUBJS.core.resolveUrl(a, b);
+
+ equal( resolved, "http://example.com/fred/chasen/derf.html", "resolved" );
+
+});
+
+test("EPUBJS.core.resolveUrl ../", 1, function() {
+ var a = "http://example.com/fred/chasen/";
+ var b = "../derf.html";
+
+ var resolved = EPUBJS.core.resolveUrl(a, b);
+
+ equal( resolved, "http://example.com/fred/derf.html", "resolved" );
+});
+
+
+test("EPUBJS.core.resolveUrl folders", 1, function() {
+ var a = "/fred/chasen/";
+ var b = "/fred/chasen/derf.html";
+
+ var resolved = EPUBJS.core.resolveUrl(a, b);
+
+ equal( resolved, "/fred/chasen/derf.html", "resolved" );
+});
+
+test("EPUBJS.core.resolveUrl ../folders", 1, function() {
+ var a = "/fred/chasen/";
+ var b = "../../derf.html";
+
+ var resolved = EPUBJS.core.resolveUrl(a, b);
+
+ equal( resolved, "/derf.html", "resolved" );
+});
+
+module('Create');
+
+asyncTest("Create new ePub(/path/to/epub/)", 1, function() {
+
+ var book = ePub("../books/moby-dick/");
+ book.opened.then(function(){
+ equal( book.url, "../books/moby-dick/OPS/", "book url is passed to new EPUBJS.Book" );
+ start();
+ });
+
+});
+
+asyncTest("Create new ePub(/path/to/epub/package.opf)", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.url, domain + "/books/moby-dick/OPS/", "bookPath is passed to new EPUBJS.Book" );
+ start();
+ });
+
+});
+
+asyncTest("Open using ePub(/path/to/epub/package.opf)", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
+ start();
+ });
+
+});
+
+asyncTest("Open Remote ePub", 1, function() {
+
+ var book = ePub("https://s3.amazonaws.com/moby-dick/");
+ book.opened.then(function(){
+ equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
+ start();
+ });
+
+});
+
+asyncTest("Open Remote ePub from Package", 1, function() {
+
+ var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
+ start();
+ });
+
+});
+
+asyncTest("Find Epub Package", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
+ start();
+ });
+
+});
+
+module('Parse');
+
+//TODO: add mocked tests for parser
+
+asyncTest("Manifest", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( Object.keys(book.package.manifest).length, 152, "Manifest is parsed" );
+ start();
+ });
+
+});
+
+asyncTest("Metadata", 3, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.package.metadata.creator, "Herman Melville", "Creator metadata is parsed" );
+ equal( book.package.metadata.title, "Moby-Dick", "Title metadata is parsed" );
+ equal( book.package.metadata.identifier, "code.google.com.epub-samples.moby-dick-basic", "Identifier metadata is parsed" );
+ start();
+ });
+
+});
+
+asyncTest("Spine", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.package.spine.length, 144, "Spine is parsed" );
+ start();
+ });
+
+});
+
+asyncTest("Cover", 1, function() {
+
+ var book = ePub("../books/moby-dick/");
+ book.opened.then(function(){
+ equal( book.cover, "../books/moby-dick/OPS/images/9780316000000.jpg", "Cover is set" );
+ start();
+ });
+
+});
+
+module('Spine');
+
+asyncTest("Length", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.spine.length, 144, "All spine items present" );
+ start();
+ });
+
+});
+
+asyncTest("Items", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ equal( book.spine.spineItems.length, 144, "All spine items added" );
+ start();
+ });
+
+});
+
+asyncTest("First Item", 2, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var section = book.spine.get(0);
+ equal( section.href, "cover.xhtml", "First spine item href found" );
+ equal( section.cfiBase, "/6/2[cover]", "First spine item cfi found" );
+
+ start();
+ });
+
+});
+
+asyncTest("Find Item by Href", 2, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var section = book.spine.get("chapter_001.xhtml");
+ equal( section.href, "chapter_001.xhtml", "chap 1 spine item href found" );
+ equal( section.cfiBase, "/6/14[xchapter_001]", "chap 1 spine item cfi found" );
+
+ start();
+ });
+
+});
+
+asyncTest("Find Item by ID", 2, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var section = book.spine.get("#xchapter_050");
+ equal( section.href, "chapter_050.xhtml", "chap 50 spine item href found" );
+ equal( section.cfiBase, "/6/112[xchapter_050]", "chap 50 spine item cfi found" );
+
+ start();
+ });
+
+});
+
+asyncTest("Render Spine Item", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var section = book.spine.get("#xchapter_050");
+ section.render().then(function(content){
+ equal( content.substring(377, 429), "<h1>Chapter 50. Ahab’s Boat and Crew. Fedallah.</h1>", "Chapter text rendered as string" );
+ });
+
+ start();
+ });
+
+});
+
+module('Navigation');
+
+asyncTest("NCX & Nav", 2, function() {
+
+ var book = ePub("../books/moby-dick/");
+ book.opened.then(function(){
+ equal( book.navigation.navUrl, "../books/moby-dick/OPS/toc.xhtml", "Nav URL found" );
+ equal( book.navigation.ncxUrl, "../books/moby-dick/OPS/toc.ncx", "NCX URL found" );
+
+ start();
+ });
+
+});
+
+
+asyncTest("Load TOC Auto Pick", 1, function() {
+
+ var book = ePub("../books/moby-dick/");
+ book.opened.then(function(){
+ book.navigation.load().then(function(toc){
+ equal( toc.length, 141, "Full Nav toc parsed" );
+ start();
+ });
+ });
+
+});
+
+asyncTest("Load TOC from Nav", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var nav = book.navigation.nav.load();
+ nav.then(function(toc){
+ equal( toc.length, 141, "Full Nav toc parsed" );
+ start();
+ });
+ });
+
+});
+
+asyncTest("Load TOC from NCX", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.opened.then(function(){
+ var ncx = book.navigation.ncx.load();
+ ncx.then(function(toc){
+ equal( toc.length, 14, "Full NCX toc parsed" );
+ start();
+ });
+ });
+
+});
+
+asyncTest("Get all TOC", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.loaded.navigation.then(function(){
+ equal( book.navigation.get().length, 141, "Full Nav toc parsed" );
+ start();
+ });
+
+});
+
+asyncTest("Get TOC item by href", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.loaded.navigation.then(function(){
+ var item = book.navigation.get("chapter_001.xhtml");
+ equal( item.id, "toc-chapter_001", "Found TOC item" );
+ start();
+ });
+
+});
+
+asyncTest("Get TOC item by ID", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ book.loaded.navigation.then(function(){
+ var item = book.navigation.get("#toc-chapter_001");
+ equal( item.href, "chapter_001.xhtml", "Found TOC item" );
+ start();
+ });
+
+});
+
+module('Hooks');
+
+asyncTest("Register a new hook", 1, function() {
+
+ var beforeDisplay = new EPUBJS.Hook();
+ beforeDisplay.register(function(args){
+ var defer = new RSVP.defer();
+ console.log("ran", 1);
+ defer.resolve();
+ return defer.promise;
+ });
+ equal( beforeDisplay.hooks.length, 1, "Registered a hook" );
+ start();
+
+// this.beforeDisplay.trigger(args).then(function(){});
+
+});
+
+asyncTest("Trigger all new hook", 4, function() {
+
+ var beforeDisplay = new EPUBJS.Hook(this);
+ this.testerObject = {tester: 1};
+
+ beforeDisplay.register(function(testerObject){
+ var defer = new RSVP.defer();
+
+ start();
+ equal( testerObject.tester, 1, "tester is 1" );
+ stop();
+
+ testerObject.tester += 1;
+
+ defer.resolve();
+ return defer.promise;
+ });
+
+ beforeDisplay.register(function(testerObject){
+ var defer = new RSVP.defer();
+
+ start();
+ equal(testerObject.tester, 2, "tester is 2" );
+ stop();
+
+ testerObject.tester += 1;
+
+ defer.resolve();
+ return defer.promise;
+ });
+
+ start();
+ equal( beforeDisplay.hooks.length, 2, "Added two hooks" );
+ stop();
+
+ beforeDisplay.trigger(this.testerObject).then(function(){
+
+ start();
+ equal( this.testerObject.tester, 3, "tester is 3" );
+
+ }.bind(this));
+
+});
diff --git a/lib/epub.js/test/old/rendering.js b/lib/epub.js/test/old/rendering.js
new file mode 100644
index 0000000..5cf1357
--- /dev/null
+++ b/lib/epub.js/test/old/rendering.js
@@ -0,0 +1,16 @@
+module('Rendering');
+/*
+asyncTest("Render To", 1, function() {
+
+ var book = ePub("../books/moby-dick/OPS/package.opf");
+ var rendition = book.renderTo("qunit-fixture", {width:400, height:600});
+ var displayed = rendition.display(0);
+
+ displayed.then(function(){
+ equal( $( "iframe", "#qunit-fixture" ).length, 1, "iframe added successfully" );
+ start();
+ });
+
+
+});
+*/
diff --git a/lib/epub.js/test/section.js b/lib/epub.js/test/section.js
new file mode 100644
index 0000000..5a2902e
--- /dev/null
+++ b/lib/epub.js/test/section.js
@@ -0,0 +1,77 @@
+import assert from 'assert';
+import ePub from '../src/epub';
+
+describe("section", function() {
+ it("finds a single result in a section", function() {
+ var book = ePub("./fixtures/alice/", {width: 400, height: 400});
+ return book.ready.then(function() {
+ var section = book.section("chapter_001.xhtml");
+ return section.load().then(function() {
+ const queryString = "they were filled with cupboards and book-shelves";
+ const findResults = section.find(queryString);
+ const searchResults = section.search(queryString);
+ [findResults , searchResults].forEach( (results)=>{
+ assert.equal(results.length, 1);
+ assert.equal(results[0].cfi, "epubcfi(/6/8[chapter_001]!/4/2/16,/1:275,/1:323)");
+ assert.equal(results[0].excerpt, "... see anything; then she looked at the sides of the well and\n\t\tnoticed that they were filled with cupboards and book-shelves; here and there she saw\n\t\t...");
+ });
+ });
+ });
+ });
+
+ it("finds multiple results in a section", function() {
+ var book = ePub("./fixtures/alice/", {width: 400, height: 400});
+ return book.ready.then(function() {
+ var section = book.section("chapter_001.xhtml");
+ return section.load().then(function() {
+ const queryString = "white rabbit";
+ const findResults = section.find(queryString);
+ const searchResults = section.search(queryString);
+ [findResults , searchResults].forEach( (results)=>{
+ assert.equal(results.length, 2);
+ assert.equal(results[0].cfi, "epubcfi(/6/8[chapter_001]!/4/2/8,/1:240,/1:252)");
+ assert.equal(results[0].excerpt, "...e worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her....");
+ assert.equal(results[1].cfi, "epubcfi(/6/8[chapter_001]!/4/2/20,/1:148,/1:160)");
+ assert.equal(results[1].excerpt, "...ut it was\n\t\tall dark overhead; before her was another long passage and the White Rabbit was still\n\t\tin sight, hurrying down it. There was not a moment...");
+ });
+ });
+ });
+
+ });
+
+ it("finds result that spanning multiple document nodes, tag at ending", function() {
+ var book = ePub("./fixtures/alice/", {width: 400, height: 400});
+ return book.ready.then(function() {
+ var section = book.section("chapter_010.xhtml");
+ return section.load().then(function() {
+ const queryString = "I beg";
+
+ const findResult = section.find(queryString);
+ assert.equal(findResult.length, 0);
+
+ const searchResults = section.search(queryString);
+ assert.equal(searchResults.length, 1);
+ assert.equal(searchResults[0].cfi, "epubcfi(/6/26[chapter_010]!/4/2/6,/1:5,/2/1:3)");
+ assert.equal(searchResults[0].excerpt,'"Oh, I beg');
+ });
+ });
+ });
+
+ it("finds result that spanning multiple document nodes, tag at middle", function() {
+ var book = ePub("./fixtures/alice/", {width: 400, height: 400});
+ return book.ready.then(function() {
+ var section = book.section("chapter_010.xhtml");
+ return section.load().then(function() {
+ const queryString = "I beg your pardon";
+
+ const findResult = section.find(queryString);
+ assert.equal(findResult.length, 0);
+
+ const searchResults = section.search(queryString);
+ assert.equal(searchResults.length, 1);
+ assert.equal(searchResults[0].cfi, "epubcfi(/6/26[chapter_010]!/4/2/6,/1:5,/3:12)");
+ assert.equal(searchResults[0].excerpt,'"Oh, I beg your pardon!" she exclaimed in a tone of great dismay.');
+ });
+ });
+ });
+});
diff --git a/lib/epub.js/types/annotations.d.ts b/lib/epub.js/types/annotations.d.ts
new file mode 100644
index 0000000..718319d
--- /dev/null
+++ b/lib/epub.js/types/annotations.d.ts
@@ -0,0 +1,53 @@
+import Rendition from "./rendition";
+import View from "./managers/view";
+
+export default class Annotations {
+ constructor(rendition: Rendition);
+
+ add(type: string, cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): Annotation;
+
+ remove(cfiRange: string, type: string): void;
+
+ highlight(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
+
+ underline(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
+
+ mark(cfiRange: string, data?: object, cb?: Function): void;
+
+ each(): Array<Annotation>
+
+ private _removeFromAnnotationBySectionIndex(sectionIndex: number, hash: string): void;
+
+ private _annotationsAt(index: number): void;
+
+ private inject(view: View): void;
+
+ private clear(view: View): void;
+}
+
+declare class Annotation {
+ constructor(options: {
+ type: string,
+ cfiRange: string,
+ data?: object,
+ sectionIndex?: number,
+ cb?: Function,
+ className?: string,
+ styles?: object
+ });
+
+ update(data: object): void;
+
+ attach(view: View): any;
+
+ detach(view: View): any;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+}
diff --git a/lib/epub.js/types/archive.d.ts b/lib/epub.js/types/archive.d.ts
new file mode 100644
index 0000000..c705aa4
--- /dev/null
+++ b/lib/epub.js/types/archive.d.ts
@@ -0,0 +1,27 @@
+import JSZip = require('jszip');
+
+export default class Archive {
+ constructor();
+
+ open(input: BinaryType, isBase64?: boolean): Promise<JSZip>;
+
+ openUrl(zipUrl: string, isBase64?: boolean): Promise<JSZip>;
+
+ request(url: string, type?: string): Promise<Blob | string | JSON | Document | XMLDocument>;
+
+ getBlob(url: string, mimeType?: string): Promise<Blob>;
+
+ getText(url: string): Promise<string>;
+
+ getBase64(url: string, mimeType?: string): Promise<string>;
+
+ createUrl(url: string, options: { base64: boolean }): Promise<string>;
+
+ revokeUrl(url: string): void;
+
+ destroy(): void;
+
+ private checkRequirements(): void;
+
+ private handleResponse(response: any, type?: string): Blob | string | JSON | Document | XMLDocument;
+}
diff --git a/lib/epub.js/types/book.d.ts b/lib/epub.js/types/book.d.ts
new file mode 100644
index 0000000..7835053
--- /dev/null
+++ b/lib/epub.js/types/book.d.ts
@@ -0,0 +1,122 @@
+import {
+ PackagingManifestObject,
+ PackagingMetadataObject,
+ PackagingSpineItem,
+ PackagingObject
+} from "./packaging";
+import Rendition, { RenditionOptions } from "./rendition";
+import Section, { SpineItem } from "./section";
+import Archive from "./archive";
+import Navigation from "./navigation";
+import PageList, {PageListItem} from "./pagelist";
+import Spine from "./spine";
+import Locations from "./locations";
+import Url from "./utils/url";
+import Path from "./utils/path";
+import Resources from "./resources";
+import Container from "./container";
+import Packaging from "./packaging";
+import Store from "./store";
+
+export interface BookOptions {
+ requestMethod?: (url: string, type: string, withCredentials: object, headers: object) => Promise<object>;
+ requestCredentials?: object,
+ requestHeaders?: object,
+ encoding?: string,
+ replacements?: string,
+ canonical?: (path: string) => string,
+ openAs?: string,
+ store?: string
+}
+
+export default class Book {
+ constructor(url: string, options?: BookOptions);
+ constructor(options?: BookOptions);
+
+ settings: BookOptions;
+ opening: any; // should be core.defer
+ opened: Promise<Book>;
+ isOpen: boolean;
+ loaded: {
+ metadata: Promise<PackagingMetadataObject>,
+ spine: Promise<SpineItem[]>,
+ manifest: Promise<PackagingManifestObject>,
+ cover: Promise<string>,
+ navigation: Promise<Navigation>,
+ pageList: Promise<PageListItem[]>,
+ resources: Promise<string[]>,
+ }
+ ready: Promise<void>;
+ request: Function;
+ spine: Spine;
+ locations: Locations;
+ navigation: Navigation;
+ pageList: PageList;
+ url: Url;
+ path: Path;
+ archived: boolean;
+ archive: Archive;
+ resources: Resources;
+ rendition: Rendition
+ container: Container;
+ packaging: Packaging;
+ storage: Store;
+
+
+ canonical(path: string): string;
+
+ coverUrl(): Promise<string | null>;
+
+ destroy(): void;
+
+ determineType(input: string): string;
+
+ getRange(cfiRange: string): Promise<Range>;
+
+ key(identifier?: string): string;
+
+ load(path: string): Promise<object>;
+
+ loadNavigation(opf: XMLDocument): Promise<Navigation>;
+
+ open(input: string, what?: string): Promise<object>;
+ open(input: ArrayBuffer, what?: string): Promise<object>;
+
+ openContainer(url: string): Promise<string>;
+
+ openEpub(data: BinaryType, encoding?: string): Promise<Book>;
+
+ openManifest(url: string): Promise<Book>;
+
+ openPackaging(url: string): Promise<Book>;
+
+ renderTo(element: Element, options?: RenditionOptions): Rendition;
+ renderTo(element: string, options?: RenditionOptions): Rendition;
+
+ private replacements(): Promise<void>;
+
+ resolve(path: string, absolute?: boolean): string;
+
+ section(target: string): Section;
+ section(target: number): Section;
+
+ setRequestCredentials(credentials: object): void;
+
+ setRequestHeaders(headers: object): void;
+
+ unarchive(input: BinaryType, encoding?: string): Promise<Archive>;
+
+ store(name: string): Store;
+
+ unpack(opf: XMLDocument): Promise<Book>;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+
+}
diff --git a/lib/epub.js/types/container.d.ts b/lib/epub.js/types/container.d.ts
new file mode 100644
index 0000000..139c941
--- /dev/null
+++ b/lib/epub.js/types/container.d.ts
@@ -0,0 +1,7 @@
+export default class Container {
+ constructor(containerDocument: Document);
+
+ parse(containerDocument: Document): void;
+
+ destroy(): void;
+}
diff --git a/lib/epub.js/types/contents.d.ts b/lib/epub.js/types/contents.d.ts
new file mode 100644
index 0000000..a0bb432
--- /dev/null
+++ b/lib/epub.js/types/contents.d.ts
@@ -0,0 +1,139 @@
+import EpubCFI from "./epubcfi";
+
+export interface ViewportSettings {
+ width: string,
+ height: string,
+ scale: string,
+ scalable: string,
+ minimum: string,
+ maximum: string
+}
+
+export default class Contents {
+ constructor(doc: Document, content: Element, cfiBase: string, sectionIndex: number);
+
+ epubcfi: EpubCFI;
+ document: Document;
+ documentElement: Element;
+ content: Element;
+ window: Window;
+ sectionIndex: number;
+ cfiBase: string;
+
+ static listenedEvents: string[];
+
+ addClass(className: string): void;
+
+ addScript(src: string): Promise<boolean>;
+
+ addStylesheet(src: string): Promise<boolean>;
+
+ addStylesheetRules(rules: Array<object> | object, key: string): Promise<boolean>;
+
+ addStylesheetCss(serializedCss: string, key: string): Promise<boolean>;
+
+ cfiFromNode(node: Node, ignoreClass?: string): string;
+
+ cfiFromRange(range: Range, ignoreClass?: string): string;
+
+ columns(width: number, height: number, columnWidth: number, gap: number, dir: string): void;
+
+ contentHeight(h: number): number;
+
+ contentWidth(w: number): number;
+
+ css(property: string, value: string, priority?: boolean): string;
+
+ destroy(): void;
+
+ direction(dir: string): void;
+
+ fit(width: number, height: number): void;
+
+ height(h: number): number;
+
+ locationOf(target: string | EpubCFI, ignoreClass?: string): Promise<{ top: number, left: number }>;
+
+ map(layout: any): any;
+
+ mapPage(cfiBase: string, layout: object, start: number, end: number, dev: boolean): any;
+
+ overflow(overflow: string): string;
+
+ overflowX(overflow: string): string;
+
+ overflowY(overflow: string): string;
+
+ range(cfi: string, ignoreClass?: string): Range;
+
+ removeClass(className: any): void;
+
+ root(): Element;
+
+ scaler(scale: number, offsetX: number, offsetY: number): void;
+
+ scrollHeight(): number;
+
+ scrollWidth(): number;
+
+ size(width: number, height: number): void;
+
+ textHeight(): number;
+
+ textWidth(): number;
+
+ viewport(options: ViewportSettings): ViewportSettings;
+
+ width(w: number): number;
+
+ writingMode(mode: string): string;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+
+ private addEventListeners(): void;
+
+ private addSelectionListeners(): void;
+
+ private epubReadingSystem(name: string, version: string): object;
+
+ private expand(): void;
+
+ private fontLoadListeners(): void;
+
+ private imageLoadListeners(): void;
+
+ private layoutStyle(style: string): string;
+
+ private linksHandler(): void;
+
+ private listeners(): void;
+
+ private mediaQueryListeners(): void;
+
+ private onSelectionChange(e: Event): void;
+
+ private removeEventListeners(): void;
+
+ private removeListeners(): void;
+
+ private removeSelectionListeners(): void;
+
+ private resizeCheck(): void;
+
+ private resizeListeners(): void;
+
+ private resizeObservers(): void;
+
+ private transitionListeners(): void;
+
+ private triggerEvent(e: Event): void;
+
+ private triggerSelectedEvent(selection: Selection): void;
+}
diff --git a/lib/epub.js/types/core.d.ts b/lib/epub.js/types/core.d.ts
new file mode 100644
index 0000000..1858cd4
--- /dev/null
+++ b/lib/epub.js/types/core.d.ts
@@ -0,0 +1,83 @@
+export module Core {
+
+ export function uuid(): string;
+
+ export function documentHeight(): number;
+
+ export function isElement(obj: object): boolean;
+
+ export function isNumber(n: any): boolean;
+
+ export function isFloat(n: any): boolean;
+
+ export function prefixed(unprefixed: string): string;
+
+ export function defaults(obj: object): object;
+
+ export function extend(target: object): object;
+
+ export function insert(item: any, array: Array<any>, compareFunction: Function): number;
+
+ export function locationOf(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
+
+ export function indexOfSorted(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
+
+ export function bounds(el: Element): { width: Number, height: Number};
+
+ export function borders(el: Element): { width: Number, height: Number};
+
+ export function nodeBounds(node: Node): object;
+
+ export function windowBounds(): { width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number };
+
+ export function indexOfNode(node: Node, typeId: string): number;
+
+ export function indexOfTextNode(textNode: Node): number;
+
+ export function indexOfElementNode(elementNode: Element): number;
+
+ export function isXml(ext: string): boolean;
+
+ export function createBlob(content: any, mime: string): Blob;
+
+ export function createBlobUrl(content: any, mime: string): string;
+
+ export function revokeBlobUrl(url: string): void;
+
+ export function createBase64Url(content: any, mime: string): string
+
+ export function type(obj: object): string;
+
+ export function parse(markup: string, mime: string, forceXMLDom: boolean): Document;
+
+ export function qs(el: Element, sel: string): Element;
+
+ export function qsa(el: Element, sel: string): ArrayLike<Element>;
+
+ export function qsp(el: Element, sel: string, props: Array<object>): ArrayLike<Element>;
+
+ export function sprint(root: Node, func: Function): void;
+
+ export function treeWalker(root: Node, func: Function, filter: object | Function): void;
+
+ export function walk(node: Node, callback: Function): void;
+
+ export function blob2base64(blob: Blob): string;
+
+ export function defer(): Promise<any>;
+
+ export function querySelectorByType(html: Element, element: string, type: string): Array<Element>;
+
+ export function findChildren(el: Element): Array<Element>;
+
+ export function parents(node: Element): Array<Element>;
+
+ export function filterChildren(el: Element, nodeName: string, single: boolean): Array<Element>;
+
+ export function getParentByTagName(node: Element, tagname: string): Array<Element>;
+
+ export class RangeObject extends Range {
+
+ }
+
+}
diff --git a/lib/epub.js/types/epub.d.ts b/lib/epub.js/types/epub.d.ts
new file mode 100644
index 0000000..c87c9de
--- /dev/null
+++ b/lib/epub.js/types/epub.d.ts
@@ -0,0 +1,6 @@
+import Book, { BookOptions } from "./book";
+
+export default Epub;
+
+declare function Epub(urlOrData: string | ArrayBuffer, options?: BookOptions) : Book;
+declare function Epub(options?: BookOptions) : Book;
diff --git a/lib/epub.js/types/epubcfi.d.ts b/lib/epub.js/types/epubcfi.d.ts
new file mode 100644
index 0000000..f9748bb
--- /dev/null
+++ b/lib/epub.js/types/epubcfi.d.ts
@@ -0,0 +1,97 @@
+interface EpubCFISegment {
+ steps: Array<object>,
+ terminal: {
+ offset: number,
+ assertion: string
+ }
+}
+
+interface EpubCFIStep {
+ id: string,
+ tagName: string,
+ type: number,
+ index: number
+}
+
+interface EpubCFIComponent {
+ steps: Array<EpubCFIStep>,
+ terminal: {
+ offset: number,
+ assertion: string
+ }
+}
+
+export default class EpubCFI {
+ constructor(cfiFrom?: string | Range | Node, base?: string | object, ignoreClass?: string);
+
+ base: EpubCFIComponent;
+ spinePos: number;
+ range: boolean;
+
+ isCfiString(str: string): boolean;
+
+ fromNode(anchor: Node, base: string | object, ignoreClass?: string): EpubCFI;
+
+ fromRange(range: Range, base: string | object, ignoreClass?: string): EpubCFI;
+
+ parse(cfiStr: string): EpubCFI;
+
+ collapse(toStart?: boolean): void;
+
+ compare(cfiOne: string | EpubCFI, cfiTwo: string | EpubCFI): number;
+
+ equalStep(stepA: object, stepB: object): boolean;
+
+ filter(anchor: Element, ignoreClass?: string): Element | false;
+
+ toRange(_doc?: Document, ignoreClass?: string): Range;
+
+ toString(): string;
+
+ private filteredStep(node: Node, ignoreClass?: string): any;
+
+ private findNode(steps: Array<EpubCFIStep>, _doc?: Document, ignoreClass?: string): Node;
+
+ private fixMiss(steps: Array<EpubCFIStep>, offset: number, _doc?: Document, ignoreClass?: string): any;
+
+ private checkType(cfi: string | Range | Node): string | false;
+
+ private generateChapterComponent(_spineNodeIndex: number, _pos: number, id: string): string;
+
+ private getChapterComponent(cfiStr: string): string;
+
+ private getCharecterOffsetComponent(cfiStr: string): string;
+
+ private getPathComponent(cfiStr: string): string;
+
+ private getRange(cfiStr: string): string;
+
+ private joinSteps(steps: Array<EpubCFIStep>): Array<EpubCFIStep>;
+
+ private normalizedMap(children: Array<Node>, nodeType: number, ignoreClass?: string): object;
+
+ private parseComponent(componentStr: string): object;
+
+ private parseStep(stepStr: string): object;
+
+ private parseTerminal(termialStr: string): object;
+
+ private patchOffset(anchor: Node, offset: number, ignoreClass?: string): number;
+
+ private pathTo(node: Node, offset: number, ignoreClass?: string): EpubCFISegment;
+
+ private position(anchor: Node): number;
+
+ private segmentString(segment: EpubCFISegment): string;
+
+ private step(node: Node): EpubCFIStep;
+
+ private stepsToQuerySelector(steps: Array<EpubCFIStep>): string;
+
+ private stepsToXpath(steps: Array<EpubCFIStep>): string;
+
+ private textNodes(container: Node, ignoreClass?: string): Array<Node>;
+
+ private walkToNode(steps: Array<EpubCFIStep>, _doc?: Document, ignoreClass?: string): Node;
+
+}
diff --git a/lib/epub.js/types/epubjs-tests.ts b/lib/epub.js/types/epubjs-tests.ts
new file mode 100644
index 0000000..e64bb87
--- /dev/null
+++ b/lib/epub.js/types/epubjs-tests.ts
@@ -0,0 +1,9 @@
+import ePub, { Book } from '../';
+
+function testEpub() {
+ const epub = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub");
+
+ const book = new Book("https://s3.amazonaws.com/moby-dick/moby-dick.epub", {});
+}
+
+testEpub();
diff --git a/lib/epub.js/types/index.d.ts b/lib/epub.js/types/index.d.ts
new file mode 100644
index 0000000..6a8ec9b
--- /dev/null
+++ b/lib/epub.js/types/index.d.ts
@@ -0,0 +1,20 @@
+// Type definitions for epubjs 0.3
+// Project: https://github.com/futurepress/epub.js#readme
+// Definitions by: Fred Chasen <https://github.com/fchasen>
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+import Epub from "./epub";
+
+export as namespace ePub;
+
+export default Epub;
+
+export { default as Book } from './book';
+export { default as EpubCFI } from './epubcfi';
+export { default as Rendition, Location } from './rendition';
+export { default as Contents } from './contents';
+export { default as Layout } from './layout';
+export { NavItem } from './navigation';
+
+declare namespace ePub {
+
+}
diff --git a/lib/epub.js/types/layout.d.ts b/lib/epub.js/types/layout.d.ts
new file mode 100644
index 0000000..04d373d
--- /dev/null
+++ b/lib/epub.js/types/layout.d.ts
@@ -0,0 +1,48 @@
+import Contents from "./contents";
+
+interface LayoutSettings {
+ layout: string,
+ spread: string,
+ minSpreadWidth: number,
+ evenSpreads: boolean
+}
+
+export default class Layout {
+ constructor(settings: LayoutSettings);
+
+ settings: LayoutSettings;
+ name: string;
+ props: {
+ name: string,
+ spread: string,
+ flow: string,
+ width: number,
+ height: number,
+ spreadWidth: number,
+ delta: number,
+ columnWidth: number,
+ gap: number,
+ divisor: number
+ };
+
+ flow(flow: string): string;
+
+ spread(spread: string, min: number): boolean;
+
+ calculate(_width:number, _height:number, _gap?:number): void;
+
+ format(contents: Contents): void | Promise<void>;
+
+ count(totalLength: number, pageLength: number): {spreads: Number, pages: Number};
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+
+ private update(props: object): void;
+}
diff --git a/lib/epub.js/types/locations.d.ts b/lib/epub.js/types/locations.d.ts
new file mode 100644
index 0000000..be314da
--- /dev/null
+++ b/lib/epub.js/types/locations.d.ts
@@ -0,0 +1,41 @@
+import Spine from "./spine";
+import Section from "./section";
+import EpubCFI from "./epubcfi";
+
+export default class Locations {
+ constructor(spine: Spine, request?: Function, pause?: number);
+
+ generate(chars: number): object;
+
+ process(section: Section): Promise<Array<string>>;
+
+ locationFromCfi(cfi: string | EpubCFI): Location;
+
+ percentageFromCfi(cfi: string | EpubCFI): number;
+
+ percentageFromLocation(loc: number): number;
+
+ cfiFromLocation(loc: number): string;
+
+ cfiFromPercentage(percentage: number): string;
+
+ load(locations: string): Array<string>;
+
+ save(): string;
+
+ currentLocation(): Location;
+ currentLocation(curr: string | number): void;
+
+ length(): number;
+
+ destroy(): void;
+
+ private createRange(): {
+ startContainer: Element,
+ startOffset: number,
+ endContainer: Element,
+ endOffset: number
+ };
+
+ private parse(contents: Node, cfiBase: string, chars: number) : Array<string>;
+}
diff --git a/lib/epub.js/types/managers/manager.d.ts b/lib/epub.js/types/managers/manager.d.ts
new file mode 100644
index 0000000..5486fb1
--- /dev/null
+++ b/lib/epub.js/types/managers/manager.d.ts
@@ -0,0 +1,90 @@
+import Section from "../section";
+import Layout from "../layout";
+import Contents from "../contents";
+import View, { ViewSettings } from "./view";
+import { EpubCFIPair } from "../mapping";
+
+export interface ViewLocation {
+ index: number,
+ href: string,
+ pages: number[],
+ totalPages: number,
+ mapping: EpubCFIPair
+}
+
+export interface ManagerOptions extends ViewSettings {
+ infinite?: boolean,
+ overflow?: string,
+ [key: string]: any
+}
+
+export default class Manager {
+ constructor(options: object);
+
+ render(element: Element, size?: { width: Number, height: Number }): void;
+
+ resize(width: Number, height: Number): void;
+
+ onOrientationChange(e: Event): void;
+
+ private createView(section: Section): View;
+
+ display(section: Section, target: string | number): Promise<void>;
+
+ private afterDisplayed(view: View): void;
+
+ private afterResized(view: View): void;
+
+ private moveTo(offset: {top: Number, left: Number}): void;
+
+ private append(section: Section): Promise<void>;
+
+ private prepend(section: Section): Promise<void>;
+
+ next(): Promise<void>;
+
+ prev(): Promise<void>;
+
+ current(): View;
+
+ clear(): void;
+
+ currentLocation(): ViewLocation[];
+
+ visible(): View[];
+
+ private scrollBy(x: number, y: number, silent: boolean): void;
+
+ private scrollTo(x: number, y: number, silent: boolean): void;
+
+ private onScroll(): void;
+
+ bounds(): object;
+
+ applyLayout(layout: Layout): void;
+
+ updateLayout(): void;
+
+ setLayout(layout: Layout): void;
+
+ updateAxis(axis: string, forceUpdate: boolean): void;
+
+ updateFlow(flow: string): void;
+
+ getContents(): Contents[];
+
+ direction(dir: string): void;
+
+ isRendered(): boolean;
+
+ destroy(): void;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+}
diff --git a/lib/epub.js/types/managers/view.d.ts b/lib/epub.js/types/managers/view.d.ts
new file mode 100644
index 0000000..559e954
--- /dev/null
+++ b/lib/epub.js/types/managers/view.d.ts
@@ -0,0 +1,79 @@
+import Section from "../section";
+import Contents from "../contents";
+import Layout from "../layout";
+
+export interface ViewSettings {
+ ignoreClass?: string,
+ axis?: string,
+ flow?: string,
+ layout?: Layout,
+ method?: string,
+ width?: number,
+ height?: number,
+ forceEvenPages?: boolean
+}
+
+export default class View {
+ constructor(section: Section, options: ViewSettings);
+
+ create(): any;
+
+ render(request?: Function, show?: boolean): Promise<void>;
+
+ reset(): void;
+
+ size(_width: Number, _height: Number): void;
+
+ load(content: Contents): Promise<any>;
+
+ setLayout(layout: Layout): void;
+
+ setAxis(axis: string): void;
+
+ display(request?: Function): Promise<any>;
+
+ show(): void;
+
+ hide(): void;
+
+ offset(): { top: Number, left: Number };
+
+ width(): Number;
+
+ height(): Number;
+
+ position(): object;
+
+ locationOf(target: string): { top: Number, left: Number };
+
+ onDisplayed(view: View): void;
+
+ onResize(view: View): void;
+
+ bounds(force?: boolean): object;
+
+ highlight(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
+
+ underline(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
+
+ mark(cfiRange: string, data?: object, cb?: Function): void;
+
+ unhighlight(cfiRange: string): void;
+
+ ununderline(cfiRange: string): void;
+
+ unmark(cfiRange: string): void;
+
+ destroy(): void;
+
+ private onLoad(event: Event, promise: Promise<any>): void;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+}
diff --git a/lib/epub.js/types/mapping.d.ts b/lib/epub.js/types/mapping.d.ts
new file mode 100644
index 0000000..00f6bb4
--- /dev/null
+++ b/lib/epub.js/types/mapping.d.ts
@@ -0,0 +1,34 @@
+import Layout from "./layout";
+import Contents from "./contents";
+
+export interface EpubCFIPair {
+ start: string,
+ end: string
+}
+
+export interface RangePair {
+ start: Range,
+ end: Range
+}
+
+export default class Mapping {
+ constructor(layout: Layout, direction?: string, axis?: string, dev?: boolean);
+
+ page(contents: Contents, cfiBase: string, start: number, end: number): EpubCFIPair;
+
+ axis(axis: string): boolean;
+
+ private walk(root: Node, func: Function);
+
+ private findStart(root: Node, start: number, end: number): Range;
+
+ private findEnd(root: Node, start: number, end: number): Range;
+
+ private findTextStartRange(node: Node, start: number, end: number): Range;
+
+ private findTextEndRange(node: Node, start: number, end: number): Range;
+
+ private splitTextNodeIntoRanges(node: Node, _splitter?: string): Array<Range>;
+
+ private rangePairToCfiPair(cfiBase: string, rangePair: RangePair): EpubCFIPair;
+}
diff --git a/lib/epub.js/types/navigation.d.ts b/lib/epub.js/types/navigation.d.ts
new file mode 100644
index 0000000..8b4f8a0
--- /dev/null
+++ b/lib/epub.js/types/navigation.d.ts
@@ -0,0 +1,46 @@
+export interface NavItem {
+ id: string,
+ href: string,
+ label: string,
+ subitems?: Array<NavItem>,
+ parent?: string
+}
+
+export interface LandmarkItem {
+ href?: string,
+ label?: string,
+ type?: string
+}
+
+export default class Navigation {
+ constructor(xml: XMLDocument);
+
+ toc: Array<NavItem>;
+ landmarks: Array<LandmarkItem>;
+
+ parse(xml: XMLDocument): void;
+
+ get(target: string) : NavItem;
+
+ landmark(type: string) : LandmarkItem;
+
+ load(json: string): Array<NavItem>;
+
+ forEach(fn: (item: NavItem) => {}): any;
+
+ private unpack(toc: Array<NavItem>): void;
+
+ private parseNav(navHtml: XMLDocument): Array<NavItem>;
+
+ private navItem(item: Element): NavItem;
+
+ private parseLandmarks(navHtml: XMLDocument): Array<LandmarkItem>;
+
+ private landmarkItem(item: Element): LandmarkItem;
+
+ private parseNcx(navHtml: XMLDocument): Array<NavItem>;
+
+ private ncxItem(item: Element): NavItem;
+
+ private getByIndex(target: string, index: number, navItems: NavItem[]): NavItem;
+}
diff --git a/lib/epub.js/types/packaging.d.ts b/lib/epub.js/types/packaging.d.ts
new file mode 100644
index 0000000..7151956
--- /dev/null
+++ b/lib/epub.js/types/packaging.d.ts
@@ -0,0 +1,78 @@
+import { SpineItem } from "./section";
+
+export interface PackagingObject {
+ metadata: PackagingMetadataObject,
+ spine: Array<SpineItem>,
+ manifest: PackagingManifestObject,
+ navPath: string,
+ ncxPath: string,
+ coverPath: string,
+ spineNodeIndex: number
+}
+
+export interface PackagingMetadataObject {
+ title: string,
+ creator: string,
+ description: string,
+ pubdate: string,
+ publisher: string,
+ identifier: string,
+ language: string,
+ rights: string,
+ modified_date: string,
+ layout: string,
+ orientation: string,
+ flow: string,
+ viewport: string,
+ spread: string
+}
+
+export interface PackagingSpineItem {
+ idref: string,
+ properties: Array<string>,
+ index: number
+}
+
+export interface PackagingManifestItem {
+ href: string,
+ type: string,
+ properties: Array<string>
+}
+
+export interface PackagingManifestObject {
+ [key: string]: PackagingManifestItem
+}
+
+export default class Packaging {
+ constructor(packageDocument: XMLDocument);
+
+ manifest: PackagingManifestObject;
+ navPath: string;
+ ncxPath: string;
+ coverPath: string;
+ spineNodeIndex: number;
+ spine: Array<PackagingSpineItem>;
+ metadata: PackagingMetadataObject;
+
+ parse(packageDocument: XMLDocument): PackagingObject;
+
+ load(json: string): PackagingObject;
+
+ destroy(): void;
+
+ private parseMetadata(xml: Node): PackagingMetadataObject;
+
+ private parseManifest(xml: Node): PackagingManifestObject;
+
+ private parseSpine(xml: Node, manifest: PackagingManifestObject): Array<PackagingSpineItem>;
+
+ private findNavPath(manifestNode: Node): string | false;
+
+ private findNcxPath(manifestNode: Node, spineNode: Node): string | false;
+
+ private findCoverPath(packageXml: Node): string;
+
+ private getElementText(xml: Node, tag: string): string
+
+ private getPropertyText(xml: Node, property: string): string
+}
diff --git a/lib/epub.js/types/pagelist.d.ts b/lib/epub.js/types/pagelist.d.ts
new file mode 100644
index 0000000..5104098
--- /dev/null
+++ b/lib/epub.js/types/pagelist.d.ts
@@ -0,0 +1,29 @@
+export interface PageListItem {
+ href: string,
+ page: string,
+ cfi?: string,
+ packageUrl?: string
+}
+
+export default class Pagelist {
+ constructor(xml: XMLDocument);
+
+ parse(xml: XMLDocument): Array<PageListItem>;
+
+ pageFromCfi(cfi: string): number;
+
+ cfiFromPage(pg: string | number): string;
+
+ pageFromPercentage(percent: number): number;
+
+ percentageFromPage(pg: number): number;
+
+ destroy(): void;
+
+ private parseNav(navHtml: Node): Array<PageListItem>;
+
+ private item(item: Node): PageListItem;
+
+ private process(pageList: Array<PageListItem>): void;
+
+}
diff --git a/lib/epub.js/types/rendition.d.ts b/lib/epub.js/types/rendition.d.ts
new file mode 100644
index 0000000..434286c
--- /dev/null
+++ b/lib/epub.js/types/rendition.d.ts
@@ -0,0 +1,151 @@
+import Book from "./book";
+import Contents from "./contents";
+import Section from "./section";
+import View from "./managers/view";
+import Hook from "./utils/hook";
+import Themes from "./themes";
+import EpubCFI from "./epubcfi";
+import Annotations from "./annotations";
+import Queue from "./utils/queue";
+
+export interface RenditionOptions {
+ width?: number | string,
+ height?: number | string,
+ ignoreClass?: string,
+ manager?: string | Function | object,
+ view?: string | Function | object,
+ flow?: string,
+ layout?: string,
+ spread?: string,
+ minSpreadWidth?: number,
+ stylesheet?: string,
+ resizeOnOrientationChange?: boolean,
+ script?: string,
+ infinite?: boolean,
+ overflow?: string,
+ snap?: boolean | object,
+ defaultDirection?: string,
+}
+
+export interface DisplayedLocation {
+ index: number,
+ href: string,
+ cfi: string,
+ displayed: {
+ page: number,
+ total: number
+ }
+}
+
+export interface Location {
+ start: DisplayedLocation,
+ end: DisplayedLocation,
+ atStart: boolean,
+ atEnd: boolean
+}
+
+export default class Rendition {
+ constructor(book: Book, options: RenditionOptions);
+
+ settings: RenditionOptions;
+ book: Book;
+ hooks: {
+ display: Hook,
+ serialize: Hook,
+ content: Hook,
+ unloaded: Hook,
+ layout: Hook,
+ render: Hook,
+ show: Hook
+ }
+ themes: Themes;
+ annotations: Annotations;
+ epubcfi: EpubCFI;
+ q: Queue;
+ location: Location;
+ started: Promise<void>;
+
+ adjustImages(contents: Contents): Promise<void>;
+
+ attachTo(element: Element): Promise<void>;
+
+ clear(): void;
+
+ currentLocation(): DisplayedLocation;
+ currentLocation(): Promise<DisplayedLocation>;
+
+ destroy(): void;
+
+ determineLayoutProperties(metadata: object): object;
+
+ direction(dir: string): void;
+
+ display(target?: string): Promise<void>;
+ display(target?: number): Promise<void>;
+
+ flow(flow: string): void;
+
+ getContents(): Contents;
+
+ getRange(cfi: string, ignoreClass?: string): Range;
+
+ handleLinks(contents: Contents): void;
+
+ injectIdentifier(doc: Document, section: Section): void;
+
+ injectScript(doc: Document, section: Section): void;
+
+ injectStylesheet(doc: Document, section: Section): void;
+
+ layout(settings: any): any;
+
+ located(location: Location): DisplayedLocation;
+
+ moveTo(offset: number): void;
+
+ next(): Promise<void>;
+
+ onOrientationChange(orientation: string): void;
+
+ passEvents(contents: Contents): void;
+
+ prev(): Promise<void>;
+
+ reportLocation(): Promise<void>;
+
+ requireManager(manager: string | Function | object): any;
+
+ requireView(view: string | Function | object): any;
+
+ resize(width: number, height: number): void;
+
+ setManager(manager: Function): void;
+
+ spread(spread: string, min?: number): void;
+
+ start(): void;
+
+ views(): Array<View>;
+
+ // Event emitters
+ emit(type: any, ...args: any[]): void;
+
+ off(type: any, listener: any): any;
+
+ on(type: any, listener: any): any;
+
+ once(type: any, listener: any, ...args: any[]): any;
+
+ private triggerMarkEvent(cfiRange: string, data: object, contents: Contents): void;
+
+ private triggerSelectedEvent(cfirange: string, contents: Contents): void;
+
+ private triggerViewEvent(e: Event, contents: Contents): void;
+
+ private onResized(size: { width: number, height: number }): void;
+
+ private afterDisplayed(view: any): void;
+
+ private afterRemoved(view: any): void;
+
+}
diff --git a/lib/epub.js/types/resources.d.ts b/lib/epub.js/types/resources.d.ts
new file mode 100644
index 0000000..f4bfb37
--- /dev/null
+++ b/lib/epub.js/types/resources.d.ts
@@ -0,0 +1,33 @@
+import { PackagingManifestObject } from "./packaging";
+import Archive from "./archive";
+
+export default class Resources {
+ constructor(manifest: PackagingManifestObject, options: {
+ replacements?: string,
+ archive?: Archive,
+ resolver?: Function,
+ request?: Function
+ });
+
+ process(manifest: PackagingManifestObject): void;
+
+ createUrl(url: string): Promise<string>;
+
+ replacements(): Promise<Array<string>>;
+
+ relativeTo(absolute: boolean, resolver?: Function): Array<string>;
+
+ get(path: string): string;
+
+ substitute(content: string, url?: string): string;
+
+ destroy(): void;
+
+ private split(): void;
+
+ private splitUrls(): void;
+
+ private replaceCss(archive: Archive, resolver?: Function): Promise<Array<string>>;
+
+ private createCssFile(href: string): Promise<string>;
+}
diff --git a/lib/epub.js/types/section.d.ts b/lib/epub.js/types/section.d.ts
new file mode 100644
index 0000000..075bef5
--- /dev/null
+++ b/lib/epub.js/types/section.d.ts
@@ -0,0 +1,64 @@
+import { HooksObject } from "./utils/hook";
+
+export interface GlobalLayout {
+ layout: string,
+ spread: string,
+ orientation: string
+}
+
+export interface LayoutSettings {
+ layout: string,
+ spread: string,
+ orientation: string
+}
+
+export interface SpineItem {
+ index: number,
+ cfiBase: string,
+ href?: string,
+ url?: string,
+ canonical?: string,
+ properties?: Array<string>,
+ linear?: string,
+ next: () => SpineItem,
+ prev: () => SpineItem,
+}
+
+export default class Section {
+ constructor(item: SpineItem, hooks: HooksObject);
+
+ idref: string;
+ linear: boolean;
+ properties: Array<string>;
+ index: number;
+ href: string;
+ url: string;
+ canonical: string;
+ next: () => SpineItem;
+ prev: () => SpineItem;
+ cfiBase: string;
+
+ document: Document;
+ contents: Element;
+ output: string;
+
+ hooks: HooksObject;
+
+ load(_request?: Function): Document;
+
+ render(_request?: Function): string;
+
+ find(_query: string): Array<Element>;
+
+ reconcileLayoutSettings(globalLayout: GlobalLayout): LayoutSettings;
+
+ cfiFromRange(_range: Range): string;
+
+ cfiFromElement(el: Element): string;
+
+ unload(): void;
+
+ destroy(): void;
+
+ private base(): void;
+}
diff --git a/lib/epub.js/types/spine.d.ts b/lib/epub.js/types/spine.d.ts
new file mode 100644
index 0000000..6cd59ce
--- /dev/null
+++ b/lib/epub.js/types/spine.d.ts
@@ -0,0 +1,30 @@
+import Packaging from "./packaging";
+import Section from "./section";
+import Hook from "./utils/hook";
+
+export default class Spine {
+ constructor();
+
+ hooks: {
+ serialize: Hook,
+ content: Hook
+ };
+
+ unpack(_package: Packaging, resolver: Function, canonical: Function): void;
+
+ get(target?: string | number): Section;
+
+ each(...args: any[]): any;
+
+ first(): Section;
+
+ last(): Section;
+
+ destroy(): void;
+
+ private append(section: Section): number;
+
+ private prepend(section: Section): number;
+
+ private remove(section: Section): number;
+}
diff --git a/lib/epub.js/types/store.d.ts b/lib/epub.js/types/store.d.ts
new file mode 100644
index 0000000..655a17d
--- /dev/null
+++ b/lib/epub.js/types/store.d.ts
@@ -0,0 +1,30 @@
+import localForage = require('localforage');
+import Resources from "./resources";
+
+export default class Store {
+ constructor(name: string, request?: Function, resolver?: Function);
+
+ add(resources: Resources, force?: boolean): Promise<Array<object>>;
+
+ put(url: string, withCredentials?: boolean, headers?: object): Promise<Blob>;
+
+ request(url: string, type?: string, withCredentials?: boolean, headers?: object): Promise<Blob | string | JSON | Document | XMLDocument>;
+
+ retrieve(url: string, type?: string): Promise<Blob | string | JSON | Document | XMLDocument>;
+
+ getBlob(url: string, mimeType?: string): Promise<Blob>;
+
+ getText(url: string): Promise<string>;
+
+ getBase64(url: string, mimeType?: string): Promise<string>;
+
+ createUrl(url: string, options: { base64: boolean }): Promise<string>;
+
+ revokeUrl(url: string): void;
+
+ destroy(): void;
+
+ private checkRequirements(): void;
+
+ private handleResponse(response: any, type?: string): Blob | string | JSON | Document | XMLDocument;
+}
diff --git a/lib/epub.js/types/themes.d.ts b/lib/epub.js/types/themes.d.ts
new file mode 100644
index 0000000..465a127
--- /dev/null
+++ b/lib/epub.js/types/themes.d.ts
@@ -0,0 +1,40 @@
+import Rendition from "./rendition";
+import Contents from "./contents";
+
+export default class Themes {
+ constructor(rendition: Rendition);
+
+ register( themeObject: object ): void;
+
+ register( theme: string, url: string ): void;
+
+ register( theme: string, themeObject: object ): void;
+
+ default( theme: object | string ): void;
+
+ registerThemes( themes: object ): void;
+
+ registerCss( name: string, css: string ): void;
+
+ registerUrl( name: string, input: string ): void;
+
+ registerRules( name: string, rules: object ): void;
+
+ select( name: string ): void;
+
+ update( name: string ): void;
+
+ inject( content: Contents ): void;
+
+ add( name: string, contents: Contents ): void;
+
+ override(name: string, value: string, priority?: boolean): void;
+
+ overrides(contents: Contents): void;
+
+ fontSize(size: string): void;
+
+ font(f: string): void;
+
+ destroy(): void;
+}
diff --git a/lib/epub.js/types/tsconfig.json b/lib/epub.js/types/tsconfig.json
new file mode 100644
index 0000000..546c5a3
--- /dev/null
+++ b/lib/epub.js/types/tsconfig.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "lib": [
+ "es6",
+ "dom"
+ ],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "baseUrl": "../",
+ "typeRoots": [
+ "../"
+ ],
+ "types": [],
+ "noEmit": true,
+ "forceConsistentCasingInFileNames": true
+ },
+ "files": [
+ "index.d.ts",
+ "epubjs-tests.ts"
+ ]
+}
diff --git a/lib/epub.js/types/tslint.json b/lib/epub.js/types/tslint.json
new file mode 100644
index 0000000..e26ec8f
--- /dev/null
+++ b/lib/epub.js/types/tslint.json
@@ -0,0 +1,4 @@
+{
+ "extends": "dtslint/dt.json",
+ "rules": {}
+}
diff --git a/lib/epub.js/types/utils/constants.d.ts b/lib/epub.js/types/utils/constants.d.ts
new file mode 100644
index 0000000..1c5c5c5
--- /dev/null
+++ b/lib/epub.js/types/utils/constants.d.ts
@@ -0,0 +1,9 @@
+export const EPUBJS_VERSION: string;
+
+export const DOM_EVENTS: Array<string>;
+
+export const EVENTS: {
+ [key: string]: {
+ [key: string]: string
+ }
+}
diff --git a/lib/epub.js/types/utils/core.d.ts b/lib/epub.js/types/utils/core.d.ts
new file mode 100644
index 0000000..6469a66
--- /dev/null
+++ b/lib/epub.js/types/utils/core.d.ts
@@ -0,0 +1,79 @@
+export function uuid(): string;
+
+export function documentHeight(): number;
+
+export function isElement(obj: object): boolean;
+
+export function isNumber(n: any): boolean;
+
+export function isFloat(n: any): boolean;
+
+export function prefixed(unprefixed: string): string;
+
+export function defaults(obj: object): object;
+
+export function extend(target: object): object;
+
+export function insert(item: any, array: Array<any>, compareFunction: Function): number;
+
+export function locationOf(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
+
+export function indexOfSorted(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
+
+export function bounds(el: Element): { width: Number, height: Number};
+
+export function borders(el: Element): { width: Number, height: Number};
+
+export function nodeBounds(node: Node): object;
+
+export function windowBounds(): { width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number };
+
+export function indexOfNode(node: Node, typeId: string): number;
+
+export function indexOfTextNode(textNode: Node): number;
+
+export function indexOfElementNode(elementNode: Element): number;
+
+export function isXml(ext: string): boolean;
+
+export function createBlob(content: any, mime: string): Blob;
+
+export function createBlobUrl(content: any, mime: string): string;
+
+export function revokeBlobUrl(url: string): void;
+
+export function createBase64Url(content: any, mime: string): string
+
+export function type(obj: object): string;
+
+export function parse(markup: string, mime: string, forceXMLDom: boolean): Document;
+
+export function qs(el: Element, sel: string): Element;
+
+export function qsa(el: Element, sel: string): ArrayLike<Element>;
+
+export function qsp(el: Element, sel: string, props: Array<object>): ArrayLike<Element>;
+
+export function sprint(root: Node, func: Function): void;
+
+export function treeWalker(root: Node, func: Function, filter: object | Function): void;
+
+export function walk(node: Node, callback: Function): void;
+
+export function blob2base64(blob: Blob): string;
+
+export function defer(): Promise<any>;
+
+export function querySelectorByType(html: Element, element: string, type: string): Array<Element>;
+
+export function findChildren(el: Element): Array<Element>;
+
+export function parents(node: Element): Array<Element>;
+
+export function filterChildren(el: Element, nodeName: string, single: boolean): Array<Element>;
+
+export function getParentByTagName(node: Element, tagname: string): Array<Element>;
+
+export class RangeObject extends Range {
+
+}
diff --git a/lib/epub.js/types/utils/hook.d.ts b/lib/epub.js/types/utils/hook.d.ts
new file mode 100644
index 0000000..9db1491
--- /dev/null
+++ b/lib/epub.js/types/utils/hook.d.ts
@@ -0,0 +1,18 @@
+interface HooksObject {
+ [key: string]: Hook
+}
+
+export default class Hook {
+ constructor(context: any);
+
+ register(func: Function): void;
+ register(arr: Array<Function>): void;
+
+ deregister(func: Function): void;
+
+ trigger(...args: any[]): Promise<any>;
+
+ list(): Array<any>;
+
+ clear(): void;
+}
diff --git a/lib/epub.js/types/utils/path.d.ts b/lib/epub.js/types/utils/path.d.ts
new file mode 100644
index 0000000..b91e88b
--- /dev/null
+++ b/lib/epub.js/types/utils/path.d.ts
@@ -0,0 +1,17 @@
+export default class Path {
+ constructor(pathString: string);
+
+ parse(what: string): object;
+
+ isAbsolute(what: string): boolean;
+
+ isDirectory(what: string): boolean;
+
+ resolve(what: string): string;
+
+ relative(what: string): string;
+
+ splitPath(filename: string): string;
+
+ toString(): string;
+}
diff --git a/lib/epub.js/types/utils/queue.d.ts b/lib/epub.js/types/utils/queue.d.ts
new file mode 100644
index 0000000..4813ef6
--- /dev/null
+++ b/lib/epub.js/types/utils/queue.d.ts
@@ -0,0 +1,34 @@
+import { defer } from "./core";
+
+export interface QueuedTask {
+ task: any | Task,
+ args: any[],
+ deferred: any, // should be defer, but not working
+ promise: Promise<any>
+}
+
+export default class Queue {
+ constructor(context: any);
+
+ enqueue(func: Promise<Function> | Function, ...args: any[]): Promise<any>;
+
+ dequeue(): Promise<QueuedTask>;
+
+ dump(): void;
+
+ run(): Promise<void>;
+
+ flush(): Promise<void>;
+
+ clear(): void;
+
+ length(): number;
+
+ pause(): void;
+
+ stop(): void;
+}
+
+declare class Task {
+ constructor(task: any, args: any[], context: any);
+}
diff --git a/lib/epub.js/types/utils/replacements.d.ts b/lib/epub.js/types/utils/replacements.d.ts
new file mode 100644
index 0000000..9728ee4
--- /dev/null
+++ b/lib/epub.js/types/utils/replacements.d.ts
@@ -0,0 +1,12 @@
+import Section from "../section";
+import Contents from "../contents";
+
+export function replaceBase(doc: Document, section: Section): void;
+
+export function replaceCanonical(doc: Document, section: Section): void;
+
+export function replaceMeta(doc: Document, section: Section): void;
+
+export function replaceLinks(contents: Contents, fn: Function): void;
+
+export function substitute(contents: Contents, urls: string[], replacements: string[]): void;
diff --git a/lib/epub.js/types/utils/request.d.ts b/lib/epub.js/types/utils/request.d.ts
new file mode 100644
index 0000000..e6c9653
--- /dev/null
+++ b/lib/epub.js/types/utils/request.d.ts
@@ -0,0 +1 @@
+export default function request(url: string, type?: string, withCredentials?: boolean, headers?: object): Promise<Blob | string | JSON | Document | XMLDocument>;
diff --git a/lib/epub.js/types/utils/scrolltype.d.ts b/lib/epub.js/types/utils/scrolltype.d.ts
new file mode 100644
index 0000000..f1dd74f
--- /dev/null
+++ b/lib/epub.js/types/utils/scrolltype.d.ts
@@ -0,0 +1,3 @@
+export default function scrollType(): string;
+
+export function createDefiner(): Node;
diff --git a/lib/epub.js/types/utils/url.d.ts b/lib/epub.js/types/utils/url.d.ts
new file mode 100644
index 0000000..bf30dfb
--- /dev/null
+++ b/lib/epub.js/types/utils/url.d.ts
@@ -0,0 +1,13 @@
+import Path from "./path";
+
+export default class Url {
+ constructor(urlString: string, baseString: string);
+
+ path(): Path;
+
+ resolve(what: string): string;
+
+ relative(what: string): string;
+
+ toString(): string;
+}
diff --git a/lib/epub.js/webpack.config.js b/lib/epub.js/webpack.config.js
new file mode 100644
index 0000000..c5a5ef0
--- /dev/null
+++ b/lib/epub.js/webpack.config.js
@@ -0,0 +1,83 @@
+var webpack = require("webpack");
+var path = require("path");
+var PROD = (process.env.NODE_ENV === "production")
+var LEGACY = (process.env.LEGACY)
+var MINIMIZE = (process.env.MINIMIZE === "true")
+var hostname = "localhost";
+var port = 8080;
+
+var filename = "[name]";
+var sourceMapFilename = "[name]";
+if (LEGACY) {
+ filename += ".legacy";
+}
+if (MINIMIZE) {
+ filename += ".min.js";
+ sourceMapFilename += ".min.js.map";
+} else {
+ filename += ".js";
+ sourceMapFilename += ".js.map";
+}
+
+module.exports = {
+ mode: process.env.NODE_ENV,
+ entry: {
+ "epub": "./src/epub.js",
+ },
+ devtool: MINIMIZE ? false : 'source-map',
+ output: {
+ path: path.resolve("./dist"),
+ filename: filename,
+ sourceMapFilename: sourceMapFilename,
+ library: "ePub",
+ libraryTarget: "umd",
+ libraryExport: "default",
+ publicPath: "/dist/"
+ },
+ optimization: {
+ minimize: MINIMIZE
+ },
+ externals: {
+ "jszip/dist/jszip": "JSZip",
+ "xmldom": "xmldom"
+ },
+ plugins: [],
+ resolve: {
+ alias: {
+ path: "path-webpack"
+ }
+ },
+ devServer: {
+ host: hostname,
+ port: port,
+ inline: true,
+ headers: {
+ "Access-Control-Allow-Origin": "*",
+ "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE",
+ "Access-Control-Allow-Headers": "Content-Type"
+ }
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: "babel-loader",
+ options: {
+ presets: [["@babel/preset-env", {
+ targets: LEGACY ? "defaults" : "last 2 Chrome versions, last 2 Safari versions, last 2 ChromeAndroid versions, last 2 iOS versions, last 2 Firefox versions, last 2 Edge versions",
+ corejs: 3,
+ useBuiltIns: "usage",
+ bugfixes: true,
+ modules: false
+ }]]
+ }
+ }
+ }
+ ]
+ },
+ performance: {
+ hints: false
+ }
+}