From d3e4bb3ed2585859a3adeb7eeff35b7c75ebd840 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 16 Sep 2018 22:40:05 +0200 Subject: auth gate on main app. pull in auth routes from bucky. --- app/client/auth/auth.actions.js | 82 + app/client/auth/auth.gate.js | 41 + app/client/auth/auth.reducer.js | 82 + app/client/auth/index.js | 11 + app/client/auth/login.component.js | 86 + app/client/auth/logout.component.js | 24 + app/client/auth/signup.component.js | 101 + app/client/common/index.js | 3 +- app/client/common/textInput.component.js | 3 + app/client/index.jsx | 27 +- app/client/store.js | 2 + app/client/types.js | 7 + app/server/site.js | 5 +- app/server/util/auth.js | 153 + package-lock.json | 91 + package.json | 4 + public/assets/css/css.css | 19 +- public/bundle.js | 52081 +++++++++++++++-------------- public/bundle.js.map | 2 +- 19 files changed, 28618 insertions(+), 24206 deletions(-) create mode 100644 app/client/auth/auth.actions.js create mode 100644 app/client/auth/auth.gate.js create mode 100644 app/client/auth/auth.reducer.js create mode 100644 app/client/auth/index.js create mode 100644 app/client/auth/login.component.js create mode 100644 app/client/auth/logout.component.js create mode 100644 app/client/auth/signup.component.js create mode 100644 app/server/util/auth.js diff --git a/app/client/auth/auth.actions.js b/app/client/auth/auth.actions.js new file mode 100644 index 0000000..5968f87 --- /dev/null +++ b/app/client/auth/auth.actions.js @@ -0,0 +1,82 @@ +import * as types from '../types'; + +export const setToken = (data) => { + return { type: types.auth.set_token, data } +} +export const setError = (data) => { + return { type: types.auth.set_error, data } +} +export const setCurrentUser = (data) => { + return { type: types.auth.set_current_user, data } +} +export function logout() { + return { type: types.auth.logout_user }; +} +export function authLoading() { + return { type: types.auth.loading }; +} + +export function InvalidCredentialsException(message) { + this.message = message; + this.name = 'InvalidCredentialsException'; +} + +export function login(username, password) { + return (dispatch) => { + dispatch(authLoading()); + apiClient() + .post(api.GET_TOKEN, { + username, + password + }) + .then(function (response) { + dispatch(setToken(response.data.token)); + dispatch(getCurrentUser()); + }) + .catch(function (error) { + dispatch(setError(true)); + if (error.response.status === 400) { + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} + +export function signup(data) { + return (dispatch) => { + dispatch(authLoading()); + apiClient() + .post(api.SIGNUP, data) + .then(function (response) { + console.log(response.data); + dispatch(login(data.username, data.password)); + }) + .catch(function (error) { + console.log(error) + if (error.response.status === 400) { + // dispatch(accountError("There was an error creating your account.")) + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} + +export function getCurrentUser() { + return (dispatch) => { + dispatch(authLoading()); + apiClient() + .get(api.CURRENT_USER) + .then(function (response) { + dispatch(setCurrentUser(response.data)); + console.log('set current user') + }) + .catch(function (error) { + if (error.response.status === 400) { + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} diff --git a/app/client/auth/auth.gate.js b/app/client/auth/auth.gate.js new file mode 100644 index 0000000..e7a9940 --- /dev/null +++ b/app/client/auth/auth.gate.js @@ -0,0 +1,41 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { BrowserRouter, Route } from 'react-router-dom' +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; + +import Login from './login.component'; +import Logout from './logout.component'; +import Signup from './signup.component'; + +import { randint } from '../util/math' + +class AuthGate extends Component { + render(){ + if (this.props.auth.isAuthenticated) return children + return ( + +
+
+ + + + +
+
+ ) + } + componentDidMount(){ + document.querySelector('.spinfx').style.backgroundImage = 'linear-gradient(' + (randint(40)-5) + 'deg, #fde, #ffe)' + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth +}); + +const mapDispatchToProps = (dispatch) => ({ +}); + +export default connect(mapStateToProps, mapDispatchToProps)(AuthGate); diff --git a/app/client/auth/auth.reducer.js b/app/client/auth/auth.reducer.js new file mode 100644 index 0000000..cacb0d5 --- /dev/null +++ b/app/client/auth/auth.reducer.js @@ -0,0 +1,82 @@ +import types from '../types'; + +const authInitialState = { + token: null, + user: {}, + groups: {}, + loading: false, + isAuthenticated: false, +}; + +const auth = (state = authInitialState, action) => { + switch(action.type) { + case types.auth.set_token: + return { + ...state, + token: action.data, + isAuthenticated: !!action.data, + loading: false, + error: null, + }; + + case types.auth.loading: + return { + ...state, + loading: true, + error: null, + }; + + case types.auth.set_current_user: + const groups = {} + action.data.groups.forEach(g => groups[g.name.toLowerCase()] = true) + if (action.data.is_staff) { + groups['staff'] = true + } + if (action.data.is_superuser) { + groups['superuser'] = true + } + return { + ...state, + user: action.data, + groups, + error: null, + }; + + case types.auth.logout_user: + return { + ...authInitialState + }; + + case types.auth.set_error: + return { + ...state, + loading: false, + error: action.data, + } + + case types.auth.loading: + // const initial_state_el = document.querySelector('#initial_state') + // if (initial_state_el) { + // try { + // const initial_state = JSON.parse(initial_state_el.innerHTML) + // if (initial_state && initial_state.auth && initial_state.auth.user) { + // console.log(initial_state.auth.user) + // return { + // ...state, + // user: { + // ...initial_state.auth.user, + // } + // } + // } + // } catch (e) { + // console.error("error loading initial state") + // } + // } + return state; + + default: + return state; + } +} + +export default auth; diff --git a/app/client/auth/index.js b/app/client/auth/index.js new file mode 100644 index 0000000..5e6b2b0 --- /dev/null +++ b/app/client/auth/index.js @@ -0,0 +1,11 @@ +import Gate from './auth.gate'; +import Login from './login.component'; +import Logout from './logout.component'; +import Signup from './signup.component'; + +export default { + Gate, + Login, + Logout, + Signup, +} \ No newline at end of file diff --git a/app/client/auth/login.component.js b/app/client/auth/login.component.js new file mode 100644 index 0000000..4ffab34 --- /dev/null +++ b/app/client/auth/login.component.js @@ -0,0 +1,86 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +// import { Link } from 'react-router-dom'; +import * as authActions from './auth.actions'; + +import { Group, Param, TextInput, Button } from '../common'; + +class Login extends Component { + state = { + username: '', + password: '', + } + constructor() { + super() + this.handleChange = this.handleChange.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + handleChange(e) { + const name = e.target.name + const value = e.target.value + this.setState({ + [name]: value, + error: null, + }) + } + handleSubmit(e) { + e.preventDefault() + this.props.actions.login(this.state.username, this.state.password) + } + render(){ + if (this.props.auth.isAuthenticated) { + return + } + return ( +
+

Log in


+ + + + + {this.renderAuthError()} + +
+ ) + } + renderAuthError(){ + if (this.props.auth.error) { + return ( +
{"There was an error logging you in (bad password?)"}
+ ) + } + return null + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth, +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(authActions, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Login); diff --git a/app/client/auth/logout.component.js b/app/client/auth/logout.component.js new file mode 100644 index 0000000..bcc3bce --- /dev/null +++ b/app/client/auth/logout.component.js @@ -0,0 +1,24 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +import * as authActions from './auth.actions'; + +class Logout extends Component { + componentWillMount(props){ + this.props.actions.logout() + } + render(){ + return + } +} + +const mapStateToProps = (state) => ({ +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(authActions, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Logout); diff --git a/app/client/auth/signup.component.js b/app/client/auth/signup.component.js new file mode 100644 index 0000000..c86d31b --- /dev/null +++ b/app/client/auth/signup.component.js @@ -0,0 +1,101 @@ +import { h, Component } from 'preact'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +import actions from './auth.actions'; + +import { Group, Param, TextInput, Button } from '../common'; + +class Signup extends Component { + state = { + username: '', + password: '', + password2: '', + } + constructor() { + super() + this.handleChange = this.handleChange.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + handleChange(e) { + const name = e.target.name + const value = e.target.value + this.setState({ + [name]: value, + error: null, + }) + } + validate(){ + if (!this.state.password || this.state.password !== this.state.password2) { + return false + } + return true + } + handleSubmit(e) { + e.preventDefault() + if (!this.validate) { + return this.props.actions.setError('bad password') + } + this.props.actions.signup(this.state) + } + render(){ + if (this.props.auth.isAuthenticated) { + return + } + return ( +
+

New account


+ + + + + + {this.renderAuthError()} + +
+ ) + } + renderAuthError(){ + if (this.props.auth.error) { + return ( +
{"Please doublecheck the form"}
+ ) + } + return null + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth, +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators({ ...actions }, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Signup); diff --git a/app/client/common/index.js b/app/client/common/index.js index 7448104..e6baafc 100644 --- a/app/client/common/index.js +++ b/app/client/common/index.js @@ -1,3 +1,4 @@ +import AudioPlayer from './audioPlayer/audioPlayer.component' import AugmentationGrid from './augmentationGrid.component' import Button from './button.component' import ButtonGrid from './buttonGrid.component' @@ -24,7 +25,7 @@ import * as Views from './views' export { Views, - Loading, Progress, Header, + Loading, Progress, Header, AudioPlayer, FolderList, FileList, FileRow, FileUpload, Gallery, Player, Group, ParamGroup, Param, diff --git a/app/client/common/textInput.component.js b/app/client/common/textInput.component.js index d429944..d3b16ad 100644 --- a/app/client/common/textInput.component.js +++ b/app/client/common/textInput.component.js @@ -34,6 +34,9 @@ class TextInput extends Component { value={this.state.changed ? this.state.value : this.props.value} onInput={this.handleInput} onKeydown={this.handleKeydown} + autofocus={this.props.autofocus} + autoComplete={this.props.autocomplete} + autoCapitalize={this.props.autocapitalize || 'off'} placeholder={this.props.placeholder} autofocus={this.props.autofocus} className={this.props.className || ''} diff --git a/app/client/index.jsx b/app/client/index.jsx index fd4679c..614bb35 100644 --- a/app/client/index.jsx +++ b/app/client/index.jsx @@ -7,8 +7,8 @@ import { store, history } from './store' import * as socket from './socket' import util from './util' -import Header from './common/header.component' -import AudioPlayer from './common/audioPlayer/audioPlayer.component' +import Auth from './auth' +import { Header, AudioPlayer } from './common' import System from './system/system.component' import Dashboard from './dashboard/dashboard.component' import modules from './modules' @@ -22,16 +22,19 @@ const module_list = Object.keys(modules).map(name => { const app = ( - -
- - - - {module_list} - - -
-
+ + +
+ + + + + {module_list} + + +
+
+
) diff --git a/app/client/store.js b/app/client/store.js index 8ffab15..654b22d 100644 --- a/app/client/store.js +++ b/app/client/store.js @@ -6,6 +6,7 @@ import createHistory from 'history/createBrowserHistory' import { routerReducer } from 'react-router-redux' // import navReducer from './nav.reducer' +import authReducer from './auth/auth.reducer' import systemReducer from './system/system.reducer' import dashboardReducer from './dashboard/dashboard.reducer' import liveReducer from './live/live.reducer' @@ -15,6 +16,7 @@ import audioPlayerReducer from './common/audioPlayer/audioPlayer.reducer' import { moduleReducer } from './modules/module.reducer' const appReducer = combineReducers({ + auth: authReducer, system: systemReducer, dashboard: dashboardReducer, live: liveReducer, diff --git a/app/client/types.js b/app/client/types.js index 22211dd..44fe434 100644 --- a/app/client/types.js +++ b/app/client/types.js @@ -36,6 +36,13 @@ export default { 'progress', 'epoch', ]), + auth: crud_type('auth', [ + 'set_token', + 'set_error', + 'set_current_user', + 'logout_user', + 'loading', + ]), socket: { connect: 'SOCKET_CONNECT', connect_error: 'SOCKET_CONNECT_ERROR', diff --git a/app/server/site.js b/app/server/site.js index 85c932f..3c58862 100644 --- a/app/server/site.js +++ b/app/server/site.js @@ -2,12 +2,14 @@ const express = require('express') const http = require('http') const path = require('path') const multer = require('multer')() -const upload = require('./util/upload') const bodyParser = require('body-parser') const compression = require('compression') // const multer = require('multer') // const upload = multer({ dest: 'uploads/' }) +const upload = require('./util/upload') +const auth = require('./util/auth') + export const app = new express() export const server = http.createServer(app) @@ -104,6 +106,7 @@ app.get('/:module/:mode/', serve_index) app.get('/system/', serve_index) app.get('/dashboard/', serve_index) app.get('/', serve_index) +auth.route(app, serve_index) server.listen(process.env.EXPRESS_PORT, () => { console.log('Cortex remote listening on http://localhost:' + server.address().port) diff --git a/app/server/util/auth.js b/app/server/util/auth.js new file mode 100644 index 0000000..d280927 --- /dev/null +++ b/app/server/util/auth.js @@ -0,0 +1,153 @@ +let passport = require('passport') +let LocalStrategy = require('passport-local').Strategy +let crypto = require('crypto') +// let fs = require('fs') +let db = require('../db') + +export function route(app, serve_index){ + passport.serializeUser(serializeUser) + passport.deserializeUser(deserializeUser) + passport.use(new LocalStrategy(verifyLocalUser)) + + app.get("/login", serve_index) + app.get("/signup", serve_index) + app.get("/logout", logout) + + app.put("/api/signup", + checkIfUserExists, + createUser, + passport.authenticate("local"), + login) + app.put("/api/login", + passport.authenticate("local"), + login) + app.put("/api/checkin", + ensureAuthenticated, + checkin + ) +} + +export function ensureAuthenticated(req, res, next) { + if (!req.isAuthenticated()) { + req.session.returnTo = req.path + return res.redirect('/login') + } + next() +} + +export function checkIfUserExists(req, res, next) { + db.getUserByUsername(sanitizeName(req.body.username)).then((user) => { + user ? res.json({ error: "user exists" }) : next() + }) +} + +export function sanitizeName(s) { return (s || "").replace(new RegExp("[^-_a-zA-Z0-9]", 'g'), "") } +export function sanitizeUser(req_user) { + // sanitize user object + var user = JSON.parse(JSON.stringify(req_user)) + delete user.password + return user +} + +export function createUser(req, res, next) { + if (req.body.password !== req.body.password2) { + return res.json({ error: "passwords don't match" }) + } + let data = { + username: sanitizeName(req.body.username), + realname: sanitize(req.body.realname), + password: makePassword(username, req.body.password), + firstseen: new Date(), + lastseen: new Date(), + // lastsession: util.now(), + } + db.createUser(data).then(() => next()) +} + +export function login(req, res) { + if (req.isAuthenticated()) { + let returnTo = req.session.returnTo + delete req.session.returnTo + console.log(">> logged in", req.user.get('username')) + return res.json({ + status: "OK", + user: sanitizeUser(req.user), + returnTo: returnTo || "/index", + }) + } + res.json({ + error: 'bad credentials', + }) +} + +export function serializeUser(user, done) { + done(null, user.id) +} + +export function deserializeUser(id, done) { + db.getUser(id).then(function(user){ + done(! user, user) + }) +} + +export function makePassword(password) { + let shasum = crypto.createHash('sha1') + shasum.update(password) + return shasum.digest('hex') +} + +export function validPassword(user, password) { + return user.get('password') === makePassword(password) +} + +export function changePassword(req, res, next) { + if (! req.body.oldpassword && ! req.body.newpassword) return next() + if (req.body.newpassword !== req.body.newpassword2) { + return res.send({ error: 'Passwords don\'t match.' }) + } + if (! validPassword(res.user, req.body.oldpassword)) { + return res.send({ error: 'Password is incorrect.' }) + } + let username = req.user.get('username') + let newPassword = makePassword(username, req.body.newpassword) + res.user.set('password', newPassword) + res.user.save().then(() => next()).catch(err => res.send({ error: err })) +} +export function changePasswordDangerously(req, res, next) { + if (! req.body.password && ! req.body.newpassword) return next() + if (req.body.newpassword !== req.body.newpassword2) { + return res.send({ error: 'Passwords don\'t match.' }) + } + if (! validPassword(req.user, req.body.password)) { + return res.send({ error: 'Password is incorrect.' }) + } + let username = res.user.get('username') + let newPassword = makePassword(username, req.body.newpassword) + res.user.set('password', newPassword) + res.user.save().then(() => next()).catch(err => res.send({ error: err })) +} + +export function verifyLocalUser(username, password, done) { + // handle passwords!! + db.getUserByUsername(username).then(function(user){ + + // if (err) { return done(err) } + if (! user) { return done("no user") } + + // return done(null, user) + if (! user || ! validPassword(user, password)) { + return done(null, false, { error: { message: 'Bad username/password.' } }) + } + return done(null, user) + }) +} + + +export function checkin(req, res) { + res.json({ user: sanitizeUser(req.user) }) +} + +export const logout = (req, res) => { + req.logout() + res.redirect('/') +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b492bc7..b61398d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5467,6 +5467,31 @@ } } }, + "history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", + "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==", + "requires": { + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "resolve-pathname": "^2.2.0", + "value-equal": "^0.4.0", + "warning": "^3.0.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.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==" + }, "jszip": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", @@ -7079,6 +7104,14 @@ } } }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "moment": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz", @@ -7493,6 +7526,41 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" }, + "passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, + "passport.socketio": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/passport.socketio/-/passport.socketio-3.7.0.tgz", + "integrity": "sha1-LuX6/paV1CgcjN3T/pdezRjmcm4=", + "requires": { + "xtend": "^4.0.0" + } + }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "preact": { "version": "8.2.9", "resolved": "https://registry.npmjs.org/preact/-/preact-8.2.9.tgz", @@ -8220,6 +8288,11 @@ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=" }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, "signal-windows": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/signal-windows/-/signal-windows-0.0.1.tgz", @@ -8532,6 +8605,19 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + }, "webm-writer": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/webm-writer/-/webm-writer-0.2.1.tgz", @@ -17677,6 +17763,11 @@ } } }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, "zerorpc": { "version": "0.9.7", "resolved": "https://registry.npmjs.org/zerorpc/-/zerorpc-0.9.7.tgz", diff --git a/package.json b/package.json index 5738dde..88b86ba 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "file-saver": "^1.3.8", "form-data": "^2.3.2", "fs-readdir-promise": "^1.0.1", + "history": "^4.7.2", "jszip": "^3.1.5", "knex": "^0.14.6", "knox": "^0.9.2", @@ -46,6 +47,9 @@ "multer": "^1.3.0", "mysql2": "^1.5.3", "node-fetch": "^2.1.2", + "passport": "^0.4.0", + "passport-local": "^1.0.0", + "passport.socketio": "^3.7.0", "preact": "^8.2.9", "preact-compat": "^3.18.0", "react-redux": "^5.0.7", diff --git a/public/assets/css/css.css b/public/assets/css/css.css index 184445b..2a2e2a9 100644 --- a/public/assets/css/css.css +++ b/public/assets/css/css.css @@ -674,4 +674,21 @@ input.small { background: rgba(238,238,238,0.4); border: 1px solid #bbb; color: #234; -} \ No newline at end of file +} + +.spinfx { + position: fixed; + left: calc(50vw - 30vmin); + top: calc(50vh - 30vmin); + height: 60vmin; + width: 60vmin; + transform-origin: center center; + animation: spinfx 10s infinite; + transform: rotateZ(45deg); + z-index: -1; +} +@keyframes spinfx { + 0% { opacity: 0.9; } + 50% { opacity: 0.5; } + 100% { opacity: 0.9; } +} diff --git a/public/bundle.js b/public/bundle.js index 6710809..85e2795 100644 --- a/public/bundle.js +++ b/public/bundle.js @@ -1921,6 +1921,756 @@ function render(pcm, sr, count, zip) { /***/ }), +/***/ "./app/client/auth/auth.actions.js": +/*!*****************************************!*\ + !*** ./app/client/auth/auth.actions.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setCurrentUser = exports.setError = exports.setToken = undefined; +exports.logout = logout; +exports.authLoading = authLoading; +exports.InvalidCredentialsException = InvalidCredentialsException; +exports.login = login; +exports.signup = signup; +exports.getCurrentUser = getCurrentUser; + +var _types = __webpack_require__(/*! ../types */ "./app/client/types.js"); + +var types = _interopRequireWildcard(_types); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var setToken = exports.setToken = function setToken(data) { + return { type: types.auth.set_token, data: data }; +}; +var setError = exports.setError = function setError(data) { + return { type: types.auth.set_error, data: data }; +}; +var setCurrentUser = exports.setCurrentUser = function setCurrentUser(data) { + return { type: types.auth.set_current_user, data: data }; +}; +function logout() { + return { type: types.auth.logout_user }; +} +function authLoading() { + return { type: types.auth.loading }; +} + +function InvalidCredentialsException(message) { + this.message = message; + this.name = 'InvalidCredentialsException'; +} + +function login(username, password) { + return function (dispatch) { + dispatch(authLoading()); + apiClient().post(api.GET_TOKEN, { + username: username, + password: password + }).then(function (response) { + dispatch(setToken(response.data.token)); + dispatch(getCurrentUser()); + }).catch(function (error) { + dispatch(setError(true)); + if (error.response.status === 400) { + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} + +function signup(data) { + return function (dispatch) { + dispatch(authLoading()); + apiClient().post(api.SIGNUP, data).then(function (response) { + console.log(response.data); + dispatch(login(data.username, data.password)); + }).catch(function (error) { + console.log(error); + if (error.response.status === 400) { + // dispatch(accountError("There was an error creating your account.")) + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} + +function getCurrentUser() { + return function (dispatch) { + dispatch(authLoading()); + apiClient().get(api.CURRENT_USER).then(function (response) { + dispatch(setCurrentUser(response.data)); + console.log('set current user'); + }).catch(function (error) { + if (error.response.status === 400) { + throw new InvalidCredentialsException(error); + } + throw error; + }); + }; +} + +/***/ }), + +/***/ "./app/client/auth/auth.gate.js": +/*!**************************************!*\ + !*** ./app/client/auth/auth.gate.js ***! + \**************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _preact = __webpack_require__(/*! preact */ "./node_modules/preact/dist/preact.esm.js"); + +var _reactRouterDom = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/es/index.js"); + +var _redux = __webpack_require__(/*! redux */ "./node_modules/redux/es/redux.js"); + +var _reactRedux = __webpack_require__(/*! react-redux */ "./node_modules/react-redux/es/index.js"); + +var _login = __webpack_require__(/*! ./login.component */ "./app/client/auth/login.component.js"); + +var _login2 = _interopRequireDefault(_login); + +var _logout = __webpack_require__(/*! ./logout.component */ "./app/client/auth/logout.component.js"); + +var _logout2 = _interopRequireDefault(_logout); + +var _signup = __webpack_require__(/*! ./signup.component */ "./app/client/auth/signup.component.js"); + +var _signup2 = _interopRequireDefault(_signup); + +var _math = __webpack_require__(/*! ../util/math */ "./app/client/util/math.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +// import PropTypes from 'prop-types'; + + +var AuthGate = function (_Component) { + _inherits(AuthGate, _Component); + + function AuthGate() { + _classCallCheck(this, AuthGate); + + return _possibleConstructorReturn(this, (AuthGate.__proto__ || Object.getPrototypeOf(AuthGate)).apply(this, arguments)); + } + + _createClass(AuthGate, [{ + key: 'render', + value: function render() { + if (this.props.auth.isAuthenticated) return children; + return (0, _preact.h)( + _reactRouterDom.BrowserRouter, + null, + (0, _preact.h)( + 'div', + null, + (0, _preact.h)('div', { className: 'spinfx' }), + (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/', component: _login2.default }), + (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/login', component: _login2.default }), + (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/logout', component: _logout2.default }), + (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/signup', component: _signup2.default }) + ) + ); + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + document.querySelector('.spinfx').style.backgroundImage = 'linear-gradient(' + ((0, _math.randint)(40) - 5) + 'deg, #fde, #ffe)'; + } + }]); + + return AuthGate; +}(_preact.Component); + +var mapStateToProps = function mapStateToProps(state) { + return { + auth: state.auth + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return {}; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(AuthGate); + +/***/ }), + +/***/ "./app/client/auth/auth.reducer.js": +/*!*****************************************!*\ + !*** ./app/client/auth/auth.reducer.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _types = __webpack_require__(/*! ../types */ "./app/client/types.js"); + +var _types2 = _interopRequireDefault(_types); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var authInitialState = { + token: null, + user: {}, + groups: {}, + loading: false, + isAuthenticated: false +}; + +var auth = function auth() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : authInitialState; + var action = arguments[1]; + + switch (action.type) { + case _types2.default.auth.set_token: + return _extends({}, state, { + token: action.data, + isAuthenticated: !!action.data, + loading: false, + error: null + }); + + case _types2.default.auth.loading: + return _extends({}, state, { + loading: true, + error: null + }); + + case _types2.default.auth.set_current_user: + var groups = {}; + action.data.groups.forEach(function (g) { + return groups[g.name.toLowerCase()] = true; + }); + if (action.data.is_staff) { + groups['staff'] = true; + } + if (action.data.is_superuser) { + groups['superuser'] = true; + } + return _extends({}, state, { + user: action.data, + groups: groups, + error: null + }); + + case _types2.default.auth.logout_user: + return _extends({}, authInitialState); + + case _types2.default.auth.set_error: + return _extends({}, state, { + loading: false, + error: action.data + }); + + case _types2.default.auth.loading: + // const initial_state_el = document.querySelector('#initial_state') + // if (initial_state_el) { + // try { + // const initial_state = JSON.parse(initial_state_el.innerHTML) + // if (initial_state && initial_state.auth && initial_state.auth.user) { + // console.log(initial_state.auth.user) + // return { + // ...state, + // user: { + // ...initial_state.auth.user, + // } + // } + // } + // } catch (e) { + // console.error("error loading initial state") + // } + // } + return state; + + default: + return state; + } +}; + +exports.default = auth; + +/***/ }), + +/***/ "./app/client/auth/index.js": +/*!**********************************!*\ + !*** ./app/client/auth/index.js ***! + \**********************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _auth = __webpack_require__(/*! ./auth.gate */ "./app/client/auth/auth.gate.js"); + +var _auth2 = _interopRequireDefault(_auth); + +var _login = __webpack_require__(/*! ./login.component */ "./app/client/auth/login.component.js"); + +var _login2 = _interopRequireDefault(_login); + +var _logout = __webpack_require__(/*! ./logout.component */ "./app/client/auth/logout.component.js"); + +var _logout2 = _interopRequireDefault(_logout); + +var _signup = __webpack_require__(/*! ./signup.component */ "./app/client/auth/signup.component.js"); + +var _signup2 = _interopRequireDefault(_signup); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + Gate: _auth2.default, + Login: _login2.default, + Logout: _logout2.default, + Signup: _signup2.default +}; + +/***/ }), + +/***/ "./app/client/auth/login.component.js": +/*!********************************************!*\ + !*** ./app/client/auth/login.component.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _preact = __webpack_require__(/*! preact */ "./node_modules/preact/dist/preact.esm.js"); + +var _redux = __webpack_require__(/*! redux */ "./node_modules/redux/es/redux.js"); + +var _reactRedux = __webpack_require__(/*! react-redux */ "./node_modules/react-redux/es/index.js"); + +var _reactRouterDom = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/es/index.js"); + +var _auth = __webpack_require__(/*! ./auth.actions */ "./app/client/auth/auth.actions.js"); + +var authActions = _interopRequireWildcard(_auth); + +var _common = __webpack_require__(/*! ../common */ "./app/client/common/index.js"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +// import PropTypes from 'prop-types'; + +// import { Link } from 'react-router-dom'; + + +var Login = function (_Component) { + _inherits(Login, _Component); + + function Login() { + _classCallCheck(this, Login); + + var _this = _possibleConstructorReturn(this, (Login.__proto__ || Object.getPrototypeOf(Login)).call(this)); + + _this.state = { + username: '', + password: '' + }; + + _this.handleChange = _this.handleChange.bind(_this); + _this.handleSubmit = _this.handleSubmit.bind(_this); + return _this; + } + + _createClass(Login, [{ + key: 'handleChange', + value: function handleChange(e) { + var _setState; + + var name = e.target.name; + var value = e.target.value; + this.setState((_setState = {}, _defineProperty(_setState, name, value), _defineProperty(_setState, 'error', null), _setState)); + } + }, { + key: 'handleSubmit', + value: function handleSubmit(e) { + e.preventDefault(); + this.props.actions.login(this.state.username, this.state.password); + } + }, { + key: 'render', + value: function render() { + if (this.props.auth.isAuthenticated) { + return (0, _preact.h)(_reactRouterDom.Redirect, { to: '/' }); + } + return (0, _preact.h)( + 'form', + { onSubmit: this.handleSubmit }, + (0, _preact.h)( + 'h1', + null, + 'Log in' + ), + (0, _preact.h)('br', null), + (0, _preact.h)( + _common.Group, + null, + (0, _preact.h)(_common.TextInput, { + autofocus: true, + autocapitalize: 'off', + autocomplete: 'off', + title: 'Username', + name: 'username', + type: 'text', + value: this.state.username, + onChange: this.handleChange + }), + (0, _preact.h)(_common.TextInput, { + title: 'Password', + name: 'password', + type: 'password', + value: this.state.password, + onChange: this.handleChange + }), + (0, _preact.h)( + _common.Button, + { + loading: this.props.auth.loading + }, + 'Login' + ), + this.renderAuthError() + ) + ); + } + }, { + key: 'renderAuthError', + value: function renderAuthError() { + if (this.props.auth.error) { + return (0, _preact.h)( + 'div', + { className: 'form-input-hint' }, + "There was an error logging you in (bad password?)" + ); + } + return null; + } + }]); + + return Login; +}(_preact.Component); + +var mapStateToProps = function mapStateToProps(state) { + return { + auth: state.auth + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + actions: (0, _redux.bindActionCreators)(authActions, dispatch) + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(Login); + +/***/ }), + +/***/ "./app/client/auth/logout.component.js": +/*!*********************************************!*\ + !*** ./app/client/auth/logout.component.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _preact = __webpack_require__(/*! preact */ "./node_modules/preact/dist/preact.esm.js"); + +var _redux = __webpack_require__(/*! redux */ "./node_modules/redux/es/redux.js"); + +var _reactRedux = __webpack_require__(/*! react-redux */ "./node_modules/react-redux/es/index.js"); + +var _reactRouterDom = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/es/index.js"); + +var _auth = __webpack_require__(/*! ./auth.actions */ "./app/client/auth/auth.actions.js"); + +var authActions = _interopRequireWildcard(_auth); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +// import PropTypes from 'prop-types'; + + +var Logout = function (_Component) { + _inherits(Logout, _Component); + + function Logout() { + _classCallCheck(this, Logout); + + return _possibleConstructorReturn(this, (Logout.__proto__ || Object.getPrototypeOf(Logout)).apply(this, arguments)); + } + + _createClass(Logout, [{ + key: 'componentWillMount', + value: function componentWillMount(props) { + this.props.actions.logout(); + } + }, { + key: 'render', + value: function render() { + return (0, _preact.h)(_reactRouterDom.Redirect, { to: '/' }); + } + }]); + + return Logout; +}(_preact.Component); + +var mapStateToProps = function mapStateToProps(state) { + return {}; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + actions: (0, _redux.bindActionCreators)(authActions, dispatch) + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(Logout); + +/***/ }), + +/***/ "./app/client/auth/signup.component.js": +/*!*********************************************!*\ + !*** ./app/client/auth/signup.component.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _preact = __webpack_require__(/*! preact */ "./node_modules/preact/dist/preact.esm.js"); + +var _redux = __webpack_require__(/*! redux */ "./node_modules/redux/es/redux.js"); + +var _reactRedux = __webpack_require__(/*! react-redux */ "./node_modules/react-redux/es/index.js"); + +var _reactRouterDom = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/es/index.js"); + +var _auth = __webpack_require__(/*! ./auth.actions */ "./app/client/auth/auth.actions.js"); + +var _auth2 = _interopRequireDefault(_auth); + +var _common = __webpack_require__(/*! ../common */ "./app/client/common/index.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var Signup = function (_Component) { + _inherits(Signup, _Component); + + function Signup() { + _classCallCheck(this, Signup); + + var _this = _possibleConstructorReturn(this, (Signup.__proto__ || Object.getPrototypeOf(Signup)).call(this)); + + _this.state = { + username: '', + password: '', + password2: '' + }; + + _this.handleChange = _this.handleChange.bind(_this); + _this.handleSubmit = _this.handleSubmit.bind(_this); + return _this; + } + + _createClass(Signup, [{ + key: 'handleChange', + value: function handleChange(e) { + var _setState; + + var name = e.target.name; + var value = e.target.value; + this.setState((_setState = {}, _defineProperty(_setState, name, value), _defineProperty(_setState, 'error', null), _setState)); + } + }, { + key: 'validate', + value: function validate() { + if (!this.state.password || this.state.password !== this.state.password2) { + return false; + } + return true; + } + }, { + key: 'handleSubmit', + value: function handleSubmit(e) { + e.preventDefault(); + if (!this.validate) { + return this.props.actions.setError('bad password'); + } + this.props.actions.signup(this.state); + } + }, { + key: 'render', + value: function render() { + if (this.props.auth.isAuthenticated) { + return (0, _preact.h)(_reactRouterDom.Redirect, { to: '/' }); + } + return (0, _preact.h)( + 'form', + { onSubmit: this.handleSubmit }, + (0, _preact.h)( + 'h1', + null, + 'New account' + ), + (0, _preact.h)('br', null), + (0, _preact.h)( + _common.Group, + null, + (0, _preact.h)(_common.TextInput, { + autofocus: true, + autocapitalize: 'off', + autocomplete: 'off', + title: 'Username', + name: 'username', + type: 'text', + value: this.state.username, + onChange: this.handleChange + }), + (0, _preact.h)(_common.TextInput, { + title: 'Password', + name: 'password', + type: 'password', + value: this.state.password, + onChange: this.handleChange + }), + (0, _preact.h)(_common.TextInput, { + title: 'Password again :)', + name: 'password2', + type: 'password', + value: this.state.password2, + onChange: this.handleChange + }), + (0, _preact.h)( + _common.Button, + { + loading: this.props.auth.loading + }, + 'Login' + ), + this.renderAuthError() + ) + ); + } + }, { + key: 'renderAuthError', + value: function renderAuthError() { + if (this.props.auth.error) { + return (0, _preact.h)( + 'div', + { className: 'form-input-hint' }, + "Please doublecheck the form" + ); + } + return null; + } + }]); + + return Signup; +}(_preact.Component); + +var mapStateToProps = function mapStateToProps(state) { + return { + auth: state.auth + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + actions: (0, _redux.bindActionCreators)(_extends({}, _auth2.default), dispatch) + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(Signup); + +/***/ }), + /***/ "./app/client/common/audioPlayer/audioPlayer.actions.js": /*!**************************************************************!*\ !*** ./app/client/common/audioPlayer/audioPlayer.actions.js ***! @@ -3395,7 +4145,11 @@ exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)( Object.defineProperty(exports, "__esModule", { value: true }); -exports.AugmentationGrid = exports.ButtonGrid = exports.TaskList = exports.CurrentTask = exports.Checkbox = exports.Button = exports.SelectGroup = exports.Select = exports.Slider = exports.NumberInput = exports.TextInput = exports.Param = exports.ParamGroup = exports.Group = exports.Player = exports.Gallery = exports.FileUpload = exports.FileRow = exports.FileList = exports.FolderList = exports.Header = exports.Progress = exports.Loading = exports.Views = undefined; +exports.AugmentationGrid = exports.ButtonGrid = exports.TaskList = exports.CurrentTask = exports.Checkbox = exports.Button = exports.SelectGroup = exports.Select = exports.Slider = exports.NumberInput = exports.TextInput = exports.Param = exports.ParamGroup = exports.Group = exports.Player = exports.Gallery = exports.FileUpload = exports.FileRow = exports.FileList = exports.FolderList = exports.AudioPlayer = exports.Header = exports.Progress = exports.Loading = exports.Views = undefined; + +var _audioPlayer = __webpack_require__(/*! ./audioPlayer/audioPlayer.component */ "./app/client/common/audioPlayer/audioPlayer.component.js"); + +var _audioPlayer2 = _interopRequireDefault(_audioPlayer); var _augmentationGrid = __webpack_require__(/*! ./augmentationGrid.component */ "./app/client/common/augmentationGrid.component.js"); @@ -3495,6 +4249,7 @@ exports.Views = Views; exports.Loading = _loading2.default; exports.Progress = _progress2.default; exports.Header = _header2.default; +exports.AudioPlayer = _audioPlayer2.default; exports.FolderList = _folderList2.default; exports.FileList = _fileList.FileList; exports.FileRow = _fileList.FileRow; @@ -4526,6 +5281,8 @@ var _createClass = function () { function defineProperties(target, props) { for var _preact = __webpack_require__(/*! preact */ "./node_modules/preact/dist/preact.esm.js"); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } @@ -4569,6 +5326,8 @@ var TextInput = function (_Component) { }, { key: 'render', value: function render() { + var _h; + return (0, _preact.h)( 'div', { className: 'textInput param' }, @@ -4580,16 +5339,17 @@ var TextInput = function (_Component) { null, this.props.title ), - (0, _preact.h)('input', { + (0, _preact.h)('input', (_h = { type: this.props.type || 'text', name: this.props.name || 'text', value: this.state.changed ? this.state.value : this.props.value, onInput: this.handleInput, onKeydown: this.handleKeydown, - placeholder: this.props.placeholder, autofocus: this.props.autofocus, - className: this.props.className || '' - }) + autoComplete: this.props.autocomplete, + autoCapitalize: this.props.autocapitalize || 'off', + placeholder: this.props.placeholder + }, _defineProperty(_h, 'autofocus', this.props.autofocus), _defineProperty(_h, 'className', this.props.className || ''), _h)) ) ); } @@ -6431,13 +7191,11 @@ var _util = __webpack_require__(/*! ./util */ "./app/client/util/index.js"); var _util2 = _interopRequireDefault(_util); -var _header = __webpack_require__(/*! ./common/header.component */ "./app/client/common/header.component.js"); - -var _header2 = _interopRequireDefault(_header); +var _auth = __webpack_require__(/*! ./auth */ "./app/client/auth/index.js"); -var _audioPlayer = __webpack_require__(/*! ./common/audioPlayer/audioPlayer.component */ "./app/client/common/audioPlayer/audioPlayer.component.js"); +var _auth2 = _interopRequireDefault(_auth); -var _audioPlayer2 = _interopRequireDefault(_audioPlayer); +var _common = __webpack_require__(/*! ./common */ "./app/client/common/index.js"); var _system = __webpack_require__(/*! ./system/system.component */ "./app/client/system/system.component.js"); @@ -6466,17 +7224,22 @@ var app = (0, _preact.h)( _reactRedux.Provider, { store: _store.store }, (0, _preact.h)( - _reactRouterDom.BrowserRouter, + _auth2.default.Gate, null, (0, _preact.h)( - 'div', + _reactRouterDom.BrowserRouter, null, - (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/', component: _dashboard2.default }), - (0, _preact.h)(_reactRouterDom.Route, { path: '/system/', component: _system2.default }), - (0, _preact.h)(_reactRouterDom.Route, { path: '/dashboard/', component: _dashboard2.default }), - module_list, - (0, _preact.h)(_reactRouterDom.Route, { path: '/', component: _header2.default }), - (0, _preact.h)(_audioPlayer2.default, null) + (0, _preact.h)( + 'div', + null, + (0, _preact.h)(_reactRouterDom.Route, { exact: true, path: '/', component: _dashboard2.default }), + (0, _preact.h)(_reactRouterDom.Route, { path: '/system/', component: _system2.default }), + (0, _preact.h)(_reactRouterDom.Route, { path: '/dashboard/', component: _dashboard2.default }), + (0, _preact.h)(_reactRouterDom.Route, { path: '/logout/', component: _auth2.default.Logout }), + module_list, + (0, _preact.h)(_reactRouterDom.Route, { path: '/', component: _common.Header }), + (0, _preact.h)(_common.AudioPlayer, null) + ) ) ) ); @@ -15565,6 +16328,10 @@ var _createBrowserHistory = __webpack_require__(/*! history/createBrowserHistory var _createBrowserHistory2 = _interopRequireDefault(_createBrowserHistory); +var _auth = __webpack_require__(/*! ./auth/auth.reducer */ "./app/client/auth/auth.reducer.js"); + +var _auth2 = _interopRequireDefault(_auth); + var _system = __webpack_require__(/*! ./system/system.reducer */ "./app/client/system/system.reducer.js"); var _system2 = _interopRequireDefault(_system); @@ -15593,7 +16360,9 @@ var _module = __webpack_require__(/*! ./modules/module.reducer */ "./app/client/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +// import navReducer from './nav.reducer' var appReducer = (0, _redux.combineReducers)({ + auth: _auth2.default, system: _system2.default, dashboard: _dashboard2.default, live: _live2.default, @@ -15604,7 +16373,6 @@ var appReducer = (0, _redux.combineReducers)({ audioPlayer: _audioPlayer2.default }); -// import navReducer from './nav.reducer' var history = exports.history = (0, _createBrowserHistory2.default)(); var store = exports.store = (0, _redux.createStore)(appReducer, (0, _redux.compose)((0, _redux.applyMiddleware)( // createLogger(), @@ -16460,6 +17228,7 @@ exports.default = { folder: (0, _crud.crud_type)('folder', []), file: (0, _crud.crud_type)('file', []), task: (0, _crud.crud_type)('task', ['starting_task', 'stopping_task', 'task_begin', 'task_finish', 'start_queue', 'stop_queue', 'starting_queue', 'stopping_queue', 'progress', 'epoch']), + auth: (0, _crud.crud_type)('auth', ['set_token', 'set_error', 'set_current_user', 'logout_user', 'loading']), socket: { connect: 'SOCKET_CONNECT', connect_error: 'SOCKET_CONNECT_ERROR', @@ -17157,2422 +17926,1763 @@ var orderByFn = exports.orderByFn = function orderByFn() { /***/ }), -/***/ "./node_modules/base64-js/index.js": -/*!*****************************************!*\ - !*** ./node_modules/base64-js/index.js ***! - \*****************************************/ +/***/ "./node_modules/fetch-jsonp/build/fetch-jsonp.js": +/*!*******************************************************!*\ + !*** ./node_modules/fetch-jsonp/build/fetch-jsonp.js ***! + \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i -} - -// Support decoding URL-safe base64 strings, as Node.js does. -// See: https://en.wikipedia.org/wiki/Base64#URL_applications -revLookup['-'.charCodeAt(0)] = 62 -revLookup['_'.charCodeAt(0)] = 63 +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) { + if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports, module], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else { var mod; } +})(this, function (exports, module) { + 'use strict'; -function getLens (b64) { - var len = b64.length + var defaultOptions = { + timeout: 5000, + jsonpCallback: 'callback', + jsonpCallbackFunction: null + }; - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') + function generateCallbackFunction() { + return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000); } - // Trim off extra bytes after placeholder bytes are found - // See: https://github.com/beatgammit/base64-js/issues/42 - var validLen = b64.indexOf('=') - if (validLen === -1) validLen = len - - var placeHoldersLen = validLen === len - ? 0 - : 4 - (validLen % 4) + function clearFunction(functionName) { + // IE8 throws an exception when you try to delete a property on window + // http://stackoverflow.com/a/1824228/751089 + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + } - return [validLen, placeHoldersLen] -} + function removeScript(scriptId) { + var script = document.getElementById(scriptId); + if (script) { + document.getElementsByTagName('head')[0].removeChild(script); + } + } -// base64 is 4/3 + up to two characters of the original data -function byteLength (b64) { - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} + function fetchJsonp(_url) { + var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; -function _byteLength (b64, validLen, placeHoldersLen) { - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} + // to avoid param reassign + var url = _url; + var timeout = options.timeout || defaultOptions.timeout; + var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback; -function toByteArray (b64) { - var tmp - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] + var timeoutId = undefined; - var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + return new Promise(function (resolve, reject) { + var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction(); + var scriptId = jsonpCallback + '_' + callbackFunction; - var curByte = 0 + window[callbackFunction] = function (response) { + resolve({ + ok: true, + // keep consistent with fetch API + json: function json() { + return Promise.resolve(response); + } + }); - // if there are placeholders, only get up to the last complete 4 chars - var len = placeHoldersLen > 0 - ? validLen - 4 - : validLen + if (timeoutId) clearTimeout(timeoutId); - for (var i = 0; i < len; i += 4) { - tmp = - (revLookup[b64.charCodeAt(i)] << 18) | - (revLookup[b64.charCodeAt(i + 1)] << 12) | - (revLookup[b64.charCodeAt(i + 2)] << 6) | - revLookup[b64.charCodeAt(i + 3)] - arr[curByte++] = (tmp >> 16) & 0xFF - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } + removeScript(scriptId); - if (placeHoldersLen === 2) { - tmp = - (revLookup[b64.charCodeAt(i)] << 2) | - (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[curByte++] = tmp & 0xFF - } + clearFunction(callbackFunction); + }; - if (placeHoldersLen === 1) { - tmp = - (revLookup[b64.charCodeAt(i)] << 10) | - (revLookup[b64.charCodeAt(i + 1)] << 4) | - (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } + // Check if the user set their own params, and if not add a ? to start a list of params + url += url.indexOf('?') === -1 ? '?' : '&'; - return arr -} + var jsonpScript = document.createElement('script'); + jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction); + if (options.charset) { + jsonpScript.setAttribute('charset', options.charset); + } + jsonpScript.id = scriptId; + document.getElementsByTagName('head')[0].appendChild(jsonpScript); -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + - lookup[num >> 12 & 0x3F] + - lookup[num >> 6 & 0x3F] + - lookup[num & 0x3F] -} + timeoutId = setTimeout(function () { + reject(new Error('JSONP request to ' + _url + ' timed out')); -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = - ((uint8[i] << 16) & 0xFF0000) + - ((uint8[i + 1] << 8) & 0xFF00) + - (uint8[i + 2] & 0xFF) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} + clearFunction(callbackFunction); + removeScript(scriptId); + window[callbackFunction] = function () { + clearFunction(callbackFunction); + }; + }, timeout); -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 + // Caught if got 404/500 + jsonpScript.onerror = function () { + reject(new Error('JSONP request to ' + _url + ' failed')); - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk( - uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) - )) + clearFunction(callbackFunction); + removeScript(scriptId); + if (timeoutId) clearTimeout(timeoutId); + }; + }); } - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - parts.push( - lookup[tmp >> 2] + - lookup[(tmp << 4) & 0x3F] + - '==' - ) - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + uint8[len - 1] - parts.push( - lookup[tmp >> 10] + - lookup[(tmp >> 4) & 0x3F] + - lookup[(tmp << 2) & 0x3F] + - '=' - ) + // export as global function + /* + let local; + if (typeof global !== 'undefined') { + local = global; + } else if (typeof self !== 'undefined') { + local = self; + } else { + try { + local = Function('return this')(); + } catch (e) { + throw new Error('polyfill failed because global object is unavailable in this environment'); + } } + local.fetchJsonp = fetchJsonp; + */ - return parts.join('') -} - + module.exports = fetchJsonp; +}); /***/ }), -/***/ "./node_modules/buffer/index.js": -/*!**************************************!*\ - !*** ./node_modules/buffer/index.js ***! - \**************************************/ +/***/ "./node_modules/fft.js/lib/fft.js": +/*!****************************************!*\ + !*** ./node_modules/fft.js/lib/fft.js ***! + \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(global) {/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - - - -var base64 = __webpack_require__(/*! base64-js */ "./node_modules/base64-js/index.js") -var ieee754 = __webpack_require__(/*! ieee754 */ "./node_modules/ieee754/index.js") -var isArray = __webpack_require__(/*! isarray */ "./node_modules/buffer/node_modules/isarray/index.js") - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() +function FFT(size) { + this.size = size | 0; + if (this.size <= 1 || (this.size & (this.size - 1)) !== 0) + throw new Error('FFT size must be a power of two and bigger than 1'); -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() + this._csize = size << 1; -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false + // NOTE: Use of `var` is intentional for old V8 versions + var table = new Array(this.size * 2); + for (var i = 0; i < table.length; i += 2) { + const angle = Math.PI * i / this.size; + table[i] = Math.cos(angle); + table[i + 1] = -Math.sin(angle); } -} + this.table = table; -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} + // Find size's power of two + var power = 0; + for (var t = 1; this.size > t; t <<= 1) + power++; -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) + // Calculate initial step's width: + // * If we are full radix-4 - it is 2x smaller to give inital len=8 + // * Otherwise it is the same as `power` to give len=4 + this._width = power % 2 === 0 ? power - 1 : power; + + // Pre-compute bit-reversal patterns + this._bitrev = new Array(1 << this._width); + for (var j = 0; j < this._bitrev.length; j++) { + this._bitrev[j] = 0; + for (var shift = 0; shift < this._width; shift += 2) { + var revShift = this._width - shift - 2; + this._bitrev[j] |= ((j >>> shift) & 3) << revShift; } - that.length = length } - return that + this._out = null; + this._data = null; + this._inv = 0; } +module.exports = FFT; -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ +FFT.prototype.fromComplexArray = function fromComplexArray(complex, storage) { + var res = storage || new Array(complex.length >>> 1); + for (var i = 0; i < complex.length; i += 2) + res[i >>> 1] = complex[i]; + return res; +}; -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) +FFT.prototype.createComplexArray = function createComplexArray() { + const res = new Array(this._csize); + for (var i = 0; i < res.length; i++) + res[i] = 0; + return res; +}; + +FFT.prototype.toComplexArray = function toComplexArray(input, storage) { + var res = storage || this.createComplexArray(); + for (var i = 0; i < res.length; i += 2) { + res[i] = input[i >>> 1]; + res[i + 1] = 0; } + return res; +}; - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) +FFT.prototype.completeSpectrum = function completeSpectrum(spectrum) { + var size = this._csize; + var half = size >>> 1; + for (var i = 2; i < half; i += 2) { + spectrum[size - i] = spectrum[i]; + spectrum[size - i + 1] = -spectrum[i + 1]; } - return from(this, arg, encodingOrOffset, length) -} +}; -Buffer.poolSize = 8192 // not used by this implementation +FFT.prototype.transform = function transform(out, data) { + if (out === data) + throw new Error('Input and output buffers must be different'); -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr -} + this._out = out; + this._data = data; + this._inv = 0; + this._transform4(); + this._out = null; + this._data = null; +}; -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } +FFT.prototype.realTransform = function realTransform(out, data) { + if (out === data) + throw new Error('Input and output buffers must be different'); - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } + this._out = out; + this._data = data; + this._inv = 0; + this._realTransform4(); + this._out = null; + this._data = null; +}; - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } +FFT.prototype.inverseTransform = function inverseTransform(out, data) { + if (out === data) + throw new Error('Input and output buffers must be different'); - return fromObject(that, value) -} + this._out = out; + this._data = data; + this._inv = 1; + this._transform4(); + for (var i = 0; i < out.length; i++) + out[i] /= this.size; + this._out = null; + this._data = null; +}; -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) -} +// radix-4 implementation +// +// NOTE: Uses of `var` are intentional for older V8 version that do not +// support both `let compound assignments` and `const phi` +FFT.prototype._transform4 = function _transform4() { + var out = this._out; + var size = this._csize; -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) + // Initial step (permute and transform) + var width = this._width; + var step = 1 << width; + var len = (size / step) << 1; + + var outOff; + var t; + var bitrev = this._bitrev; + if (len === 4) { + for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { + const off = bitrev[t]; + this._singleTransform2(outOff, off, step); + } + } else { + // len === 8 + for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { + const off = bitrev[t]; + this._singleTransform4(outOff, off, step); + } } -} -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} - -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } + // Loop through steps in decreasing order + var inv = this._inv ? -1 : 1; + var table = this.table; + for (step >>= 2; step >= 2; step >>= 2) { + len = (size / step) << 1; + var quarterLen = len >>> 2; - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) + // Loop through offsets in the data + for (outOff = 0; outOff < size; outOff += len) { + // Full case + var limit = outOff + quarterLen; + for (var i = outOff, k = 0; i < limit; i += 2, k += step) { + const A = i; + const B = A + quarterLen; + const C = B + quarterLen; + const D = C + quarterLen; - var actual = that.write(string, encoding) + // Original values + const Ar = out[A]; + const Ai = out[A + 1]; + const Br = out[B]; + const Bi = out[B + 1]; + const Cr = out[C]; + const Ci = out[C + 1]; + const Dr = out[D]; + const Di = out[D + 1]; - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - that = that.slice(0, actual) - } + // Middle values + const MAr = Ar; + const MAi = Ai; - return that -} + const tableBr = table[k]; + const tableBi = inv * table[k + 1]; + const MBr = Br * tableBr - Bi * tableBi; + const MBi = Br * tableBi + Bi * tableBr; -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that -} + const tableCr = table[2 * k]; + const tableCi = inv * table[2 * k + 1]; + const MCr = Cr * tableCr - Ci * tableCi; + const MCi = Cr * tableCi + Ci * tableCr; -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer + const tableDr = table[3 * k]; + const tableDi = inv * table[3 * k + 1]; + const MDr = Dr * tableDr - Di * tableDi; + const MDi = Dr * tableDi + Di * tableDr; - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } + // Pre-Final values + const T0r = MAr + MCr; + const T0i = MAi + MCi; + const T1r = MAr - MCr; + const T1i = MAi - MCi; + const T2r = MBr + MDr; + const T2i = MBi + MDi; + const T3r = inv * (MBr - MDr); + const T3i = inv * (MBi - MDi); - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } + // Final values + const FAr = T0r + T2r; + const FAi = T0i + T2i; - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } + const FCr = T0r - T2r; + const FCi = T0i - T2i; - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) - } - return that -} + const FBr = T1r + T3i; + const FBi = T1i - T3r; -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) + const FDr = T1r - T3i; + const FDi = T1i + T3r; - if (that.length === 0) { - return that + out[A] = FAr; + out[A + 1] = FAi; + out[B] = FBr; + out[B + 1] = FBi; + out[C] = FCr; + out[C + 1] = FCi; + out[D] = FDr; + out[D + 1] = FDi; + } } - - obj.copy(that, 0, 0, len) - return that } +}; - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } +// radix-2 implementation +// +// NOTE: Only called for len=4 +FFT.prototype._singleTransform2 = function _singleTransform2(outOff, off, + step) { + const out = this._out; + const data = this._data; - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } + const evenR = data[off]; + const evenI = data[off + 1]; + const oddR = data[off + step]; + const oddI = data[off + step + 1]; - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} + const leftR = evenR + oddR; + const leftI = evenI + oddI; + const rightR = evenR - oddR; + const rightI = evenI - oddI; -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} + out[outOff] = leftR; + out[outOff + 1] = leftI; + out[outOff + 2] = rightR; + out[outOff + 3] = rightI; +}; -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} +// radix-4 +// +// NOTE: Only called for len=8 +FFT.prototype._singleTransform4 = function _singleTransform4(outOff, off, + step) { + const out = this._out; + const data = this._data; + const inv = this._inv ? -1 : 1; + const step2 = step * 2; + const step3 = step * 3; -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} + // Original values + const Ar = data[off]; + const Ai = data[off + 1]; + const Br = data[off + step]; + const Bi = data[off + step + 1]; + const Cr = data[off + step2]; + const Ci = data[off + step2 + 1]; + const Dr = data[off + step3]; + const Di = data[off + step3 + 1]; -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } + // Pre-Final values + const T0r = Ar + Cr; + const T0i = Ai + Ci; + const T1r = Ar - Cr; + const T1i = Ai - Ci; + const T2r = Br + Dr; + const T2i = Bi + Di; + const T3r = inv * (Br - Dr); + const T3i = inv * (Bi - Di); - if (a === b) return 0 + // Final values + const FAr = T0r + T2r; + const FAi = T0i + T2i; - var x = a.length - var y = b.length + const FBr = T1r + T3i; + const FBi = T1i - T3r; - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } + const FCr = T0r - T2r; + const FCi = T0i - T2i; - if (x < y) return -1 - if (y < x) return 1 - return 0 -} + const FDr = T1r - T3i; + const FDi = T1i + T3r; -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} + out[outOff] = FAr; + out[outOff + 1] = FAi; + out[outOff + 2] = FBr; + out[outOff + 3] = FBi; + out[outOff + 4] = FCr; + out[outOff + 5] = FCi; + out[outOff + 6] = FDr; + out[outOff + 7] = FDi; +}; -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } +// Real input radix-4 implementation +FFT.prototype._realTransform4 = function _realTransform4() { + var out = this._out; + var size = this._csize; - if (list.length === 0) { - return Buffer.alloc(0) - } + // Initial step (permute and transform) + var width = this._width; + var step = 1 << width; + var len = (size / step) << 1; - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length + var outOff; + var t; + var bitrev = this._bitrev; + if (len === 4) { + for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { + const off = bitrev[t]; + this._singleRealTransform2(outOff, off >>> 1, step >>> 1); } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') + } else { + // len === 8 + for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { + const off = bitrev[t]; + this._singleRealTransform4(outOff, off >>> 1, step >>> 1); } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string } - var len = string.length - if (len === 0) return 0 + // Loop through steps in decreasing order + var inv = this._inv ? -1 : 1; + var table = this.table; + for (step >>= 2; step >= 2; step >>= 2) { + len = (size / step) << 1; + var halfLen = len >>> 1; + var quarterLen = halfLen >>> 1; + var hquarterLen = quarterLen >>> 1; - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength + // Loop through offsets in the data + for (outOff = 0; outOff < size; outOff += len) { + for (var i = 0, k = 0; i <= hquarterLen; i += 2, k += step) { + var A = outOff + i; + var B = A + quarterLen; + var C = B + quarterLen; + var D = C + quarterLen; -function slowToString (encoding, start, end) { - var loweredCase = false + // Original values + var Ar = out[A]; + var Ai = out[A + 1]; + var Br = out[B]; + var Bi = out[B + 1]; + var Cr = out[C]; + var Ci = out[C + 1]; + var Dr = out[D]; + var Di = out[D + 1]; - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. + // Middle values + var MAr = Ar; + var MAi = Ai; - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } + var tableBr = table[k]; + var tableBi = inv * table[k + 1]; + var MBr = Br * tableBr - Bi * tableBi; + var MBi = Br * tableBi + Bi * tableBr; - if (end === undefined || end > this.length) { - end = this.length - } + var tableCr = table[2 * k]; + var tableCi = inv * table[2 * k + 1]; + var MCr = Cr * tableCr - Ci * tableCi; + var MCi = Cr * tableCi + Ci * tableCr; - if (end <= 0) { - return '' - } + var tableDr = table[3 * k]; + var tableDi = inv * table[3 * k + 1]; + var MDr = Dr * tableDr - Di * tableDi; + var MDi = Dr * tableDi + Di * tableDr; - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 + // Pre-Final values + var T0r = MAr + MCr; + var T0i = MAi + MCi; + var T1r = MAr - MCr; + var T1i = MAi - MCi; + var T2r = MBr + MDr; + var T2i = MBi + MDi; + var T3r = inv * (MBr - MDr); + var T3i = inv * (MBi - MDi); - if (end <= start) { - return '' - } + // Final values + var FAr = T0r + T2r; + var FAi = T0i + T2i; - if (!encoding) encoding = 'utf8' + var FBr = T1r + T3i; + var FBi = T1i - T3r; - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) + out[A] = FAr; + out[A + 1] = FAi; + out[B] = FBr; + out[B + 1] = FBi; - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) + // Output final middle point + if (i === 0) { + var FCr = T0r - T2r; + var FCi = T0i - T2i; + out[C] = FCr; + out[C + 1] = FCi; + continue; + } - case 'ascii': - return asciiSlice(this, start, end) + // Do not overwrite ourselves + if (i === hquarterLen) + continue; - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) + // In the flipped case: + // MAi = -MAi + // MBr=-MBi, MBi=-MBr + // MCr=-MCr + // MDr=MDi, MDi=MDr + var ST0r = T1r; + var ST0i = -T1i; + var ST1r = T0r; + var ST1i = -T0i; + var ST2r = -inv * T3i; + var ST2i = -inv * T3r; + var ST3r = -inv * T2i; + var ST3i = -inv * T2r; - case 'base64': - return base64Slice(this, start, end) + var SFAr = ST0r + ST2r; + var SFAi = ST0i + ST2i; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) + var SFBr = ST1r + ST3i; + var SFBi = ST1i - ST3r; - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true + var SA = outOff + quarterLen - i; + var SB = outOff + halfLen - i; + + out[SA] = SFAr; + out[SA + 1] = SFAi; + out[SB] = SFBr; + out[SB + 1] = SFBi; + } } } -} +}; -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true +// radix-2 implementation +// +// NOTE: Only called for len=4 +FFT.prototype._singleRealTransform2 = function _singleRealTransform2(outOff, + off, + step) { + const out = this._out; + const data = this._data; -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} + const evenR = data[off]; + const oddR = data[off + step]; -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} + const leftR = evenR + oddR; + const rightR = evenR - oddR; -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} + out[outOff] = leftR; + out[outOff + 1] = 0; + out[outOff + 2] = rightR; + out[outOff + 3] = 0; +}; -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} +// radix-4 +// +// NOTE: Only called for len=8 +FFT.prototype._singleRealTransform4 = function _singleRealTransform4(outOff, + off, + step) { + const out = this._out; + const data = this._data; + const inv = this._inv ? -1 : 1; + const step2 = step * 2; + const step3 = step * 3; -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} + // Original values + const Ar = data[off]; + const Br = data[off + step]; + const Cr = data[off + step2]; + const Dr = data[off + step3]; -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} + // Pre-Final values + const T0r = Ar + Cr; + const T1r = Ar - Cr; + const T2r = Br + Dr; + const T3r = inv * (Br - Dr); -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} + // Final values + const FAr = T0r + T2r; -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } + const FBr = T1r; + const FBi = -T3r; - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } + const FCr = T0r - T2r; - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } + const FDr = T1r; + const FDi = T3r; - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } + out[outOff] = FAr; + out[outOff + 1] = 0; + out[outOff + 2] = FBr; + out[outOff + 3] = FBi; + out[outOff + 4] = FCr; + out[outOff + 5] = 0; + out[outOff + 6] = FDr; + out[outOff + 7] = FDi; +}; - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - if (this === target) return 0 +/***/ }), - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) +/***/ "./node_modules/file-saver/FileSaver.js": +/*!**********************************************!*\ + !*** ./node_modules/file-saver/FileSaver.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) +var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js + * A saveAs() FileSaver implementation. + * 1.3.2 + * 2016-06-16 18:25:19 + * + * By Eli Grey, http://eligrey.com + * License: MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ - if (x < y) return -1 - if (y < x) return 1 - return 0 -} +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = new MouseEvent("click"); + node.dispatchEvent(event); + } + , is_safari = /constructor/i.test(view.HTMLElement) || view.safari + , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to + , arbitrary_revoke_timeout = 1000 * 40 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + setTimeout(revoker, arbitrary_revoke_timeout); + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , force = type === force_saveable_type + , object_url + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { + // Safari doesn't allow downloading of blob urls + var reader = new FileReader(); + reader.onloadend = function() { + var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); + var popup = view.open(url, '_blank'); + if(!popup) view.location.href = url; + url=undefined; // release reference before dispatching + filesaver.readyState = filesaver.DONE; + dispatch_all(); + }; + reader.readAsDataURL(blob); + filesaver.readyState = filesaver.INIT; + return; + } + // don't create more object URLs than needed + if (!object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (force) { + view.location.href = object_url; + } else { + var opened = view.open(object_url, "_blank"); + if (!opened) { + // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html + view.location.href = object_url; + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + ; + filesaver.readyState = filesaver.INIT; - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (isNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + setTimeout(function() { + save_link.href = object_url; + save_link.download = name; + click(save_link); + dispatch_all(); + revoke(object_url); + filesaver.readyState = filesaver.DONE; + }); + return; + } - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 - } + fs_error(); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name, no_auto_bom) { + return new FileSaver(blob, name || blob.name || "download", no_auto_bom); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name, no_auto_bom) { + name = name || blob.name || "download"; - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } + if (!no_auto_bom) { + blob = auto_bom(blob); + } + return navigator.msSaveOrOpenBlob(blob, name); + }; + } - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } + FS_proto.abort = function(){}; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; - throw new TypeError('val must be string, number or Buffer') -} + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length + return saveAs; +}( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content +)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs; +} else if (("function" !== "undefined" && __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js") !== null) && (__webpack_require__(/*! !webpack amd options */ "./node_modules/webpack/buildin/amd-options.js") !== null)) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() { + return saveAs; + }).call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +} - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } +/***/ }), - return -1 -} +/***/ "./node_modules/history/DOMUtils.js": +/*!******************************************!*\ + !*** ./node_modules/history/DOMUtils.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} +"use strict"; -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } +exports.__esModule = true; +var canUseDOM = exports.canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') +var addEventListener = exports.addEventListener = function addEventListener(node, event, listener) { + return node.addEventListener ? node.addEventListener(event, listener, false) : node.attachEvent('on' + event, listener); +}; - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} +var removeEventListener = exports.removeEventListener = function removeEventListener(node, event, listener) { + return node.removeEventListener ? node.removeEventListener(event, listener, false) : node.detachEvent('on' + event, listener); +}; -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} +var getConfirmation = exports.getConfirmation = function getConfirmation(message, callback) { + return callback(window.confirm(message)); +}; // eslint-disable-line no-alert -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} +/** + * Returns true if the HTML5 history API is supported. Taken from Modernizr. + * + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586 + */ +var supportsHistory = exports.supportsHistory = function supportsHistory() { + var ua = window.navigator.userAgent; -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} + if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} + return window.history && 'pushState' in window.history; +}; -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} +/** + * Returns true if browser fires popstate on hash change. + * IE10 and IE11 do not. + */ +var supportsPopStateOnHashChange = exports.supportsPopStateOnHashChange = function supportsPopStateOnHashChange() { + return window.navigator.userAgent.indexOf('Trident') === -1; +}; -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } +/** + * Returns false if using go(n) with hash history causes a full page reload. + */ +var supportsGoWithoutReloadUsingHash = exports.supportsGoWithoutReloadUsingHash = function supportsGoWithoutReloadUsingHash() { + return window.navigator.userAgent.indexOf('Firefox') === -1; +}; - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining +/** + * Returns true if a given popstate event is an extraneous WebKit event. + * Accounts for the fact that Chrome on iOS fires real popstate events + * containing undefined state when pressing the back button. + */ +var isExtraneousPopstateEvent = exports.isExtraneousPopstateEvent = function isExtraneousPopstateEvent(event) { + return event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1; +}; - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } +/***/ }), - if (!encoding) encoding = 'utf8' +/***/ "./node_modules/history/LocationUtils.js": +/*!***********************************************!*\ + !*** ./node_modules/history/LocationUtils.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) +"use strict"; - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - case 'ascii': - return asciiWrite(this, string, offset, length) +exports.__esModule = true; +exports.locationsAreEqual = exports.createLocation = undefined; - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) +var _resolvePathname = __webpack_require__(/*! resolve-pathname */ "./node_modules/resolve-pathname/index.js"); - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) +var _resolvePathname2 = _interopRequireDefault(_resolvePathname); - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} +var _valueEqual = __webpack_require__(/*! value-equal */ "./node_modules/value-equal/index.js"); -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} +var _valueEqual2 = _interopRequireDefault(_valueEqual); -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} +var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 +var createLocation = exports.createLocation = function createLocation(path, state, key, currentLocation) { + var location = void 0; + if (typeof path === 'string') { + // Two-arg form: push(path, state) + location = (0, _PathUtils.parsePath)(path); + location.state = state; + } else { + // One-arg form: push(location) + location = _extends({}, path); - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint + if (location.pathname === undefined) location.pathname = ''; - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } + if (location.search) { + if (location.search.charAt(0) !== '?') location.search = '?' + location.search; + } else { + location.search = ''; } - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF + if (location.hash) { + if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash; + } else { + location.hash = ''; } - res.push(codePoint) - i += bytesPerSequence + if (state !== undefined && location.state === undefined) location.state = state; } - return decodeCodePointsArray(res) -} + try { + location.pathname = decodeURI(location.pathname); + } catch (e) { + if (e instanceof URIError) { + throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.'); + } else { + throw e; + } + } -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 + if (key) location.key = key; -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + if (currentLocation) { + // Resolve incomplete/relative pathname relative to current location. + if (!location.pathname) { + location.pathname = currentLocation.pathname; + } else if (location.pathname.charAt(0) !== '/') { + location.pathname = (0, _resolvePathname2.default)(location.pathname, currentLocation.pathname); + } + } else { + // When there is no prior location and pathname is empty, set it to / + if (!location.pathname) { + location.pathname = '/'; + } } - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} + return location; +}; -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) +var locationsAreEqual = exports.locationsAreEqual = function locationsAreEqual(a, b) { + return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && (0, _valueEqual2.default)(a.state, b.state); +}; - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} +/***/ }), -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) +/***/ "./node_modules/history/PathUtils.js": +/*!*******************************************!*\ + !*** ./node_modules/history/PathUtils.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} +"use strict"; -function hexSlice (buf, start, end) { - var len = buf.length - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len +exports.__esModule = true; +var addLeadingSlash = exports.addLeadingSlash = function addLeadingSlash(path) { + return path.charAt(0) === '/' ? path : '/' + path; +}; - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} +var stripLeadingSlash = exports.stripLeadingSlash = function stripLeadingSlash(path) { + return path.charAt(0) === '/' ? path.substr(1) : path; +}; -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} +var hasBasename = exports.hasBasename = function hasBasename(path, prefix) { + return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); +}; -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end +var stripBasename = exports.stripBasename = function stripBasename(path, prefix) { + return hasBasename(path, prefix) ? path.substr(prefix.length) : path; +}; - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } +var stripTrailingSlash = exports.stripTrailingSlash = function stripTrailingSlash(path) { + return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path; +}; - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } +var parsePath = exports.parsePath = function parsePath(path) { + var pathname = path || '/'; + var search = ''; + var hash = ''; - if (end < start) end = start + var hashIndex = pathname.indexOf('#'); + if (hashIndex !== -1) { + hash = pathname.substr(hashIndex); + pathname = pathname.substr(0, hashIndex); + } - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] - } + var searchIndex = pathname.indexOf('?'); + if (searchIndex !== -1) { + search = pathname.substr(searchIndex); + pathname = pathname.substr(0, searchIndex); } - return newBuf -} + return { + pathname: pathname, + search: search === '?' ? '' : search, + hash: hash === '#' ? '' : hash + }; +}; -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} +var createPath = exports.createPath = function createPath(location) { + var pathname = location.pathname, + search = location.search, + hash = location.hash; -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } + var path = pathname || '/'; - return val -} + if (search && search !== '?') path += search.charAt(0) === '?' ? search : '?' + search; -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } + if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : '#' + hash; - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } + return path; +}; - return val -} +/***/ }), -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} +/***/ "./node_modules/history/createBrowserHistory.js": +/*!******************************************************!*\ + !*** ./node_modules/history/createBrowserHistory.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} +"use strict"; -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +exports.__esModule = true; - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} +var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +var _warning2 = _interopRequireDefault(_warning); - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 +var _invariant = __webpack_require__(/*! invariant */ "./node_modules/invariant/browser.js"); - if (val >= mul) val -= Math.pow(2, 8 * byteLength) +var _invariant2 = _interopRequireDefault(_invariant); - return val -} +var _LocationUtils = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/LocationUtils.js"); -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 +var _createTransitionManager = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/createTransitionManager.js"); - if (val >= mul) val -= Math.pow(2, 8 * byteLength) +var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); - return val -} +var _DOMUtils = __webpack_require__(/*! ./DOMUtils */ "./node_modules/history/DOMUtils.js"); -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} +var PopStateEvent = 'popstate'; +var HashChangeEvent = 'hashchange'; -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} +var getHistoryState = function getHistoryState() { + try { + return window.history.state || {}; + } catch (e) { + // IE 11 sometimes throws when accessing window.history.state + // See https://github.com/ReactTraining/history/pull/289 + return {}; + } +}; -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +/** + * Creates a history object that uses the HTML5 history API including + * pushState, replaceState, and the popstate event. + */ +var createBrowserHistory = function createBrowserHistory() { + var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} + (0, _invariant2.default)(_DOMUtils.canUseDOM, 'Browser history needs a DOM'); -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) + var globalHistory = window.history; + var canUseHistory = (0, _DOMUtils.supportsHistory)(); + var needsHashChangeListener = !(0, _DOMUtils.supportsPopStateOnHashChange)(); - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} + var _props$forceRefresh = props.forceRefresh, + forceRefresh = _props$forceRefresh === undefined ? false : _props$forceRefresh, + _props$getUserConfirm = props.getUserConfirmation, + getUserConfirmation = _props$getUserConfirm === undefined ? _DOMUtils.getConfirmation : _props$getUserConfirm, + _props$keyLength = props.keyLength, + keyLength = _props$keyLength === undefined ? 6 : _props$keyLength; -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} + var basename = props.basename ? (0, _PathUtils.stripTrailingSlash)((0, _PathUtils.addLeadingSlash)(props.basename)) : ''; -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} + var getDOMLocation = function getDOMLocation(historyState) { + var _ref = historyState || {}, + key = _ref.key, + state = _ref.state; -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} + var _window$location = window.location, + pathname = _window$location.pathname, + search = _window$location.search, + hash = _window$location.hash; -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} + var path = pathname + search + hash; -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } + (0, _warning2.default)(!basename || (0, _PathUtils.hasBasename)(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } + if (basename) path = (0, _PathUtils.stripBasename)(path, basename); - return offset + byteLength -} + return (0, _LocationUtils.createLocation)(path, state, key); + }; -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } + var createKey = function createKey() { + return Math.random().toString(36).substr(2, keyLength); + }; - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } + var transitionManager = (0, _createTransitionManager2.default)(); - return offset + byteLength -} + var setState = function setState(nextState) { + _extends(history, nextState); -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} + history.length = globalHistory.length; -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} + transitionManager.notifyListeners(history.location, history.action); + }; -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} + var handlePopState = function handlePopState(event) { + // Ignore extraneous popstate events in WebKit. + if ((0, _DOMUtils.isExtraneousPopstateEvent)(event)) return; -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} + handlePop(getDOMLocation(event.state)); + }; -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} + var handleHashChange = function handleHashChange() { + handlePop(getDOMLocation(getHistoryState())); + }; -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} + var forceNextPop = false; -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} + var handlePop = function handlePop(location) { + if (forceNextPop) { + forceNextPop = false; + setState(); + } else { + var action = 'POP'; -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (ok) { + setState({ action: action, location: location }); + } else { + revertPop(location); + } + }); + } + }; - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } + var revertPop = function revertPop(fromLocation) { + var toLocation = history.location; - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } + // TODO: We could probably make this more reliable by + // keeping a list of keys we've seen in sessionStorage. + // Instead, we just default to 0 for keys we don't know. - return offset + byteLength -} + var toIndex = allKeys.indexOf(toLocation.key); -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) + if (toIndex === -1) toIndex = 0; - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } + var fromIndex = allKeys.indexOf(fromLocation.key); - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 + if (fromIndex === -1) fromIndex = 0; + + var delta = toIndex - fromIndex; + + if (delta) { + forceNextPop = true; + go(delta); } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } + }; - return offset + byteLength -} + var initialLocation = getDOMLocation(getHistoryState()); + var allKeys = [initialLocation.key]; -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} + // Public interface -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} + var createHref = function createHref(location) { + return basename + (0, _PathUtils.createPath)(location); + }; -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} + var push = function push(path, state) { + (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} + var action = 'PUSH'; + var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} + var href = createHref(location); + var key = location.key, + state = location.state; -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} + if (canUseHistory) { + globalHistory.pushState({ key: key, state: state }, null, href); -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} + if (forceRefresh) { + window.location.href = href; + } else { + var prevIndex = allKeys.indexOf(history.location.key); + var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} + nextKeys.push(location.key); + allKeys = nextKeys; -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} + setState({ action: action, location: location }); + } + } else { + (0, _warning2.default)(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history'); -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} + window.location.href = href; + } + }); + }; -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start + var replace = function replace(path, state) { + (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 + var action = 'REPLACE'; + var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } + var href = createHref(location); + var key = location.key, + state = location.state; - var len = end - start - var i - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } + if (canUseHistory) { + globalHistory.replaceState({ key: key, state: state }, null, href); - return len -} + if (forceRefresh) { + window.location.replace(href); + } else { + var prevIndex = allKeys.indexOf(history.location.key); -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } + if (prevIndex !== -1) allKeys[prevIndex] = location.key; - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } + setState({ action: action, location: location }); + } + } else { + (0, _warning2.default)(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history'); - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 + window.location.replace(href); + } + }); + }; - if (!val) val = 0 + var go = function go(n) { + globalHistory.go(n); + }; - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } + var goBack = function goBack() { + return go(-1); + }; - return this -} + var goForward = function goForward() { + return go(1); + }; -// HELPER FUNCTIONS -// ================ + var listenerCount = 0; -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + var checkDOMListeners = function checkDOMListeners(delta) { + listenerCount += delta; -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} + if (listenerCount === 1) { + (0, _DOMUtils.addEventListener)(window, PopStateEvent, handlePopState); -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} + if (needsHashChangeListener) (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleHashChange); + } else if (listenerCount === 0) { + (0, _DOMUtils.removeEventListener)(window, PopStateEvent, handlePopState); -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} + if (needsHashChangeListener) (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleHashChange); + } + }; -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] + var isBlocked = false; - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) + var block = function block() { + var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } + var unblock = transitionManager.setPrompt(prompt); - // valid lead - leadSurrogate = codePoint + if (!isBlocked) { + checkDOMListeners(1); + isBlocked = true; + } - continue + return function () { + if (isBlocked) { + isBlocked = false; + checkDOMListeners(-1); } - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } + return unblock(); + }; + }; - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } + var listen = function listen(listener) { + var unlisten = transitionManager.appendListener(listener); + checkDOMListeners(1); - leadSurrogate = null + return function () { + checkDOMListeners(-1); + unlisten(); + }; + }; - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } + var history = { + length: globalHistory.length, + action: 'POP', + location: initialLocation, + createHref: createHref, + push: push, + replace: replace, + go: go, + goBack: goBack, + goForward: goForward, + block: block, + listen: listen + }; - return bytes -} + return history; +}; -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} +exports.default = createBrowserHistory; -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break +/***/ }), - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } +/***/ "./node_modules/history/createTransitionManager.js": +/*!*********************************************************!*\ + !*** ./node_modules/history/createTransitionManager.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - return byteArray -} +"use strict"; -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} +exports.__esModule = true; -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} +var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"))) +var _warning2 = _interopRequireDefault(_warning); -/***/ }), +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/***/ "./node_modules/buffer/node_modules/isarray/index.js": -/*!***********************************************************!*\ - !*** ./node_modules/buffer/node_modules/isarray/index.js ***! - \***********************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { +var createTransitionManager = function createTransitionManager() { + var prompt = null; -var toString = {}.toString; + var setPrompt = function setPrompt(nextPrompt) { + (0, _warning2.default)(prompt == null, 'A history supports only one prompt at a time'); -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; + prompt = nextPrompt; + return function () { + if (prompt === nextPrompt) prompt = null; + }; + }; -/***/ }), + var confirmTransitionTo = function confirmTransitionTo(location, action, getUserConfirmation, callback) { + // TODO: If another transition starts while we're still confirming + // the previous one, we may end up in a weird state. Figure out the + // best way to handle this. + if (prompt != null) { + var result = typeof prompt === 'function' ? prompt(location, action) : prompt; -/***/ "./node_modules/core-util-is/lib/util.js": -/*!***********************************************!*\ - !*** ./node_modules/core-util-is/lib/util.js ***! - \***********************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof result === 'string') { + if (typeof getUserConfirmation === 'function') { + getUserConfirmation(result, callback); + } else { + (0, _warning2.default)(false, 'A history needs a getUserConfirmation function in order to use a prompt message'); -/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + callback(true); + } + } else { + // Return false from a transition hook to cancel the transition. + callback(result !== false); + } + } else { + callback(true); + } + }; -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. + var listeners = []; -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; + var appendListener = function appendListener(fn) { + var isActive = true; -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; + var listener = function listener() { + if (isActive) fn.apply(undefined, arguments); + }; -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; + listeners.push(listener); -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; + return function () { + isActive = false; + listeners = listeners.filter(function (item) { + return item !== listener; + }); + }; + }; -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; + var notifyListeners = function notifyListeners() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; + listeners.forEach(function (listener) { + return listener.apply(undefined, args); + }); + }; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; + return { + setPrompt: setPrompt, + confirmTransitionTo: confirmTransitionTo, + appendListener: appendListener, + notifyListeners: notifyListeners + }; +}; -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; +exports.default = createTransitionManager; -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; +/***/ }), -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; +/***/ "./node_modules/invariant/browser.js": +/*!*******************************************!*\ + !*** ./node_modules/invariant/browser.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ -exports.isBuffer = Buffer.isBuffer; +var invariant = function(condition, format, a, b, c, d, e, f) { + if (true) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } -function objectToString(o) { - return Object.prototype.toString.call(o); -} + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; + } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer)) + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +}; -/***/ }), +module.exports = invariant; -/***/ "./node_modules/events/events.js": -/*!***************************************!*\ - !*** ./node_modules/events/events.js ***! - \***************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +/***/ }), -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; +/***/ "./node_modules/jszip/lib/base64.js": +/*!******************************************!*\ + !*** ./node_modules/jszip/lib/base64.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; +"use strict"; -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); +// private property +var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; +// public method for encoding +exports.encode = function(input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0, len = input.length, remainingBytes = len; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; + var isArray = utils.getTypeOf(input) !== "string"; + while (i < input.length) { + remainingBytes = len - i; - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } + if (!isArray) { + chr1 = input.charCodeAt(i++); + chr2 = i < len ? input.charCodeAt(i++) : 0; + chr3 = i < len ? input.charCodeAt(i++) : 0; + } else { + chr1 = input[i++]; + chr2 = i < len ? input[i++] : 0; + chr3 = i < len ? input[i++] : 0; + } - handler = this._events[type]; + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64; + enc4 = remainingBytes > 2 ? (chr3 & 63) : 64; - if (isUndefined(handler)) - return false; + output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)); - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - return true; + return output.join(""); }; -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +// public method for decoding +exports.decode = function(input) { + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0, resultIndex = 0; - if (!this._events) - this._events = {}; + var dataUrlPrefix = "data:"; - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); + if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { + // This is a common error: people give a data url + // (data:image/png;base64,iVBOR...) with a {base64: true} and + // wonders why things don't work. + // We can detect that the string input looks like a data url but we + // *can't* be sure it is one: removing everything up to the comma would + // be too dangerous. + throw new Error("Invalid base64 input, it looks like a data url."); + } - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; + var totalLength = input.length * 3 / 4; + if(input.charAt(input.length - 1) === _keyStr.charAt(64)) { + totalLength--; } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } + if(input.charAt(input.length - 2) === _keyStr.charAt(64)) { + totalLength--; } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); + if (totalLength % 1 !== 0) { + // totalLength is not an integer, the length does not match a valid + // base64 content. That can happen if: + // - the input is not a base64 content + // - the input is *almost* a base64 content, with a extra chars at the + // beginning or at the end + // - the input uses a base64 variant (base64url for example) + throw new Error("Invalid base64 input, bad content length."); + } + var output; + if (support.uint8array) { + output = new Uint8Array(totalLength|0); + } else { + output = new Array(totalLength|0); } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - if (!this._events || !this._events[type]) - return this; + while (i < input.length) { - list = this._events[type]; - length = list.length; - position = -1; + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } + output[resultIndex++] = chr1; - if (position < 0) - return this; + if (enc3 !== 64) { + output[resultIndex++] = chr2; + } + if (enc4 !== 64) { + output[resultIndex++] = chr3; + } - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); } - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; + return output; }; -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } +/***/ }), - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } +/***/ "./node_modules/jszip/lib/compressedObject.js": +/*!****************************************************!*\ + !*** ./node_modules/jszip/lib/compressedObject.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - listeners = this._events[type]; +"use strict"; - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - return this; -}; +var external = __webpack_require__(/*! ./external */ "./node_modules/jszip/lib/external.js"); +var DataWorker = __webpack_require__(/*! ./stream/DataWorker */ "./node_modules/jszip/lib/stream/DataWorker.js"); +var DataLengthProbe = __webpack_require__(/*! ./stream/DataLengthProbe */ "./node_modules/jszip/lib/stream/DataLengthProbe.js"); +var Crc32Probe = __webpack_require__(/*! ./stream/Crc32Probe */ "./node_modules/jszip/lib/stream/Crc32Probe.js"); +var DataLengthProbe = __webpack_require__(/*! ./stream/DataLengthProbe */ "./node_modules/jszip/lib/stream/DataLengthProbe.js"); -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; +/** + * Represent a compressed object, with everything needed to decompress it. + * @constructor + * @param {number} compressedSize the size of the data compressed. + * @param {number} uncompressedSize the size of the data after decompression. + * @param {number} crc32 the crc32 of the decompressed file. + * @param {object} compression the type of compression, see lib/compressions.js. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. + */ +function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) { + this.compressedSize = compressedSize; + this.uncompressedSize = uncompressedSize; + this.crc32 = crc32; + this.compression = compression; + this.compressedContent = data; +} -EventEmitter.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; +CompressedObject.prototype = { + /** + * Create a worker to get the uncompressed content. + * @return {GenericWorker} the worker. + */ + getContentWorker : function () { + var worker = new DataWorker(external.Promise.resolve(this.compressedContent)) + .pipe(this.compression.uncompressWorker()) + .pipe(new DataLengthProbe("data_length")); - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; - } - return 0; + var that = this; + worker.on("end", function () { + if(this.streamInfo['data_length'] !== that.uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + }); + return worker; + }, + /** + * Create a worker to get the compressed content. + * @return {GenericWorker} the worker. + */ + getCompressedWorker : function () { + return new DataWorker(external.Promise.resolve(this.compressedContent)) + .withStreamInfo("compressedSize", this.compressedSize) + .withStreamInfo("uncompressedSize", this.uncompressedSize) + .withStreamInfo("crc32", this.crc32) + .withStreamInfo("compression", this.compression) + ; + } }; -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); +/** + * Chain the given worker with other workers to compress the content with the + * given compresion. + * @param {GenericWorker} uncompressedWorker the worker to pipe. + * @param {Object} compression the compression object. + * @param {Object} compressionOptions the options to use when compressing. + * @return {GenericWorker} the new worker compressing the content. + */ +CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) { + return uncompressedWorker + .pipe(new Crc32Probe()) + .pipe(new DataLengthProbe("uncompressedSize")) + .pipe(compression.compressWorker(compressionOptions)) + .pipe(new DataLengthProbe("compressedSize")) + .withStreamInfo("compression", compression); }; -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} +module.exports = CompressedObject; /***/ }), -/***/ "./node_modules/fbjs/lib/emptyFunction.js": +/***/ "./node_modules/jszip/lib/compressions.js": /*!************************************************!*\ - !*** ./node_modules/fbjs/lib/emptyFunction.js ***! + !*** ./node_modules/jszip/lib/compressions.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { @@ -19580,5050 +19690,6404 @@ function isUndefined(arg) { "use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * - */ - -function makeEmptyFunction(arg) { - return function () { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -var emptyFunction = function emptyFunction() {}; +var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function () { - return this; -}; -emptyFunction.thatReturnsArgument = function (arg) { - return arg; +exports.STORE = { + magic: "\x00\x00", + compressWorker : function (compressionOptions) { + return new GenericWorker("STORE compression"); + }, + uncompressWorker : function () { + return new GenericWorker("STORE decompression"); + } }; +exports.DEFLATE = __webpack_require__(/*! ./flate */ "./node_modules/jszip/lib/flate.js"); -module.exports = emptyFunction; /***/ }), -/***/ "./node_modules/fbjs/lib/invariant.js": -/*!********************************************!*\ - !*** ./node_modules/fbjs/lib/invariant.js ***! - \********************************************/ +/***/ "./node_modules/jszip/lib/crc32.js": +/*!*****************************************!*\ + !*** ./node_modules/jszip/lib/crc32.js ***! + \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); /** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. + * The following functions come from pako, from pako/lib/zlib/crc32.js + * released under the MIT license, see pako https://github.com/nodeca/pako/ */ -var validateFormat = function validateFormat(format) {}; - -if (true) { - validateFormat = function validateFormat(format) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - }; -} - -function invariant(condition, format, a, b, c, d, e, f) { - validateFormat(format); +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; - if (!condition) { - var error; - if (format === undefined) { - error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error(format.replace(/%s/g, function () { - return args[argIndex++]; - })); - error.name = 'Invariant Violation'; + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; } - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } + return table; } -module.exports = invariant; +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); -/***/ }), -/***/ "./node_modules/fbjs/lib/warning.js": -/*!******************************************!*\ - !*** ./node_modules/fbjs/lib/warning.js ***! - \******************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { +function crc32(crc, buf, len, pos) { + var t = crcTable, end = pos + len; -"use strict"; -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ + crc = crc ^ (-1); + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + return (crc ^ (-1)); // >>> 0; +} -var emptyFunction = __webpack_require__(/*! ./emptyFunction */ "./node_modules/fbjs/lib/emptyFunction.js"); +// That's all for the pako functions. /** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. + * Compute the crc32 of a string. + * This is almost the same as the function crc32, but for strings. Using the + * same function for the two use cases leads to horrible performances. + * @param {Number} crc the starting value of the crc. + * @param {String} str the string to use. + * @param {Number} len the length of the string. + * @param {Number} pos the starting position for the crc32 computation. + * @return {Number} the computed crc32. */ +function crc32str(crc, str, len, pos) { + var t = crcTable, end = pos + len; -var warning = emptyFunction; + crc = crc ^ (-1); -if (true) { - var printWarning = function printWarning(format) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF]; } - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function () { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - warning = function warning(condition, format) { - if (format === undefined) { - throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); - } + return (crc ^ (-1)); // >>> 0; +} - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. +module.exports = function crc32wrapper(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; } - if (!condition) { - for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { - args[_key2 - 2] = arguments[_key2]; - } + var isArray = utils.getTypeOf(input) !== "string"; - printWarning.apply(undefined, [format].concat(args)); + if(isArray) { + return crc32(crc|0, input, input.length, 0); + } else { + return crc32str(crc|0, input, input.length, 0); } - }; -} +}; -module.exports = warning; /***/ }), -/***/ "./node_modules/fetch-jsonp/build/fetch-jsonp.js": -/*!*******************************************************!*\ - !*** ./node_modules/fetch-jsonp/build/fetch-jsonp.js ***! - \*******************************************************/ +/***/ "./node_modules/jszip/lib/defaults.js": +/*!********************************************!*\ + !*** ./node_modules/jszip/lib/defaults.js ***! + \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) { - if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports, module], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { var mod; } -})(this, function (exports, module) { - 'use strict'; +"use strict"; - var defaultOptions = { - timeout: 5000, - jsonpCallback: 'callback', - jsonpCallbackFunction: null - }; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = true; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; - function generateCallbackFunction() { - return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000); - } - function clearFunction(functionName) { - // IE8 throws an exception when you try to delete a property on window - // http://stackoverflow.com/a/1824228/751089 - try { - delete window[functionName]; - } catch (e) { - window[functionName] = undefined; - } - } +/***/ }), - function removeScript(scriptId) { - var script = document.getElementById(scriptId); - if (script) { - document.getElementsByTagName('head')[0].removeChild(script); - } - } +/***/ "./node_modules/jszip/lib/external.js": +/*!********************************************!*\ + !*** ./node_modules/jszip/lib/external.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - function fetchJsonp(_url) { - var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; +"use strict"; +/* global Promise */ - // to avoid param reassign - var url = _url; - var timeout = options.timeout || defaultOptions.timeout; - var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback; - var timeoutId = undefined; +// load the global object first: +// - it should be better integrated in the system (unhandledRejection in node) +// - the environment may have a custom Promise implementation (see zone.js) +var ES6Promise = null; +if (typeof Promise !== "undefined") { + ES6Promise = Promise; +} else { + ES6Promise = __webpack_require__(/*! lie */ "./node_modules/jszip/node_modules/lie/lib/browser.js"); +} - return new Promise(function (resolve, reject) { - var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction(); - var scriptId = jsonpCallback + '_' + callbackFunction; +/** + * Let the user use/change some implementations. + */ +module.exports = { + Promise: ES6Promise +}; - window[callbackFunction] = function (response) { - resolve({ - ok: true, - // keep consistent with fetch API - json: function json() { - return Promise.resolve(response); - } - }); - if (timeoutId) clearTimeout(timeoutId); +/***/ }), - removeScript(scriptId); +/***/ "./node_modules/jszip/lib/flate.js": +/*!*****************************************!*\ + !*** ./node_modules/jszip/lib/flate.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - clearFunction(callbackFunction); - }; +"use strict"; - // Check if the user set their own params, and if not add a ? to start a list of params - url += url.indexOf('?') === -1 ? '?' : '&'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); - var jsonpScript = document.createElement('script'); - jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction); - if (options.charset) { - jsonpScript.setAttribute('charset', options.charset); - } - jsonpScript.id = scriptId; - document.getElementsByTagName('head')[0].appendChild(jsonpScript); +var pako = __webpack_require__(/*! pako */ "./node_modules/jszip/node_modules/pako/index.js"); +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); - timeoutId = setTimeout(function () { - reject(new Error('JSONP request to ' + _url + ' timed out')); +var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array"; - clearFunction(callbackFunction); - removeScript(scriptId); - window[callbackFunction] = function () { - clearFunction(callbackFunction); - }; - }, timeout); +exports.magic = "\x08\x00"; - // Caught if got 404/500 - jsonpScript.onerror = function () { - reject(new Error('JSONP request to ' + _url + ' failed')); +/** + * Create a worker that uses pako to inflate/deflate. + * @constructor + * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". + * @param {Object} options the options to use when (de)compressing. + */ +function FlateWorker(action, options) { + GenericWorker.call(this, "FlateWorker/" + action); - clearFunction(callbackFunction); - removeScript(scriptId); - if (timeoutId) clearTimeout(timeoutId); - }; - }); - } + this._pako = null; + this._pakoAction = action; + this._pakoOptions = options; + // the `meta` object from the last chunk received + // this allow this worker to pass around metadata + this.meta = {}; +} - // export as global function - /* - let local; - if (typeof global !== 'undefined') { - local = global; - } else if (typeof self !== 'undefined') { - local = self; - } else { - try { - local = Function('return this')(); - } catch (e) { - throw new Error('polyfill failed because global object is unavailable in this environment'); +utils.inherits(FlateWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +FlateWorker.prototype.processChunk = function (chunk) { + this.meta = chunk.meta; + if (this._pako === null) { + this._createPako(); } - } - local.fetchJsonp = fetchJsonp; - */ + this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false); +}; + +/** + * @see GenericWorker.flush + */ +FlateWorker.prototype.flush = function () { + GenericWorker.prototype.flush.call(this); + if (this._pako === null) { + this._createPako(); + } + this._pako.push([], true); +}; +/** + * @see GenericWorker.cleanUp + */ +FlateWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this._pako = null; +}; + +/** + * Create the _pako object. + * TODO: lazy-loading this object isn't the best solution but it's the + * quickest. The best solution is to lazy-load the worker list. See also the + * issue #446. + */ +FlateWorker.prototype._createPako = function () { + this._pako = new pako[this._pakoAction]({ + raw: true, + level: this._pakoOptions.level || -1 // default compression + }); + var self = this; + this._pako.onData = function(data) { + self.push({ + data : data, + meta : self.meta + }); + }; +}; + +exports.compressWorker = function (compressionOptions) { + return new FlateWorker("Deflate", compressionOptions); +}; +exports.uncompressWorker = function () { + return new FlateWorker("Inflate", {}); +}; - module.exports = fetchJsonp; -}); /***/ }), -/***/ "./node_modules/fft.js/lib/fft.js": -/*!****************************************!*\ - !*** ./node_modules/fft.js/lib/fft.js ***! - \****************************************/ +/***/ "./node_modules/jszip/lib/generate/ZipFileWorker.js": +/*!**********************************************************!*\ + !*** ./node_modules/jszip/lib/generate/ZipFileWorker.js ***! + \**********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -function FFT(size) { - this.size = size | 0; - if (this.size <= 1 || (this.size & (this.size - 1)) !== 0) - throw new Error('FFT size must be a power of two and bigger than 1'); - - this._csize = size << 1; - - // NOTE: Use of `var` is intentional for old V8 versions - var table = new Array(this.size * 2); - for (var i = 0; i < table.length; i += 2) { - const angle = Math.PI * i / this.size; - table[i] = Math.cos(angle); - table[i + 1] = -Math.sin(angle); - } - this.table = table; - - // Find size's power of two - var power = 0; - for (var t = 1; this.size > t; t <<= 1) - power++; - - // Calculate initial step's width: - // * If we are full radix-4 - it is 2x smaller to give inital len=8 - // * Otherwise it is the same as `power` to give len=4 - this._width = power % 2 === 0 ? power - 1 : power; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); +var utf8 = __webpack_require__(/*! ../utf8 */ "./node_modules/jszip/lib/utf8.js"); +var crc32 = __webpack_require__(/*! ../crc32 */ "./node_modules/jszip/lib/crc32.js"); +var signature = __webpack_require__(/*! ../signature */ "./node_modules/jszip/lib/signature.js"); - // Pre-compute bit-reversal patterns - this._bitrev = new Array(1 << this._width); - for (var j = 0; j < this._bitrev.length; j++) { - this._bitrev[j] = 0; - for (var shift = 0; shift < this._width; shift += 2) { - var revShift = this._width - shift - 2; - this._bitrev[j] |= ((j >>> shift) & 3) << revShift; +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; } - } - - this._out = null; - this._data = null; - this._inv = 0; -} -module.exports = FFT; - -FFT.prototype.fromComplexArray = function fromComplexArray(complex, storage) { - var res = storage || new Array(complex.length >>> 1); - for (var i = 0; i < complex.length; i += 2) - res[i >>> 1] = complex[i]; - return res; -}; - -FFT.prototype.createComplexArray = function createComplexArray() { - const res = new Array(this._csize); - for (var i = 0; i < res.length; i++) - res[i] = 0; - return res; + return hex; }; -FFT.prototype.toComplexArray = function toComplexArray(input, storage) { - var res = storage || this.createComplexArray(); - for (var i = 0; i < res.length; i += 2) { - res[i] = input[i >>> 1]; - res[i + 1] = 0; - } - return res; -}; +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { -FFT.prototype.completeSpectrum = function completeSpectrum(spectrum) { - var size = this._csize; - var half = size >>> 1; - for (var i = 2; i < half; i += 2) { - spectrum[size - i] = spectrum[i]; - spectrum[size - i + 1] = -spectrum[i + 1]; - } + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + return (result & 0xFFFF) << 16; }; -FFT.prototype.transform = function transform(out, data) { - if (out === data) - throw new Error('Input and output buffers must be different'); +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { - this._out = out; - this._data = data; - this._inv = 0; - this._transform4(); - this._out = null; - this._data = null; + // the dir flag is already set for compatibility + return (dosPermissions || 0) & 0x3F; }; -FFT.prototype.realTransform = function realTransform(out, data) { - if (out === data) - throw new Error('Input and output buffers must be different'); +/** + * Generate the various parts used in the construction of the final zip file. + * @param {Object} streamInfo the hash with informations about the compressed file. + * @param {Boolean} streamedContent is the content streamed ? + * @param {Boolean} streamingEnded is the stream finished ? + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @param {Function} encodeFileName the function to encode the file name / comment. + * @return {Object} the zip parts. + */ +var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) { + var file = streamInfo['file'], + compression = streamInfo['compression'], + useCustomEncoding = encodeFileName !== utf8.utf8encode, + encodedFileName = utils.transformTo("string", encodeFileName(file.name)), + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment, + encodedComment = utils.transformTo("string", encodeFileName(comment)), + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir = file.dir, + date = file.date; - this._out = out; - this._data = data; - this._inv = 0; - this._realTransform4(); - this._out = null; - this._data = null; -}; -FFT.prototype.inverseTransform = function inverseTransform(out, data) { - if (out === data) - throw new Error('Input and output buffers must be different'); + var dataInfo = { + crc32 : 0, + compressedSize : 0, + uncompressedSize : 0 + }; - this._out = out; - this._data = data; - this._inv = 1; - this._transform4(); - for (var i = 0; i < out.length; i++) - out[i] /= this.size; - this._out = null; - this._data = null; -}; + // if the content is streamed, the sizes/crc32 are only available AFTER + // the end of the stream. + if (!streamedContent || streamingEnded) { + dataInfo.crc32 = streamInfo['crc32']; + dataInfo.compressedSize = streamInfo['compressedSize']; + dataInfo.uncompressedSize = streamInfo['uncompressedSize']; + } -// radix-4 implementation -// -// NOTE: Uses of `var` are intentional for older V8 version that do not -// support both `let compound assignments` and `const phi` -FFT.prototype._transform4 = function _transform4() { - var out = this._out; - var size = this._csize; + var bitflag = 0; + if (streamedContent) { + // Bit 3: the sizes/crc32 are set to zero in the local header. + // The correct values are put in the data descriptor immediately + // following the compressed data. + bitflag |= 0x0008; + } + if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) { + // Bit 11: Language encoding flag (EFS). + bitflag |= 0x0800; + } - // Initial step (permute and transform) - var width = this._width; - var step = 1 << width; - var len = (size / step) << 1; - var outOff; - var t; - var bitrev = this._bitrev; - if (len === 4) { - for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { - const off = bitrev[t]; - this._singleTransform2(outOff, off, step); + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; } - } else { - // len === 8 - for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { - const off = bitrev[t]; - this._singleTransform4(outOff, off, step); + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); } - } - // Loop through steps in decreasing order - var inv = this._inv ? -1 : 1; - var table = this.table; - for (step >>= 2; step >= 2; step >>= 2) { - len = (size / step) << 1; - var quarterLen = len >>> 2; + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html - // Loop through offsets in the data - for (outOff = 0; outOff < size; outOff += len) { - // Full case - var limit = outOff + quarterLen; - for (var i = outOff, k = 0; i < limit; i += 2, k += step) { - const A = i; - const B = A + quarterLen; - const C = B + quarterLen; - const D = C + quarterLen; + dosTime = date.getUTCHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getUTCMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getUTCSeconds() / 2; - // Original values - const Ar = out[A]; - const Ai = out[A + 1]; - const Br = out[B]; - const Bi = out[B + 1]; - const Cr = out[C]; - const Ci = out[C + 1]; - const Dr = out[D]; - const Di = out[D + 1]; + dosDate = date.getUTCFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getUTCMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getUTCDate(); - // Middle values - const MAr = Ar; - const MAi = Ai; + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(encodedFileName), 4) + + // UnicodeName + utfEncodedFileName; - const tableBr = table[k]; - const tableBi = inv * table[k + 1]; - const MBr = Br * tableBr - Bi * tableBi; - const MBi = Br * tableBi + Bi * tableBr; + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } - const tableCr = table[2 * k]; - const tableCi = inv * table[2 * k + 1]; - const MCr = Cr * tableCr - Ci * tableCi; - const MCi = Cr * tableCi + Ci * tableCr; + if(useUTF8ForComment) { - const tableDr = table[3 * k]; - const tableDi = inv * table[3 * k + 1]; - const MDr = Dr * tableDr - Di * tableDi; - const MDi = Dr * tableDi + Di * tableDr; + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(crc32(encodedComment), 4) + + // UnicodeName + utfEncodedComment; - // Pre-Final values - const T0r = MAr + MCr; - const T0i = MAi + MCi; - const T1r = MAr - MCr; - const T1i = MAi - MCi; - const T2r = MBr + MDr; - const T2i = MBi + MDi; - const T3r = inv * (MBr - MDr); - const T3i = inv * (MBi - MDi); + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } - // Final values - const FAr = T0r + T2r; - const FAi = T0i + T2i; + var header = ""; - const FCr = T0r - T2r; - const FCi = T0i - T2i; + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + header += decToHex(bitflag, 2); + // compression method + header += compression.magic; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(dataInfo.crc32, 4); + // compressed size + header += decToHex(dataInfo.compressedSize, 4); + // uncompressed size + header += decToHex(dataInfo.uncompressedSize, 4); + // file name length + header += decToHex(encodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); - const FBr = T1r + T3i; - const FBi = T1i - T3r; - const FDr = T1r - T3i; - const FDi = T1i + T3r; + var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields; - out[A] = FAr; - out[A + 1] = FAi; - out[B] = FBr; - out[B + 1] = FBi; - out[C] = FCr; - out[C + 1] = FCi; - out[D] = FDr; - out[D + 1] = FDi; - } - } - } -}; + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(encodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + encodedFileName + + // extra field + extraFields + + // file comment + encodedComment; -// radix-2 implementation -// -// NOTE: Only called for len=4 -FFT.prototype._singleTransform2 = function _singleTransform2(outOff, off, - step) { - const out = this._out; - const data = this._data; + return { + fileRecord: fileRecord, + dirRecord: dirRecord + }; +}; - const evenR = data[off]; - const evenI = data[off + 1]; - const oddR = data[off + step]; - const oddI = data[off + step + 1]; +/** + * Generate the EOCD record. + * @param {Number} entriesCount the number of entries in the zip file. + * @param {Number} centralDirLength the length (in bytes) of the central dir. + * @param {Number} localDirLength the length (in bytes) of the local dir. + * @param {String} comment the zip file comment as a binary string. + * @param {Function} encodeFileName the function to encode the comment. + * @return {String} the EOCD record. + */ +var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) { + var dirEnd = ""; + var encodedComment = utils.transformTo("string", encodeFileName(comment)); - const leftR = evenR + oddR; - const leftI = evenI + oddI; - const rightR = evenR - oddR; - const rightI = evenI - oddI; + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(entriesCount, 2) + + // total number of entries in the central directory + decToHex(entriesCount, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(encodedComment.length, 2) + + // .ZIP file comment + encodedComment; - out[outOff] = leftR; - out[outOff + 1] = leftI; - out[outOff + 2] = rightR; - out[outOff + 3] = rightI; + return dirEnd; }; -// radix-4 -// -// NOTE: Only called for len=8 -FFT.prototype._singleTransform4 = function _singleTransform4(outOff, off, - step) { - const out = this._out; - const data = this._data; - const inv = this._inv ? -1 : 1; - const step2 = step * 2; - const step3 = step * 3; +/** + * Generate data descriptors for a file entry. + * @param {Object} streamInfo the hash generated by a worker, containing informations + * on the file entry. + * @return {String} the data descriptors. + */ +var generateDataDescriptors = function (streamInfo) { + var descriptor = ""; + descriptor = signature.DATA_DESCRIPTOR + + // crc-32 4 bytes + decToHex(streamInfo['crc32'], 4) + + // compressed size 4 bytes + decToHex(streamInfo['compressedSize'], 4) + + // uncompressed size 4 bytes + decToHex(streamInfo['uncompressedSize'], 4); - // Original values - const Ar = data[off]; - const Ai = data[off + 1]; - const Br = data[off + step]; - const Bi = data[off + step + 1]; - const Cr = data[off + step2]; - const Ci = data[off + step2 + 1]; - const Dr = data[off + step3]; - const Di = data[off + step3 + 1]; + return descriptor; +}; - // Pre-Final values - const T0r = Ar + Cr; - const T0i = Ai + Ci; - const T1r = Ar - Cr; - const T1i = Ai - Ci; - const T2r = Br + Dr; - const T2i = Bi + Di; - const T3r = inv * (Br - Dr); - const T3i = inv * (Bi - Di); - // Final values - const FAr = T0r + T2r; - const FAi = T0i + T2i; +/** + * A worker to concatenate other workers to create a zip file. + * @param {Boolean} streamFiles `true` to stream the content of the files, + * `false` to accumulate it. + * @param {String} comment the comment to use. + * @param {String} platform the platform to use, "UNIX" or "DOS". + * @param {Function} encodeFileName the function to encode file names and comments. + */ +function ZipFileWorker(streamFiles, comment, platform, encodeFileName) { + GenericWorker.call(this, "ZipFileWorker"); + // The number of bytes written so far. This doesn't count accumulated chunks. + this.bytesWritten = 0; + // The comment of the zip file + this.zipComment = comment; + // The platform "generating" the zip file. + this.zipPlatform = platform; + // the function to encode file names and comments. + this.encodeFileName = encodeFileName; + // Should we stream the content of the files ? + this.streamFiles = streamFiles; + // If `streamFiles` is false, we will need to accumulate the content of the + // files to calculate sizes / crc32 (and write them *before* the content). + // This boolean indicates if we are accumulating chunks (it will change a lot + // during the lifetime of this worker). + this.accumulate = false; + // The buffer receiving chunks when accumulating content. + this.contentBuffer = []; + // The list of generated directory records. + this.dirRecords = []; + // The offset (in bytes) from the beginning of the zip file for the current source. + this.currentSourceOffset = 0; + // The total number of entries in this zip file. + this.entriesCount = 0; + // the name of the file currently being added, null when handling the end of the zip file. + // Used for the emited metadata. + this.currentFile = null; - const FBr = T1r + T3i; - const FBi = T1i - T3r; - const FCr = T0r - T2r; - const FCi = T0i - T2i; - const FDr = T1r - T3i; - const FDi = T1i + T3r; + this._sources = []; +} +utils.inherits(ZipFileWorker, GenericWorker); - out[outOff] = FAr; - out[outOff + 1] = FAi; - out[outOff + 2] = FBr; - out[outOff + 3] = FBi; - out[outOff + 4] = FCr; - out[outOff + 5] = FCi; - out[outOff + 6] = FDr; - out[outOff + 7] = FDi; -}; +/** + * @see GenericWorker.push + */ +ZipFileWorker.prototype.push = function (chunk) { -// Real input radix-4 implementation -FFT.prototype._realTransform4 = function _realTransform4() { - var out = this._out; - var size = this._csize; + var currentFilePercent = chunk.meta.percent || 0; + var entriesCount = this.entriesCount; + var remainingFiles = this._sources.length; - // Initial step (permute and transform) - var width = this._width; - var step = 1 << width; - var len = (size / step) << 1; + if(this.accumulate) { + this.contentBuffer.push(chunk); + } else { + this.bytesWritten += chunk.data.length; - var outOff; - var t; - var bitrev = this._bitrev; - if (len === 4) { - for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { - const off = bitrev[t]; - this._singleRealTransform2(outOff, off >>> 1, step >>> 1); - } - } else { - // len === 8 - for (outOff = 0, t = 0; outOff < size; outOff += len, t++) { - const off = bitrev[t]; - this._singleRealTransform4(outOff, off >>> 1, step >>> 1); + GenericWorker.prototype.push.call(this, { + data : chunk.data, + meta : { + currentFile : this.currentFile, + percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100 + } + }); } - } - - // Loop through steps in decreasing order - var inv = this._inv ? -1 : 1; - var table = this.table; - for (step >>= 2; step >= 2; step >>= 2) { - len = (size / step) << 1; - var halfLen = len >>> 1; - var quarterLen = halfLen >>> 1; - var hquarterLen = quarterLen >>> 1; +}; - // Loop through offsets in the data - for (outOff = 0; outOff < size; outOff += len) { - for (var i = 0, k = 0; i <= hquarterLen; i += 2, k += step) { - var A = outOff + i; - var B = A + quarterLen; - var C = B + quarterLen; - var D = C + quarterLen; +/** + * The worker started a new source (an other worker). + * @param {Object} streamInfo the streamInfo object from the new source. + */ +ZipFileWorker.prototype.openedSource = function (streamInfo) { + this.currentSourceOffset = this.bytesWritten; + this.currentFile = streamInfo['file'].name; - // Original values - var Ar = out[A]; - var Ai = out[A + 1]; - var Br = out[B]; - var Bi = out[B + 1]; - var Cr = out[C]; - var Ci = out[C + 1]; - var Dr = out[D]; - var Di = out[D + 1]; + var streamedContent = this.streamFiles && !streamInfo['file'].dir; - // Middle values - var MAr = Ar; - var MAi = Ai; + // don't stream folders (because they don't have any content) + if(streamedContent) { + var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + } else { + // we need to wait for the whole file before pushing anything + this.accumulate = true; + } +}; - var tableBr = table[k]; - var tableBi = inv * table[k + 1]; - var MBr = Br * tableBr - Bi * tableBi; - var MBi = Br * tableBi + Bi * tableBr; +/** + * The worker finished a source (an other worker). + * @param {Object} streamInfo the streamInfo object from the finished source. + */ +ZipFileWorker.prototype.closedSource = function (streamInfo) { + this.accumulate = false; + var streamedContent = this.streamFiles && !streamInfo['file'].dir; + var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); - var tableCr = table[2 * k]; - var tableCi = inv * table[2 * k + 1]; - var MCr = Cr * tableCr - Ci * tableCi; - var MCi = Cr * tableCi + Ci * tableCr; + this.dirRecords.push(record.dirRecord); + if(streamedContent) { + // after the streamed file, we put data descriptors + this.push({ + data : generateDataDescriptors(streamInfo), + meta : {percent:100} + }); + } else { + // the content wasn't streamed, we need to push everything now + // first the file record, then the content + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + while(this.contentBuffer.length) { + this.push(this.contentBuffer.shift()); + } + } + this.currentFile = null; +}; - var tableDr = table[3 * k]; - var tableDi = inv * table[3 * k + 1]; - var MDr = Dr * tableDr - Di * tableDi; - var MDi = Dr * tableDi + Di * tableDr; +/** + * @see GenericWorker.flush + */ +ZipFileWorker.prototype.flush = function () { - // Pre-Final values - var T0r = MAr + MCr; - var T0i = MAi + MCi; - var T1r = MAr - MCr; - var T1i = MAi - MCi; - var T2r = MBr + MDr; - var T2i = MBi + MDi; - var T3r = inv * (MBr - MDr); - var T3i = inv * (MBi - MDi); + var localDirLength = this.bytesWritten; + for(var i = 0; i < this.dirRecords.length; i++) { + this.push({ + data : this.dirRecords[i], + meta : {percent:100} + }); + } + var centralDirLength = this.bytesWritten - localDirLength; - // Final values - var FAr = T0r + T2r; - var FAi = T0i + T2i; + var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName); - var FBr = T1r + T3i; - var FBi = T1i - T3r; + this.push({ + data : dirEnd, + meta : {percent:100} + }); +}; - out[A] = FAr; - out[A + 1] = FAi; - out[B] = FBr; - out[B + 1] = FBi; +/** + * Prepare the next source to be read. + */ +ZipFileWorker.prototype.prepareNextSource = function () { + this.previous = this._sources.shift(); + this.openedSource(this.previous.streamInfo); + if (this.isPaused) { + this.previous.pause(); + } else { + this.previous.resume(); + } +}; - // Output final middle point - if (i === 0) { - var FCr = T0r - T2r; - var FCi = T0i - T2i; - out[C] = FCr; - out[C + 1] = FCi; - continue; - } +/** + * @see GenericWorker.registerPrevious + */ +ZipFileWorker.prototype.registerPrevious = function (previous) { + this._sources.push(previous); + var self = this; - // Do not overwrite ourselves - if (i === hquarterLen) - continue; - - // In the flipped case: - // MAi = -MAi - // MBr=-MBi, MBi=-MBr - // MCr=-MCr - // MDr=MDi, MDi=MDr - var ST0r = T1r; - var ST0i = -T1i; - var ST1r = T0r; - var ST1i = -T0i; - var ST2r = -inv * T3i; - var ST2i = -inv * T3r; - var ST3r = -inv * T2i; - var ST3i = -inv * T2r; - - var SFAr = ST0r + ST2r; - var SFAi = ST0i + ST2i; - - var SFBr = ST1r + ST3i; - var SFBi = ST1i - ST3r; + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.closedSource(self.previous.streamInfo); + if(self._sources.length) { + self.prepareNextSource(); + } else { + self.end(); + } + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; +}; - var SA = outOff + quarterLen - i; - var SB = outOff + halfLen - i; +/** + * @see GenericWorker.resume + */ +ZipFileWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } - out[SA] = SFAr; - out[SA + 1] = SFAi; - out[SB] = SFBr; - out[SB + 1] = SFBi; - } + if (!this.previous && this._sources.length) { + this.prepareNextSource(); + return true; + } + if (!this.previous && !this._sources.length && !this.generatedError) { + this.end(); + return true; } - } }; -// radix-2 implementation -// -// NOTE: Only called for len=4 -FFT.prototype._singleRealTransform2 = function _singleRealTransform2(outOff, - off, - step) { - const out = this._out; - const data = this._data; - - const evenR = data[off]; - const oddR = data[off + step]; - - const leftR = evenR + oddR; - const rightR = evenR - oddR; - - out[outOff] = leftR; - out[outOff + 1] = 0; - out[outOff + 2] = rightR; - out[outOff + 3] = 0; +/** + * @see GenericWorker.error + */ +ZipFileWorker.prototype.error = function (e) { + var sources = this._sources; + if(!GenericWorker.prototype.error.call(this, e)) { + return false; + } + for(var i = 0; i < sources.length; i++) { + try { + sources[i].error(e); + } catch(e) { + // the `error` exploded, nothing to do + } + } + return true; }; -// radix-4 -// -// NOTE: Only called for len=8 -FFT.prototype._singleRealTransform4 = function _singleRealTransform4(outOff, - off, - step) { - const out = this._out; - const data = this._data; - const inv = this._inv ? -1 : 1; - const step2 = step * 2; - const step3 = step * 3; - - // Original values - const Ar = data[off]; - const Br = data[off + step]; - const Cr = data[off + step2]; - const Dr = data[off + step3]; - - // Pre-Final values - const T0r = Ar + Cr; - const T1r = Ar - Cr; - const T2r = Br + Dr; - const T3r = inv * (Br - Dr); - - // Final values - const FAr = T0r + T2r; - - const FBr = T1r; - const FBi = -T3r; - - const FCr = T0r - T2r; - - const FDr = T1r; - const FDi = T3r; - - out[outOff] = FAr; - out[outOff + 1] = 0; - out[outOff + 2] = FBr; - out[outOff + 3] = FBi; - out[outOff + 4] = FCr; - out[outOff + 5] = 0; - out[outOff + 6] = FDr; - out[outOff + 7] = FDi; +/** + * @see GenericWorker.lock + */ +ZipFileWorker.prototype.lock = function () { + GenericWorker.prototype.lock.call(this); + var sources = this._sources; + for(var i = 0; i < sources.length; i++) { + sources[i].lock(); + } }; +module.exports = ZipFileWorker; + /***/ }), -/***/ "./node_modules/file-saver/FileSaver.js": -/*!**********************************************!*\ - !*** ./node_modules/file-saver/FileSaver.js ***! - \**********************************************/ +/***/ "./node_modules/jszip/lib/generate/index.js": +/*!**************************************************!*\ + !*** ./node_modules/jszip/lib/generate/index.js ***! + \**************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js - * A saveAs() FileSaver implementation. - * 1.3.2 - * 2016-06-16 18:25:19 - * - * By Eli Grey, http://eligrey.com - * License: MIT - * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md - */ - -/*global self */ -/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ +"use strict"; -/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -var saveAs = saveAs || (function(view) { - "use strict"; - // IE <10 is explicitly unsupported - if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { - return; - } - var - doc = view.document - // only get URL when necessary in case Blob.js hasn't overridden it yet - , get_URL = function() { - return view.URL || view.webkitURL || view; - } - , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") - , can_use_save_link = "download" in save_link - , click = function(node) { - var event = new MouseEvent("click"); - node.dispatchEvent(event); - } - , is_safari = /constructor/i.test(view.HTMLElement) || view.safari - , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) - , throw_outside = function(ex) { - (view.setImmediate || view.setTimeout)(function() { - throw ex; - }, 0); - } - , force_saveable_type = "application/octet-stream" - // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to - , arbitrary_revoke_timeout = 1000 * 40 // in ms - , revoke = function(file) { - var revoker = function() { - if (typeof file === "string") { // file is an object URL - get_URL().revokeObjectURL(file); - } else { // file is a File - file.remove(); - } - }; - setTimeout(revoker, arbitrary_revoke_timeout); - } - , dispatch = function(filesaver, event_types, event) { - event_types = [].concat(event_types); - var i = event_types.length; - while (i--) { - var listener = filesaver["on" + event_types[i]]; - if (typeof listener === "function") { - try { - listener.call(filesaver, event || filesaver); - } catch (ex) { - throw_outside(ex); - } - } - } - } - , auto_bom = function(blob) { - // prepend BOM for UTF-8 XML and text/* types (including HTML) - // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF - if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { - return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); - } - return blob; - } - , FileSaver = function(blob, name, no_auto_bom) { - if (!no_auto_bom) { - blob = auto_bom(blob); - } - // First try a.download, then web filesystem, then object URLs - var - filesaver = this - , type = blob.type - , force = type === force_saveable_type - , object_url - , dispatch_all = function() { - dispatch(filesaver, "writestart progress write writeend".split(" ")); - } - // on any filesys errors revert to saving with object URLs - , fs_error = function() { - if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { - // Safari doesn't allow downloading of blob urls - var reader = new FileReader(); - reader.onloadend = function() { - var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); - var popup = view.open(url, '_blank'); - if(!popup) view.location.href = url; - url=undefined; // release reference before dispatching - filesaver.readyState = filesaver.DONE; - dispatch_all(); - }; - reader.readAsDataURL(blob); - filesaver.readyState = filesaver.INIT; - return; - } - // don't create more object URLs than needed - if (!object_url) { - object_url = get_URL().createObjectURL(blob); - } - if (force) { - view.location.href = object_url; - } else { - var opened = view.open(object_url, "_blank"); - if (!opened) { - // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html - view.location.href = object_url; - } - } - filesaver.readyState = filesaver.DONE; - dispatch_all(); - revoke(object_url); - } - ; - filesaver.readyState = filesaver.INIT; +var compressions = __webpack_require__(/*! ../compressions */ "./node_modules/jszip/lib/compressions.js"); +var ZipFileWorker = __webpack_require__(/*! ./ZipFileWorker */ "./node_modules/jszip/lib/generate/ZipFileWorker.js"); - if (can_use_save_link) { - object_url = get_URL().createObjectURL(blob); - setTimeout(function() { - save_link.href = object_url; - save_link.download = name; - click(save_link); - dispatch_all(); - revoke(object_url); - filesaver.readyState = filesaver.DONE; - }); - return; - } +/** + * Find the compression to use. + * @param {String} fileCompression the compression defined at the file level, if any. + * @param {String} zipCompression the compression defined at the load() level. + * @return {Object} the compression object to use. + */ +var getCompression = function (fileCompression, zipCompression) { - fs_error(); - } - , FS_proto = FileSaver.prototype - , saveAs = function(blob, name, no_auto_bom) { - return new FileSaver(blob, name || blob.name || "download", no_auto_bom); - } - ; - // IE 10+ (native saveAs) - if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { - return function(blob, name, no_auto_bom) { - name = name || blob.name || "download"; + var compressionName = fileCompression || zipCompression; + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + return compression; +}; - if (!no_auto_bom) { - blob = auto_bom(blob); - } - return navigator.msSaveOrOpenBlob(blob, name); - }; - } +/** + * Create a worker to generate a zip file. + * @param {JSZip} zip the JSZip instance at the right root level. + * @param {Object} options to generate the zip file. + * @param {String} comment the comment to use. + */ +exports.generateWorker = function (zip, options, comment) { - FS_proto.abort = function(){}; - FS_proto.readyState = FS_proto.INIT = 0; - FS_proto.WRITING = 1; - FS_proto.DONE = 2; + var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName); + var entriesCount = 0; + try { - FS_proto.error = - FS_proto.onwritestart = - FS_proto.onprogress = - FS_proto.onwrite = - FS_proto.onabort = - FS_proto.onerror = - FS_proto.onwriteend = - null; + zip.forEach(function (relativePath, file) { + entriesCount++; + var compression = getCompression(file.options.compression, options.compression); + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + var dir = file.dir, date = file.date; - return saveAs; -}( - typeof self !== "undefined" && self - || typeof window !== "undefined" && window - || this.content -)); -// `self` is undefined in Firefox for Android content script context -// while `this` is nsIContentFrameMessageManager -// with an attribute `content` that corresponds to the window + file._compressWorker(compression, compressionOptions) + .withStreamInfo("file", { + name : relativePath, + dir : dir, + date : date, + comment : file.comment || "", + unixPermissions : file.unixPermissions, + dosPermissions : file.dosPermissions + }) + .pipe(zipFileWorker); + }); + zipFileWorker.entriesCount = entriesCount; + } catch (e) { + zipFileWorker.error(e); + } -if (typeof module !== "undefined" && module.exports) { - module.exports.saveAs = saveAs; -} else if (("function" !== "undefined" && __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js") !== null) && (__webpack_require__(/*! !webpack amd options */ "./node_modules/webpack/buildin/amd-options.js") !== null)) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() { - return saveAs; - }).call(exports, __webpack_require__, exports, module), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -} + return zipFileWorker; +}; /***/ }), -/***/ "./node_modules/history/DOMUtils.js": -/*!******************************************!*\ - !*** ./node_modules/history/DOMUtils.js ***! - \******************************************/ +/***/ "./node_modules/jszip/lib/index.js": +/*!*****************************************!*\ + !*** ./node_modules/jszip/lib/index.js ***! + \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; -var canUseDOM = exports.canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); - -var addEventListener = exports.addEventListener = function addEventListener(node, event, listener) { - return node.addEventListener ? node.addEventListener(event, listener, false) : node.attachEvent('on' + event, listener); -}; +/** + * Representation a of zip file in js + * @constructor + */ +function JSZip() { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) { + return new JSZip(); + } -var removeEventListener = exports.removeEventListener = function removeEventListener(node, event, listener) { - return node.removeEventListener ? node.removeEventListener(event, listener, false) : node.detachEvent('on' + event, listener); -}; + if(arguments.length) { + throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide."); + } -var getConfirmation = exports.getConfirmation = function getConfirmation(message, callback) { - return callback(window.confirm(message)); -}; // eslint-disable-line no-alert + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + this.files = {}; -/** - * Returns true if the HTML5 history API is supported. Taken from Modernizr. - * - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586 - */ -var supportsHistory = exports.supportsHistory = function supportsHistory() { - var ua = window.navigator.userAgent; + this.comment = null; - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; + // Where we are in the hierarchy + this.root = ""; + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = __webpack_require__(/*! ./object */ "./node_modules/jszip/lib/object.js"); +JSZip.prototype.loadAsync = __webpack_require__(/*! ./load */ "./node_modules/jszip/lib/load.js"); +JSZip.support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); +JSZip.defaults = __webpack_require__(/*! ./defaults */ "./node_modules/jszip/lib/defaults.js"); - return window.history && 'pushState' in window.history; -}; +// TODO find a better way to handle this version, +// a require('package.json').version doesn't work with webpack, see #327 +JSZip.version = "3.1.5"; -/** - * Returns true if browser fires popstate on hash change. - * IE10 and IE11 do not. - */ -var supportsPopStateOnHashChange = exports.supportsPopStateOnHashChange = function supportsPopStateOnHashChange() { - return window.navigator.userAgent.indexOf('Trident') === -1; +JSZip.loadAsync = function (content, options) { + return new JSZip().loadAsync(content, options); }; -/** - * Returns false if using go(n) with hash history causes a full page reload. - */ -var supportsGoWithoutReloadUsingHash = exports.supportsGoWithoutReloadUsingHash = function supportsGoWithoutReloadUsingHash() { - return window.navigator.userAgent.indexOf('Firefox') === -1; -}; +JSZip.external = __webpack_require__(/*! ./external */ "./node_modules/jszip/lib/external.js"); +module.exports = JSZip; -/** - * Returns true if a given popstate event is an extraneous WebKit event. - * Accounts for the fact that Chrome on iOS fires real popstate events - * containing undefined state when pressing the back button. - */ -var isExtraneousPopstateEvent = exports.isExtraneousPopstateEvent = function isExtraneousPopstateEvent(event) { - return event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1; -}; /***/ }), -/***/ "./node_modules/history/LocationUtils.js": -/*!***********************************************!*\ - !*** ./node_modules/history/LocationUtils.js ***! - \***********************************************/ +/***/ "./node_modules/jszip/lib/load.js": +/*!****************************************!*\ + !*** ./node_modules/jszip/lib/load.js ***! + \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var external = __webpack_require__(/*! ./external */ "./node_modules/jszip/lib/external.js"); +var utf8 = __webpack_require__(/*! ./utf8 */ "./node_modules/jszip/lib/utf8.js"); +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var ZipEntries = __webpack_require__(/*! ./zipEntries */ "./node_modules/jszip/lib/zipEntries.js"); +var Crc32Probe = __webpack_require__(/*! ./stream/Crc32Probe */ "./node_modules/jszip/lib/stream/Crc32Probe.js"); +var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ "./node_modules/jszip/lib/nodejsUtils.js"); -exports.__esModule = true; -exports.locationsAreEqual = exports.createLocation = undefined; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _resolvePathname = __webpack_require__(/*! resolve-pathname */ "./node_modules/resolve-pathname/index.js"); - -var _resolvePathname2 = _interopRequireDefault(_resolvePathname); - -var _valueEqual = __webpack_require__(/*! value-equal */ "./node_modules/value-equal/index.js"); - -var _valueEqual2 = _interopRequireDefault(_valueEqual); - -var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var createLocation = exports.createLocation = function createLocation(path, state, key, currentLocation) { - var location = void 0; - if (typeof path === 'string') { - // Two-arg form: push(path, state) - location = (0, _PathUtils.parsePath)(path); - location.state = state; - } else { - // One-arg form: push(location) - location = _extends({}, path); - - if (location.pathname === undefined) location.pathname = ''; - - if (location.search) { - if (location.search.charAt(0) !== '?') location.search = '?' + location.search; - } else { - location.search = ''; - } - - if (location.hash) { - if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash; - } else { - location.hash = ''; - } +/** + * Check the CRC32 of an entry. + * @param {ZipEntry} zipEntry the zip entry to check. + * @return {Promise} the result. + */ +function checkEntryCRC32(zipEntry) { + return new external.Promise(function (resolve, reject) { + var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe()); + worker.on("error", function (e) { + reject(e); + }) + .on("end", function () { + if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) { + reject(new Error("Corrupted zip : CRC32 mismatch")); + } else { + resolve(); + } + }) + .resume(); + }); +} - if (state !== undefined && location.state === undefined) location.state = state; - } +module.exports = function(data, options) { + var zip = this; + options = utils.extend(options || {}, { + base64: false, + checkCRC32: false, + optimizedBinaryString: false, + createFolders: false, + decodeFileName: utf8.utf8decode + }); - try { - location.pathname = decodeURI(location.pathname); - } catch (e) { - if (e instanceof URIError) { - throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.'); - } else { - throw e; + if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")); } - } - - if (key) location.key = key; - if (currentLocation) { - // Resolve incomplete/relative pathname relative to current location. - if (!location.pathname) { - location.pathname = currentLocation.pathname; - } else if (location.pathname.charAt(0) !== '/') { - location.pathname = (0, _resolvePathname2.default)(location.pathname, currentLocation.pathname); - } - } else { - // When there is no prior location and pathname is empty, set it to / - if (!location.pathname) { - location.pathname = '/'; - } - } + return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64) + .then(function(data) { + var zipEntries = new ZipEntries(options); + zipEntries.load(data); + return zipEntries; + }).then(function checkCRC32(zipEntries) { + var promises = [external.Promise.resolve(zipEntries)]; + var files = zipEntries.files; + if (options.checkCRC32) { + for (var i = 0; i < files.length; i++) { + promises.push(checkEntryCRC32(files[i])); + } + } + return external.Promise.all(promises); + }).then(function addFiles(results) { + var zipEntries = results.shift(); + var files = zipEntries.files; + for (var i = 0; i < files.length; i++) { + var input = files[i]; + zip.file(input.fileNameStr, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment : input.fileCommentStr.length ? input.fileCommentStr : null, + unixPermissions : input.unixPermissions, + dosPermissions : input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + zip.comment = zipEntries.zipComment; + } - return location; + return zip; + }); }; -var locationsAreEqual = exports.locationsAreEqual = function locationsAreEqual(a, b) { - return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && (0, _valueEqual2.default)(a.state, b.state); -}; /***/ }), -/***/ "./node_modules/history/PathUtils.js": -/*!*******************************************!*\ - !*** ./node_modules/history/PathUtils.js ***! - \*******************************************/ +/***/ "./node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js": +/*!*******************************************************************!*\ + !*** ./node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js ***! + \*******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; -var addLeadingSlash = exports.addLeadingSlash = function addLeadingSlash(path) { - return path.charAt(0) === '/' ? path : '/' + path; -}; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); -var stripLeadingSlash = exports.stripLeadingSlash = function stripLeadingSlash(path) { - return path.charAt(0) === '/' ? path.substr(1) : path; -}; +/** + * A worker that use a nodejs stream as source. + * @constructor + * @param {String} filename the name of the file entry for this stream. + * @param {Readable} stream the nodejs stream. + */ +function NodejsStreamInputAdapter(filename, stream) { + GenericWorker.call(this, "Nodejs stream input adapter for " + filename); + this._upstreamEnded = false; + this._bindStream(stream); +} -var hasBasename = exports.hasBasename = function hasBasename(path, prefix) { - return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); -}; +utils.inherits(NodejsStreamInputAdapter, GenericWorker); -var stripBasename = exports.stripBasename = function stripBasename(path, prefix) { - return hasBasename(path, prefix) ? path.substr(prefix.length) : path; +/** + * Prepare the stream and bind the callbacks on it. + * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. + * @param {Stream} stream the nodejs stream to use. + */ +NodejsStreamInputAdapter.prototype._bindStream = function (stream) { + var self = this; + this._stream = stream; + stream.pause(); + stream + .on("data", function (chunk) { + self.push({ + data: chunk, + meta : { + percent : 0 + } + }); + }) + .on("error", function (e) { + if(self.isPaused) { + this.generatedError = e; + } else { + self.error(e); + } + }) + .on("end", function () { + if(self.isPaused) { + self._upstreamEnded = true; + } else { + self.end(); + } + }); }; - -var stripTrailingSlash = exports.stripTrailingSlash = function stripTrailingSlash(path) { - return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path; +NodejsStreamInputAdapter.prototype.pause = function () { + if(!GenericWorker.prototype.pause.call(this)) { + return false; + } + this._stream.pause(); + return true; }; +NodejsStreamInputAdapter.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } -var parsePath = exports.parsePath = function parsePath(path) { - var pathname = path || '/'; - var search = ''; - var hash = ''; - - var hashIndex = pathname.indexOf('#'); - if (hashIndex !== -1) { - hash = pathname.substr(hashIndex); - pathname = pathname.substr(0, hashIndex); - } - - var searchIndex = pathname.indexOf('?'); - if (searchIndex !== -1) { - search = pathname.substr(searchIndex); - pathname = pathname.substr(0, searchIndex); - } + if(this._upstreamEnded) { + this.end(); + } else { + this._stream.resume(); + } - return { - pathname: pathname, - search: search === '?' ? '' : search, - hash: hash === '#' ? '' : hash - }; + return true; }; -var createPath = exports.createPath = function createPath(location) { - var pathname = location.pathname, - search = location.search, - hash = location.hash; - - - var path = pathname || '/'; - - if (search && search !== '?') path += search.charAt(0) === '?' ? search : '?' + search; - - if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : '#' + hash; +module.exports = NodejsStreamInputAdapter; - return path; -}; /***/ }), -/***/ "./node_modules/history/createBrowserHistory.js": -/*!******************************************************!*\ - !*** ./node_modules/history/createBrowserHistory.js ***! - \******************************************************/ +/***/ "./node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js": +/*!********************************************************************!*\ + !*** ./node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js ***! + \********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +var Readable = __webpack_require__(/*! readable-stream */ "./node_modules/jszip/lib/readable-stream-browser.js").Readable; -var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +utils.inherits(NodejsStreamOutputAdapter, Readable); -var _warning2 = _interopRequireDefault(_warning); +/** +* A nodejs stream using a worker as source. +* @see the SourceWrapper in http://nodejs.org/api/stream.html +* @constructor +* @param {StreamHelper} helper the helper wrapping the worker +* @param {Object} options the nodejs stream options +* @param {Function} updateCb the update callback. +*/ +function NodejsStreamOutputAdapter(helper, options, updateCb) { + Readable.call(this, options); + this._helper = helper; -var _invariant = __webpack_require__(/*! invariant */ "./node_modules/invariant/browser.js"); + var self = this; + helper.on("data", function (data, meta) { + if (!self.push(data)) { + self._helper.pause(); + } + if(updateCb) { + updateCb(meta); + } + }) + .on("error", function(e) { + self.emit('error', e); + }) + .on("end", function () { + self.push(null); + }); +} -var _invariant2 = _interopRequireDefault(_invariant); -var _LocationUtils = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/LocationUtils.js"); +NodejsStreamOutputAdapter.prototype._read = function() { + this._helper.resume(); +}; -var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); +module.exports = NodejsStreamOutputAdapter; -var _createTransitionManager = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/createTransitionManager.js"); -var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); +/***/ }), -var _DOMUtils = __webpack_require__(/*! ./DOMUtils */ "./node_modules/history/DOMUtils.js"); +/***/ "./node_modules/jszip/lib/nodejsUtils.js": +/*!***********************************************!*\ + !*** ./node_modules/jszip/lib/nodejsUtils.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +"use strict"; +/* WEBPACK VAR INJECTION */(function(Buffer) { -var PopStateEvent = 'popstate'; -var HashChangeEvent = 'hashchange'; +module.exports = { + /** + * True if this is running in Nodejs, will be undefined in a browser. + * In a browser, browserify won't include this file and the whole module + * will be resolved an empty object. + */ + isNode : typeof Buffer !== "undefined", + /** + * Create a new nodejs Buffer from an existing content. + * @param {Object} data the data to pass to the constructor. + * @param {String} encoding the encoding to use. + * @return {Buffer} a new Buffer. + */ + newBufferFrom: function(data, encoding) { + // XXX We can't use `Buffer.from` which comes from `Uint8Array.from` + // in nodejs v4 (< v.4.5). It's not the expected implementation (and + // has a different signature). + // see https://github.com/nodejs/node/issues/8053 + // A condition on nodejs' version won't solve the issue as we don't + // control the Buffer polyfills that may or may not be used. + return new Buffer(data, encoding); + }, + /** + * Create a new nodejs Buffer with the specified size. + * @param {Integer} size the size of the buffer. + * @return {Buffer} a new Buffer. + */ + allocBuffer: function (size) { + if (Buffer.alloc) { + return Buffer.alloc(size); + } else { + return new Buffer(size); + } + }, + /** + * Find out if an object is a Buffer. + * @param {Object} b the object to test. + * @return {Boolean} true if the object is a Buffer, false otherwise. + */ + isBuffer : function(b){ + return Buffer.isBuffer(b); + }, -var getHistoryState = function getHistoryState() { - try { - return window.history.state || {}; - } catch (e) { - // IE 11 sometimes throws when accessing window.history.state - // See https://github.com/ReactTraining/history/pull/289 - return {}; - } + isStream : function (obj) { + return obj && + typeof obj.on === "function" && + typeof obj.pause === "function" && + typeof obj.resume === "function"; + } }; -/** - * Creates a history object that uses the HTML5 history API including - * pushState, replaceState, and the popstate event. - */ -var createBrowserHistory = function createBrowserHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - (0, _invariant2.default)(_DOMUtils.canUseDOM, 'Browser history needs a DOM'); - - var globalHistory = window.history; - var canUseHistory = (0, _DOMUtils.supportsHistory)(); - var needsHashChangeListener = !(0, _DOMUtils.supportsPopStateOnHashChange)(); - - var _props$forceRefresh = props.forceRefresh, - forceRefresh = _props$forceRefresh === undefined ? false : _props$forceRefresh, - _props$getUserConfirm = props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === undefined ? _DOMUtils.getConfirmation : _props$getUserConfirm, - _props$keyLength = props.keyLength, - keyLength = _props$keyLength === undefined ? 6 : _props$keyLength; +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/node_modules/buffer/index.js */ "./node_modules/webpack/node_modules/buffer/index.js").Buffer)) - var basename = props.basename ? (0, _PathUtils.stripTrailingSlash)((0, _PathUtils.addLeadingSlash)(props.basename)) : ''; +/***/ }), - var getDOMLocation = function getDOMLocation(historyState) { - var _ref = historyState || {}, - key = _ref.key, - state = _ref.state; +/***/ "./node_modules/jszip/lib/object.js": +/*!******************************************!*\ + !*** ./node_modules/jszip/lib/object.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var _window$location = window.location, - pathname = _window$location.pathname, - search = _window$location.search, - hash = _window$location.hash; +"use strict"; +var utf8 = __webpack_require__(/*! ./utf8 */ "./node_modules/jszip/lib/utf8.js"); +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); +var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ "./node_modules/jszip/lib/stream/StreamHelper.js"); +var defaults = __webpack_require__(/*! ./defaults */ "./node_modules/jszip/lib/defaults.js"); +var CompressedObject = __webpack_require__(/*! ./compressedObject */ "./node_modules/jszip/lib/compressedObject.js"); +var ZipObject = __webpack_require__(/*! ./zipObject */ "./node_modules/jszip/lib/zipObject.js"); +var generate = __webpack_require__(/*! ./generate */ "./node_modules/jszip/lib/generate/index.js"); +var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ "./node_modules/jszip/lib/nodejsUtils.js"); +var NodejsStreamInputAdapter = __webpack_require__(/*! ./nodejs/NodejsStreamInputAdapter */ "./node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js"); - var path = pathname + search + hash; - (0, _warning2.default)(!basename || (0, _PathUtils.hasBasename)(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} originalOptions the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, originalOptions) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; - if (basename) path = (0, _PathUtils.stripBasename)(path, basename); - return (0, _LocationUtils.createLocation)(path, state, key); - }; + /* + * Correct options. + */ - var createKey = function createKey() { - return Math.random().toString(36).substr(2, keyLength); - }; + var o = utils.extend(originalOptions || {}, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) { + o.compression = o.compression.toUpperCase(); + } - var transitionManager = (0, _createTransitionManager2.default)(); + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } - var setState = function setState(nextState) { - _extends(history, nextState); + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } - history.length = globalHistory.length; + if (o.dir) { + name = forceTrailingSlash(name); + } + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } - transitionManager.notifyListeners(history.location, history.action); - }; + var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false; + if (!originalOptions || typeof originalOptions.binary === "undefined") { + o.binary = !isUnicodeString; + } - var handlePopState = function handlePopState(event) { - // Ignore extraneous popstate events in WebKit. - if ((0, _DOMUtils.isExtraneousPopstateEvent)(event)) return; - handlePop(getDOMLocation(event.state)); - }; + var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0; - var handleHashChange = function handleHashChange() { - handlePop(getDOMLocation(getHistoryState())); - }; + if (isCompressedEmpty || o.dir || !data || data.length === 0) { + o.base64 = false; + o.binary = true; + data = ""; + o.compression = "STORE"; + dataType = "string"; + } - var forceNextPop = false; + /* + * Convert content to fit. + */ - var handlePop = function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); + var zipObjectContent = null; + if (data instanceof CompressedObject || data instanceof GenericWorker) { + zipObjectContent = data; + } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + zipObjectContent = new NodejsStreamInputAdapter(name, data); } else { - var action = 'POP'; - - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ action: action, location: location }); - } else { - revertPop(location); - } - }); + zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64); } - }; - var revertPop = function revertPop(fromLocation) { - var toLocation = history.location; - - // TODO: We could probably make this more reliable by - // keeping a list of keys we've seen in sessionStorage. - // Instead, we just default to 0 for keys we don't know. - - var toIndex = allKeys.indexOf(toLocation.key); - - if (toIndex === -1) toIndex = 0; - - var fromIndex = allKeys.indexOf(fromLocation.key); - - if (fromIndex === -1) fromIndex = 0; + var object = new ZipObject(name, zipObjectContent, o); + this.files[name] = object; + /* + TODO: we can't throw an exception because we have async promises + (we can have a promise of a Date() for example) but returning a + promise is useless because file(name, data) returns the JSZip + object for chaining. Should we break that to allow the user + to catch the error ? - var delta = toIndex - fromIndex; + return external.Promise.resolve(zipObjectContent) + .then(function () { + return object; + }); + */ +}; - if (delta) { - forceNextPop = true; - go(delta); +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) === '/') { + path = path.substring(0, path.length - 1); } - }; - - var initialLocation = getDOMLocation(getHistoryState()); - var allKeys = [initialLocation.key]; + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; - // Public interface +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) !== "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; - var createHref = function createHref(location) { - return basename + (0, _PathUtils.createPath)(location); - }; +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders; - var push = function push(path, state) { - (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + name = forceTrailingSlash(name); - var action = 'PUSH'; - var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +function isRegExp(object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +} - var href = createHref(location); - var key = location.key, - state = location.state; +// return the actual prototype of JSZip +var out = { + /** + * @see loadAsync + */ + load: function() { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, - if (canUseHistory) { - globalHistory.pushState({ key: key, state: state }, null, href); + /** + * Call a callback function for each entry at this folder level. + * @param {Function} cb the callback function: + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + */ + forEach: function(cb) { + var filename, relativePath, file; + for (filename in this.files) { + if (!this.files.hasOwnProperty(filename)) { + continue; + } + file = this.files[filename]; + relativePath = filename.slice(this.root.length, filename.length); + if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root + cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn... + } + } + }, - if (forceRefresh) { - window.location.href = href; - } else { - var prevIndex = allKeys.indexOf(history.location.key); - var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = []; + this.forEach(function (relativePath, entry) { + if (search(relativePath, entry)) { // the file matches the function + result.push(entry); + } - nextKeys.push(location.key); - allKeys = nextKeys; + }); + return result; + }, - setState({ action: action, location: location }); + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + var obj = this.files[this.root + name]; + if (obj && !obj.dir) { + return obj; + } else { + return null; + } + } } - } else { - (0, _warning2.default)(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history'); - - window.location.href = href; - } - }); - }; - - var replace = function replace(path, state) { - (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, - var action = 'REPLACE'; - var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; + if (isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } - var href = createHref(location); - var key = location.key, - state = location.state; + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, - if (canUseHistory) { - globalHistory.replaceState({ key: key, state: state }, null, href); + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) !== "/") { + name += "/"; + } + file = this.files[name]; + } - if (forceRefresh) { - window.location.replace(href); + if (file && !file.dir) { + // file + delete this.files[name]; } else { - var prevIndex = allKeys.indexOf(history.location.key); - - if (prevIndex !== -1) allKeys[prevIndex] = location.key; - - setState({ action: action, location: location }); + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } } - } else { - (0, _warning2.default)(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history'); - - window.location.replace(href); - } - }); - }; - - var go = function go(n) { - globalHistory.go(n); - }; - - var goBack = function goBack() { - return go(-1); - }; - - var goForward = function goForward() { - return go(1); - }; - - var listenerCount = 0; - var checkDOMListeners = function checkDOMListeners(delta) { - listenerCount += delta; + return this; + }, - if (listenerCount === 1) { - (0, _DOMUtils.addEventListener)(window, PopStateEvent, handlePopState); + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, - if (needsHashChangeListener) (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleHashChange); - } else if (listenerCount === 0) { - (0, _DOMUtils.removeEventListener)(window, PopStateEvent, handlePopState); + /** + * Generate the complete zip file as an internal stream. + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {StreamHelper} the streamed zip file. + */ + generateInternalStream: function(options) { + var worker, opts = {}; + try { + opts = utils.extend(options || {}, { + streamFiles: false, + compression: "STORE", + compressionOptions : null, + type: "", + platform: "DOS", + comment: null, + mimeType: 'application/zip', + encodeFileName: utf8.utf8encode + }); - if (needsHashChangeListener) (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleHashChange); - } - }; + opts.type = opts.type.toLowerCase(); + opts.compression = opts.compression.toUpperCase(); - var isBlocked = false; + // "binarystring" is prefered but the internals use "string". + if(opts.type === "binarystring") { + opts.type = "string"; + } - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (!opts.type) { + throw new Error("No output type specified."); + } - var unblock = transitionManager.setPrompt(prompt); + utils.checkSupport(opts.type); - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; - } + // accept nodejs `process.platform` + if( + opts.platform === 'darwin' || + opts.platform === 'freebsd' || + opts.platform === 'linux' || + opts.platform === 'sunos' + ) { + opts.platform = "UNIX"; + } + if (opts.platform === 'win32') { + opts.platform = "DOS"; + } - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); + var comment = opts.comment || this.comment || ""; + worker = generate.generateWorker(this, opts, comment); + } catch (e) { + worker = new GenericWorker("error"); + worker.error(e); } - - return unblock(); - }; - }; - - var listen = function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); - - return function () { - checkDOMListeners(-1); - unlisten(); - }; - }; - - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; - - return history; + return new StreamHelper(worker, opts.type || "string", opts.mimeType); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateAsync: function(options, onUpdate) { + return this.generateInternalStream(options).accumulate(onUpdate); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateNodeStream: function(options, onUpdate) { + options = options || {}; + if (!options.type) { + options.type = "nodebuffer"; + } + return this.generateInternalStream(options).toNodejsStream(onUpdate); + } }; +module.exports = out; -exports.default = createBrowserHistory; /***/ }), -/***/ "./node_modules/history/createHashHistory.js": -/*!***************************************************!*\ - !*** ./node_modules/history/createHashHistory.js ***! - \***************************************************/ +/***/ "./node_modules/jszip/lib/readable-stream-browser.js": +/*!***********************************************************!*\ + !*** ./node_modules/jszip/lib/readable-stream-browser.js ***! + \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -exports.__esModule = true; +/* + * This file is used by module bundlers (browserify/webpack/etc) when + * including a stream implementation. We use "readable-stream" to get a + * consistent behavior between nodejs versions but bundlers often have a shim + * for "stream". Using this shim greatly improve the compatibility and greatly + * reduce the final size of the bundle (only one stream implementation, not + * two). + */ +module.exports = __webpack_require__(/*! stream */ "./node_modules/webpack/node_modules/stream-browserify/index.js"); -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); +/***/ }), -var _warning2 = _interopRequireDefault(_warning); +/***/ "./node_modules/jszip/lib/reader/ArrayReader.js": +/*!******************************************************!*\ + !*** ./node_modules/jszip/lib/reader/ArrayReader.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -var _invariant = __webpack_require__(/*! invariant */ "./node_modules/invariant/browser.js"); +"use strict"; -var _invariant2 = _interopRequireDefault(_invariant); +var DataReader = __webpack_require__(/*! ./DataReader */ "./node_modules/jszip/lib/reader/DataReader.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); -var _LocationUtils = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/LocationUtils.js"); +function ArrayReader(data) { + DataReader.call(this, data); + for(var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xFF; + } +} +utils.inherits(ArrayReader, DataReader); +/** + * @see DataReader.byteAt + */ +ArrayReader.prototype.byteAt = function(i) { + return this.data[this.zero + i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i - this.zero; + } + } -var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); + return -1; +}; +/** + * @see DataReader.readAndCheckSignature + */ +ArrayReader.prototype.readAndCheckSignature = function (sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3), + data = this.readData(4); + return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3]; +}; +/** + * @see DataReader.readData + */ +ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + return []; + } + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = ArrayReader; -var _createTransitionManager = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/createTransitionManager.js"); -var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); +/***/ }), -var _DOMUtils = __webpack_require__(/*! ./DOMUtils */ "./node_modules/history/DOMUtils.js"); +/***/ "./node_modules/jszip/lib/reader/DataReader.js": +/*!*****************************************************!*\ + !*** ./node_modules/jszip/lib/reader/DataReader.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +"use strict"; -var HashChangeEvent = 'hashchange'; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); -var HashPathCoders = { - hashbang: { - encodePath: function encodePath(path) { - return path.charAt(0) === '!' ? path : '!/' + (0, _PathUtils.stripLeadingSlash)(path); - }, - decodePath: function decodePath(path) { - return path.charAt(0) === '!' ? path.substr(1) : path; +function DataReader(data) { + this.data = data; // type : see implementation + this.length = data.length; + this.index = 0; + this.zero = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specified index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < this.zero + newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function(i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function(size) { + // see implementations + }, + /** + * Find the last occurence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurence, -1 if not found. + */ + lastIndexOfSignature: function(sig) { + // see implementations + }, + /** + * Read the signature (4 bytes) at the current position and compare it with sig. + * @param {string} sig the expected signature + * @return {boolean} true if the signature matches, false otherwise. + */ + readAndCheckSignature: function(sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date(Date.UTC( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1)); // second } - }, - noslash: { - encodePath: _PathUtils.stripLeadingSlash, - decodePath: _PathUtils.addLeadingSlash - }, - slash: { - encodePath: _PathUtils.addLeadingSlash, - decodePath: _PathUtils.addLeadingSlash - } }; +module.exports = DataReader; -var getHashPath = function getHashPath() { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - var href = window.location.href; - var hashIndex = href.indexOf('#'); - return hashIndex === -1 ? '' : href.substring(hashIndex + 1); -}; -var pushHashPath = function pushHashPath(path) { - return window.location.hash = path; -}; +/***/ }), -var replaceHashPath = function replaceHashPath(path) { - var hashIndex = window.location.href.indexOf('#'); +/***/ "./node_modules/jszip/lib/reader/NodeBufferReader.js": +/*!***********************************************************!*\ + !*** ./node_modules/jszip/lib/reader/NodeBufferReader.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path); -}; +"use strict"; -var createHashHistory = function createHashHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; +var Uint8ArrayReader = __webpack_require__(/*! ./Uint8ArrayReader */ "./node_modules/jszip/lib/reader/Uint8ArrayReader.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); - (0, _invariant2.default)(_DOMUtils.canUseDOM, 'Hash history needs a DOM'); +function NodeBufferReader(data) { + Uint8ArrayReader.call(this, data); +} +utils.inherits(NodeBufferReader, Uint8ArrayReader); - var globalHistory = window.history; - var canGoWithoutReload = (0, _DOMUtils.supportsGoWithoutReloadUsingHash)(); +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; - var _props$getUserConfirm = props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === undefined ? _DOMUtils.getConfirmation : _props$getUserConfirm, - _props$hashType = props.hashType, - hashType = _props$hashType === undefined ? 'slash' : _props$hashType; - var basename = props.basename ? (0, _PathUtils.stripTrailingSlash)((0, _PathUtils.addLeadingSlash)(props.basename)) : ''; +/***/ }), - var _HashPathCoders$hashT = HashPathCoders[hashType], - encodePath = _HashPathCoders$hashT.encodePath, - decodePath = _HashPathCoders$hashT.decodePath; +/***/ "./node_modules/jszip/lib/reader/StringReader.js": +/*!*******************************************************!*\ + !*** ./node_modules/jszip/lib/reader/StringReader.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; - var getDOMLocation = function getDOMLocation() { - var path = decodePath(getHashPath()); +var DataReader = __webpack_require__(/*! ./DataReader */ "./node_modules/jszip/lib/reader/DataReader.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); - (0, _warning2.default)(!basename || (0, _PathUtils.hasBasename)(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); +function StringReader(data) { + DataReader.call(this, data); +} +utils.inherits(StringReader, DataReader); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(this.zero + i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig) - this.zero; +}; +/** + * @see DataReader.readAndCheckSignature + */ +StringReader.prototype.readAndCheckSignature = function (sig) { + var data = this.readData(4); + return sig === data; +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; - if (basename) path = (0, _PathUtils.stripBasename)(path, basename); - return (0, _LocationUtils.createLocation)(path); - }; +/***/ }), - var transitionManager = (0, _createTransitionManager2.default)(); +/***/ "./node_modules/jszip/lib/reader/Uint8ArrayReader.js": +/*!***********************************************************!*\ + !*** ./node_modules/jszip/lib/reader/Uint8ArrayReader.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var setState = function setState(nextState) { - _extends(history, nextState); +"use strict"; - history.length = globalHistory.length; +var ArrayReader = __webpack_require__(/*! ./ArrayReader */ "./node_modules/jszip/lib/reader/ArrayReader.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); - transitionManager.notifyListeners(history.location, history.action); - }; +function Uint8ArrayReader(data) { + ArrayReader.call(this, data); +} +utils.inherits(Uint8ArrayReader, ArrayReader); +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; - var forceNextPop = false; - var ignorePath = null; - var handleHashChange = function handleHashChange() { - var path = getHashPath(); - var encodedPath = encodePath(path); +/***/ }), - if (path !== encodedPath) { - // Ensure we always have a properly-encoded hash. - replaceHashPath(encodedPath); - } else { - var location = getDOMLocation(); - var prevLocation = history.location; +/***/ "./node_modules/jszip/lib/reader/readerFor.js": +/*!****************************************************!*\ + !*** ./node_modules/jszip/lib/reader/readerFor.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - if (!forceNextPop && (0, _LocationUtils.locationsAreEqual)(prevLocation, location)) return; // A hashchange doesn't always == location change. +"use strict"; - if (ignorePath === (0, _PathUtils.createPath)(location)) return; // Ignore this change; we already setState in push/replace. - ignorePath = null; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var support = __webpack_require__(/*! ../support */ "./node_modules/jszip/lib/support.js"); +var ArrayReader = __webpack_require__(/*! ./ArrayReader */ "./node_modules/jszip/lib/reader/ArrayReader.js"); +var StringReader = __webpack_require__(/*! ./StringReader */ "./node_modules/jszip/lib/reader/StringReader.js"); +var NodeBufferReader = __webpack_require__(/*! ./NodeBufferReader */ "./node_modules/jszip/lib/reader/NodeBufferReader.js"); +var Uint8ArrayReader = __webpack_require__(/*! ./Uint8ArrayReader */ "./node_modules/jszip/lib/reader/Uint8ArrayReader.js"); - handlePop(location); +/** + * Create a reader adapted to the data. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. + * @return {DataReader} the data reader. + */ +module.exports = function (data) { + var type = utils.getTypeOf(data); + utils.checkSupport(type); + if (type === "string" && !support.uint8array) { + return new StringReader(data); } - }; + if (type === "nodebuffer") { + return new NodeBufferReader(data); + } + if (support.uint8array) { + return new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + return new ArrayReader(utils.transformTo("array", data)); +}; - var handlePop = function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); - } else { - var action = 'POP'; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ action: action, location: location }); - } else { - revertPop(location); - } - }); - } - }; +/***/ }), - var revertPop = function revertPop(fromLocation) { - var toLocation = history.location; +/***/ "./node_modules/jszip/lib/signature.js": +/*!*********************************************!*\ + !*** ./node_modules/jszip/lib/signature.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - // TODO: We could probably make this more reliable by - // keeping a list of paths we've seen in sessionStorage. - // Instead, we just default to 0 for paths we don't know. +"use strict"; - var toIndex = allPaths.lastIndexOf((0, _PathUtils.createPath)(toLocation)); +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; - if (toIndex === -1) toIndex = 0; - var fromIndex = allPaths.lastIndexOf((0, _PathUtils.createPath)(fromLocation)); +/***/ }), - if (fromIndex === -1) fromIndex = 0; +/***/ "./node_modules/jszip/lib/stream/ConvertWorker.js": +/*!********************************************************!*\ + !*** ./node_modules/jszip/lib/stream/ConvertWorker.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var delta = toIndex - fromIndex; +"use strict"; - if (delta) { - forceNextPop = true; - go(delta); - } - }; - // Ensure the hash is encoded properly before doing anything else. - var path = getHashPath(); - var encodedPath = encodePath(path); +var GenericWorker = __webpack_require__(/*! ./GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); - if (path !== encodedPath) replaceHashPath(encodedPath); +/** + * A worker which convert chunks to a specified type. + * @constructor + * @param {String} destType the destination type. + */ +function ConvertWorker(destType) { + GenericWorker.call(this, "ConvertWorker to " + destType); + this.destType = destType; +} +utils.inherits(ConvertWorker, GenericWorker); - var initialLocation = getDOMLocation(); - var allPaths = [(0, _PathUtils.createPath)(initialLocation)]; +/** + * @see GenericWorker.processChunk + */ +ConvertWorker.prototype.processChunk = function (chunk) { + this.push({ + data : utils.transformTo(this.destType, chunk.data), + meta : chunk.meta + }); +}; +module.exports = ConvertWorker; - // Public interface - var createHref = function createHref(location) { - return '#' + encodePath(basename + (0, _PathUtils.createPath)(location)); - }; +/***/ }), - var push = function push(path, state) { - (0, _warning2.default)(state === undefined, 'Hash history cannot push state; it is ignored'); +/***/ "./node_modules/jszip/lib/stream/Crc32Probe.js": +/*!*****************************************************!*\ + !*** ./node_modules/jszip/lib/stream/Crc32Probe.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var action = 'PUSH'; - var location = (0, _LocationUtils.createLocation)(path, undefined, undefined, history.location); +"use strict"; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var path = (0, _PathUtils.createPath)(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; +var GenericWorker = __webpack_require__(/*! ./GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); +var crc32 = __webpack_require__(/*! ../crc32 */ "./node_modules/jszip/lib/crc32.js"); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); - if (hashChanged) { - // We cannot tell if a hashchange was caused by a PUSH, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - pushHashPath(encodedPath); +/** + * A worker which calculate the crc32 of the data flowing through. + * @constructor + */ +function Crc32Probe() { + GenericWorker.call(this, "Crc32Probe"); + this.withStreamInfo("crc32", 0); +} +utils.inherits(Crc32Probe, GenericWorker); - var prevIndex = allPaths.lastIndexOf((0, _PathUtils.createPath)(history.location)); - var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); +/** + * @see GenericWorker.processChunk + */ +Crc32Probe.prototype.processChunk = function (chunk) { + this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0); + this.push(chunk); +}; +module.exports = Crc32Probe; - nextPaths.push(path); - allPaths = nextPaths; - setState({ action: action, location: location }); - } else { - (0, _warning2.default)(false, 'Hash history cannot PUSH the same path; a new entry will not be added to the history stack'); +/***/ }), - setState(); - } - }); - }; +/***/ "./node_modules/jszip/lib/stream/DataLengthProbe.js": +/*!**********************************************************!*\ + !*** ./node_modules/jszip/lib/stream/DataLengthProbe.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var replace = function replace(path, state) { - (0, _warning2.default)(state === undefined, 'Hash history cannot replace state; it is ignored'); +"use strict"; - var action = 'REPLACE'; - var location = (0, _LocationUtils.createLocation)(path, undefined, undefined, history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ./GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); - var path = (0, _PathUtils.createPath)(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; +/** + * A worker which calculate the total length of the data flowing through. + * @constructor + * @param {String} propName the name used to expose the length + */ +function DataLengthProbe(propName) { + GenericWorker.call(this, "DataLengthProbe for " + propName); + this.propName = propName; + this.withStreamInfo(propName, 0); +} +utils.inherits(DataLengthProbe, GenericWorker); - if (hashChanged) { - // We cannot tell if a hashchange was caused by a REPLACE, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - replaceHashPath(encodedPath); - } +/** + * @see GenericWorker.processChunk + */ +DataLengthProbe.prototype.processChunk = function (chunk) { + if(chunk) { + var length = this.streamInfo[this.propName] || 0; + this.streamInfo[this.propName] = length + chunk.data.length; + } + GenericWorker.prototype.processChunk.call(this, chunk); +}; +module.exports = DataLengthProbe; - var prevIndex = allPaths.indexOf((0, _PathUtils.createPath)(history.location)); - if (prevIndex !== -1) allPaths[prevIndex] = path; - setState({ action: action, location: location }); - }); - }; +/***/ }), - var go = function go(n) { - (0, _warning2.default)(canGoWithoutReload, 'Hash history go(n) causes a full page reload in this browser'); +/***/ "./node_modules/jszip/lib/stream/DataWorker.js": +/*!*****************************************************!*\ + !*** ./node_modules/jszip/lib/stream/DataWorker.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - globalHistory.go(n); - }; +"use strict"; - var goBack = function goBack() { - return go(-1); - }; - var goForward = function goForward() { - return go(1); - }; +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var GenericWorker = __webpack_require__(/*! ./GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); - var listenerCount = 0; +// the size of the generated chunks +// TODO expose this as a public variable +var DEFAULT_BLOCK_SIZE = 16 * 1024; - var checkDOMListeners = function checkDOMListeners(delta) { - listenerCount += delta; +/** + * A worker that reads a content and emits chunks. + * @constructor + * @param {Promise} dataP the promise of the data to split + */ +function DataWorker(dataP) { + GenericWorker.call(this, "DataWorker"); + var self = this; + this.dataIsReady = false; + this.index = 0; + this.max = 0; + this.data = null; + this.type = ""; - if (listenerCount === 1) { - (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleHashChange); - } else if (listenerCount === 0) { - (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleHashChange); - } - }; + this._tickScheduled = false; - var isBlocked = false; + dataP.then(function (data) { + self.dataIsReady = true; + self.data = data; + self.max = data && data.length || 0; + self.type = utils.getTypeOf(data); + if(!self.isPaused) { + self._tickAndRepeat(); + } + }, function (e) { + self.error(e); + }); +} - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +utils.inherits(DataWorker, GenericWorker); - var unblock = transitionManager.setPrompt(prompt); +/** + * @see GenericWorker.cleanUp + */ +DataWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this.data = null; +}; - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; +/** + * @see GenericWorker.resume + */ +DataWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; } - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); - } - - return unblock(); - }; - }; + if (!this._tickScheduled && this.dataIsReady) { + this._tickScheduled = true; + utils.delay(this._tickAndRepeat, [], this); + } + return true; +}; - var listen = function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); +/** + * Trigger a tick a schedule an other call to this function. + */ +DataWorker.prototype._tickAndRepeat = function() { + this._tickScheduled = false; + if(this.isPaused || this.isFinished) { + return; + } + this._tick(); + if(!this.isFinished) { + utils.delay(this._tickAndRepeat, [], this); + this._tickScheduled = true; + } +}; - return function () { - checkDOMListeners(-1); - unlisten(); - }; - }; +/** + * Read and push a chunk. + */ +DataWorker.prototype._tick = function() { - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; + if(this.isPaused || this.isFinished) { + return false; + } - return history; + var size = DEFAULT_BLOCK_SIZE; + var data = null, nextIndex = Math.min(this.max, this.index + size); + if (this.index >= this.max) { + // EOF + return this.end(); + } else { + switch(this.type) { + case "string": + data = this.data.substring(this.index, nextIndex); + break; + case "uint8array": + data = this.data.subarray(this.index, nextIndex); + break; + case "array": + case "nodebuffer": + data = this.data.slice(this.index, nextIndex); + break; + } + this.index = nextIndex; + return this.push({ + data : data, + meta : { + percent : this.max ? this.index / this.max * 100 : 0 + } + }); + } }; -exports.default = createHashHistory; +module.exports = DataWorker; + /***/ }), -/***/ "./node_modules/history/createMemoryHistory.js": -/*!*****************************************************!*\ - !*** ./node_modules/history/createMemoryHistory.js ***! - \*****************************************************/ +/***/ "./node_modules/jszip/lib/stream/GenericWorker.js": +/*!********************************************************!*\ + !*** ./node_modules/jszip/lib/stream/GenericWorker.js ***! + \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); - -var _warning2 = _interopRequireDefault(_warning); - -var _PathUtils = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/PathUtils.js"); - -var _LocationUtils = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/LocationUtils.js"); - -var _createTransitionManager = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/createTransitionManager.js"); - -var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var clamp = function clamp(n, lowerBound, upperBound) { - return Math.min(Math.max(n, lowerBound), upperBound); -}; - /** - * Creates a history object that stores locations in memory. + * A worker that does nothing but passing chunks to the next one. This is like + * a nodejs stream but with some differences. On the good side : + * - it works on IE 6-9 without any issue / polyfill + * - it weights less than the full dependencies bundled with browserify + * - it forwards errors (no need to declare an error handler EVERYWHERE) + * + * A chunk is an object with 2 attributes : `meta` and `data`. The former is an + * object containing anything (`percent` for example), see each worker for more + * details. The latter is the real data (String, Uint8Array, etc). + * + * @constructor + * @param {String} name the name of the stream (mainly used for debugging purposes) */ -var createMemoryHistory = function createMemoryHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var getUserConfirmation = props.getUserConfirmation, - _props$initialEntries = props.initialEntries, - initialEntries = _props$initialEntries === undefined ? ['/'] : _props$initialEntries, - _props$initialIndex = props.initialIndex, - initialIndex = _props$initialIndex === undefined ? 0 : _props$initialIndex, - _props$keyLength = props.keyLength, - keyLength = _props$keyLength === undefined ? 6 : _props$keyLength; - - - var transitionManager = (0, _createTransitionManager2.default)(); - - var setState = function setState(nextState) { - _extends(history, nextState); +function GenericWorker(name) { + // the name of the worker + this.name = name || "default"; + // an object containing metadata about the workers chain + this.streamInfo = {}; + // an error which happened when the worker was paused + this.generatedError = null; + // an object containing metadata to be merged by this worker into the general metadata + this.extraStreamInfo = {}; + // true if the stream is paused (and should not do anything), false otherwise + this.isPaused = true; + // true if the stream is finished (and should not do anything), false otherwise + this.isFinished = false; + // true if the stream is locked to prevent further structure updates (pipe), false otherwise + this.isLocked = false; + // the event listeners + this._listeners = { + 'data':[], + 'end':[], + 'error':[] + }; + // the previous worker, if any + this.previous = null; +} - history.length = history.entries.length; +GenericWorker.prototype = { + /** + * Push a chunk to the next workers. + * @param {Object} chunk the chunk to push + */ + push : function (chunk) { + this.emit("data", chunk); + }, + /** + * End the stream. + * @return {Boolean} true if this call ended the worker, false otherwise. + */ + end : function () { + if (this.isFinished) { + return false; + } - transitionManager.notifyListeners(history.location, history.action); - }; + this.flush(); + try { + this.emit("end"); + this.cleanUp(); + this.isFinished = true; + } catch (e) { + this.emit("error", e); + } + return true; + }, + /** + * End the stream with an error. + * @param {Error} e the error which caused the premature end. + * @return {Boolean} true if this call ended the worker with an error, false otherwise. + */ + error : function (e) { + if (this.isFinished) { + return false; + } - var createKey = function createKey() { - return Math.random().toString(36).substr(2, keyLength); - }; + if(this.isPaused) { + this.generatedError = e; + } else { + this.isFinished = true; - var index = clamp(initialIndex, 0, initialEntries.length - 1); - var entries = initialEntries.map(function (entry) { - return typeof entry === 'string' ? (0, _LocationUtils.createLocation)(entry, undefined, createKey()) : (0, _LocationUtils.createLocation)(entry, undefined, entry.key || createKey()); - }); + this.emit("error", e); - // Public interface + // in the workers chain exploded in the middle of the chain, + // the error event will go downward but we also need to notify + // workers upward that there has been an error. + if(this.previous) { + this.previous.error(e); + } - var createHref = _PathUtils.createPath; + this.cleanUp(); + } + return true; + }, + /** + * Add a callback on an event. + * @param {String} name the name of the event (data, end, error) + * @param {Function} listener the function to call when the event is triggered + * @return {GenericWorker} the current object for chainability + */ + on : function (name, listener) { + this._listeners[name].push(listener); + return this; + }, + /** + * Clean any references when a worker is ending. + */ + cleanUp : function () { + this.streamInfo = this.generatedError = this.extraStreamInfo = null; + this._listeners = []; + }, + /** + * Trigger an event. This will call registered callback with the provided arg. + * @param {String} name the name of the event (data, end, error) + * @param {Object} arg the argument to call the callback with. + */ + emit : function (name, arg) { + if (this._listeners[name]) { + for(var i = 0; i < this._listeners[name].length; i++) { + this._listeners[name][i].call(this, arg); + } + } + }, + /** + * Chain a worker with an other. + * @param {Worker} next the worker receiving events from the current one. + * @return {worker} the next worker for chainability + */ + pipe : function (next) { + return next.registerPrevious(this); + }, + /** + * Same as `pipe` in the other direction. + * Using an API with `pipe(next)` is very easy. + * Implementing the API with the point of view of the next one registering + * a source is easier, see the ZipFileWorker. + * @param {Worker} previous the previous worker, sending events to this one + * @return {Worker} the current worker for chainability + */ + registerPrevious : function (previous) { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } - var push = function push(path, state) { - (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + // sharing the streamInfo... + this.streamInfo = previous.streamInfo; + // ... and adding our own bits + this.mergeStreamInfo(); + this.previous = previous; + var self = this; + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.end(); + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; + }, + /** + * Pause the stream so it doesn't send events anymore. + * @return {Boolean} true if this call paused the worker, false otherwise. + */ + pause : function () { + if(this.isPaused || this.isFinished) { + return false; + } + this.isPaused = true; - var action = 'PUSH'; - var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); + if(this.previous) { + this.previous.pause(); + } + return true; + }, + /** + * Resume a paused stream. + * @return {Boolean} true if this call resumed the worker, false otherwise. + */ + resume : function () { + if(!this.isPaused || this.isFinished) { + return false; + } + this.isPaused = false; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; + // if true, the worker tried to resume but failed + var withError = false; + if(this.generatedError) { + this.error(this.generatedError); + withError = true; + } + if(this.previous) { + this.previous.resume(); + } - var prevIndex = history.index; - var nextIndex = prevIndex + 1; + return !withError; + }, + /** + * Flush any remaining bytes as the stream is ending. + */ + flush : function () {}, + /** + * Process a chunk. This is usually the method overridden. + * @param {Object} chunk the chunk to process. + */ + processChunk : function(chunk) { + this.push(chunk); + }, + /** + * Add a key/value to be added in the workers chain streamInfo once activated. + * @param {String} key the key to use + * @param {Object} value the associated value + * @return {Worker} the current worker for chainability + */ + withStreamInfo : function (key, value) { + this.extraStreamInfo[key] = value; + this.mergeStreamInfo(); + return this; + }, + /** + * Merge this worker's streamInfo into the chain's streamInfo. + */ + mergeStreamInfo : function () { + for(var key in this.extraStreamInfo) { + if (!this.extraStreamInfo.hasOwnProperty(key)) { + continue; + } + this.streamInfo[key] = this.extraStreamInfo[key]; + } + }, - var nextEntries = history.entries.slice(0); - if (nextEntries.length > nextIndex) { - nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location); - } else { - nextEntries.push(location); - } + /** + * Lock the stream to prevent further updates on the workers chain. + * After calling this method, all calls to pipe will fail. + */ + lock: function () { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + this.isLocked = true; + if (this.previous) { + this.previous.lock(); + } + }, - setState({ - action: action, - location: location, - index: nextIndex, - entries: nextEntries - }); - }); - }; + /** + * + * Pretty print the workers chain. + */ + toString : function () { + var me = "Worker " + this.name; + if (this.previous) { + return this.previous + " -> " + me; + } else { + return me; + } + } +}; - var replace = function replace(path, state) { - (0, _warning2.default)(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); +module.exports = GenericWorker; - var action = 'REPLACE'; - var location = (0, _LocationUtils.createLocation)(path, state, createKey(), history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/***/ }), - history.entries[history.index] = location; +/***/ "./node_modules/jszip/lib/stream/StreamHelper.js": +/*!*******************************************************!*\ + !*** ./node_modules/jszip/lib/stream/StreamHelper.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - setState({ action: action, location: location }); - }); - }; +"use strict"; +/* WEBPACK VAR INJECTION */(function(Buffer) { - var go = function go(n) { - var nextIndex = clamp(history.index + n, 0, history.entries.length - 1); +var utils = __webpack_require__(/*! ../utils */ "./node_modules/jszip/lib/utils.js"); +var ConvertWorker = __webpack_require__(/*! ./ConvertWorker */ "./node_modules/jszip/lib/stream/ConvertWorker.js"); +var GenericWorker = __webpack_require__(/*! ./GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); +var base64 = __webpack_require__(/*! ../base64 */ "./node_modules/jszip/lib/base64.js"); +var support = __webpack_require__(/*! ../support */ "./node_modules/jszip/lib/support.js"); +var external = __webpack_require__(/*! ../external */ "./node_modules/jszip/lib/external.js"); - var action = 'POP'; - var location = history.entries[nextIndex]; +var NodejsStreamOutputAdapter = null; +if (support.nodestream) { + try { + NodejsStreamOutputAdapter = __webpack_require__(/*! ../nodejs/NodejsStreamOutputAdapter */ "./node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js"); + } catch(e) {} +} - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ - action: action, - location: location, - index: nextIndex - }); - } else { - // Mimic the behavior of DOM histories by - // causing a render after a cancelled POP. - setState(); - } - }); - }; +/** + * Apply the final transformation of the data. If the user wants a Blob for + * example, it's easier to work with an U8intArray and finally do the + * ArrayBuffer/Blob conversion. + * @param {String} type the name of the final type + * @param {String|Uint8Array|Buffer} content the content to transform + * @param {String} mimeType the mime type of the content, if applicable. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. + */ +function transformZipOutput(type, content, mimeType) { + switch(type) { + case "blob" : + return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType); + case "base64" : + return base64.encode(content); + default : + return utils.transformTo(type, content); + } +} - var goBack = function goBack() { - return go(-1); - }; +/** + * Concatenate an array of data of the given type. + * @param {String} type the type of the data in the given array. + * @param {Array} dataArray the array containing the data chunks to concatenate + * @return {String|Uint8Array|Buffer} the concatenated data + * @throws Error if the asked type is unsupported + */ +function concat (type, dataArray) { + var i, index = 0, res = null, totalLength = 0; + for(i = 0; i < dataArray.length; i++) { + totalLength += dataArray[i].length; + } + switch(type) { + case "string": + return dataArray.join(""); + case "array": + return Array.prototype.concat.apply([], dataArray); + case "uint8array": + res = new Uint8Array(totalLength); + for(i = 0; i < dataArray.length; i++) { + res.set(dataArray[i], index); + index += dataArray[i].length; + } + return res; + case "nodebuffer": + return Buffer.concat(dataArray); + default: + throw new Error("concat : unsupported type '" + type + "'"); + } +} - var goForward = function goForward() { - return go(1); - }; +/** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {StreamHelper} helper the helper to use. + * @param {Function} updateCallback a callback called on each update. Called + * with one arg : + * - the metadata linked to the update received. + * @return Promise the promise for the accumulation. + */ +function accumulate(helper, updateCallback) { + return new external.Promise(function (resolve, reject){ + var dataArray = []; + var chunkType = helper._internalType, + resultType = helper._outputType, + mimeType = helper._mimeType; + helper + .on('data', function (data, meta) { + dataArray.push(data); + if(updateCallback) { + updateCallback(meta); + } + }) + .on('error', function(err) { + dataArray = []; + reject(err); + }) + .on('end', function (){ + try { + var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType); + resolve(result); + } catch (e) { + reject(e); + } + dataArray = []; + }) + .resume(); + }); +} - var canGo = function canGo(n) { - var nextIndex = history.index + n; - return nextIndex >= 0 && nextIndex < history.entries.length; - }; +/** + * An helper to easily use workers outside of JSZip. + * @constructor + * @param {Worker} worker the worker to wrap + * @param {String} outputType the type of data expected by the use + * @param {String} mimeType the mime type of the content, if applicable. + */ +function StreamHelper(worker, outputType, mimeType) { + var internalType = outputType; + switch(outputType) { + case "blob": + case "arraybuffer": + internalType = "uint8array"; + break; + case "base64": + internalType = "string"; + break; + } - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - return transitionManager.setPrompt(prompt); - }; + try { + // the type used internally + this._internalType = internalType; + // the type used to output results + this._outputType = outputType; + // the mime type + this._mimeType = mimeType; + utils.checkSupport(internalType); + this._worker = worker.pipe(new ConvertWorker(internalType)); + // the last workers can be rewired without issues but we need to + // prevent any updates on previous workers. + worker.lock(); + } catch(e) { + this._worker = new GenericWorker("error"); + this._worker.error(e); + } +} - var listen = function listen(listener) { - return transitionManager.appendListener(listener); - }; +StreamHelper.prototype = { + /** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {Function} updateCb the update callback. + * @return Promise the promise for the accumulation. + */ + accumulate : function (updateCb) { + return accumulate(this, updateCb); + }, + /** + * Add a listener on an event triggered on a stream. + * @param {String} evt the name of the event + * @param {Function} fn the listener + * @return {StreamHelper} the current helper. + */ + on : function (evt, fn) { + var self = this; - var history = { - length: entries.length, - action: 'POP', - location: entries[index], - index: index, - entries: entries, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - canGo: canGo, - block: block, - listen: listen - }; + if(evt === "data") { + this._worker.on(evt, function (chunk) { + fn.call(self, chunk.data, chunk.meta); + }); + } else { + this._worker.on(evt, function () { + utils.delay(fn, arguments, self); + }); + } + return this; + }, + /** + * Resume the flow of chunks. + * @return {StreamHelper} the current helper. + */ + resume : function () { + utils.delay(this._worker.resume, [], this._worker); + return this; + }, + /** + * Pause the flow of chunks. + * @return {StreamHelper} the current helper. + */ + pause : function () { + this._worker.pause(); + return this; + }, + /** + * Return a nodejs stream for this helper. + * @param {Function} updateCb the update callback. + * @return {NodejsStreamOutputAdapter} the nodejs stream. + */ + toNodejsStream : function (updateCb) { + utils.checkSupport("nodestream"); + if (this._outputType !== "nodebuffer") { + // an object stream containing blob/arraybuffer/uint8array/string + // is strange and I don't know if it would be useful. + // I you find this comment and have a good usecase, please open a + // bug report ! + throw new Error(this._outputType + " is not supported by this method"); + } - return history; + return new NodejsStreamOutputAdapter(this, { + objectMode : this._outputType !== "nodebuffer" + }, updateCb); + } }; -exports.default = createMemoryHistory; + +module.exports = StreamHelper; + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/node_modules/buffer/index.js */ "./node_modules/webpack/node_modules/buffer/index.js").Buffer)) /***/ }), -/***/ "./node_modules/history/createTransitionManager.js": -/*!*********************************************************!*\ - !*** ./node_modules/history/createTransitionManager.js ***! - \*********************************************************/ +/***/ "./node_modules/jszip/lib/support.js": +/*!*******************************************!*\ + !*** ./node_modules/jszip/lib/support.js ***! + \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function(Buffer) { +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; -exports.__esModule = true; +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob('application/zip').size === 0; + } + catch (e) { + exports.blob = false; + } + } +} -var _warning = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); +try { + exports.nodestream = !!__webpack_require__(/*! readable-stream */ "./node_modules/jszip/lib/readable-stream-browser.js").Readable; +} catch(e) { + exports.nodestream = false; +} -var _warning2 = _interopRequireDefault(_warning); +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/node_modules/buffer/index.js */ "./node_modules/webpack/node_modules/buffer/index.js").Buffer)) -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/***/ }), -var createTransitionManager = function createTransitionManager() { - var prompt = null; +/***/ "./node_modules/jszip/lib/utf8.js": +/*!****************************************!*\ + !*** ./node_modules/jszip/lib/utf8.js ***! + \****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var setPrompt = function setPrompt(nextPrompt) { - (0, _warning2.default)(prompt == null, 'A history supports only one prompt at a time'); +"use strict"; - prompt = nextPrompt; - return function () { - if (prompt === nextPrompt) prompt = null; - }; - }; +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); +var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ "./node_modules/jszip/lib/nodejsUtils.js"); +var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); - var confirmTransitionTo = function confirmTransitionTo(location, action, getUserConfirmation, callback) { - // TODO: If another transition starts while we're still confirming - // the previous one, we may end up in a weird state. Figure out the - // best way to handle this. - if (prompt != null) { - var result = typeof prompt === 'function' ? prompt(location, action) : prompt; +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ - if (typeof result === 'string') { - if (typeof getUserConfirmation === 'function') { - getUserConfirmation(result, callback); - } else { - (0, _warning2.default)(false, 'A history needs a getUserConfirmation function in order to use a prompt message'); +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start - callback(true); +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } } - } else { - // Return false from a transition hook to cancel the transition. - callback(result !== false); - } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); } else { - callback(true); + buf = new Array(buf_len); } - }; - var listeners = []; + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } - var appendListener = function appendListener(fn) { - var isActive = true; + return buf; +}; - var listener = function listener() { - if (isActive) fn.apply(undefined, arguments); - }; +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; - listeners.push(listener); + max = max || buf.length; + if (max > buf.length) { max = buf.length; } - return function () { - isActive = false; - listeners = listeners.filter(function (item) { - return item !== listener; - }); - }; - }; + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - var notifyListeners = function notifyListeners() { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } - listeners.forEach(function (listener) { - return listener.apply(undefined, args); - }); - }; + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } - return { - setPrompt: setPrompt, - confirmTransitionTo: confirmTransitionTo, - appendListener: appendListener, - notifyListeners: notifyListeners - }; + return (pos + _utf8len[buf[pos]] > max) ? pos : max; }; -exports.default = createTransitionManager; - -/***/ }), +// convert array to string +var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; -/***/ "./node_modules/history/es/DOMUtils.js": -/*!*********************************************!*\ - !*** ./node_modules/history/es/DOMUtils.js ***! - \*********************************************/ -/*! exports provided: canUseDOM, addEventListener, removeEventListener, getConfirmation, supportsHistory, supportsPopStateOnHashChange, supportsGoWithoutReloadUsingHash, isExtraneousPopstateEvent */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canUseDOM", function() { return canUseDOM; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addEventListener", function() { return addEventListener; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeEventListener", function() { return removeEventListener; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getConfirmation", function() { return getConfirmation; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportsHistory", function() { return supportsHistory; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportsPopStateOnHashChange", function() { return supportsPopStateOnHashChange; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportsGoWithoutReloadUsingHash", function() { return supportsGoWithoutReloadUsingHash; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isExtraneousPopstateEvent", function() { return isExtraneousPopstateEvent; }); -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } -var removeEventListener = function removeEventListener(node, event, listener) { - return node.removeEventListener ? node.removeEventListener(event, listener, false) : node.detachEvent('on' + event, listener); -}; + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } -var getConfirmation = function getConfirmation(message, callback) { - return callback(window.confirm(message)); -}; // eslint-disable-line no-alert + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } -/** - * Returns true if the HTML5 history API is supported. Taken from Modernizr. - * - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586 - */ -var supportsHistory = function supportsHistory() { - var ua = window.navigator.userAgent; + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } - return window.history && 'pushState' in window.history; + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); }; -/** - * Returns true if browser fires popstate on hash change. - * IE10 and IE11 do not. - */ -var supportsPopStateOnHashChange = function supportsPopStateOnHashChange() { - return window.navigator.userAgent.indexOf('Trident') === -1; -}; -/** - * Returns false if using go(n) with hash history causes a full page reload. - */ -var supportsGoWithoutReloadUsingHash = function supportsGoWithoutReloadUsingHash() { - return window.navigator.userAgent.indexOf('Firefox') === -1; -}; +// That's all for the pako functions. + /** - * Returns true if a given popstate event is an extraneous WebKit event. - * Accounts for the fact that Chrome on iOS fires real popstate events - * containing undefined state when pressing the back button. + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. */ -var isExtraneousPopstateEvent = function isExtraneousPopstateEvent(event) { - return event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1; -}; - -/***/ }), - -/***/ "./node_modules/history/es/LocationUtils.js": -/*!**************************************************!*\ - !*** ./node_modules/history/es/LocationUtils.js ***! - \**************************************************/ -/*! exports provided: createLocation, locationsAreEqual */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createLocation", function() { return createLocation; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "locationsAreEqual", function() { return locationsAreEqual; }); -/* harmony import */ var resolve_pathname__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! resolve-pathname */ "./node_modules/resolve-pathname/index.js"); -/* harmony import */ var value_equal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! value-equal */ "./node_modules/value-equal/index.js"); -/* harmony import */ var _PathUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/es/PathUtils.js"); -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - - -var createLocation = function createLocation(path, state, key, currentLocation) { - var location = void 0; - if (typeof path === 'string') { - // Two-arg form: push(path, state) - location = Object(_PathUtils__WEBPACK_IMPORTED_MODULE_2__["parsePath"])(path); - location.state = state; - } else { - // One-arg form: push(location) - location = _extends({}, path); - - if (location.pathname === undefined) location.pathname = ''; - - if (location.search) { - if (location.search.charAt(0) !== '?') location.search = '?' + location.search; - } else { - location.search = ''; - } - - if (location.hash) { - if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash; - } else { - location.hash = ''; +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodejsUtils.newBufferFrom(str, "utf-8"); } - if (state !== undefined && location.state === undefined) location.state = state; - } - - try { - location.pathname = decodeURI(location.pathname); - } catch (e) { - if (e instanceof URIError) { - throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.'); - } else { - throw e; - } - } + return string2buf(str); +}; - if (key) location.key = key; - if (currentLocation) { - // Resolve incomplete/relative pathname relative to current location. - if (!location.pathname) { - location.pathname = currentLocation.pathname; - } else if (location.pathname.charAt(0) !== '/') { - location.pathname = Object(resolve_pathname__WEBPACK_IMPORTED_MODULE_0__["default"])(location.pathname, currentLocation.pathname); - } - } else { - // When there is no prior location and pathname is empty, set it to / - if (!location.pathname) { - location.pathname = '/'; +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); } - } - return location; -}; + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); -var locationsAreEqual = function locationsAreEqual(a, b) { - return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && Object(value_equal__WEBPACK_IMPORTED_MODULE_1__["default"])(a.state, b.state); + return buf2string(buf); }; -/***/ }), +/** + * A worker to decode utf8 encoded binary chunks into string chunks. + * @constructor + */ +function Utf8DecodeWorker() { + GenericWorker.call(this, "utf-8 decode"); + // the last bytes if a chunk didn't end with a complete codepoint. + this.leftOver = null; +} +utils.inherits(Utf8DecodeWorker, GenericWorker); -/***/ "./node_modules/history/es/PathUtils.js": -/*!**********************************************!*\ - !*** ./node_modules/history/es/PathUtils.js ***! - \**********************************************/ -/*! exports provided: addLeadingSlash, stripLeadingSlash, hasBasename, stripBasename, stripTrailingSlash, parsePath, createPath */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/** + * @see GenericWorker.processChunk + */ +Utf8DecodeWorker.prototype.processChunk = function (chunk) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addLeadingSlash", function() { return addLeadingSlash; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stripLeadingSlash", function() { return stripLeadingSlash; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasBasename", function() { return hasBasename; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stripBasename", function() { return stripBasename; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stripTrailingSlash", function() { return stripTrailingSlash; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parsePath", function() { return parsePath; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createPath", function() { return createPath; }); -var addLeadingSlash = function addLeadingSlash(path) { - return path.charAt(0) === '/' ? path : '/' + path; -}; + var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data); -var stripLeadingSlash = function stripLeadingSlash(path) { - return path.charAt(0) === '/' ? path.substr(1) : path; -}; + // 1st step, re-use what's left of the previous chunk + if (this.leftOver && this.leftOver.length) { + if(support.uint8array) { + var previousData = data; + data = new Uint8Array(previousData.length + this.leftOver.length); + data.set(this.leftOver, 0); + data.set(previousData, this.leftOver.length); + } else { + data = this.leftOver.concat(data); + } + this.leftOver = null; + } -var hasBasename = function hasBasename(path, prefix) { - return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); -}; + var nextBoundary = utf8border(data); + var usableData = data; + if (nextBoundary !== data.length) { + if (support.uint8array) { + usableData = data.subarray(0, nextBoundary); + this.leftOver = data.subarray(nextBoundary, data.length); + } else { + usableData = data.slice(0, nextBoundary); + this.leftOver = data.slice(nextBoundary, data.length); + } + } -var stripBasename = function stripBasename(path, prefix) { - return hasBasename(path, prefix) ? path.substr(prefix.length) : path; + this.push({ + data : exports.utf8decode(usableData), + meta : chunk.meta + }); }; -var stripTrailingSlash = function stripTrailingSlash(path) { - return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path; +/** + * @see GenericWorker.flush + */ +Utf8DecodeWorker.prototype.flush = function () { + if(this.leftOver && this.leftOver.length) { + this.push({ + data : exports.utf8decode(this.leftOver), + meta : {} + }); + this.leftOver = null; + } }; +exports.Utf8DecodeWorker = Utf8DecodeWorker; -var parsePath = function parsePath(path) { - var pathname = path || '/'; - var search = ''; - var hash = ''; - - var hashIndex = pathname.indexOf('#'); - if (hashIndex !== -1) { - hash = pathname.substr(hashIndex); - pathname = pathname.substr(0, hashIndex); - } - - var searchIndex = pathname.indexOf('?'); - if (searchIndex !== -1) { - search = pathname.substr(searchIndex); - pathname = pathname.substr(0, searchIndex); - } +/** + * A worker to endcode string chunks into utf8 encoded binary chunks. + * @constructor + */ +function Utf8EncodeWorker() { + GenericWorker.call(this, "utf-8 encode"); +} +utils.inherits(Utf8EncodeWorker, GenericWorker); - return { - pathname: pathname, - search: search === '?' ? '' : search, - hash: hash === '#' ? '' : hash - }; +/** + * @see GenericWorker.processChunk + */ +Utf8EncodeWorker.prototype.processChunk = function (chunk) { + this.push({ + data : exports.utf8encode(chunk.data), + meta : chunk.meta + }); }; +exports.Utf8EncodeWorker = Utf8EncodeWorker; -var createPath = function createPath(location) { - var pathname = location.pathname, - search = location.search, - hash = location.hash; - - - var path = pathname || '/'; - - if (search && search !== '?') path += search.charAt(0) === '?' ? search : '?' + search; - - if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : '#' + hash; - - return path; -}; /***/ }), -/***/ "./node_modules/history/es/createBrowserHistory.js": -/*!*********************************************************!*\ - !*** ./node_modules/history/es/createBrowserHistory.js ***! - \*********************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ "./node_modules/jszip/lib/utils.js": +/*!*****************************************!*\ + !*** ./node_modules/jszip/lib/utils.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(warning__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! invariant */ "./node_modules/invariant/browser.js"); -/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(invariant__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _LocationUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/es/LocationUtils.js"); -/* harmony import */ var _PathUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/es/PathUtils.js"); -/* harmony import */ var _createTransitionManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/es/createTransitionManager.js"); -/* harmony import */ var _DOMUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./DOMUtils */ "./node_modules/history/es/DOMUtils.js"); -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +var support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); +var base64 = __webpack_require__(/*! ./base64 */ "./node_modules/jszip/lib/base64.js"); +var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ "./node_modules/jszip/lib/nodejsUtils.js"); +var setImmediate = __webpack_require__(/*! core-js/library/fn/set-immediate */ "./node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js"); +var external = __webpack_require__(/*! ./external */ "./node_modules/jszip/lib/external.js"); +/** + * Convert a string that pass as a "binary string": it should represent a byte + * array but may have > 255 char codes. Be sure to take only the first byte + * and returns the byte array. + * @param {String} str the string to transform. + * @return {Array|Uint8Array} the string in a binary format. + */ +function string2binary(str) { + var result = null; + if (support.uint8array) { + result = new Uint8Array(str.length); + } else { + result = new Array(str.length); + } + return stringToArrayLike(str, result); +} +/** + * Create a new blob with the given content and the given type. + * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use + * an Uint8Array because the stock browser of android 4 won't accept it (it + * will be silently converted to a string, "[object Uint8Array]"). + * + * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge: + * when a large amount of Array is used to create the Blob, the amount of + * memory consumed is nearly 100 times the original data amount. + * + * @param {String} type the mime type of the blob. + * @return {Blob} the created blob. + */ +exports.newBlob = function(part, type) { + exports.checkSupport("blob"); + try { + // Blob constructor + return new Blob([part], { + type: type + }); + } + catch (e) { + try { + // deprecated, browser only, old way + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(part); + return builder.getBlob(type); + } + catch (e) { + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } -var PopStateEvent = 'popstate'; -var HashChangeEvent = 'hashchange'; -var getHistoryState = function getHistoryState() { - try { - return window.history.state || {}; - } catch (e) { - // IE 11 sometimes throws when accessing window.history.state - // See https://github.com/ReactTraining/history/pull/289 - return {}; - } }; - /** - * Creates a history object that uses the HTML5 history API including - * pushState, replaceState, and the popstate event. + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. */ -var createBrowserHistory = function createBrowserHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - invariant__WEBPACK_IMPORTED_MODULE_1___default()(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["canUseDOM"], 'Browser history needs a DOM'); - - var globalHistory = window.history; - var canUseHistory = Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["supportsHistory"])(); - var needsHashChangeListener = !Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["supportsPopStateOnHashChange"])(); +function identity(input) { + return input; +} - var _props$forceRefresh = props.forceRefresh, - forceRefresh = _props$forceRefresh === undefined ? false : _props$forceRefresh, - _props$getUserConfirm = props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === undefined ? _DOMUtils__WEBPACK_IMPORTED_MODULE_5__["getConfirmation"] : _props$getUserConfirm, - _props$keyLength = props.keyLength, - keyLength = _props$keyLength === undefined ? 6 : _props$keyLength; +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} - var basename = props.basename ? Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripTrailingSlash"])(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["addLeadingSlash"])(props.basename)) : ''; +/** + * An helper for the function arrayLikeToString. + * This contains static informations and functions that + * can be optimized by the browser JIT compiler. + */ +var arrayToStringHelper = { + /** + * Transform an array of int into a string, chunk by chunk. + * See the performances notes on arrayLikeToString. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @param {String} type the type of the array. + * @param {Integer} chunk the chunk size. + * @return {String} the resulting string. + * @throws Error if the chunk is too big for the stack. + */ + stringifyByChunk: function(array, type, chunk) { + var result = [], k = 0, len = array.length; + // shortcut + if (len <= chunk) { + return String.fromCharCode.apply(null, array); + } + while (k < len) { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + return result.join(""); + }, + /** + * Call String.fromCharCode on every item in the array. + * This is the naive implementation, which generate A LOT of intermediate string. + * This should be used when everything else fail. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ + stringifyByChar: function(array){ + var resultStr = ""; + for(var i = 0; i < array.length; i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + }, + applyCanBeUsed : { + /** + * true if the browser accepts to use String.fromCharCode on Uint8Array + */ + uint8array : (function () { + try { + return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1; + } catch (e) { + return false; + } + })(), + /** + * true if the browser accepts to use String.fromCharCode on nodejs Buffer. + */ + nodebuffer : (function () { + try { + return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)).length === 1; + } catch (e) { + return false; + } + })() + } +}; - var getDOMLocation = function getDOMLocation(historyState) { - var _ref = historyState || {}, - key = _ref.key, - state = _ref.state; +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + // TODO : we now have workers that split the work. Do we still need that ? + var chunk = 65536, + type = exports.getTypeOf(array), + canUseApply = true; + if (type === "uint8array") { + canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array; + } else if (type === "nodebuffer") { + canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer; + } - var _window$location = window.location, - pathname = _window$location.pathname, - search = _window$location.search, - hash = _window$location.hash; + if (canUseApply) { + while (chunk > 1) { + try { + return arrayToStringHelper.stringifyByChunk(array, type, chunk); + } catch (e) { + chunk = Math.floor(chunk / 2); + } + } + } + // no apply or chunk error : slow and painful algorithm + // default browser on android 4.* + return arrayToStringHelper.stringifyByChar(array); +} - var path = pathname + search + hash; +exports.applyFromCharCode = arrayLikeToString; - warning__WEBPACK_IMPORTED_MODULE_0___default()(!basename || Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["hasBasename"])(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); - if (basename) path = Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripBasename"])(path, basename); +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} - return Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, state, key); - }; +// a matrix containing functions to transform everything into everything. +var transform = {}; - var createKey = function createKey() { - return Math.random().toString(36).substr(2, keyLength); - }; +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodejsUtils.allocBuffer(input.length)); + } +}; - var transitionManager = Object(_createTransitionManager__WEBPACK_IMPORTED_MODULE_4__["default"])(); - - var setState = function setState(nextState) { - _extends(history, nextState); - - history.length = globalHistory.length; - - transitionManager.notifyListeners(history.location, history.action); - }; - - var handlePopState = function handlePopState(event) { - // Ignore extraneous popstate events in WebKit. - if (Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["isExtraneousPopstateEvent"])(event)) return; - - handlePop(getDOMLocation(event.state)); - }; - - var handleHashChange = function handleHashChange() { - handlePop(getDOMLocation(getHistoryState())); - }; - - var forceNextPop = false; - - var handlePop = function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); - } else { - var action = 'POP'; - - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ action: action, location: location }); - } else { - revertPop(location); - } - }); +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); } - }; - - var revertPop = function revertPop(fromLocation) { - var toLocation = history.location; - - // TODO: We could probably make this more reliable by - // keeping a list of keys we've seen in sessionStorage. - // Instead, we just default to 0 for keys we don't know. - - var toIndex = allKeys.indexOf(toLocation.key); +}; - if (toIndex === -1) toIndex = 0; +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(new Uint8Array(input)); + } +}; - var fromIndex = allKeys.indexOf(fromLocation.key); +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); + } +}; - if (fromIndex === -1) fromIndex = 0; +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; - var delta = toIndex - fromIndex; +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; - if (delta) { - forceNextPop = true; - go(delta); +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; } - }; + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodejsUtils.isBuffer(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; - var initialLocation = getDOMLocation(getHistoryState()); - var allKeys = [initialLocation.key]; +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this platform"); + } +}; - // Public interface +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 - var createHref = function createHref(location) { - return basename + Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(location); - }; +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = '', + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; - var push = function push(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); +/** + * Defer the call of a function. + * @param {Function} callback the function to call asynchronously. + * @param {Array} args the arguments to give to the callback. + */ +exports.delay = function(callback, args, self) { + setImmediate(function () { + callback.apply(self || null, args || []); + }); +}; - var action = 'PUSH'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, state, createKey(), history.location); +/** + * Extends a prototype with an other, without calling a constructor with + * side effects. Inspired by nodejs' `utils.inherits` + * @param {Function} ctor the constructor to augment + * @param {Function} superCtor the parent constructor to use + */ +exports.inherits = function (ctor, superCtor) { + var Obj = function() {}; + Obj.prototype = superCtor.prototype; + ctor.prototype = new Obj(); +}; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +exports.extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; - var href = createHref(location); - var key = location.key, - state = location.state; +/** + * Transform arbitrary content into a Promise. + * @param {String} name a name for the content being processed. + * @param {Object} inputData the content to process. + * @param {Boolean} isBinary true if the content is not an unicode string + * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. + * @param {Boolean} isBase64 true if the string content is encoded with base64. + * @return {Promise} a promise in a format usable by JSZip. + */ +exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) { + // if inputData is already a promise, this flatten it. + var promise = external.Promise.resolve(inputData).then(function(data) { + + + var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1); - if (canUseHistory) { - globalHistory.pushState({ key: key, state: state }, null, href); + if (isBlob && typeof FileReader !== "undefined") { + return new external.Promise(function (resolve, reject) { + var reader = new FileReader(); - if (forceRefresh) { - window.location.href = href; + reader.onload = function(e) { + resolve(e.target.result); + }; + reader.onerror = function(e) { + reject(e.target.error); + }; + reader.readAsArrayBuffer(data); + }); } else { - var prevIndex = allKeys.indexOf(history.location.key); - var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); + return data; + } + }); - nextKeys.push(location.key); - allKeys = nextKeys; + return promise.then(function(data) { + var dataType = exports.getTypeOf(data); - setState({ action: action, location: location }); + if (!dataType) { + return external.Promise.reject( + new Error("Can't read the data of '" + name + "'. Is it " + + "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?") + ); } - } else { - warning__WEBPACK_IMPORTED_MODULE_0___default()(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history'); - - window.location.href = href; - } + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = exports.transformTo("uint8array", data); + } else if (dataType === "string") { + if (isBase64) { + data = base64.decode(data); + } + else if (isBinary) { + // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask + if (isOptimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = string2binary(data); + } + } + } + return data; }); - }; +}; - var replace = function replace(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - var action = 'REPLACE'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, state, createKey(), history.location); +/***/ }), - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/***/ "./node_modules/jszip/lib/zipEntries.js": +/*!**********************************************!*\ + !*** ./node_modules/jszip/lib/zipEntries.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var href = createHref(location); - var key = location.key, - state = location.state; +"use strict"; +var readerFor = __webpack_require__(/*! ./reader/readerFor */ "./node_modules/jszip/lib/reader/readerFor.js"); +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var sig = __webpack_require__(/*! ./signature */ "./node_modules/jszip/lib/signature.js"); +var ZipEntry = __webpack_require__(/*! ./zipEntry */ "./node_modules/jszip/lib/zipEntry.js"); +var utf8 = __webpack_require__(/*! ./utf8 */ "./node_modules/jszip/lib/utf8.js"); +var support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(loadOptions) { + this.files = []; + this.loadOptions = loadOptions; +} +ZipEntries.prototype = { + /** + * Check that the reader is on the specified signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + if (!this.reader.readAndCheckSignature(expectedSignature)) { + this.reader.index -= 4; + var signature = this.reader.readString(4); + throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Check if the given signature is at the given index. + * @param {number} askedIndex the index to check. + * @param {string} expectedSignature the signature to expect. + * @return {boolean} true if the signature is here, false otherwise. + */ + isSignature: function(askedIndex, expectedSignature) { + var currentIndex = this.reader.index; + this.reader.setIndex(askedIndex); + var signature = this.reader.readString(4); + var result = signature === expectedSignature; + this.reader.setIndex(currentIndex); + return result; + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); - if (canUseHistory) { - globalHistory.replaceState({ key: key, state: state }, null, href); + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + var zipComment = this.reader.readData(this.zipCommentLength); + var decodeParamType = support.uint8array ? "uint8array" : "array"; + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded unless specified otherwise. + var decodeContent = utils.transformTo(decodeParamType, zipComment); + this.zipComment = this.loadOptions.decodeFileName(decodeContent); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.reader.skip(4); + // this.versionMadeBy = this.reader.readString(2); + // this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); - if (forceRefresh) { - window.location.replace(href); - } else { - var prevIndex = allKeys.indexOf(history.location.key); + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readData(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; - if (prevIndex !== -1) allKeys[prevIndex] = location.key; + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) { + file = new ZipEntry({ + zip64: this.zip64 + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } - setState({ action: action, location: location }); + if (this.centralDirRecords !== this.files.length) { + if (this.centralDirRecords !== 0 && this.files.length === 0) { + // We expected some records but couldn't find ANY. + // This is really suspicious, as if something went wrong. + throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); + } else { + // We found some records but not all. + // Something is wrong but we got something for the user: no error here. + // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); + } } - } else { - warning__WEBPACK_IMPORTED_MODULE_0___default()(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history'); + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset < 0) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); - window.location.replace(href); - } - }); - }; + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip: can't find end of central directory"); + } - var go = function go(n) { - globalHistory.go(n); - }; + } + this.reader.setIndex(offset); + var endOfCentralDirOffset = offset; + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); - var goBack = function goBack() { - return go(-1); - }; - var goForward = function goForward() { - return go(1); - }; - - var listenerCount = 0; - - var checkDOMListeners = function checkDOMListeners(delta) { - listenerCount += delta; - - if (listenerCount === 1) { - Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["addEventListener"])(window, PopStateEvent, handlePopState); + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; - if (needsHashChangeListener) Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["addEventListener"])(window, HashChangeEvent, handleHashChange); - } else if (listenerCount === 0) { - Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["removeEventListener"])(window, PopStateEvent, handlePopState); + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ - if (needsHashChangeListener) Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["removeEventListener"])(window, HashChangeEvent, handleHashChange); - } - }; + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); - var isBlocked = false; + // now the zip64 EOCD record + if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) { + // console.warn("ZIP64 end of central directory not where expected."); + this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + if (this.relativeOffsetEndOfZip64CentralDir < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory"); + } + } + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize; + if (this.zip64) { + expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator + expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize; + } - var unblock = transitionManager.setPrompt(prompt); + var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset; - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; + if (extraBytes > 0) { + // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); + if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) { + // The offsets seem wrong, but we have something at the specified offset. + // So… we keep it. + } else { + // the offset is wrong, update the "zero" of the reader + // this happens if data has been prepended (crx files for example) + this.reader.zero = extraBytes; + } + } else if (extraBytes < 0) { + throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes."); + } + }, + prepareReader: function(data) { + this.reader = readerFor(data); + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); } - - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); - } - - return unblock(); - }; - }; - - var listen = function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); - - return function () { - checkDOMListeners(-1); - unlisten(); - }; - }; - - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; - - return history; }; +// }}} end of ZipEntries +module.exports = ZipEntries; -/* harmony default export */ __webpack_exports__["default"] = (createBrowserHistory); /***/ }), -/***/ "./node_modules/history/es/createHashHistory.js": -/*!******************************************************!*\ - !*** ./node_modules/history/es/createHashHistory.js ***! - \******************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ "./node_modules/jszip/lib/zipEntry.js": +/*!********************************************!*\ + !*** ./node_modules/jszip/lib/zipEntry.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(warning__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! invariant */ "./node_modules/invariant/browser.js"); -/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(invariant__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _LocationUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/es/LocationUtils.js"); -/* harmony import */ var _PathUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/es/PathUtils.js"); -/* harmony import */ var _createTransitionManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/es/createTransitionManager.js"); -/* harmony import */ var _DOMUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./DOMUtils */ "./node_modules/history/es/DOMUtils.js"); -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - - - +var readerFor = __webpack_require__(/*! ./reader/readerFor */ "./node_modules/jszip/lib/reader/readerFor.js"); +var utils = __webpack_require__(/*! ./utils */ "./node_modules/jszip/lib/utils.js"); +var CompressedObject = __webpack_require__(/*! ./compressedObject */ "./node_modules/jszip/lib/compressedObject.js"); +var crc32fn = __webpack_require__(/*! ./crc32 */ "./node_modules/jszip/lib/crc32.js"); +var utf8 = __webpack_require__(/*! ./utf8 */ "./node_modules/jszip/lib/utf8.js"); +var compressions = __webpack_require__(/*! ./compressions */ "./node_modules/jszip/lib/compressions.js"); +var support = __webpack_require__(/*! ./support */ "./node_modules/jszip/lib/support.js"); -var HashChangeEvent = 'hashchange'; +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; -var HashPathCoders = { - hashbang: { - encodePath: function encodePath(path) { - return path.charAt(0) === '!' ? path : '!/' + Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripLeadingSlash"])(path); - }, - decodePath: function decodePath(path) { - return path.charAt(0) === '!' ? path.substr(1) : path; +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +var findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } } - }, - noslash: { - encodePath: _PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripLeadingSlash"], - decodePath: _PathUtils__WEBPACK_IMPORTED_MODULE_3__["addLeadingSlash"] - }, - slash: { - encodePath: _PathUtils__WEBPACK_IMPORTED_MODULE_3__["addLeadingSlash"], - decodePath: _PathUtils__WEBPACK_IMPORTED_MODULE_3__["addLeadingSlash"] - } + return null; }; -var getHashPath = function getHashPath() { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - var href = window.location.href; - var hashIndex = href.indexOf('#'); - return hashIndex === -1 ? '' : href.substring(hashIndex + 1); -}; +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var compression, localExtraFieldsLength; -var pushHashPath = function pushHashPath(path) { - return window.location.hash = path; -}; + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. + this.fileName = reader.readData(this.fileNameLength); + reader.skip(localExtraFieldsLength); -var replaceHashPath = function replaceHashPath(path) { - var hashIndex = window.location.href.indexOf('#'); + if (this.compressedSize === -1 || this.uncompressedSize === -1) { + throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); + } - window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path); -}; + compression = findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); + } + this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize)); + }, -var createHashHistory = function createHashHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + reader.skip(2); + // this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + var fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); - invariant__WEBPACK_IMPORTED_MODULE_1___default()(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["canUseDOM"], 'Hash history needs a DOM'); + if (this.isEncrypted()) { + throw new Error("Encrypted zip are not supported"); + } - var globalHistory = window.history; - var canGoWithoutReload = Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["supportsGoWithoutReloadUsingHash"])(); + // will be read in the local part, see the comments there + reader.skip(fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readData(this.fileCommentLength); + }, - var _props$getUserConfirm = props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === undefined ? _DOMUtils__WEBPACK_IMPORTED_MODULE_5__["getConfirmation"] : _props$getUserConfirm, - _props$hashType = props.hashType, - hashType = _props$hashType === undefined ? 'slash' : _props$hashType; + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; - var basename = props.basename ? Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripTrailingSlash"])(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["addLeadingSlash"])(props.basename)) : ''; + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; - var _HashPathCoders$hashT = HashPathCoders[hashType], - encodePath = _HashPathCoders$hashT.encodePath, - decodePath = _HashPathCoders$hashT.decodePath; + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } - var getDOMLocation = function getDOMLocation() { - var path = decodePath(getHashPath()); + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileNameStr.slice(-1) === '/') { + this.dir = true; + } + }, - warning__WEBPACK_IMPORTED_MODULE_0___default()(!basename || Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["hasBasename"])(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function(reader) { - if (basename) path = Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["stripBasename"])(path, basename); + if (!this.extraFields[0x0001]) { + return; + } - return Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path); - }; + // should be something, preparing the extra reader + var extraReader = readerFor(this.extraFields[0x0001].value); - var transitionManager = Object(_createTransitionManager__WEBPACK_IMPORTED_MODULE_4__["default"])(); + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var end = reader.index + this.extraFieldsLength, + extraFieldId, + extraFieldLength, + extraFieldValue; - var setState = function setState(nextState) { - _extends(history, nextState); + if (!this.extraFields) { + this.extraFields = {}; + } - history.length = globalHistory.length; + while (reader.index < end) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readData(extraFieldLength); - transitionManager.notifyListeners(history.location, history.action); - }; + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + var decodeParamType = support.uint8array ? "uint8array" : "array"; + if (this.useUTF8()) { + this.fileNameStr = utf8.utf8decode(this.fileName); + this.fileCommentStr = utf8.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileNameStr = upath; + } else { + // ASCII text or unsupported code page + var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); + this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); + } - var forceNextPop = false; - var ignorePath = null; + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileCommentStr = ucomment; + } else { + // ASCII text or unsupported code page + var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); + this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); + } + } + }, - var handleHashChange = function handleHashChange() { - var path = getHashPath(); - var encodedPath = encodePath(path); + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = readerFor(upathField.value); - if (path !== encodedPath) { - // Ensure we always have a properly-encoded hash. - replaceHashPath(encodedPath); - } else { - var location = getDOMLocation(); - var prevLocation = history.location; + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } - if (!forceNextPop && Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["locationsAreEqual"])(prevLocation, location)) return; // A hashchange doesn't always == location change. + // the crc of the filename changed, this field is out of date. + if (crc32fn(this.fileName) !== extraReader.readInt(4)) { + return null; + } - if (ignorePath === Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(location)) return; // Ignore this change; we already setState in push/replace. + return utf8.utf8decode(extraReader.readData(upathField.length - 5)); + } + return null; + }, - ignorePath = null; + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = readerFor(ucommentField.value); - handlePop(location); - } - }; + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } - var handlePop = function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); - } else { - var action = 'POP'; + // the crc of the comment changed, this field is out of date. + if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { + return null; + } - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ action: action, location: location }); - } else { - revertPop(location); + return utf8.utf8decode(extraReader.readData(ucommentField.length - 5)); } - }); + return null; } - }; +}; +module.exports = ZipEntry; - var revertPop = function revertPop(fromLocation) { - var toLocation = history.location; - // TODO: We could probably make this more reliable by - // keeping a list of paths we've seen in sessionStorage. - // Instead, we just default to 0 for paths we don't know. +/***/ }), - var toIndex = allPaths.lastIndexOf(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(toLocation)); +/***/ "./node_modules/jszip/lib/zipObject.js": +/*!*********************************************!*\ + !*** ./node_modules/jszip/lib/zipObject.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - if (toIndex === -1) toIndex = 0; +"use strict"; - var fromIndex = allPaths.lastIndexOf(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(fromLocation)); - if (fromIndex === -1) fromIndex = 0; +var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ "./node_modules/jszip/lib/stream/StreamHelper.js"); +var DataWorker = __webpack_require__(/*! ./stream/DataWorker */ "./node_modules/jszip/lib/stream/DataWorker.js"); +var utf8 = __webpack_require__(/*! ./utf8 */ "./node_modules/jszip/lib/utf8.js"); +var CompressedObject = __webpack_require__(/*! ./compressedObject */ "./node_modules/jszip/lib/compressedObject.js"); +var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ "./node_modules/jszip/lib/stream/GenericWorker.js"); - var delta = toIndex - fromIndex; +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; - if (delta) { - forceNextPop = true; - go(delta); - } - }; + this._data = data; + this._dataBinary = options.binary; + // keep only the compression + this.options = { + compression : options.compression, + compressionOptions : options.compressionOptions + }; +}; - // Ensure the hash is encoded properly before doing anything else. - var path = getHashPath(); - var encodedPath = encodePath(path); +ZipObject.prototype = { + /** + * Create an internal stream for the content of this object. + * @param {String} type the type of each chunk. + * @return StreamHelper the stream. + */ + internalStream: function (type) { + var result = null, outputType = "string"; + try { + if (!type) { + throw new Error("No output type specified."); + } + outputType = type.toLowerCase(); + var askUnicodeString = outputType === "string" || outputType === "text"; + if (outputType === "binarystring" || outputType === "text") { + outputType = "string"; + } + result = this._decompressWorker(); - if (path !== encodedPath) replaceHashPath(encodedPath); + var isUnicodeString = !this._dataBinary; - var initialLocation = getDOMLocation(); - var allPaths = [Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(initialLocation)]; + if (isUnicodeString && !askUnicodeString) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + if (!isUnicodeString && askUnicodeString) { + result = result.pipe(new utf8.Utf8DecodeWorker()); + } + } catch (e) { + result = new GenericWorker("error"); + result.error(e); + } - // Public interface + return new StreamHelper(result, outputType, ""); + }, - var createHref = function createHref(location) { - return '#' + encodePath(basename + Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(location)); - }; + /** + * Prepare the content in the asked type. + * @param {String} type the type of the result. + * @param {Function} onUpdate a function to call on each internal update. + * @return Promise the promise of the result. + */ + async: function (type, onUpdate) { + return this.internalStream(type).accumulate(onUpdate); + }, - var push = function push(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(state === undefined, 'Hash history cannot push state; it is ignored'); + /** + * Prepare the content as a nodejs stream. + * @param {String} type the type of each chunk. + * @param {Function} onUpdate a function to call on each internal update. + * @return Stream the stream. + */ + nodeStream: function (type, onUpdate) { + return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate); + }, - var action = 'PUSH'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, undefined, undefined, history.location); + /** + * Return a worker for the compressed content. + * @private + * @param {Object} compression the compression object to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return Worker the worker. + */ + _compressWorker: function (compression, compressionOptions) { + if ( + this._data instanceof CompressedObject && + this._data.compression.magic === compression.magic + ) { + return this._data.getCompressedWorker(); + } else { + var result = this._decompressWorker(); + if(!this._dataBinary) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + return CompressedObject.createWorkerFrom(result, compression, compressionOptions); + } + }, + /** + * Return a worker for the decompressed content. + * @private + * @return Worker the worker. + */ + _decompressWorker : function () { + if (this._data instanceof CompressedObject) { + return this._data.getContentWorker(); + } else if (this._data instanceof GenericWorker) { + return this._data; + } else { + return new DataWorker(this._data); + } + } +}; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"]; +var removedFn = function () { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); +}; - var path = Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; +for(var i = 0; i < removedMethods.length; i++) { + ZipObject.prototype[removedMethods[i]] = removedFn; +} +module.exports = ZipObject; - if (hashChanged) { - // We cannot tell if a hashchange was caused by a PUSH, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - pushHashPath(encodedPath); - var prevIndex = allPaths.lastIndexOf(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(history.location)); - var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); +/***/ }), - nextPaths.push(path); - allPaths = nextPaths; +/***/ "./node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js": +/*!*****************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js ***! + \*****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - setState({ action: action, location: location }); - } else { - warning__WEBPACK_IMPORTED_MODULE_0___default()(false, 'Hash history cannot PUSH the same path; a new entry will not be added to the history stack'); +__webpack_require__(/*! ../modules/web.immediate */ "./node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js"); +module.exports = __webpack_require__(/*! ../modules/_core */ "./node_modules/jszip/node_modules/core-js/library/modules/_core.js").setImmediate; - setState(); - } - }); - }; +/***/ }), - var replace = function replace(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(state === undefined, 'Hash history cannot replace state; it is ignored'); +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_a-function.js": +/*!********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_a-function.js ***! + \********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - var action = 'REPLACE'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, undefined, undefined, history.location); +module.exports = function(it){ + if(typeof it != 'function')throw TypeError(it + ' is not a function!'); + return it; +}; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/***/ }), - var path = Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_an-object.js": +/*!*******************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_an-object.js ***! + \*******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - if (hashChanged) { - // We cannot tell if a hashchange was caused by a REPLACE, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - replaceHashPath(encodedPath); - } +var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/jszip/node_modules/core-js/library/modules/_is-object.js"); +module.exports = function(it){ + if(!isObject(it))throw TypeError(it + ' is not an object!'); + return it; +}; - var prevIndex = allPaths.indexOf(Object(_PathUtils__WEBPACK_IMPORTED_MODULE_3__["createPath"])(history.location)); +/***/ }), - if (prevIndex !== -1) allPaths[prevIndex] = path; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_cof.js": +/*!*************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_cof.js ***! + \*************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - setState({ action: action, location: location }); - }); - }; +var toString = {}.toString; - var go = function go(n) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(canGoWithoutReload, 'Hash history go(n) causes a full page reload in this browser'); +module.exports = function(it){ + return toString.call(it).slice(8, -1); +}; - globalHistory.go(n); - }; +/***/ }), - var goBack = function goBack() { - return go(-1); - }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_core.js": +/*!**************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_core.js ***! + \**************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - var goForward = function goForward() { - return go(1); - }; +var core = module.exports = {version: '2.3.0'}; +if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef - var listenerCount = 0; +/***/ }), - var checkDOMListeners = function checkDOMListeners(delta) { - listenerCount += delta; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_ctx.js": +/*!*************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_ctx.js ***! + \*************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - if (listenerCount === 1) { - Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["addEventListener"])(window, HashChangeEvent, handleHashChange); - } else if (listenerCount === 0) { - Object(_DOMUtils__WEBPACK_IMPORTED_MODULE_5__["removeEventListener"])(window, HashChangeEvent, handleHashChange); - } +// optional / simple context binding +var aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/jszip/node_modules/core-js/library/modules/_a-function.js"); +module.exports = function(fn, that, length){ + aFunction(fn); + if(that === undefined)return fn; + switch(length){ + case 1: return function(a){ + return fn.call(that, a); + }; + case 2: return function(a, b){ + return fn.call(that, a, b); + }; + case 3: return function(a, b, c){ + return fn.call(that, a, b, c); + }; + } + return function(/* ...args */){ + return fn.apply(that, arguments); }; +}; - var isBlocked = false; +/***/ }), - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js": +/*!*********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js ***! + \*********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var unblock = transitionManager.setPrompt(prompt); +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(/*! ./_fails */ "./node_modules/jszip/node_modules/core-js/library/modules/_fails.js")(function(){ + return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; +}); - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; - } +/***/ }), - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); - } +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js": +/*!********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js ***! + \********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - return unblock(); - }; - }; +var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/jszip/node_modules/core-js/library/modules/_is-object.js") + , document = __webpack_require__(/*! ./_global */ "./node_modules/jszip/node_modules/core-js/library/modules/_global.js").document + // in old IE typeof document.createElement is 'object' + , is = isObject(document) && isObject(document.createElement); +module.exports = function(it){ + return is ? document.createElement(it) : {}; +}; - var listen = function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); +/***/ }), - return function () { - checkDOMListeners(-1); - unlisten(); - }; - }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_export.js": +/*!****************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_export.js ***! + \****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; +var global = __webpack_require__(/*! ./_global */ "./node_modules/jszip/node_modules/core-js/library/modules/_global.js") + , core = __webpack_require__(/*! ./_core */ "./node_modules/jszip/node_modules/core-js/library/modules/_core.js") + , ctx = __webpack_require__(/*! ./_ctx */ "./node_modules/jszip/node_modules/core-js/library/modules/_ctx.js") + , hide = __webpack_require__(/*! ./_hide */ "./node_modules/jszip/node_modules/core-js/library/modules/_hide.js") + , PROTOTYPE = 'prototype'; - return history; +var $export = function(type, name, source){ + var IS_FORCED = type & $export.F + , IS_GLOBAL = type & $export.G + , IS_STATIC = type & $export.S + , IS_PROTO = type & $export.P + , IS_BIND = type & $export.B + , IS_WRAP = type & $export.W + , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) + , expProto = exports[PROTOTYPE] + , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] + , key, own, out; + if(IS_GLOBAL)source = name; + for(key in source){ + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if(own && key in exports)continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function(C){ + var F = function(a, b, c){ + if(this instanceof C){ + switch(arguments.length){ + case 0: return new C; + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if(IS_PROTO){ + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); + } + } }; - -/* harmony default export */ __webpack_exports__["default"] = (createHashHistory); +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; /***/ }), -/***/ "./node_modules/history/es/createMemoryHistory.js": -/*!********************************************************!*\ - !*** ./node_modules/history/es/createMemoryHistory.js ***! - \********************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(warning__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _PathUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PathUtils */ "./node_modules/history/es/PathUtils.js"); -/* harmony import */ var _LocationUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./LocationUtils */ "./node_modules/history/es/LocationUtils.js"); -/* harmony import */ var _createTransitionManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./createTransitionManager */ "./node_modules/history/es/createTransitionManager.js"); -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_fails.js": +/*!***************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_fails.js ***! + \***************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +module.exports = function(exec){ + try { + return !!exec(); + } catch(e){ + return true; + } +}; +/***/ }), +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_global.js": +/*!****************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_global.js ***! + \****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); +if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef +/***/ }), +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_hide.js": +/*!**************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_hide.js ***! + \**************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -var clamp = function clamp(n, lowerBound, upperBound) { - return Math.min(Math.max(n, lowerBound), upperBound); +var dP = __webpack_require__(/*! ./_object-dp */ "./node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js") + , createDesc = __webpack_require__(/*! ./_property-desc */ "./node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js"); +module.exports = __webpack_require__(/*! ./_descriptors */ "./node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js") ? function(object, key, value){ + return dP.f(object, key, createDesc(1, value)); +} : function(object, key, value){ + object[key] = value; + return object; }; -/** - * Creates a history object that stores locations in memory. - */ -var createMemoryHistory = function createMemoryHistory() { - var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var getUserConfirmation = props.getUserConfirmation, - _props$initialEntries = props.initialEntries, - initialEntries = _props$initialEntries === undefined ? ['/'] : _props$initialEntries, - _props$initialIndex = props.initialIndex, - initialIndex = _props$initialIndex === undefined ? 0 : _props$initialIndex, - _props$keyLength = props.keyLength, - keyLength = _props$keyLength === undefined ? 6 : _props$keyLength; +/***/ }), +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_html.js": +/*!**************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_html.js ***! + \**************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var transitionManager = Object(_createTransitionManager__WEBPACK_IMPORTED_MODULE_3__["default"])(); +module.exports = __webpack_require__(/*! ./_global */ "./node_modules/jszip/node_modules/core-js/library/modules/_global.js").document && document.documentElement; - var setState = function setState(nextState) { - _extends(history, nextState); +/***/ }), - history.length = history.entries.length; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js": +/*!************************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js ***! + \************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - transitionManager.notifyListeners(history.location, history.action); - }; +module.exports = !__webpack_require__(/*! ./_descriptors */ "./node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js") && !__webpack_require__(/*! ./_fails */ "./node_modules/jszip/node_modules/core-js/library/modules/_fails.js")(function(){ + return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ "./node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js")('div'), 'a', {get: function(){ return 7; }}).a != 7; +}); - var createKey = function createKey() { - return Math.random().toString(36).substr(2, keyLength); - }; +/***/ }), - var index = clamp(initialIndex, 0, initialEntries.length - 1); - var entries = initialEntries.map(function (entry) { - return typeof entry === 'string' ? Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(entry, undefined, createKey()) : Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(entry, undefined, entry.key || createKey()); - }); +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_invoke.js": +/*!****************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_invoke.js ***! + \****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - // Public interface - - var createHref = _PathUtils__WEBPACK_IMPORTED_MODULE_1__["createPath"]; - - var push = function push(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - - var action = 'PUSH'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, state, createKey(), history.location); - - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - - var prevIndex = history.index; - var nextIndex = prevIndex + 1; +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function(fn, args, that){ + var un = that === undefined; + switch(args.length){ + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); +}; - var nextEntries = history.entries.slice(0); - if (nextEntries.length > nextIndex) { - nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location); - } else { - nextEntries.push(location); - } +/***/ }), - setState({ - action: action, - location: location, - index: nextIndex, - entries: nextEntries - }); - }); - }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_is-object.js": +/*!*******************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_is-object.js ***! + \*******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - var replace = function replace(path, state) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(!((typeof path === 'undefined' ? 'undefined' : _typeof(path)) === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); +module.exports = function(it){ + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; - var action = 'REPLACE'; - var location = Object(_LocationUtils__WEBPACK_IMPORTED_MODULE_2__["createLocation"])(path, state, createKey(), history.location); +/***/ }), - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js": +/*!*******************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js ***! + \*******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - history.entries[history.index] = location; +var anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/jszip/node_modules/core-js/library/modules/_an-object.js") + , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ "./node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js") + , toPrimitive = __webpack_require__(/*! ./_to-primitive */ "./node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js") + , dP = Object.defineProperty; - setState({ action: action, location: location }); - }); - }; +exports.f = __webpack_require__(/*! ./_descriptors */ "./node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js") ? Object.defineProperty : function defineProperty(O, P, Attributes){ + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if(IE8_DOM_DEFINE)try { + return dP(O, P, Attributes); + } catch(e){ /* empty */ } + if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); + if('value' in Attributes)O[P] = Attributes.value; + return O; +}; - var go = function go(n) { - var nextIndex = clamp(history.index + n, 0, history.entries.length - 1); +/***/ }), - var action = 'POP'; - var location = history.entries[nextIndex]; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js": +/*!***********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js ***! + \***********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ - action: action, - location: location, - index: nextIndex - }); - } else { - // Mimic the behavior of DOM histories by - // causing a render after a cancelled POP. - setState(); - } - }); +module.exports = function(bitmap, value){ + return { + enumerable : !(bitmap & 1), + configurable: !(bitmap & 2), + writable : !(bitmap & 4), + value : value }; +}; - var goBack = function goBack() { - return go(-1); - }; +/***/ }), - var goForward = function goForward() { - return go(1); - }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_task.js": +/*!**************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_task.js ***! + \**************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var canGo = function canGo(n) { - var nextIndex = history.index + n; - return nextIndex >= 0 && nextIndex < history.entries.length; +var ctx = __webpack_require__(/*! ./_ctx */ "./node_modules/jszip/node_modules/core-js/library/modules/_ctx.js") + , invoke = __webpack_require__(/*! ./_invoke */ "./node_modules/jszip/node_modules/core-js/library/modules/_invoke.js") + , html = __webpack_require__(/*! ./_html */ "./node_modules/jszip/node_modules/core-js/library/modules/_html.js") + , cel = __webpack_require__(/*! ./_dom-create */ "./node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js") + , global = __webpack_require__(/*! ./_global */ "./node_modules/jszip/node_modules/core-js/library/modules/_global.js") + , process = global.process + , setTask = global.setImmediate + , clearTask = global.clearImmediate + , MessageChannel = global.MessageChannel + , counter = 0 + , queue = {} + , ONREADYSTATECHANGE = 'onreadystatechange' + , defer, channel, port; +var run = function(){ + var id = +this; + if(queue.hasOwnProperty(id)){ + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function(event){ + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if(!setTask || !clearTask){ + setTask = function setImmediate(fn){ + var args = [], i = 1; + while(arguments.length > i)args.push(arguments[i++]); + queue[++counter] = function(){ + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; }; - - var block = function block() { - var prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - return transitionManager.setPrompt(prompt); + clearTask = function clearImmediate(id){ + delete queue[id]; }; + // Node.js 0.8- + if(__webpack_require__(/*! ./_cof */ "./node_modules/jszip/node_modules/core-js/library/modules/_cof.js")(process) == 'process'){ + defer = function(id){ + process.nextTick(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if(MessageChannel){ + channel = new MessageChannel; + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ + defer = function(id){ + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if(ONREADYSTATECHANGE in cel('script')){ + defer = function(id){ + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function(id){ + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask +}; - var listen = function listen(listener) { - return transitionManager.appendListener(listener); - }; +/***/ }), - var history = { - length: entries.length, - action: 'POP', - location: entries[index], - index: index, - entries: entries, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - canGo: canGo, - block: block, - listen: listen - }; +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js": +/*!**********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js ***! + \**********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - return history; +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/jszip/node_modules/core-js/library/modules/_is-object.js"); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function(it, S){ + if(!isObject(it))return it; + var fn, val; + if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; + if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + throw TypeError("Can't convert object to primitive value"); }; -/* harmony default export */ __webpack_exports__["default"] = (createMemoryHistory); - /***/ }), -/***/ "./node_modules/history/es/createTransitionManager.js": -/*!************************************************************!*\ - !*** ./node_modules/history/es/createTransitionManager.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ "./node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js": +/*!**********************************************************************************!*\ + !*** ./node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js ***! + \**********************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! warning */ "./node_modules/warning/browser.js"); -/* harmony import */ var warning__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(warning__WEBPACK_IMPORTED_MODULE_0__); +var $export = __webpack_require__(/*! ./_export */ "./node_modules/jszip/node_modules/core-js/library/modules/_export.js") + , $task = __webpack_require__(/*! ./_task */ "./node_modules/jszip/node_modules/core-js/library/modules/_task.js"); +$export($export.G + $export.B, { + setImmediate: $task.set, + clearImmediate: $task.clear +}); +/***/ }), -var createTransitionManager = function createTransitionManager() { - var prompt = null; +/***/ "./node_modules/jszip/node_modules/immediate/lib/browser.js": +/*!******************************************************************!*\ + !*** ./node_modules/jszip/node_modules/immediate/lib/browser.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { - var setPrompt = function setPrompt(nextPrompt) { - warning__WEBPACK_IMPORTED_MODULE_0___default()(prompt == null, 'A history supports only one prompt at a time'); +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) { +var Mutation = global.MutationObserver || global.WebKitMutationObserver; - prompt = nextPrompt; +var scheduleDrain; - return function () { - if (prompt === nextPrompt) prompt = null; +{ + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = global.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); }; - }; - - var confirmTransitionTo = function confirmTransitionTo(location, action, getUserConfirmation, callback) { - // TODO: If another transition starts while we're still confirming - // the previous one, we may end up in a weird state. Figure out the - // best way to handle this. - if (prompt != null) { - var result = typeof prompt === 'function' ? prompt(location, action) : prompt; - - if (typeof result === 'string') { - if (typeof getUserConfirmation === 'function') { - getUserConfirmation(result, callback); - } else { - warning__WEBPACK_IMPORTED_MODULE_0___default()(false, 'A history needs a getUserConfirmation function in order to use a prompt message'); - - callback(true); - } - } else { - // Return false from a transition hook to cancel the transition. - callback(result !== false); - } - } else { - callback(true); - } - }; - - var listeners = []; - - var appendListener = function appendListener(fn) { - var isActive = true; - - var listener = function listener() { - if (isActive) fn.apply(undefined, arguments); + } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { + var channel = new global.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); }; + } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { + scheduleDrain = function () { - listeners.push(listener); + // Create a