Make WordPress Core

Ticket #9757: 9757.2.patch

File 9757.2.patch, 403.1 KB (added by imath, 7 years ago)
  • src/wp-admin/css/themes.css

    diff --git src/wp-admin/css/themes.css src/wp-admin/css/themes.css
    index eece216..7865cae 100644
    body.folded .theme-browser ~ .theme-overlay .theme-wrap { 
    10541054        margin: 30px auto;
    10551055        max-width: 380px;
    10561056}
     1057.upload-plugin .wp-upload-form #existing-plugin-info h3 {
     1058        margin-top: 8px;
     1059}
     1060.upload-plugin .wp-upload-form .plugin-card-top {
     1061        padding-top: 10px;
     1062}
     1063.upload-plugin .wp-upload-form.has-existing-plugin #install-plugin-submit,
     1064.upload-plugin .wp-upload-form.has-existing-plugin .install-plugin-reset {
     1065        display: inline-block;
     1066        margin-top: 20px;
     1067        margin-right: 10px;
     1068}
     1069
    10571070.upload-theme .install-help,
    10581071.upload-plugin .install-help {
    10591072        color: #555d66; /* #f1f1f1 background */
  • src/wp-admin/includes/class-plugin-upgrader.php

    diff --git src/wp-admin/includes/class-plugin-upgrader.php src/wp-admin/includes/class-plugin-upgrader.php
    index 3c05353..e6abed1 100644
    class Plugin_Upgrader extends WP_Upgrader { 
    5353                $this->strings['remove_old_failed'] = __('Could not remove the old plugin.');
    5454                $this->strings['process_failed'] = __('Plugin update failed.');
    5555                $this->strings['process_success'] = __('Plugin updated successfully.');
     56                $this->strings['overwrite_success'] = __('Plugin replaced successfully.');
    5657                $this->strings['process_bulk_success'] = __('Plugins updated successfully.');
    5758        }
    5859
    class Plugin_Upgrader extends WP_Upgrader { 
    136137         * @param array  $args {
    137138         *     Optional. Other arguments for upgrading a plugin package. Default empty array.
    138139         *
    139          *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
    140          *                                    Default true.
     140         *     @type bool   $clear_update_cache Whether to clear the plugin updates cache if successful.
     141         *                                      Default true.
     142         *     @type string $package            Path to the package to replace an existing plugin with.
     143         *                                      Default ''.
    141144         * }
    142145         * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise.
    143146         */
    class Plugin_Upgrader extends WP_Upgrader { 
    145148
    146149                $defaults = array(
    147150                        'clear_update_cache' => true,
     151                        'package'            => '',
    148152                );
    149153                $parsed_args = wp_parse_args( $args, $defaults );
    150154
    151155                $this->init();
    152156                $this->upgrade_strings();
    153157
    154                 $current = get_site_transient( 'update_plugins' );
    155                 if ( !isset( $current->response[ $plugin ] ) ) {
    156                         $this->skin->before();
    157                         $this->skin->set_result(false);
    158                         $this->skin->error('up_to_date');
    159                         $this->skin->after();
    160                         return false;
    161                 }
     158                $package = $parsed_args['package'];
     159                if ( ! $package ) {
     160                        $current = get_site_transient( 'update_plugins' );
     161                        if ( !isset( $current->response[ $plugin ] ) ) {
     162                                $this->skin->before();
     163                                $this->skin->set_result(false);
     164                                $this->skin->error('up_to_date');
     165                                $this->skin->after();
     166                                return false;
     167                        }
    162168
    163                 // Get the URL to the zip file
    164                 $r = $current->response[ $plugin ];
     169                        // Get the URL to the zip file
     170                        $r = $current->response[ $plugin ];
     171                        $package = $r->package;
     172                        $action  = 'update';
     173                } else {
     174                        $action  = 'overwrite';
     175                }
    165176
    166177                add_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'), 10, 2);
    167178                add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);
    class Plugin_Upgrader extends WP_Upgrader { 
    172183                }
    173184
    174185                $this->run( array(
    175                         'package' => $r->package,
     186                        'package' => $package,
    176187                        'destination' => WP_PLUGIN_DIR,
    177188                        'clear_destination' => true,
    178189                        'clear_working' => true,
    179190                        'hook_extra' => array(
    180191                                'plugin' => $plugin,
    181192                                'type' => 'plugin',
    182                                 'action' => 'update',
     193                                'action' => $action,
    183194                        ),
    184195                ) );
    185196
  • src/wp-admin/includes/class-wp-upgrader.php

    diff --git src/wp-admin/includes/class-wp-upgrader.php src/wp-admin/includes/class-wp-upgrader.php
    index fd70ba4..7f8469c 100644
    class WP_Upgrader { 
    157157
    158158                $this->strings['download_failed'] = __('Download failed.');
    159159                $this->strings['installing_package'] = __('Installing the latest version…');
     160                $this->strings['package_overwriting'] = __('Replacing the installed version…');
    160161                $this->strings['no_files'] = __('The package contains no files.');
    161162                $this->strings['folder_exists'] = __('Destination folder already exists.');
    162163                $this->strings['mkdir_failed'] = __('Could not create directory.');
    class WP_Upgrader { 
    451452                if ( empty( $source ) || empty( $destination ) ) {
    452453                        return new WP_Error( 'bad_request', $this->strings['bad_request'] );
    453454                }
    454                 $this->skin->feedback( 'installing_package' );
     455
     456                if ( isset( $args['hook_extra']['action'] ) && 'overwrite' === $args['hook_extra']['action'] ) {
     457                        // Overwriting the existing plugin
     458                        $this->skin->feedback( 'package_overwriting' );
     459                } else {
     460                        $this->skin->feedback( 'installing_package' );
     461                }
    455462
    456463                /**
    457464                 * Filters the install response before the installation has started.
    class WP_Upgrader { 
    751758                        $this->skin->error($result);
    752759                        $this->skin->feedback('process_failed');
    753760                } else {
    754                         // Installation succeeded.
    755                         $this->skin->feedback('process_success');
     761
     762                        if ( isset( $options['hook_extra']['action'] ) && 'overwrite' === $options['hook_extra']['action'] ) {
     763                                // Overwrite succeeded.
     764                                $this->skin->feedback( 'overwrite_success' );
     765                        } else {
     766                                // Installation succeeded.
     767                                $this->skin->feedback('process_success');
     768                        }
    756769                }
    757770
    758771                $this->skin->after();
  • src/wp-admin/includes/plugin-install.php

    diff --git src/wp-admin/includes/plugin-install.php src/wp-admin/includes/plugin-install.php
    index 1714acd..c4087f4 100644
    function install_plugins_upload() { 
    310310                <?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?>
    311311        </form>
    312312</div>
     313<script type="text/html" id="tmpl-existing-plugin-data">
     314        <div id="existing-plugin-info">
     315                <p class="attention">{{{data.warnOverwrite}}}</p>
     316                <div class="plugin-card-top">
     317                        <h3>{{data.pluginDetailsIntro}}</h3>
     318                        <div class="desc">
     319                                <h4>{{data.name}} {{data.version}}</h4>
     320                                <p class="description">{{{data.description}}}</p>
     321                        </div>
     322                </div>
     323                <input type="hidden" name="overwrite" value="{{data.id}}"/>
     324        </div>
     325</script>
    313326<?php
    314327}
    315328
  • src/wp-admin/js/common.js

    diff --git src/wp-admin/js/common.js src/wp-admin/js/common.js
    index e57af5d..e40015c 100644
    $document.ready( function() { 
    687687                        e.target.scrollIntoView(false);
    688688        });
    689689
    690         // Disable upload buttons until files are selected
    691         (function(){
    692                 var button, input, form = $('form.wp-upload-form');
    693                 if ( ! form.length )
    694                         return;
    695                 button = form.find('input[type="submit"]');
    696                 input = form.find('input[type="file"]');
    697 
    698                 function toggleUploadButton() {
    699                         button.prop('disabled', '' === input.map( function() {
    700                                 return $(this).val();
    701                         }).get().join(''));
    702                 }
    703                 toggleUploadButton();
    704                 input.on('change', toggleUploadButton);
    705         })();
    706 
    707690        function pinMenu( event ) {
    708691                var windowPos = $window.scrollTop(),
    709692                        resizing = ! event || event.type !== 'scroll';
  • src/wp-admin/js/plugin-install.js

    diff --git src/wp-admin/js/plugin-install.js src/wp-admin/js/plugin-install.js
    index 9fa218f..9faade1 100644
    jQuery( document ).ready( function( $ ) { 
    1212                $firstTabbable,
    1313                $lastTabbable,
    1414                $focusedBefore = $(),
    15                 $uploadViewToggle = $( '.upload-view-toggle' ),
    16                 $wrap = $ ( '.wrap' ),
    1715                $body = $( document.body );
    1816
    1917        tb_position = function() {
    jQuery( document ).ready( function( $ ) { 
    191189                $( '#section-holder div.section' ).hide(); // Hide 'em all.
    192190                $( '#section-' + tab ).show();
    193191        });
    194 
    195         /*
    196          * When a user presses the "Upload Plugin" button, show the upload form in place
    197          * rather than sending them to the devoted upload plugin page.
    198          * The `?tab=upload` page still exists for no-js support and for plugins that
    199          * might access it directly. When we're in this page, let the link behave
    200          * like a link. Otherwise we're in the normal plugin installer pages and the
    201          * link should behave like a toggle button.
    202          */
    203         if ( ! $wrap.hasClass( 'plugin-install-tab-upload' ) ) {
    204                 $uploadViewToggle
    205                         .attr({
    206                                 role: 'button',
    207                                 'aria-expanded': 'false'
    208                         })
    209                         .on( 'click', function( event ) {
    210                                 event.preventDefault();
    211                                 $body.toggleClass( 'show-upload-view' );
    212                                 $uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
    213                         });
    214         }
    215192});
  • src/wp-admin/js/plugin-upload.js

    diff --git src/wp-admin/js/plugin-upload.js src/wp-admin/js/plugin-upload.js
    index e69de29..4dd0c62 100644
     
     1window.wp = window.wp || {};
     2
     3( function( $, _, wp ){
     4
     5        window.toggleUploadButton = function() {
     6                var button, input, form = $('form.wp-upload-form');
     7
     8                if ( ! form.length ) {
     9                        return;
     10                }
     11
     12                button = form.find('input[type="submit"]');
     13                input  = form.find('input[type="file"]');
     14
     15                button.prop('disabled', '' === input.map( function() {
     16                        return $(this).val();
     17                } ).get().join( '' ) );
     18        };
     19        window.toggleUploadButton();
     20
     21        // Checks if there is an existing plugin.
     22        window.pluginExists = function( slug, form ) {
     23                var template = wp.template( 'existing-plugin-data' ), pluginData = {};
     24
     25                wp.apiRequest( {
     26                        path: 'wp/v2/plugins/' + slug,
     27                        type: 'GET',
     28                        dataType: 'json'
     29                } ).done( function( response ) {
     30                        // The plugin exists, display a warning and informations about the Plugin.
     31                        if ( response && response.id ) {
     32                                form.addClass( 'has-existing-plugin' );
     33                                window.toggleUploadButton();
     34
     35                                $( '#install-plugin-submit' ).after(
     36                                        $( '<input></input' )
     37                                                .prop( 'type', 'reset' )
     38                                                .val( pluginUploadL10n.cancel )
     39                                                .addClass( 'button button-secondary install-plugin-reset' )
     40                                );
     41
     42                                pluginData = _.extend( response, _.pick( pluginUploadL10n, [ 'warnOverwrite','pluginDetailsIntro' ] ) );
     43
     44                                $( '#pluginzip' ).after( template( pluginData ) );
     45                        }
     46
     47                // The plugin is not installed yet.
     48                } ).fail( function() {
     49                        window.toggleUploadButton();
     50                } );
     51        };
     52
     53        $( 'form.wp-upload-form' ).on( 'change', 'input[type="file"]', function( event ) {
     54                if ( ! event.currentTarget.files || 'undefined' === typeof pluginUploadL10n ) {
     55                        toggleUploadButton();
     56                        return event;
     57                }
     58
     59                var file = _.first( event.currentTarget.files ), form = $( event.delegateTarget ), pluginSlug;
     60
     61                if ( file.name ) {
     62                        // Users using modern Browsers won't need to rename the package.
     63                        if ( window.FileReader && window.File && window.FileList && window.Blob ) {
     64                                JSZip.loadAsync( file ).then( function( zip ) {
     65                                        if ( zip.files ) {
     66                                                pluginSlug = _.first( _.keys( zip.files ) ).replace( '/', '' );
     67                                                window.pluginExists( pluginSlug, form );
     68                                        }
     69                                } );
     70
     71                        // Users using old Browsers will need to rename the package.
     72                        } else {
     73                                pluginSlug = file.name.replace( '.zip', '' );
     74                                window.pluginExists( pluginSlug, form );
     75                        }
     76                }
     77        } );
     78
     79        // Resets the Upload form when 'Cancel' is clicked.
     80        $( 'form.wp-upload-form' ).on( 'reset', function( event ) {
     81                $( '#existing-plugin-info' ).remove();
     82                $( event.currentTarget ).removeClass( 'has-existing-plugin' );
     83                $( event.currentTarget ).find( 'input[type="file"]' ).val( '' );
     84                $( event.currentTarget ).find( '.install-plugin-reset' ).remove();
     85                window.toggleUploadButton();
     86        } );
     87
     88        /*
     89         * When a user presses the "Upload Plugin" button, show the upload form in place
     90         * rather than sending them to the devoted upload plugin page.
     91         * The `?tab=upload` page still exists for no-js support and for plugins that
     92         * might access it directly. When we're in this page, let the link behave
     93         * like a link. Otherwise we're in the normal plugin installer pages and the
     94         * link should behave like a toggle button.
     95         */
     96        if ( ! $( '.wrap' ).hasClass( 'plugin-install-tab-upload' ) ) {
     97                $( '.upload-view-toggle' )
     98                        .attr({
     99                                role: 'button',
     100                                'aria-expanded': 'false'
     101                        } )
     102                        .on( 'click', function( event ) {
     103                                var $body = $( document.body ), $uploadViewToggle = $( event.currentTarget );
     104                                event.preventDefault();
     105                                $body.toggleClass( 'show-upload-view' );
     106                                $uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
     107                        } );
     108        }
     109
     110}( jQuery, _, window.wp ) );
  • src/wp-admin/plugin-install.php

    diff --git src/wp-admin/plugin-install.php src/wp-admin/plugin-install.php
    index 855beb6..e59e266 100644
    if ( 'plugin-information' != $tab ) 
    5555$body_id = $tab;
    5656
    5757wp_enqueue_script( 'updates' );
     58wp_enqueue_script( 'plugin-upload' );
    5859
    5960/**
    6061 * Fires before each tab on the Install Plugins screen is loaded.
  • src/wp-admin/update.php

    diff --git src/wp-admin/update.php src/wp-admin/update.php
    index 12b8f56..0573a3a 100644
    if ( isset($_GET['action']) ) { 
    159159                $type = 'upload'; //Install plugin type, From Web or an Upload.
    160160
    161161                $upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( compact('type', 'title', 'nonce', 'url') ) );
    162                 $result = $upgrader->install( $file_upload->package );
     162
     163                // Overwrite an existing plugin.
     164                if ( isset( $_POST['overwrite'] ) && $_POST['overwrite'] ) {
     165                        $result = $upgrader->upgrade( wp_unslash( $_POST['overwrite'] ), array( 'package' => $file_upload->package ) );
     166
     167                // Install a new plugin.
     168                } else {
     169                        $result = $upgrader->install( $file_upload->package );
     170                }
    163171
    164172                if ( $result || is_wp_error($result) )
    165173                        $file_upload->cleanup();
  • src/wp-includes/js/jszip.js

    diff --git src/wp-includes/js/jszip.js src/wp-includes/js/jszip.js
    index e69de29..6b09f2b 100644
     
     1/*!
     2
     3JSZip v3.1.3 - A Javascript class for generating and reading zip files
     4<http://stuartk.com/jszip>
     5
     6(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
     7Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
     8
     9JSZip uses the library pako released under the MIT license :
     10https://github.com/nodeca/pako/blob/master/LICENSE
     11*/
     12
     13(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.JSZip = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
     14'use strict';
     15var utils = require('./utils');
     16var support = require('./support');
     17// private property
     18var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
     19
     20
     21// public method for encoding
     22exports.encode = function(input) {
     23    var output = [];
     24    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
     25    var i = 0, len = input.length, remainingBytes = len;
     26
     27    var isArray = utils.getTypeOf(input) !== "string";
     28    while (i < input.length) {
     29        remainingBytes = len - i;
     30
     31        if (!isArray) {
     32            chr1 = input.charCodeAt(i++);
     33            chr2 = i < len ? input.charCodeAt(i++) : 0;
     34            chr3 = i < len ? input.charCodeAt(i++) : 0;
     35        } else {
     36            chr1 = input[i++];
     37            chr2 = i < len ? input[i++] : 0;
     38            chr3 = i < len ? input[i++] : 0;
     39        }
     40
     41        enc1 = chr1 >> 2;
     42        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
     43        enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64;
     44        enc4 = remainingBytes > 2 ? (chr3 & 63) : 64;
     45
     46        output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4));
     47
     48    }
     49
     50    return output.join("");
     51};
     52
     53// public method for decoding
     54exports.decode = function(input) {
     55    var chr1, chr2, chr3;
     56    var enc1, enc2, enc3, enc4;
     57    var i = 0, resultIndex = 0;
     58
     59    var dataUrlPrefix = "data:";
     60
     61    if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) {
     62        // This is a common error: people give a data url
     63        // (data:image/png;base64,iVBOR...) with a {base64: true} and
     64        // wonders why things don't work.
     65        // We can detect that the string input looks like a data url but we
     66        // *can't* be sure it is one: removing everything up to the comma would
     67        // be too dangerous.
     68        throw new Error("Invalid base64 input, it looks like a data url.");
     69    }
     70
     71    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
     72
     73    var totalLength = input.length * 3 / 4;
     74    if(input.charAt(input.length - 1) === _keyStr.charAt(64)) {
     75        totalLength--;
     76    }
     77    if(input.charAt(input.length - 2) === _keyStr.charAt(64)) {
     78        totalLength--;
     79    }
     80    if (totalLength % 1 !== 0) {
     81        // totalLength is not an integer, the length does not match a valid
     82        // base64 content. That can happen if:
     83        // - the input is not a base64 content
     84        // - the input is *almost* a base64 content, with a extra chars at the
     85        //   beginning or at the end
     86        // - the input uses a base64 variant (base64url for example)
     87        throw new Error("Invalid base64 input, bad content length.");
     88    }
     89    var output;
     90    if (support.uint8array) {
     91        output = new Uint8Array(totalLength|0);
     92    } else {
     93        output = new Array(totalLength|0);
     94    }
     95
     96    while (i < input.length) {
     97
     98        enc1 = _keyStr.indexOf(input.charAt(i++));
     99        enc2 = _keyStr.indexOf(input.charAt(i++));
     100        enc3 = _keyStr.indexOf(input.charAt(i++));
     101        enc4 = _keyStr.indexOf(input.charAt(i++));
     102
     103        chr1 = (enc1 << 2) | (enc2 >> 4);
     104        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
     105        chr3 = ((enc3 & 3) << 6) | enc4;
     106
     107        output[resultIndex++] = chr1;
     108
     109        if (enc3 !== 64) {
     110            output[resultIndex++] = chr2;
     111        }
     112        if (enc4 !== 64) {
     113            output[resultIndex++] = chr3;
     114        }
     115
     116    }
     117
     118    return output;
     119};
     120
     121},{"./support":30,"./utils":32}],2:[function(require,module,exports){
     122'use strict';
     123
     124var external = require("./external");
     125var DataWorker = require('./stream/DataWorker');
     126var DataLengthProbe = require('./stream/DataLengthProbe');
     127var Crc32Probe = require('./stream/Crc32Probe');
     128var DataLengthProbe = require('./stream/DataLengthProbe');
     129
     130/**
     131 * Represent a compressed object, with everything needed to decompress it.
     132 * @constructor
     133 * @param {number} compressedSize the size of the data compressed.
     134 * @param {number} uncompressedSize the size of the data after decompression.
     135 * @param {number} crc32 the crc32 of the decompressed file.
     136 * @param {object} compression the type of compression, see lib/compressions.js.
     137 * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data.
     138 */
     139function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) {
     140    this.compressedSize = compressedSize;
     141    this.uncompressedSize = uncompressedSize;
     142    this.crc32 = crc32;
     143    this.compression = compression;
     144    this.compressedContent = data;
     145}
     146
     147CompressedObject.prototype = {
     148    /**
     149     * Create a worker to get the uncompressed content.
     150     * @return {GenericWorker} the worker.
     151     */
     152    getContentWorker : function () {
     153        var worker = new DataWorker(external.Promise.resolve(this.compressedContent))
     154        .pipe(this.compression.uncompressWorker())
     155        .pipe(new DataLengthProbe("data_length"));
     156
     157        var that = this;
     158        worker.on("end", function () {
     159            if(this.streamInfo['data_length'] !== that.uncompressedSize) {
     160                throw new Error("Bug : uncompressed data size mismatch");
     161            }
     162        });
     163        return worker;
     164    },
     165    /**
     166     * Create a worker to get the compressed content.
     167     * @return {GenericWorker} the worker.
     168     */
     169    getCompressedWorker : function () {
     170        return new DataWorker(external.Promise.resolve(this.compressedContent))
     171        .withStreamInfo("compressedSize", this.compressedSize)
     172        .withStreamInfo("uncompressedSize", this.uncompressedSize)
     173        .withStreamInfo("crc32", this.crc32)
     174        .withStreamInfo("compression", this.compression)
     175        ;
     176    }
     177};
     178
     179/**
     180 * Chain the given worker with other workers to compress the content with the
     181 * given compresion.
     182 * @param {GenericWorker} uncompressedWorker the worker to pipe.
     183 * @param {Object} compression the compression object.
     184 * @param {Object} compressionOptions the options to use when compressing.
     185 * @return {GenericWorker} the new worker compressing the content.
     186 */
     187CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) {
     188    return uncompressedWorker
     189    .pipe(new Crc32Probe())
     190    .pipe(new DataLengthProbe("uncompressedSize"))
     191    .pipe(compression.compressWorker(compressionOptions))
     192    .pipe(new DataLengthProbe("compressedSize"))
     193    .withStreamInfo("compression", compression);
     194};
     195
     196module.exports = CompressedObject;
     197
     198},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(require,module,exports){
     199'use strict';
     200
     201var GenericWorker = require("./stream/GenericWorker");
     202
     203exports.STORE = {
     204    magic: "\x00\x00",
     205    compressWorker : function (compressionOptions) {
     206        return new GenericWorker("STORE compression");
     207    },
     208    uncompressWorker : function () {
     209        return new GenericWorker("STORE decompression");
     210    }
     211};
     212exports.DEFLATE = require('./flate');
     213
     214},{"./flate":7,"./stream/GenericWorker":28}],4:[function(require,module,exports){
     215'use strict';
     216
     217var utils = require('./utils');
     218
     219/**
     220 * The following functions come from pako, from pako/lib/zlib/crc32.js
     221 * released under the MIT license, see pako https://github.com/nodeca/pako/
     222 */
     223
     224// Use ordinary array, since untyped makes no boost here
     225function makeTable() {
     226    var c, table = [];
     227
     228    for(var n =0; n < 256; n++){
     229        c = n;
     230        for(var k =0; k < 8; k++){
     231            c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
     232        }
     233        table[n] = c;
     234    }
     235
     236    return table;
     237}
     238
     239// Create table on load. Just 255 signed longs. Not a problem.
     240var crcTable = makeTable();
     241
     242
     243function crc32(crc, buf, len, pos) {
     244    var t = crcTable, end = pos + len;
     245
     246    crc = crc ^ (-1);
     247
     248    for (var i = pos; i < end; i++ ) {
     249        crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
     250    }
     251
     252    return (crc ^ (-1)); // >>> 0;
     253}
     254
     255// That's all for the pako functions.
     256
     257/**
     258 * Compute the crc32 of a string.
     259 * This is almost the same as the function crc32, but for strings. Using the
     260 * same function for the two use cases leads to horrible performances.
     261 * @param {Number} crc the starting value of the crc.
     262 * @param {String} str the string to use.
     263 * @param {Number} len the length of the string.
     264 * @param {Number} pos the starting position for the crc32 computation.
     265 * @return {Number} the computed crc32.
     266 */
     267function crc32str(crc, str, len, pos) {
     268    var t = crcTable, end = pos + len;
     269
     270    crc = crc ^ (-1);
     271
     272    for (var i = pos; i < end; i++ ) {
     273        crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF];
     274    }
     275
     276    return (crc ^ (-1)); // >>> 0;
     277}
     278
     279module.exports = function crc32wrapper(input, crc) {
     280    if (typeof input === "undefined" || !input.length) {
     281        return 0;
     282    }
     283
     284    var isArray = utils.getTypeOf(input) !== "string";
     285
     286    if(isArray) {
     287        return crc32(crc|0, input, input.length, 0);
     288    } else {
     289        return crc32str(crc|0, input, input.length, 0);
     290    }
     291};
     292
     293},{"./utils":32}],5:[function(require,module,exports){
     294'use strict';
     295exports.base64 = false;
     296exports.binary = false;
     297exports.dir = false;
     298exports.createFolders = true;
     299exports.date = null;
     300exports.compression = null;
     301exports.compressionOptions = null;
     302exports.comment = null;
     303exports.unixPermissions = null;
     304exports.dosPermissions = null;
     305
     306},{}],6:[function(require,module,exports){
     307/* global Promise */
     308'use strict';
     309
     310// load the global object first:
     311// - it should be better integrated in the system (unhandledRejection in node)
     312// - the environment may have a custom Promise implementation (see zone.js)
     313var ES6Promise = null;
     314if (typeof Promise !== "undefined") {
     315    ES6Promise = Promise;
     316} else {
     317    ES6Promise = require("lie");
     318}
     319
     320/**
     321 * Let the user use/change some implementations.
     322 */
     323module.exports = {
     324    Promise: ES6Promise
     325};
     326
     327},{"lie":58}],7:[function(require,module,exports){
     328'use strict';
     329var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');
     330
     331var pako = require("pako");
     332var utils = require("./utils");
     333var GenericWorker = require("./stream/GenericWorker");
     334
     335var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
     336
     337exports.magic = "\x08\x00";
     338
     339/**
     340 * Create a worker that uses pako to inflate/deflate.
     341 * @constructor
     342 * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
     343 * @param {Object} options the options to use when (de)compressing.
     344 */
     345function FlateWorker(action, options) {
     346    GenericWorker.call(this, "FlateWorker/" + action);
     347
     348    this._pako = null;
     349    this._pakoAction = action;
     350    this._pakoOptions = options;
     351    // the `meta` object from the last chunk received
     352    // this allow this worker to pass around metadata
     353    this.meta = {};
     354}
     355
     356utils.inherits(FlateWorker, GenericWorker);
     357
     358/**
     359 * @see GenericWorker.processChunk
     360 */
     361FlateWorker.prototype.processChunk = function (chunk) {
     362    this.meta = chunk.meta;
     363    if (this._pako === null) {
     364        this._createPako();
     365    }
     366    this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
     367};
     368
     369/**
     370 * @see GenericWorker.flush
     371 */
     372FlateWorker.prototype.flush = function () {
     373    GenericWorker.prototype.flush.call(this);
     374    if (this._pako === null) {
     375        this._createPako();
     376    }
     377    this._pako.push([], true);
     378};
     379/**
     380 * @see GenericWorker.cleanUp
     381 */
     382FlateWorker.prototype.cleanUp = function () {
     383    GenericWorker.prototype.cleanUp.call(this);
     384    this._pako = null;
     385};
     386
     387/**
     388 * Create the _pako object.
     389 * TODO: lazy-loading this object isn't the best solution but it's the
     390 * quickest. The best solution is to lazy-load the worker list. See also the
     391 * issue #446.
     392 */
     393FlateWorker.prototype._createPako = function () {
     394    this._pako = new pako[this._pakoAction]({
     395        raw: true,
     396        level: this._pakoOptions.level || -1 // default compression
     397    });
     398    var self = this;
     399    this._pako.onData = function(data) {
     400        self.push({
     401            data : data,
     402            meta : self.meta
     403        });
     404    };
     405};
     406
     407exports.compressWorker = function (compressionOptions) {
     408    return new FlateWorker("Deflate", compressionOptions);
     409};
     410exports.uncompressWorker = function () {
     411    return new FlateWorker("Inflate", {});
     412};
     413
     414},{"./stream/GenericWorker":28,"./utils":32,"pako":59}],8:[function(require,module,exports){
     415'use strict';
     416
     417var utils = require('../utils');
     418var GenericWorker = require('../stream/GenericWorker');
     419var utf8 = require('../utf8');
     420var crc32 = require('../crc32');
     421var signature = require('../signature');
     422
     423/**
     424 * Transform an integer into a string in hexadecimal.
     425 * @private
     426 * @param {number} dec the number to convert.
     427 * @param {number} bytes the number of bytes to generate.
     428 * @returns {string} the result.
     429 */
     430var decToHex = function(dec, bytes) {
     431    var hex = "", i;
     432    for (i = 0; i < bytes; i++) {
     433        hex += String.fromCharCode(dec & 0xff);
     434        dec = dec >>> 8;
     435    }
     436    return hex;
     437};
     438
     439/**
     440 * Generate the UNIX part of the external file attributes.
     441 * @param {Object} unixPermissions the unix permissions or null.
     442 * @param {Boolean} isDir true if the entry is a directory, false otherwise.
     443 * @return {Number} a 32 bit integer.
     444 *
     445 * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute :
     446 *
     447 * TTTTsstrwxrwxrwx0000000000ADVSHR
     448 * ^^^^____________________________ file type, see zipinfo.c (UNX_*)
     449 *     ^^^_________________________ setuid, setgid, sticky
     450 *        ^^^^^^^^^________________ permissions
     451 *                 ^^^^^^^^^^______ not used ?
     452 *                           ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only
     453 */
     454var generateUnixExternalFileAttr = function (unixPermissions, isDir) {
     455
     456    var result = unixPermissions;
     457    if (!unixPermissions) {
     458        // I can't use octal values in strict mode, hence the hexa.
     459        //  040775 => 0x41fd
     460        // 0100664 => 0x81b4
     461        result = isDir ? 0x41fd : 0x81b4;
     462    }
     463    return (result & 0xFFFF) << 16;
     464};
     465
     466/**
     467 * Generate the DOS part of the external file attributes.
     468 * @param {Object} dosPermissions the dos permissions or null.
     469 * @param {Boolean} isDir true if the entry is a directory, false otherwise.
     470 * @return {Number} a 32 bit integer.
     471 *
     472 * Bit 0     Read-Only
     473 * Bit 1     Hidden
     474 * Bit 2     System
     475 * Bit 3     Volume Label
     476 * Bit 4     Directory
     477 * Bit 5     Archive
     478 */
     479var generateDosExternalFileAttr = function (dosPermissions, isDir) {
     480
     481    // the dir flag is already set for compatibility
     482    return (dosPermissions || 0)  & 0x3F;
     483};
     484
     485/**
     486 * Generate the various parts used in the construction of the final zip file.
     487 * @param {Object} streamInfo the hash with informations about the compressed file.
     488 * @param {Boolean} streamedContent is the content streamed ?
     489 * @param {Boolean} streamingEnded is the stream finished ?
     490 * @param {number} offset the current offset from the start of the zip file.
     491 * @param {String} platform let's pretend we are this platform (change platform dependents fields)
     492 * @param {Function} encodeFileName the function to encode the file name / comment.
     493 * @return {Object} the zip parts.
     494 */
     495var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {
     496    var file = streamInfo['file'],
     497    compression = streamInfo['compression'],
     498    useCustomEncoding = encodeFileName !== utf8.utf8encode,
     499    encodedFileName = utils.transformTo("string", encodeFileName(file.name)),
     500    utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
     501    comment = file.comment,
     502    encodedComment = utils.transformTo("string", encodeFileName(comment)),
     503    utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
     504    useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
     505    useUTF8ForComment = utfEncodedComment.length !== comment.length,
     506    dosTime,
     507    dosDate,
     508    extraFields = "",
     509    unicodePathExtraField = "",
     510    unicodeCommentExtraField = "",
     511    dir = file.dir,
     512    date = file.date;
     513
     514
     515    var dataInfo = {
     516        crc32 : 0,
     517        compressedSize : 0,
     518        uncompressedSize : 0
     519    };
     520
     521    // if the content is streamed, the sizes/crc32 are only available AFTER
     522    // the end of the stream.
     523    if (!streamedContent || streamingEnded) {
     524        dataInfo.crc32 = streamInfo['crc32'];
     525        dataInfo.compressedSize = streamInfo['compressedSize'];
     526        dataInfo.uncompressedSize = streamInfo['uncompressedSize'];
     527    }
     528
     529    var bitflag = 0;
     530    if (streamedContent) {
     531        // Bit 3: the sizes/crc32 are set to zero in the local header.
     532        // The correct values are put in the data descriptor immediately
     533        // following the compressed data.
     534        bitflag |= 0x0008;
     535    }
     536    if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {
     537        // Bit 11: Language encoding flag (EFS).
     538        bitflag |= 0x0800;
     539    }
     540
     541
     542    var extFileAttr = 0;
     543    var versionMadeBy = 0;
     544    if (dir) {
     545        // dos or unix, we set the dos dir flag
     546        extFileAttr |= 0x00010;
     547    }
     548    if(platform === "UNIX") {
     549        versionMadeBy = 0x031E; // UNIX, version 3.0
     550        extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
     551    } else { // DOS or other, fallback to DOS
     552        versionMadeBy = 0x0014; // DOS, version 2.0
     553        extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);
     554    }
     555
     556    // date
     557    // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
     558    // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
     559    // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
     560
     561    dosTime = date.getUTCHours();
     562    dosTime = dosTime << 6;
     563    dosTime = dosTime | date.getUTCMinutes();
     564    dosTime = dosTime << 5;
     565    dosTime = dosTime | date.getUTCSeconds() / 2;
     566
     567    dosDate = date.getUTCFullYear() - 1980;
     568    dosDate = dosDate << 4;
     569    dosDate = dosDate | (date.getUTCMonth() + 1);
     570    dosDate = dosDate << 5;
     571    dosDate = dosDate | date.getUTCDate();
     572
     573    if (useUTF8ForFileName) {
     574        // set the unicode path extra field. unzip needs at least one extra
     575        // field to correctly handle unicode path, so using the path is as good
     576        // as any other information. This could improve the situation with
     577        // other archive managers too.
     578        // This field is usually used without the utf8 flag, with a non
     579        // unicode path in the header (winrar, winzip). This helps (a bit)
     580        // with the messy Windows' default compressed folders feature but
     581        // breaks on p7zip which doesn't seek the unicode path extra field.
     582        // So for now, UTF-8 everywhere !
     583        unicodePathExtraField =
     584            // Version
     585            decToHex(1, 1) +
     586            // NameCRC32
     587            decToHex(crc32(encodedFileName), 4) +
     588            // UnicodeName
     589            utfEncodedFileName;
     590
     591        extraFields +=
     592            // Info-ZIP Unicode Path Extra Field
     593            "\x75\x70" +
     594            // size
     595            decToHex(unicodePathExtraField.length, 2) +
     596            // content
     597            unicodePathExtraField;
     598    }
     599
     600    if(useUTF8ForComment) {
     601
     602        unicodeCommentExtraField =
     603            // Version
     604            decToHex(1, 1) +
     605            // CommentCRC32
     606            decToHex(crc32(encodedComment), 4) +
     607            // UnicodeName
     608            utfEncodedComment;
     609
     610        extraFields +=
     611            // Info-ZIP Unicode Path Extra Field
     612            "\x75\x63" +
     613            // size
     614            decToHex(unicodeCommentExtraField.length, 2) +
     615            // content
     616            unicodeCommentExtraField;
     617    }
     618
     619    var header = "";
     620
     621    // version needed to extract
     622    header += "\x0A\x00";
     623    // general purpose bit flag
     624    header += decToHex(bitflag, 2);
     625    // compression method
     626    header += compression.magic;
     627    // last mod file time
     628    header += decToHex(dosTime, 2);
     629    // last mod file date
     630    header += decToHex(dosDate, 2);
     631    // crc-32
     632    header += decToHex(dataInfo.crc32, 4);
     633    // compressed size
     634    header += decToHex(dataInfo.compressedSize, 4);
     635    // uncompressed size
     636    header += decToHex(dataInfo.uncompressedSize, 4);
     637    // file name length
     638    header += decToHex(encodedFileName.length, 2);
     639    // extra field length
     640    header += decToHex(extraFields.length, 2);
     641
     642
     643    var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;
     644
     645    var dirRecord = signature.CENTRAL_FILE_HEADER +
     646        // version made by (00: DOS)
     647        decToHex(versionMadeBy, 2) +
     648        // file header (common to file and central directory)
     649        header +
     650        // file comment length
     651        decToHex(encodedComment.length, 2) +
     652        // disk number start
     653        "\x00\x00" +
     654        // internal file attributes TODO
     655        "\x00\x00" +
     656        // external file attributes
     657        decToHex(extFileAttr, 4) +
     658        // relative offset of local header
     659        decToHex(offset, 4) +
     660        // file name
     661        encodedFileName +
     662        // extra field
     663        extraFields +
     664        // file comment
     665        encodedComment;
     666
     667    return {
     668        fileRecord: fileRecord,
     669        dirRecord: dirRecord
     670    };
     671};
     672
     673/**
     674 * Generate the EOCD record.
     675 * @param {Number} entriesCount the number of entries in the zip file.
     676 * @param {Number} centralDirLength the length (in bytes) of the central dir.
     677 * @param {Number} localDirLength the length (in bytes) of the local dir.
     678 * @param {String} comment the zip file comment as a binary string.
     679 * @param {Function} encodeFileName the function to encode the comment.
     680 * @return {String} the EOCD record.
     681 */
     682var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {
     683    var dirEnd = "";
     684    var encodedComment = utils.transformTo("string", encodeFileName(comment));
     685
     686    // end of central dir signature
     687    dirEnd = signature.CENTRAL_DIRECTORY_END +
     688        // number of this disk
     689        "\x00\x00" +
     690        // number of the disk with the start of the central directory
     691        "\x00\x00" +
     692        // total number of entries in the central directory on this disk
     693        decToHex(entriesCount, 2) +
     694        // total number of entries in the central directory
     695        decToHex(entriesCount, 2) +
     696        // size of the central directory   4 bytes
     697        decToHex(centralDirLength, 4) +
     698        // offset of start of central directory with respect to the starting disk number
     699        decToHex(localDirLength, 4) +
     700        // .ZIP file comment length
     701        decToHex(encodedComment.length, 2) +
     702        // .ZIP file comment
     703        encodedComment;
     704
     705    return dirEnd;
     706};
     707
     708/**
     709 * Generate data descriptors for a file entry.
     710 * @param {Object} streamInfo the hash generated by a worker, containing informations
     711 * on the file entry.
     712 * @return {String} the data descriptors.
     713 */
     714var generateDataDescriptors = function (streamInfo) {
     715    var descriptor = "";
     716    descriptor = signature.DATA_DESCRIPTOR +
     717        // crc-32                          4 bytes
     718        decToHex(streamInfo['crc32'], 4) +
     719        // compressed size                 4 bytes
     720        decToHex(streamInfo['compressedSize'], 4) +
     721        // uncompressed size               4 bytes
     722        decToHex(streamInfo['uncompressedSize'], 4);
     723
     724    return descriptor;
     725};
     726
     727
     728/**
     729 * A worker to concatenate other workers to create a zip file.
     730 * @param {Boolean} streamFiles `true` to stream the content of the files,
     731 * `false` to accumulate it.
     732 * @param {String} comment the comment to use.
     733 * @param {String} platform the platform to use, "UNIX" or "DOS".
     734 * @param {Function} encodeFileName the function to encode file names and comments.
     735 */
     736function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {
     737    GenericWorker.call(this, "ZipFileWorker");
     738    // The number of bytes written so far. This doesn't count accumulated chunks.
     739    this.bytesWritten = 0;
     740    // The comment of the zip file
     741    this.zipComment = comment;
     742    // The platform "generating" the zip file.
     743    this.zipPlatform = platform;
     744    // the function to encode file names and comments.
     745    this.encodeFileName = encodeFileName;
     746    // Should we stream the content of the files ?
     747    this.streamFiles = streamFiles;
     748    // If `streamFiles` is false, we will need to accumulate the content of the
     749    // files to calculate sizes / crc32 (and write them *before* the content).
     750    // This boolean indicates if we are accumulating chunks (it will change a lot
     751    // during the lifetime of this worker).
     752    this.accumulate = false;
     753    // The buffer receiving chunks when accumulating content.
     754    this.contentBuffer = [];
     755    // The list of generated directory records.
     756    this.dirRecords = [];
     757    // The offset (in bytes) from the beginning of the zip file for the current source.
     758    this.currentSourceOffset = 0;
     759    // The total number of entries in this zip file.
     760    this.entriesCount = 0;
     761    // the name of the file currently being added, null when handling the end of the zip file.
     762    // Used for the emited metadata.
     763    this.currentFile = null;
     764
     765
     766
     767    this._sources = [];
     768}
     769utils.inherits(ZipFileWorker, GenericWorker);
     770
     771/**
     772 * @see GenericWorker.push
     773 */
     774ZipFileWorker.prototype.push = function (chunk) {
     775
     776    var currentFilePercent = chunk.meta.percent || 0;
     777    var entriesCount = this.entriesCount;
     778    var remainingFiles = this._sources.length;
     779
     780    if(this.accumulate) {
     781        this.contentBuffer.push(chunk);
     782    } else {
     783        this.bytesWritten += chunk.data.length;
     784
     785        GenericWorker.prototype.push.call(this, {
     786            data : chunk.data,
     787            meta : {
     788                currentFile : this.currentFile,
     789                percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100
     790            }
     791        });
     792    }
     793};
     794
     795/**
     796 * The worker started a new source (an other worker).
     797 * @param {Object} streamInfo the streamInfo object from the new source.
     798 */
     799ZipFileWorker.prototype.openedSource = function (streamInfo) {
     800    this.currentSourceOffset = this.bytesWritten;
     801    this.currentFile = streamInfo['file'].name;
     802
     803    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
     804
     805    // don't stream folders (because they don't have any content)
     806    if(streamedContent) {
     807        var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
     808        this.push({
     809            data : record.fileRecord,
     810            meta : {percent:0}
     811        });
     812    } else {
     813        // we need to wait for the whole file before pushing anything
     814        this.accumulate = true;
     815    }
     816};
     817
     818/**
     819 * The worker finished a source (an other worker).
     820 * @param {Object} streamInfo the streamInfo object from the finished source.
     821 */
     822ZipFileWorker.prototype.closedSource = function (streamInfo) {
     823    this.accumulate = false;
     824    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
     825    var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
     826
     827    this.dirRecords.push(record.dirRecord);
     828    if(streamedContent) {
     829        // after the streamed file, we put data descriptors
     830        this.push({
     831            data : generateDataDescriptors(streamInfo),
     832            meta : {percent:100}
     833        });
     834    } else {
     835        // the content wasn't streamed, we need to push everything now
     836        // first the file record, then the content
     837        this.push({
     838            data : record.fileRecord,
     839            meta : {percent:0}
     840        });
     841        while(this.contentBuffer.length) {
     842            this.push(this.contentBuffer.shift());
     843        }
     844    }
     845    this.currentFile = null;
     846};
     847
     848/**
     849 * @see GenericWorker.flush
     850 */
     851ZipFileWorker.prototype.flush = function () {
     852
     853    var localDirLength = this.bytesWritten;
     854    for(var i = 0; i < this.dirRecords.length; i++) {
     855        this.push({
     856            data : this.dirRecords[i],
     857            meta : {percent:100}
     858        });
     859    }
     860    var centralDirLength = this.bytesWritten - localDirLength;
     861
     862    var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);
     863
     864    this.push({
     865        data : dirEnd,
     866        meta : {percent:100}
     867    });
     868};
     869
     870/**
     871 * Prepare the next source to be read.
     872 */
     873ZipFileWorker.prototype.prepareNextSource = function () {
     874    this.previous = this._sources.shift();
     875    this.openedSource(this.previous.streamInfo);
     876    if (this.isPaused) {
     877        this.previous.pause();
     878    } else {
     879        this.previous.resume();
     880    }
     881};
     882
     883/**
     884 * @see GenericWorker.registerPrevious
     885 */
     886ZipFileWorker.prototype.registerPrevious = function (previous) {
     887    this._sources.push(previous);
     888    var self = this;
     889
     890    previous.on('data', function (chunk) {
     891        self.processChunk(chunk);
     892    });
     893    previous.on('end', function () {
     894        self.closedSource(self.previous.streamInfo);
     895        if(self._sources.length) {
     896            self.prepareNextSource();
     897        } else {
     898            self.end();
     899        }
     900    });
     901    previous.on('error', function (e) {
     902        self.error(e);
     903    });
     904    return this;
     905};
     906
     907/**
     908 * @see GenericWorker.resume
     909 */
     910ZipFileWorker.prototype.resume = function () {
     911    if(!GenericWorker.prototype.resume.call(this)) {
     912        return false;
     913    }
     914
     915    if (!this.previous && this._sources.length) {
     916        this.prepareNextSource();
     917        return true;
     918    }
     919    if (!this.previous && !this._sources.length && !this.generatedError) {
     920        this.end();
     921        return true;
     922    }
     923};
     924
     925/**
     926 * @see GenericWorker.error
     927 */
     928ZipFileWorker.prototype.error = function (e) {
     929    var sources = this._sources;
     930    if(!GenericWorker.prototype.error.call(this, e)) {
     931        return false;
     932    }
     933    for(var i = 0; i < sources.length; i++) {
     934        try {
     935            sources[i].error(e);
     936        } catch(e) {
     937            // the `error` exploded, nothing to do
     938        }
     939    }
     940    return true;
     941};
     942
     943/**
     944 * @see GenericWorker.lock
     945 */
     946ZipFileWorker.prototype.lock = function () {
     947    GenericWorker.prototype.lock.call(this);
     948    var sources = this._sources;
     949    for(var i = 0; i < sources.length; i++) {
     950        sources[i].lock();
     951    }
     952};
     953
     954module.exports = ZipFileWorker;
     955
     956},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(require,module,exports){
     957'use strict';
     958
     959var compressions = require('../compressions');
     960var ZipFileWorker = require('./ZipFileWorker');
     961
     962/**
     963 * Find the compression to use.
     964 * @param {String} fileCompression the compression defined at the file level, if any.
     965 * @param {String} zipCompression the compression defined at the load() level.
     966 * @return {Object} the compression object to use.
     967 */
     968var getCompression = function (fileCompression, zipCompression) {
     969
     970    var compressionName = fileCompression || zipCompression;
     971    var compression = compressions[compressionName];
     972    if (!compression) {
     973        throw new Error(compressionName + " is not a valid compression method !");
     974    }
     975    return compression;
     976};
     977
     978/**
     979 * Create a worker to generate a zip file.
     980 * @param {JSZip} zip the JSZip instance at the right root level.
     981 * @param {Object} options to generate the zip file.
     982 * @param {String} comment the comment to use.
     983 */
     984exports.generateWorker = function (zip, options, comment) {
     985
     986    var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);
     987    var entriesCount = 0;
     988    try {
     989
     990        zip.forEach(function (relativePath, file) {
     991            entriesCount++;
     992            var compression = getCompression(file.options.compression, options.compression);
     993            var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
     994            var dir = file.dir, date = file.date;
     995
     996            file._compressWorker(compression, compressionOptions)
     997            .withStreamInfo("file", {
     998                name : relativePath,
     999                dir : dir,
     1000                date : date,
     1001                comment : file.comment || "",
     1002                unixPermissions : file.unixPermissions,
     1003                dosPermissions : file.dosPermissions
     1004            })
     1005            .pipe(zipFileWorker);
     1006        });
     1007        zipFileWorker.entriesCount = entriesCount;
     1008    } catch (e) {
     1009        zipFileWorker.error(e);
     1010    }
     1011
     1012    return zipFileWorker;
     1013};
     1014
     1015},{"../compressions":3,"./ZipFileWorker":8}],10:[function(require,module,exports){
     1016'use strict';
     1017
     1018/**
     1019 * Representation a of zip file in js
     1020 * @constructor
     1021 */
     1022function JSZip() {
     1023    // if this constructor is used without `new`, it adds `new` before itself:
     1024    if(!(this instanceof JSZip)) {
     1025        return new JSZip();
     1026    }
     1027
     1028    if(arguments.length) {
     1029        throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
     1030    }
     1031
     1032    // object containing the files :
     1033    // {
     1034    //   "folder/" : {...},
     1035    //   "folder/data.txt" : {...}
     1036    // }
     1037    this.files = {};
     1038
     1039    this.comment = null;
     1040
     1041    // Where we are in the hierarchy
     1042    this.root = "";
     1043    this.clone = function() {
     1044        var newObj = new JSZip();
     1045        for (var i in this) {
     1046            if (typeof this[i] !== "function") {
     1047                newObj[i] = this[i];
     1048            }
     1049        }
     1050        return newObj;
     1051    };
     1052}
     1053JSZip.prototype = require('./object');
     1054JSZip.prototype.loadAsync = require('./load');
     1055JSZip.support = require('./support');
     1056JSZip.defaults = require('./defaults');
     1057
     1058// TODO find a better way to handle this version,
     1059// a require('package.json').version doesn't work with webpack, see #327
     1060JSZip.version = "3.1.3";
     1061
     1062JSZip.loadAsync = function (content, options) {
     1063    return new JSZip().loadAsync(content, options);
     1064};
     1065
     1066JSZip.external = require("./external");
     1067module.exports = JSZip;
     1068
     1069},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(require,module,exports){
     1070'use strict';
     1071var utils = require('./utils');
     1072var external = require("./external");
     1073var utf8 = require('./utf8');
     1074var utils = require('./utils');
     1075var ZipEntries = require('./zipEntries');
     1076var Crc32Probe = require('./stream/Crc32Probe');
     1077var nodejsUtils = require("./nodejsUtils");
     1078
     1079/**
     1080 * Check the CRC32 of an entry.
     1081 * @param {ZipEntry} zipEntry the zip entry to check.
     1082 * @return {Promise} the result.
     1083 */
     1084function checkEntryCRC32(zipEntry) {
     1085    return new external.Promise(function (resolve, reject) {
     1086        var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
     1087        worker.on("error", function (e) {
     1088            reject(e);
     1089        })
     1090        .on("end", function () {
     1091            if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
     1092                reject(new Error("Corrupted zip : CRC32 mismatch"));
     1093            } else {
     1094                resolve();
     1095            }
     1096        })
     1097        .resume();
     1098    });
     1099}
     1100
     1101module.exports = function(data, options) {
     1102    var zip = this;
     1103    options = utils.extend(options || {}, {
     1104        base64: false,
     1105        checkCRC32: false,
     1106        optimizedBinaryString: false,
     1107        createFolders: false,
     1108        decodeFileName: utf8.utf8decode
     1109    });
     1110
     1111    if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
     1112        return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file."));
     1113    }
     1114
     1115    return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64)
     1116    .then(function(data) {
     1117        var zipEntries = new ZipEntries(options);
     1118        zipEntries.load(data);
     1119        return zipEntries;
     1120    }).then(function checkCRC32(zipEntries) {
     1121        var promises = [external.Promise.resolve(zipEntries)];
     1122        var files = zipEntries.files;
     1123        if (options.checkCRC32) {
     1124            for (var i = 0; i < files.length; i++) {
     1125                promises.push(checkEntryCRC32(files[i]));
     1126            }
     1127        }
     1128        return external.Promise.all(promises);
     1129    }).then(function addFiles(results) {
     1130        var zipEntries = results.shift();
     1131        var files = zipEntries.files;
     1132        for (var i = 0; i < files.length; i++) {
     1133            var input = files[i];
     1134            zip.file(input.fileNameStr, input.decompressed, {
     1135                binary: true,
     1136                optimizedBinaryString: true,
     1137                date: input.date,
     1138                dir: input.dir,
     1139                comment : input.fileCommentStr.length ? input.fileCommentStr : null,
     1140                unixPermissions : input.unixPermissions,
     1141                dosPermissions : input.dosPermissions,
     1142                createFolders: options.createFolders
     1143            });
     1144        }
     1145        if (zipEntries.zipComment.length) {
     1146            zip.comment = zipEntries.zipComment;
     1147        }
     1148
     1149        return zip;
     1150    });
     1151};
     1152
     1153},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(require,module,exports){
     1154"use strict";
     1155
     1156var utils = require('../utils');
     1157var GenericWorker = require('../stream/GenericWorker');
     1158
     1159/**
     1160 * A worker that use a nodejs stream as source.
     1161 * @constructor
     1162 * @param {String} filename the name of the file entry for this stream.
     1163 * @param {Readable} stream the nodejs stream.
     1164 */
     1165function NodejsStreamInputAdapter(filename, stream) {
     1166    GenericWorker.call(this, "Nodejs stream input adapter for " + filename);
     1167    this._upstreamEnded = false;
     1168    this._bindStream(stream);
     1169}
     1170
     1171utils.inherits(NodejsStreamInputAdapter, GenericWorker);
     1172
     1173/**
     1174 * Prepare the stream and bind the callbacks on it.
     1175 * Do this ASAP on node 0.10 ! A lazy binding doesn't always work.
     1176 * @param {Stream} stream the nodejs stream to use.
     1177 */
     1178NodejsStreamInputAdapter.prototype._bindStream = function (stream) {
     1179    var self = this;
     1180    this._stream = stream;
     1181    stream.pause();
     1182    stream
     1183    .on("data", function (chunk) {
     1184        self.push({
     1185            data: chunk,
     1186            meta : {
     1187                percent : 0
     1188            }
     1189        });
     1190    })
     1191    .on("error", function (e) {
     1192        if(self.isPaused) {
     1193            this.generatedError = e;
     1194        } else {
     1195            self.error(e);
     1196        }
     1197    })
     1198    .on("end", function () {
     1199        if(self.isPaused) {
     1200            self._upstreamEnded = true;
     1201        } else {
     1202            self.end();
     1203        }
     1204    });
     1205};
     1206NodejsStreamInputAdapter.prototype.pause = function () {
     1207    if(!GenericWorker.prototype.pause.call(this)) {
     1208        return false;
     1209    }
     1210    this._stream.pause();
     1211    return true;
     1212};
     1213NodejsStreamInputAdapter.prototype.resume = function () {
     1214    if(!GenericWorker.prototype.resume.call(this)) {
     1215        return false;
     1216    }
     1217
     1218    if(this._upstreamEnded) {
     1219        this.end();
     1220    } else {
     1221        this._stream.resume();
     1222    }
     1223
     1224    return true;
     1225};
     1226
     1227module.exports = NodejsStreamInputAdapter;
     1228
     1229},{"../stream/GenericWorker":28,"../utils":32}],13:[function(require,module,exports){
     1230'use strict';
     1231
     1232var Readable = require('readable-stream').Readable;
     1233
     1234var utils = require('../utils');
     1235utils.inherits(NodejsStreamOutputAdapter, Readable);
     1236
     1237/**
     1238* A nodejs stream using a worker as source.
     1239* @see the SourceWrapper in http://nodejs.org/api/stream.html
     1240* @constructor
     1241* @param {StreamHelper} helper the helper wrapping the worker
     1242* @param {Object} options the nodejs stream options
     1243* @param {Function} updateCb the update callback.
     1244*/
     1245function NodejsStreamOutputAdapter(helper, options, updateCb) {
     1246    Readable.call(this, options);
     1247    this._helper = helper;
     1248
     1249    var self = this;
     1250    helper.on("data", function (data, meta) {
     1251        if (!self.push(data)) {
     1252            self._helper.pause();
     1253        }
     1254        if(updateCb) {
     1255            updateCb(meta);
     1256        }
     1257    })
     1258    .on("error", function(e) {
     1259        self.emit('error', e);
     1260    })
     1261    .on("end", function () {
     1262        self.push(null);
     1263    });
     1264}
     1265
     1266
     1267NodejsStreamOutputAdapter.prototype._read = function() {
     1268    this._helper.resume();
     1269};
     1270
     1271module.exports = NodejsStreamOutputAdapter;
     1272
     1273},{"../utils":32,"readable-stream":16}],14:[function(require,module,exports){
     1274'use strict';
     1275
     1276module.exports = {
     1277    /**
     1278     * True if this is running in Nodejs, will be undefined in a browser.
     1279     * In a browser, browserify won't include this file and the whole module
     1280     * will be resolved an empty object.
     1281     */
     1282    isNode : typeof Buffer !== "undefined",
     1283    /**
     1284     * Create a new nodejs Buffer.
     1285     * @param {Object} data the data to pass to the constructor.
     1286     * @param {String} encoding the encoding to use.
     1287     * @return {Buffer} a new Buffer.
     1288     */
     1289    newBuffer : function(data, encoding){
     1290        return new Buffer(data, encoding);
     1291    },
     1292    /**
     1293     * Find out if an object is a Buffer.
     1294     * @param {Object} b the object to test.
     1295     * @return {Boolean} true if the object is a Buffer, false otherwise.
     1296     */
     1297    isBuffer : function(b){
     1298        return Buffer.isBuffer(b);
     1299    },
     1300
     1301    isStream : function (obj) {
     1302        return obj &&
     1303            typeof obj.on === "function" &&
     1304            typeof obj.pause === "function" &&
     1305            typeof obj.resume === "function";
     1306    }
     1307};
     1308
     1309},{}],15:[function(require,module,exports){
     1310'use strict';
     1311var utf8 = require('./utf8');
     1312var utils = require('./utils');
     1313var GenericWorker = require('./stream/GenericWorker');
     1314var StreamHelper = require('./stream/StreamHelper');
     1315var defaults = require('./defaults');
     1316var CompressedObject = require('./compressedObject');
     1317var ZipObject = require('./zipObject');
     1318var generate = require("./generate");
     1319var nodejsUtils = require("./nodejsUtils");
     1320var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter");
     1321
     1322
     1323/**
     1324 * Add a file in the current folder.
     1325 * @private
     1326 * @param {string} name the name of the file
     1327 * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
     1328 * @param {Object} originalOptions the options of the file
     1329 * @return {Object} the new file.
     1330 */
     1331var fileAdd = function(name, data, originalOptions) {
     1332    // be sure sub folders exist
     1333    var dataType = utils.getTypeOf(data),
     1334        parent;
     1335
     1336
     1337    /*
     1338     * Correct options.
     1339     */
     1340
     1341    var o = utils.extend(originalOptions || {}, defaults);
     1342    o.date = o.date || new Date();
     1343    if (o.compression !== null) {
     1344        o.compression = o.compression.toUpperCase();
     1345    }
     1346
     1347    if (typeof o.unixPermissions === "string") {
     1348        o.unixPermissions = parseInt(o.unixPermissions, 8);
     1349    }
     1350
     1351    // UNX_IFDIR  0040000 see zipinfo.c
     1352    if (o.unixPermissions && (o.unixPermissions & 0x4000)) {
     1353        o.dir = true;
     1354    }
     1355    // Bit 4    Directory
     1356    if (o.dosPermissions && (o.dosPermissions & 0x0010)) {
     1357        o.dir = true;
     1358    }
     1359
     1360    if (o.dir) {
     1361        name = forceTrailingSlash(name);
     1362    }
     1363    if (o.createFolders && (parent = parentFolder(name))) {
     1364        folderAdd.call(this, parent, true);
     1365    }
     1366
     1367    var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false;
     1368    if (!originalOptions || typeof originalOptions.binary === "undefined") {
     1369        o.binary = !isUnicodeString;
     1370    }
     1371
     1372
     1373    var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0;
     1374
     1375    if (isCompressedEmpty || o.dir || !data || data.length === 0) {
     1376        o.base64 = false;
     1377        o.binary = true;
     1378        data = "";
     1379        o.compression = "STORE";
     1380        dataType = "string";
     1381    }
     1382
     1383    /*
     1384     * Convert content to fit.
     1385     */
     1386
     1387    var zipObjectContent = null;
     1388    if (data instanceof CompressedObject || data instanceof GenericWorker) {
     1389        zipObjectContent = data;
     1390    } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
     1391        zipObjectContent = new NodejsStreamInputAdapter(name, data);
     1392    } else {
     1393        zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64);
     1394    }
     1395
     1396    var object = new ZipObject(name, zipObjectContent, o);
     1397    this.files[name] = object;
     1398    /*
     1399    TODO: we can't throw an exception because we have async promises
     1400    (we can have a promise of a Date() for example) but returning a
     1401    promise is useless because file(name, data) returns the JSZip
     1402    object for chaining. Should we break that to allow the user
     1403    to catch the error ?
     1404
     1405    return external.Promise.resolve(zipObjectContent)
     1406    .then(function () {
     1407        return object;
     1408    });
     1409    */
     1410};
     1411
     1412/**
     1413 * Find the parent folder of the path.
     1414 * @private
     1415 * @param {string} path the path to use
     1416 * @return {string} the parent folder, or ""
     1417 */
     1418var parentFolder = function (path) {
     1419    if (path.slice(-1) === '/') {
     1420        path = path.substring(0, path.length - 1);
     1421    }
     1422    var lastSlash = path.lastIndexOf('/');
     1423    return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
     1424};
     1425
     1426/**
     1427 * Returns the path with a slash at the end.
     1428 * @private
     1429 * @param {String} path the path to check.
     1430 * @return {String} the path with a trailing slash.
     1431 */
     1432var forceTrailingSlash = function(path) {
     1433    // Check the name ends with a /
     1434    if (path.slice(-1) !== "/") {
     1435        path += "/"; // IE doesn't like substr(-1)
     1436    }
     1437    return path;
     1438};
     1439
     1440/**
     1441 * Add a (sub) folder in the current folder.
     1442 * @private
     1443 * @param {string} name the folder's name
     1444 * @param {boolean=} [createFolders] If true, automatically create sub
     1445 *  folders. Defaults to false.
     1446 * @return {Object} the new folder.
     1447 */
     1448var folderAdd = function(name, createFolders) {
     1449    createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders;
     1450
     1451    name = forceTrailingSlash(name);
     1452
     1453    // Does this folder already exist?
     1454    if (!this.files[name]) {
     1455        fileAdd.call(this, name, null, {
     1456            dir: true,
     1457            createFolders: createFolders
     1458        });
     1459    }
     1460    return this.files[name];
     1461};
     1462
     1463/**
     1464* Cross-window, cross-Node-context regular expression detection
     1465* @param  {Object}  object Anything
     1466* @return {Boolean}        true if the object is a regular expression,
     1467* false otherwise
     1468*/
     1469function isRegExp(object) {
     1470    return Object.prototype.toString.call(object) === "[object RegExp]";
     1471}
     1472
     1473// return the actual prototype of JSZip
     1474var out = {
     1475    /**
     1476     * @see loadAsync
     1477     */
     1478    load: function() {
     1479        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
     1480    },
     1481
     1482
     1483    /**
     1484     * Call a callback function for each entry at this folder level.
     1485     * @param {Function} cb the callback function:
     1486     * function (relativePath, file) {...}
     1487     * It takes 2 arguments : the relative path and the file.
     1488     */
     1489    forEach: function(cb) {
     1490        var filename, relativePath, file;
     1491        for (filename in this.files) {
     1492            if (!this.files.hasOwnProperty(filename)) {
     1493                continue;
     1494            }
     1495            file = this.files[filename];
     1496            relativePath = filename.slice(this.root.length, filename.length);
     1497            if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root
     1498                cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn...
     1499            }
     1500        }
     1501    },
     1502
     1503    /**
     1504     * Filter nested files/folders with the specified function.
     1505     * @param {Function} search the predicate to use :
     1506     * function (relativePath, file) {...}
     1507     * It takes 2 arguments : the relative path and the file.
     1508     * @return {Array} An array of matching elements.
     1509     */
     1510    filter: function(search) {
     1511        var result = [];
     1512        this.forEach(function (relativePath, entry) {
     1513            if (search(relativePath, entry)) { // the file matches the function
     1514                result.push(entry);
     1515            }
     1516
     1517        });
     1518        return result;
     1519    },
     1520
     1521    /**
     1522     * Add a file to the zip file, or search a file.
     1523     * @param   {string|RegExp} name The name of the file to add (if data is defined),
     1524     * the name of the file to find (if no data) or a regex to match files.
     1525     * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded
     1526     * @param   {Object} o     File options
     1527     * @return  {JSZip|Object|Array} this JSZip object (when adding a file),
     1528     * a file (when searching by string) or an array of files (when searching by regex).
     1529     */
     1530    file: function(name, data, o) {
     1531        if (arguments.length === 1) {
     1532            if (isRegExp(name)) {
     1533                var regexp = name;
     1534                return this.filter(function(relativePath, file) {
     1535                    return !file.dir && regexp.test(relativePath);
     1536                });
     1537            }
     1538            else { // text
     1539                var obj = this.files[this.root + name];
     1540                if (obj && !obj.dir) {
     1541                    return obj;
     1542                } else {
     1543                    return null;
     1544                }
     1545            }
     1546        }
     1547        else { // more than one argument : we have data !
     1548            name = this.root + name;
     1549            fileAdd.call(this, name, data, o);
     1550        }
     1551        return this;
     1552    },
     1553
     1554    /**
     1555     * Add a directory to the zip file, or search.
     1556     * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.
     1557     * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.
     1558     */
     1559    folder: function(arg) {
     1560        if (!arg) {
     1561            return this;
     1562        }
     1563
     1564        if (isRegExp(arg)) {
     1565            return this.filter(function(relativePath, file) {
     1566                return file.dir && arg.test(relativePath);
     1567            });
     1568        }
     1569
     1570        // else, name is a new folder
     1571        var name = this.root + arg;
     1572        var newFolder = folderAdd.call(this, name);
     1573
     1574        // Allow chaining by returning a new object with this folder as the root
     1575        var ret = this.clone();
     1576        ret.root = newFolder.name;
     1577        return ret;
     1578    },
     1579
     1580    /**
     1581     * Delete a file, or a directory and all sub-files, from the zip
     1582     * @param {string} name the name of the file to delete
     1583     * @return {JSZip} this JSZip object
     1584     */
     1585    remove: function(name) {
     1586        name = this.root + name;
     1587        var file = this.files[name];
     1588        if (!file) {
     1589            // Look for any folders
     1590            if (name.slice(-1) !== "/") {
     1591                name += "/";
     1592            }
     1593            file = this.files[name];
     1594        }
     1595
     1596        if (file && !file.dir) {
     1597            // file
     1598            delete this.files[name];
     1599        } else {
     1600            // maybe a folder, delete recursively
     1601            var kids = this.filter(function(relativePath, file) {
     1602                return file.name.slice(0, name.length) === name;
     1603            });
     1604            for (var i = 0; i < kids.length; i++) {
     1605                delete this.files[kids[i].name];
     1606            }
     1607        }
     1608
     1609        return this;
     1610    },
     1611
     1612    /**
     1613     * Generate the complete zip file
     1614     * @param {Object} options the options to generate the zip file :
     1615     * - compression, "STORE" by default.
     1616     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
     1617     * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
     1618     */
     1619    generate: function(options) {
     1620        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
     1621    },
     1622
     1623    /**
     1624     * Generate the complete zip file as an internal stream.
     1625     * @param {Object} options the options to generate the zip file :
     1626     * - compression, "STORE" by default.
     1627     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
     1628     * @return {StreamHelper} the streamed zip file.
     1629     */
     1630    generateInternalStream: function(options) {
     1631      var worker, opts = {};
     1632      try {
     1633          opts = utils.extend(options || {}, {
     1634              streamFiles: false,
     1635              compression: "STORE",
     1636              compressionOptions : null,
     1637              type: "",
     1638              platform: "DOS",
     1639              comment: null,
     1640              mimeType: 'application/zip',
     1641              encodeFileName: utf8.utf8encode
     1642          });
     1643
     1644          opts.type = opts.type.toLowerCase();
     1645          opts.compression = opts.compression.toUpperCase();
     1646
     1647          // "binarystring" is prefered but the internals use "string".
     1648          if(opts.type === "binarystring") {
     1649            opts.type = "string";
     1650          }
     1651
     1652          if (!opts.type) {
     1653            throw new Error("No output type specified.");
     1654          }
     1655
     1656          utils.checkSupport(opts.type);
     1657
     1658          // accept nodejs `process.platform`
     1659          if(
     1660              opts.platform === 'darwin' ||
     1661              opts.platform === 'freebsd' ||
     1662              opts.platform === 'linux' ||
     1663              opts.platform === 'sunos'
     1664          ) {
     1665              opts.platform = "UNIX";
     1666          }
     1667          if (opts.platform === 'win32') {
     1668              opts.platform = "DOS";
     1669          }
     1670
     1671          var comment = opts.comment || this.comment || "";
     1672          worker = generate.generateWorker(this, opts, comment);
     1673      } catch (e) {
     1674        worker = new GenericWorker("error");
     1675        worker.error(e);
     1676      }
     1677      return new StreamHelper(worker, opts.type || "string", opts.mimeType);
     1678    },
     1679    /**
     1680     * Generate the complete zip file asynchronously.
     1681     * @see generateInternalStream
     1682     */
     1683    generateAsync: function(options, onUpdate) {
     1684        return this.generateInternalStream(options).accumulate(onUpdate);
     1685    },
     1686    /**
     1687     * Generate the complete zip file asynchronously.
     1688     * @see generateInternalStream
     1689     */
     1690    generateNodeStream: function(options, onUpdate) {
     1691        options = options || {};
     1692        if (!options.type) {
     1693            options.type = "nodebuffer";
     1694        }
     1695        return this.generateInternalStream(options).toNodejsStream(onUpdate);
     1696    }
     1697};
     1698module.exports = out;
     1699
     1700},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(require,module,exports){
     1701/*
     1702 * This file is used by module bundlers (browserify/webpack/etc) when
     1703 * including a stream implementation. We use "readable-stream" to get a
     1704 * consistent behavior between nodejs versions but bundlers often have a shim
     1705 * for "stream". Using this shim greatly improve the compatibility and greatly
     1706 * reduce the final size of the bundle (only one stream implementation, not
     1707 * two).
     1708 */
     1709module.exports = require("stream");
     1710
     1711},{"stream":undefined}],17:[function(require,module,exports){
     1712'use strict';
     1713var DataReader = require('./DataReader');
     1714var utils = require('../utils');
     1715
     1716function ArrayReader(data) {
     1717    DataReader.call(this, data);
     1718        for(var i = 0; i < this.data.length; i++) {
     1719                data[i] = data[i] & 0xFF;
     1720        }
     1721}
     1722utils.inherits(ArrayReader, DataReader);
     1723/**
     1724 * @see DataReader.byteAt
     1725 */
     1726ArrayReader.prototype.byteAt = function(i) {
     1727    return this.data[this.zero + i];
     1728};
     1729/**
     1730 * @see DataReader.lastIndexOfSignature
     1731 */
     1732ArrayReader.prototype.lastIndexOfSignature = function(sig) {
     1733    var sig0 = sig.charCodeAt(0),
     1734        sig1 = sig.charCodeAt(1),
     1735        sig2 = sig.charCodeAt(2),
     1736        sig3 = sig.charCodeAt(3);
     1737    for (var i = this.length - 4; i >= 0; --i) {
     1738        if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) {
     1739            return i - this.zero;
     1740        }
     1741    }
     1742
     1743    return -1;
     1744};
     1745/**
     1746 * @see DataReader.readAndCheckSignature
     1747 */
     1748ArrayReader.prototype.readAndCheckSignature = function (sig) {
     1749    var sig0 = sig.charCodeAt(0),
     1750        sig1 = sig.charCodeAt(1),
     1751        sig2 = sig.charCodeAt(2),
     1752        sig3 = sig.charCodeAt(3),
     1753        data = this.readData(4);
     1754    return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3];
     1755};
     1756/**
     1757 * @see DataReader.readData
     1758 */
     1759ArrayReader.prototype.readData = function(size) {
     1760    this.checkOffset(size);
     1761    if(size === 0) {
     1762        return [];
     1763    }
     1764    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
     1765    this.index += size;
     1766    return result;
     1767};
     1768module.exports = ArrayReader;
     1769
     1770},{"../utils":32,"./DataReader":18}],18:[function(require,module,exports){
     1771'use strict';
     1772var utils = require('../utils');
     1773
     1774function DataReader(data) {
     1775    this.data = data; // type : see implementation
     1776    this.length = data.length;
     1777    this.index = 0;
     1778    this.zero = 0;
     1779}
     1780DataReader.prototype = {
     1781    /**
     1782     * Check that the offset will not go too far.
     1783     * @param {string} offset the additional offset to check.
     1784     * @throws {Error} an Error if the offset is out of bounds.
     1785     */
     1786    checkOffset: function(offset) {
     1787        this.checkIndex(this.index + offset);
     1788    },
     1789    /**
     1790     * Check that the specifed index will not be too far.
     1791     * @param {string} newIndex the index to check.
     1792     * @throws {Error} an Error if the index is out of bounds.
     1793     */
     1794    checkIndex: function(newIndex) {
     1795        if (this.length < this.zero + newIndex || newIndex < 0) {
     1796            throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?");
     1797        }
     1798    },
     1799    /**
     1800     * Change the index.
     1801     * @param {number} newIndex The new index.
     1802     * @throws {Error} if the new index is out of the data.
     1803     */
     1804    setIndex: function(newIndex) {
     1805        this.checkIndex(newIndex);
     1806        this.index = newIndex;
     1807    },
     1808    /**
     1809     * Skip the next n bytes.
     1810     * @param {number} n the number of bytes to skip.
     1811     * @throws {Error} if the new index is out of the data.
     1812     */
     1813    skip: function(n) {
     1814        this.setIndex(this.index + n);
     1815    },
     1816    /**
     1817     * Get the byte at the specified index.
     1818     * @param {number} i the index to use.
     1819     * @return {number} a byte.
     1820     */
     1821    byteAt: function(i) {
     1822        // see implementations
     1823    },
     1824    /**
     1825     * Get the next number with a given byte size.
     1826     * @param {number} size the number of bytes to read.
     1827     * @return {number} the corresponding number.
     1828     */
     1829    readInt: function(size) {
     1830        var result = 0,
     1831            i;
     1832        this.checkOffset(size);
     1833        for (i = this.index + size - 1; i >= this.index; i--) {
     1834            result = (result << 8) + this.byteAt(i);
     1835        }
     1836        this.index += size;
     1837        return result;
     1838    },
     1839    /**
     1840     * Get the next string with a given byte size.
     1841     * @param {number} size the number of bytes to read.
     1842     * @return {string} the corresponding string.
     1843     */
     1844    readString: function(size) {
     1845        return utils.transformTo("string", this.readData(size));
     1846    },
     1847    /**
     1848     * Get raw data without conversion, <size> bytes.
     1849     * @param {number} size the number of bytes to read.
     1850     * @return {Object} the raw data, implementation specific.
     1851     */
     1852    readData: function(size) {
     1853        // see implementations
     1854    },
     1855    /**
     1856     * Find the last occurence of a zip signature (4 bytes).
     1857     * @param {string} sig the signature to find.
     1858     * @return {number} the index of the last occurence, -1 if not found.
     1859     */
     1860    lastIndexOfSignature: function(sig) {
     1861        // see implementations
     1862    },
     1863    /**
     1864     * Read the signature (4 bytes) at the current position and compare it with sig.
     1865     * @param {string} sig the expected signature
     1866     * @return {boolean} true if the signature matches, false otherwise.
     1867     */
     1868    readAndCheckSignature: function(sig) {
     1869        // see implementations
     1870    },
     1871    /**
     1872     * Get the next date.
     1873     * @return {Date} the date.
     1874     */
     1875    readDate: function() {
     1876        var dostime = this.readInt(4);
     1877        return new Date(Date.UTC(
     1878        ((dostime >> 25) & 0x7f) + 1980, // year
     1879        ((dostime >> 21) & 0x0f) - 1, // month
     1880        (dostime >> 16) & 0x1f, // day
     1881        (dostime >> 11) & 0x1f, // hour
     1882        (dostime >> 5) & 0x3f, // minute
     1883        (dostime & 0x1f) << 1)); // second
     1884    }
     1885};
     1886module.exports = DataReader;
     1887
     1888},{"../utils":32}],19:[function(require,module,exports){
     1889'use strict';
     1890var Uint8ArrayReader = require('./Uint8ArrayReader');
     1891var utils = require('../utils');
     1892
     1893function NodeBufferReader(data) {
     1894    Uint8ArrayReader.call(this, data);
     1895}
     1896utils.inherits(NodeBufferReader, Uint8ArrayReader);
     1897
     1898/**
     1899 * @see DataReader.readData
     1900 */
     1901NodeBufferReader.prototype.readData = function(size) {
     1902    this.checkOffset(size);
     1903    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
     1904    this.index += size;
     1905    return result;
     1906};
     1907module.exports = NodeBufferReader;
     1908
     1909},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(require,module,exports){
     1910'use strict';
     1911var DataReader = require('./DataReader');
     1912var utils = require('../utils');
     1913
     1914function StringReader(data) {
     1915    DataReader.call(this, data);
     1916}
     1917utils.inherits(StringReader, DataReader);
     1918/**
     1919 * @see DataReader.byteAt
     1920 */
     1921StringReader.prototype.byteAt = function(i) {
     1922    return this.data.charCodeAt(this.zero + i);
     1923};
     1924/**
     1925 * @see DataReader.lastIndexOfSignature
     1926 */
     1927StringReader.prototype.lastIndexOfSignature = function(sig) {
     1928    return this.data.lastIndexOf(sig) - this.zero;
     1929};
     1930/**
     1931 * @see DataReader.readAndCheckSignature
     1932 */
     1933StringReader.prototype.readAndCheckSignature = function (sig) {
     1934    var data = this.readData(4);
     1935    return sig === data;
     1936};
     1937/**
     1938 * @see DataReader.readData
     1939 */
     1940StringReader.prototype.readData = function(size) {
     1941    this.checkOffset(size);
     1942    // this will work because the constructor applied the "& 0xff" mask.
     1943    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
     1944    this.index += size;
     1945    return result;
     1946};
     1947module.exports = StringReader;
     1948
     1949},{"../utils":32,"./DataReader":18}],21:[function(require,module,exports){
     1950'use strict';
     1951var ArrayReader = require('./ArrayReader');
     1952var utils = require('../utils');
     1953
     1954function Uint8ArrayReader(data) {
     1955    ArrayReader.call(this, data);
     1956}
     1957utils.inherits(Uint8ArrayReader, ArrayReader);
     1958/**
     1959 * @see DataReader.readData
     1960 */
     1961Uint8ArrayReader.prototype.readData = function(size) {
     1962    this.checkOffset(size);
     1963    if(size === 0) {
     1964        // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of [].
     1965        return new Uint8Array(0);
     1966    }
     1967    var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size);
     1968    this.index += size;
     1969    return result;
     1970};
     1971module.exports = Uint8ArrayReader;
     1972
     1973},{"../utils":32,"./ArrayReader":17}],22:[function(require,module,exports){
     1974'use strict';
     1975
     1976var utils = require('../utils');
     1977var support = require('../support');
     1978var ArrayReader = require('./ArrayReader');
     1979var StringReader = require('./StringReader');
     1980var NodeBufferReader = require('./NodeBufferReader');
     1981var Uint8ArrayReader = require('./Uint8ArrayReader');
     1982
     1983/**
     1984 * Create a reader adapted to the data.
     1985 * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read.
     1986 * @return {DataReader} the data reader.
     1987 */
     1988module.exports = function (data) {
     1989    var type = utils.getTypeOf(data);
     1990    utils.checkSupport(type);
     1991    if (type === "string" && !support.uint8array) {
     1992        return new StringReader(data);
     1993    }
     1994    if (type === "nodebuffer") {
     1995        return new NodeBufferReader(data);
     1996    }
     1997    if (support.uint8array) {
     1998        return new Uint8ArrayReader(utils.transformTo("uint8array", data));
     1999    }
     2000    return new ArrayReader(utils.transformTo("array", data));
     2001};
     2002
     2003},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(require,module,exports){
     2004'use strict';
     2005exports.LOCAL_FILE_HEADER = "PK\x03\x04";
     2006exports.CENTRAL_FILE_HEADER = "PK\x01\x02";
     2007exports.CENTRAL_DIRECTORY_END = "PK\x05\x06";
     2008exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07";
     2009exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06";
     2010exports.DATA_DESCRIPTOR = "PK\x07\x08";
     2011
     2012},{}],24:[function(require,module,exports){
     2013'use strict';
     2014
     2015var GenericWorker = require('./GenericWorker');
     2016var utils = require('../utils');
     2017
     2018/**
     2019 * A worker which convert chunks to a specified type.
     2020 * @constructor
     2021 * @param {String} destType the destination type.
     2022 */
     2023function ConvertWorker(destType) {
     2024    GenericWorker.call(this, "ConvertWorker to " + destType);
     2025    this.destType = destType;
     2026}
     2027utils.inherits(ConvertWorker, GenericWorker);
     2028
     2029/**
     2030 * @see GenericWorker.processChunk
     2031 */
     2032ConvertWorker.prototype.processChunk = function (chunk) {
     2033    this.push({
     2034        data : utils.transformTo(this.destType, chunk.data),
     2035        meta : chunk.meta
     2036    });
     2037};
     2038module.exports = ConvertWorker;
     2039
     2040},{"../utils":32,"./GenericWorker":28}],25:[function(require,module,exports){
     2041'use strict';
     2042
     2043var GenericWorker = require('./GenericWorker');
     2044var crc32 = require('../crc32');
     2045var utils = require('../utils');
     2046
     2047/**
     2048 * A worker which calculate the crc32 of the data flowing through.
     2049 * @constructor
     2050 */
     2051function Crc32Probe() {
     2052    GenericWorker.call(this, "Crc32Probe");
     2053    this.withStreamInfo("crc32", 0);
     2054}
     2055utils.inherits(Crc32Probe, GenericWorker);
     2056
     2057/**
     2058 * @see GenericWorker.processChunk
     2059 */
     2060Crc32Probe.prototype.processChunk = function (chunk) {
     2061    this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0);
     2062    this.push(chunk);
     2063};
     2064module.exports = Crc32Probe;
     2065
     2066},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(require,module,exports){
     2067'use strict';
     2068
     2069var utils = require('../utils');
     2070var GenericWorker = require('./GenericWorker');
     2071
     2072/**
     2073 * A worker which calculate the total length of the data flowing through.
     2074 * @constructor
     2075 * @param {String} propName the name used to expose the length
     2076 */
     2077function DataLengthProbe(propName) {
     2078    GenericWorker.call(this, "DataLengthProbe for " + propName);
     2079    this.propName = propName;
     2080    this.withStreamInfo(propName, 0);
     2081}
     2082utils.inherits(DataLengthProbe, GenericWorker);
     2083
     2084/**
     2085 * @see GenericWorker.processChunk
     2086 */
     2087DataLengthProbe.prototype.processChunk = function (chunk) {
     2088    if(chunk) {
     2089        var length = this.streamInfo[this.propName] || 0;
     2090        this.streamInfo[this.propName] = length + chunk.data.length;
     2091    }
     2092    GenericWorker.prototype.processChunk.call(this, chunk);
     2093};
     2094module.exports = DataLengthProbe;
     2095
     2096
     2097},{"../utils":32,"./GenericWorker":28}],27:[function(require,module,exports){
     2098'use strict';
     2099
     2100var utils = require('../utils');
     2101var GenericWorker = require('./GenericWorker');
     2102
     2103// the size of the generated chunks
     2104// TODO expose this as a public variable
     2105var DEFAULT_BLOCK_SIZE = 16 * 1024;
     2106
     2107/**
     2108 * A worker that reads a content and emits chunks.
     2109 * @constructor
     2110 * @param {Promise} dataP the promise of the data to split
     2111 */
     2112function DataWorker(dataP) {
     2113    GenericWorker.call(this, "DataWorker");
     2114    var self = this;
     2115    this.dataIsReady = false;
     2116    this.index = 0;
     2117    this.max = 0;
     2118    this.data = null;
     2119    this.type = "";
     2120
     2121    this._tickScheduled = false;
     2122
     2123    dataP.then(function (data) {
     2124        self.dataIsReady = true;
     2125        self.data = data;
     2126        self.max = data && data.length || 0;
     2127        self.type = utils.getTypeOf(data);
     2128        if(!self.isPaused) {
     2129            self._tickAndRepeat();
     2130        }
     2131    }, function (e) {
     2132        self.error(e);
     2133    });
     2134}
     2135
     2136utils.inherits(DataWorker, GenericWorker);
     2137
     2138/**
     2139 * @see GenericWorker.cleanUp
     2140 */
     2141DataWorker.prototype.cleanUp = function () {
     2142    GenericWorker.prototype.cleanUp.call(this);
     2143    this.data = null;
     2144};
     2145
     2146/**
     2147 * @see GenericWorker.resume
     2148 */
     2149DataWorker.prototype.resume = function () {
     2150    if(!GenericWorker.prototype.resume.call(this)) {
     2151        return false;
     2152    }
     2153
     2154    if (!this._tickScheduled && this.dataIsReady) {
     2155        this._tickScheduled = true;
     2156        utils.delay(this._tickAndRepeat, [], this);
     2157    }
     2158    return true;
     2159};
     2160
     2161/**
     2162 * Trigger a tick a schedule an other call to this function.
     2163 */
     2164DataWorker.prototype._tickAndRepeat = function() {
     2165    this._tickScheduled = false;
     2166    if(this.isPaused || this.isFinished) {
     2167        return;
     2168    }
     2169    this._tick();
     2170    if(!this.isFinished) {
     2171        utils.delay(this._tickAndRepeat, [], this);
     2172        this._tickScheduled = true;
     2173    }
     2174};
     2175
     2176/**
     2177 * Read and push a chunk.
     2178 */
     2179DataWorker.prototype._tick = function() {
     2180
     2181    if(this.isPaused || this.isFinished) {
     2182        return false;
     2183    }
     2184
     2185    var size = DEFAULT_BLOCK_SIZE;
     2186    var data = null, nextIndex = Math.min(this.max, this.index + size);
     2187    if (this.index >= this.max) {
     2188        // EOF
     2189        return this.end();
     2190    } else {
     2191        switch(this.type) {
     2192            case "string":
     2193                data = this.data.substring(this.index, nextIndex);
     2194            break;
     2195            case "uint8array":
     2196                data = this.data.subarray(this.index, nextIndex);
     2197            break;
     2198            case "array":
     2199            case "nodebuffer":
     2200                data = this.data.slice(this.index, nextIndex);
     2201            break;
     2202        }
     2203        this.index = nextIndex;
     2204        return this.push({
     2205            data : data,
     2206            meta : {
     2207                percent : this.max ? this.index / this.max * 100 : 0
     2208            }
     2209        });
     2210    }
     2211};
     2212
     2213module.exports = DataWorker;
     2214
     2215},{"../utils":32,"./GenericWorker":28}],28:[function(require,module,exports){
     2216'use strict';
     2217
     2218/**
     2219 * A worker that does nothing but passing chunks to the next one. This is like
     2220 * a nodejs stream but with some differences. On the good side :
     2221 * - it works on IE 6-9 without any issue / polyfill
     2222 * - it weights less than the full dependencies bundled with browserify
     2223 * - it forwards errors (no need to declare an error handler EVERYWHERE)
     2224 *
     2225 * A chunk is an object with 2 attributes : `meta` and `data`. The former is an
     2226 * object containing anything (`percent` for example), see each worker for more
     2227 * details. The latter is the real data (String, Uint8Array, etc).
     2228 *
     2229 * @constructor
     2230 * @param {String} name the name of the stream (mainly used for debugging purposes)
     2231 */
     2232function GenericWorker(name) {
     2233    // the name of the worker
     2234    this.name = name || "default";
     2235    // an object containing metadata about the workers chain
     2236    this.streamInfo = {};
     2237    // an error which happened when the worker was paused
     2238    this.generatedError = null;
     2239    // an object containing metadata to be merged by this worker into the general metadata
     2240    this.extraStreamInfo = {};
     2241    // true if the stream is paused (and should not do anything), false otherwise
     2242    this.isPaused = true;
     2243    // true if the stream is finished (and should not do anything), false otherwise
     2244    this.isFinished = false;
     2245    // true if the stream is locked to prevent further structure updates (pipe), false otherwise
     2246    this.isLocked = false;
     2247    // the event listeners
     2248    this._listeners = {
     2249        'data':[],
     2250        'end':[],
     2251        'error':[]
     2252    };
     2253    // the previous worker, if any
     2254    this.previous = null;
     2255}
     2256
     2257GenericWorker.prototype = {
     2258    /**
     2259     * Push a chunk to the next workers.
     2260     * @param {Object} chunk the chunk to push
     2261     */
     2262    push : function (chunk) {
     2263        this.emit("data", chunk);
     2264    },
     2265    /**
     2266     * End the stream.
     2267     * @return {Boolean} true if this call ended the worker, false otherwise.
     2268     */
     2269    end : function () {
     2270        if (this.isFinished) {
     2271            return false;
     2272        }
     2273
     2274        this.flush();
     2275        try {
     2276            this.emit("end");
     2277            this.cleanUp();
     2278            this.isFinished = true;
     2279        } catch (e) {
     2280            this.emit("error", e);
     2281        }
     2282        return true;
     2283    },
     2284    /**
     2285     * End the stream with an error.
     2286     * @param {Error} e the error which caused the premature end.
     2287     * @return {Boolean} true if this call ended the worker with an error, false otherwise.
     2288     */
     2289    error : function (e) {
     2290        if (this.isFinished) {
     2291            return false;
     2292        }
     2293
     2294        if(this.isPaused) {
     2295            this.generatedError = e;
     2296        } else {
     2297            this.isFinished = true;
     2298
     2299            this.emit("error", e);
     2300
     2301            // in the workers chain exploded in the middle of the chain,
     2302            // the error event will go downward but we also need to notify
     2303            // workers upward that there has been an error.
     2304            if(this.previous) {
     2305                this.previous.error(e);
     2306            }
     2307
     2308            this.cleanUp();
     2309        }
     2310        return true;
     2311    },
     2312    /**
     2313     * Add a callback on an event.
     2314     * @param {String} name the name of the event (data, end, error)
     2315     * @param {Function} listener the function to call when the event is triggered
     2316     * @return {GenericWorker} the current object for chainability
     2317     */
     2318    on : function (name, listener) {
     2319        this._listeners[name].push(listener);
     2320        return this;
     2321    },
     2322    /**
     2323     * Clean any references when a worker is ending.
     2324     */
     2325    cleanUp : function () {
     2326        this.streamInfo = this.generatedError = this.extraStreamInfo = null;
     2327        this._listeners = [];
     2328    },
     2329    /**
     2330     * Trigger an event. This will call registered callback with the provided arg.
     2331     * @param {String} name the name of the event (data, end, error)
     2332     * @param {Object} arg the argument to call the callback with.
     2333     */
     2334    emit : function (name, arg) {
     2335        if (this._listeners[name]) {
     2336            for(var i = 0; i < this._listeners[name].length; i++) {
     2337                this._listeners[name][i].call(this, arg);
     2338            }
     2339        }
     2340    },
     2341    /**
     2342     * Chain a worker with an other.
     2343     * @param {Worker} next the worker receiving events from the current one.
     2344     * @return {worker} the next worker for chainability
     2345     */
     2346    pipe : function (next) {
     2347        return next.registerPrevious(this);
     2348    },
     2349    /**
     2350     * Same as `pipe` in the other direction.
     2351     * Using an API with `pipe(next)` is very easy.
     2352     * Implementing the API with the point of view of the next one registering
     2353     * a source is easier, see the ZipFileWorker.
     2354     * @param {Worker} previous the previous worker, sending events to this one
     2355     * @return {Worker} the current worker for chainability
     2356     */
     2357    registerPrevious : function (previous) {
     2358        if (this.isLocked) {
     2359            throw new Error("The stream '" + this + "' has already been used.");
     2360        }
     2361
     2362        // sharing the streamInfo...
     2363        this.streamInfo = previous.streamInfo;
     2364        // ... and adding our own bits
     2365        this.mergeStreamInfo();
     2366        this.previous =  previous;
     2367        var self = this;
     2368        previous.on('data', function (chunk) {
     2369            self.processChunk(chunk);
     2370        });
     2371        previous.on('end', function () {
     2372            self.end();
     2373        });
     2374        previous.on('error', function (e) {
     2375            self.error(e);
     2376        });
     2377        return this;
     2378    },
     2379    /**
     2380     * Pause the stream so it doesn't send events anymore.
     2381     * @return {Boolean} true if this call paused the worker, false otherwise.
     2382     */
     2383    pause : function () {
     2384        if(this.isPaused || this.isFinished) {
     2385            return false;
     2386        }
     2387        this.isPaused = true;
     2388
     2389        if(this.previous) {
     2390            this.previous.pause();
     2391        }
     2392        return true;
     2393    },
     2394    /**
     2395     * Resume a paused stream.
     2396     * @return {Boolean} true if this call resumed the worker, false otherwise.
     2397     */
     2398    resume : function () {
     2399        if(!this.isPaused || this.isFinished) {
     2400            return false;
     2401        }
     2402        this.isPaused = false;
     2403
     2404        // if true, the worker tried to resume but failed
     2405        var withError = false;
     2406        if(this.generatedError) {
     2407            this.error(this.generatedError);
     2408            withError = true;
     2409        }
     2410        if(this.previous) {
     2411            this.previous.resume();
     2412        }
     2413
     2414        return !withError;
     2415    },
     2416    /**
     2417     * Flush any remaining bytes as the stream is ending.
     2418     */
     2419    flush : function () {},
     2420    /**
     2421     * Process a chunk. This is usually the method overridden.
     2422     * @param {Object} chunk the chunk to process.
     2423     */
     2424    processChunk : function(chunk) {
     2425        this.push(chunk);
     2426    },
     2427    /**
     2428     * Add a key/value to be added in the workers chain streamInfo once activated.
     2429     * @param {String} key the key to use
     2430     * @param {Object} value the associated value
     2431     * @return {Worker} the current worker for chainability
     2432     */
     2433    withStreamInfo : function (key, value) {
     2434        this.extraStreamInfo[key] = value;
     2435        this.mergeStreamInfo();
     2436        return this;
     2437    },
     2438    /**
     2439     * Merge this worker's streamInfo into the chain's streamInfo.
     2440     */
     2441    mergeStreamInfo : function () {
     2442        for(var key in this.extraStreamInfo) {
     2443            if (!this.extraStreamInfo.hasOwnProperty(key)) {
     2444                continue;
     2445            }
     2446            this.streamInfo[key] = this.extraStreamInfo[key];
     2447        }
     2448    },
     2449
     2450    /**
     2451     * Lock the stream to prevent further updates on the workers chain.
     2452     * After calling this method, all calls to pipe will fail.
     2453     */
     2454    lock: function () {
     2455        if (this.isLocked) {
     2456            throw new Error("The stream '" + this + "' has already been used.");
     2457        }
     2458        this.isLocked = true;
     2459        if (this.previous) {
     2460            this.previous.lock();
     2461        }
     2462    },
     2463
     2464    /**
     2465     *
     2466     * Pretty print the workers chain.
     2467     */
     2468    toString : function () {
     2469        var me = "Worker " + this.name;
     2470        if (this.previous) {
     2471            return this.previous + " -> " + me;
     2472        } else {
     2473            return me;
     2474        }
     2475    }
     2476};
     2477
     2478module.exports = GenericWorker;
     2479
     2480},{}],29:[function(require,module,exports){
     2481'use strict';
     2482
     2483var utils = require('../utils');
     2484var ConvertWorker = require('./ConvertWorker');
     2485var GenericWorker = require('./GenericWorker');
     2486var base64 = require('../base64');
     2487var support = require("../support");
     2488var external = require("../external");
     2489
     2490var NodejsStreamOutputAdapter = null;
     2491if (support.nodestream) {
     2492    try {
     2493        NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter');
     2494    } catch(e) {}
     2495}
     2496
     2497/**
     2498 * Apply the final transformation of the data. If the user wants a Blob for
     2499 * example, it's easier to work with an U8intArray and finally do the
     2500 * ArrayBuffer/Blob conversion.
     2501 * @param {String} resultType the name of the final type
     2502 * @param {String} chunkType the type of the data in the given array.
     2503 * @param {Array} dataArray the array containing the data chunks to concatenate
     2504 * @param {String|Uint8Array|Buffer} content the content to transform
     2505 * @param {String} mimeType the mime type of the content, if applicable.
     2506 * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format.
     2507 */
     2508function transformZipOutput(resultType, chunkType, dataArray, mimeType) {
     2509    var content = null;
     2510    switch(resultType) {
     2511        case "blob" :
     2512            return utils.newBlob(dataArray, mimeType);
     2513        case "base64" :
     2514            content = concat(chunkType, dataArray);
     2515            return base64.encode(content);
     2516        default :
     2517            content = concat(chunkType, dataArray);
     2518            return utils.transformTo(resultType, content);
     2519    }
     2520}
     2521
     2522/**
     2523 * Concatenate an array of data of the given type.
     2524 * @param {String} type the type of the data in the given array.
     2525 * @param {Array} dataArray the array containing the data chunks to concatenate
     2526 * @return {String|Uint8Array|Buffer} the concatenated data
     2527 * @throws Error if the asked type is unsupported
     2528 */
     2529function concat (type, dataArray) {
     2530    var i, index = 0, res = null, totalLength = 0;
     2531    for(i = 0; i < dataArray.length; i++) {
     2532        totalLength += dataArray[i].length;
     2533    }
     2534    switch(type) {
     2535        case "string":
     2536            return dataArray.join("");
     2537          case "array":
     2538            return Array.prototype.concat.apply([], dataArray);
     2539        case "uint8array":
     2540            res = new Uint8Array(totalLength);
     2541            for(i = 0; i < dataArray.length; i++) {
     2542                res.set(dataArray[i], index);
     2543                index += dataArray[i].length;
     2544            }
     2545            return res;
     2546        case "nodebuffer":
     2547            return Buffer.concat(dataArray);
     2548        default:
     2549            throw new Error("concat : unsupported type '"  + type + "'");
     2550    }
     2551}
     2552
     2553/**
     2554 * Listen a StreamHelper, accumulate its content and concatenate it into a
     2555 * complete block.
     2556 * @param {StreamHelper} helper the helper to use.
     2557 * @param {Function} updateCallback a callback called on each update. Called
     2558 * with one arg :
     2559 * - the metadata linked to the update received.
     2560 * @return Promise the promise for the accumulation.
     2561 */
     2562function accumulate(helper, updateCallback) {
     2563    return new external.Promise(function (resolve, reject){
     2564        var dataArray = [];
     2565        var chunkType = helper._internalType,
     2566            resultType = helper._outputType,
     2567            mimeType = helper._mimeType;
     2568        helper
     2569        .on('data', function (data, meta) {
     2570            dataArray.push(data);
     2571            if(updateCallback) {
     2572                updateCallback(meta);
     2573            }
     2574        })
     2575        .on('error', function(err) {
     2576            dataArray = [];
     2577            reject(err);
     2578        })
     2579        .on('end', function (){
     2580            try {
     2581                var result = transformZipOutput(resultType, chunkType, dataArray, mimeType);
     2582                resolve(result);
     2583            } catch (e) {
     2584                reject(e);
     2585            }
     2586            dataArray = [];
     2587        })
     2588        .resume();
     2589    });
     2590}
     2591
     2592/**
     2593 * An helper to easily use workers outside of JSZip.
     2594 * @constructor
     2595 * @param {Worker} worker the worker to wrap
     2596 * @param {String} outputType the type of data expected by the use
     2597 * @param {String} mimeType the mime type of the content, if applicable.
     2598 */
     2599function StreamHelper(worker, outputType, mimeType) {
     2600    var internalType = outputType;
     2601    switch(outputType) {
     2602        case "blob":
     2603            internalType = "arraybuffer";
     2604        break;
     2605        case "arraybuffer":
     2606            internalType = "uint8array";
     2607        break;
     2608        case "base64":
     2609            internalType = "string";
     2610        break;
     2611    }
     2612
     2613    try {
     2614        // the type used internally
     2615        this._internalType = internalType;
     2616        // the type used to output results
     2617        this._outputType = outputType;
     2618        // the mime type
     2619        this._mimeType = mimeType;
     2620        utils.checkSupport(internalType);
     2621        this._worker = worker.pipe(new ConvertWorker(internalType));
     2622        // the last workers can be rewired without issues but we need to
     2623        // prevent any updates on previous workers.
     2624        worker.lock();
     2625    } catch(e) {
     2626        this._worker = new GenericWorker("error");
     2627        this._worker.error(e);
     2628    }
     2629}
     2630
     2631StreamHelper.prototype = {
     2632    /**
     2633     * Listen a StreamHelper, accumulate its content and concatenate it into a
     2634     * complete block.
     2635     * @param {Function} updateCb the update callback.
     2636     * @return Promise the promise for the accumulation.
     2637     */
     2638    accumulate : function (updateCb) {
     2639        return accumulate(this, updateCb);
     2640    },
     2641    /**
     2642     * Add a listener on an event triggered on a stream.
     2643     * @param {String} evt the name of the event
     2644     * @param {Function} fn the listener
     2645     * @return {StreamHelper} the current helper.
     2646     */
     2647    on : function (evt, fn) {
     2648        var self = this;
     2649
     2650        if(evt === "data") {
     2651            this._worker.on(evt, function (chunk) {
     2652                fn.call(self, chunk.data, chunk.meta);
     2653            });
     2654        } else {
     2655            this._worker.on(evt, function () {
     2656                utils.delay(fn, arguments, self);
     2657            });
     2658        }
     2659        return this;
     2660    },
     2661    /**
     2662     * Resume the flow of chunks.
     2663     * @return {StreamHelper} the current helper.
     2664     */
     2665    resume : function () {
     2666        utils.delay(this._worker.resume, [], this._worker);
     2667        return this;
     2668    },
     2669    /**
     2670     * Pause the flow of chunks.
     2671     * @return {StreamHelper} the current helper.
     2672     */
     2673    pause : function () {
     2674        this._worker.pause();
     2675        return this;
     2676    },
     2677    /**
     2678     * Return a nodejs stream for this helper.
     2679     * @param {Function} updateCb the update callback.
     2680     * @return {NodejsStreamOutputAdapter} the nodejs stream.
     2681     */
     2682    toNodejsStream : function (updateCb) {
     2683        utils.checkSupport("nodestream");
     2684        if (this._outputType !== "nodebuffer") {
     2685            // an object stream containing blob/arraybuffer/uint8array/string
     2686            // is strange and I don't know if it would be useful.
     2687            // I you find this comment and have a good usecase, please open a
     2688            // bug report !
     2689            throw new Error(this._outputType + " is not supported by this method");
     2690        }
     2691
     2692        return new NodejsStreamOutputAdapter(this, {
     2693            objectMode : this._outputType !== "nodebuffer"
     2694        }, updateCb);
     2695    }
     2696};
     2697
     2698
     2699module.exports = StreamHelper;
     2700
     2701},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(require,module,exports){
     2702'use strict';
     2703
     2704exports.base64 = true;
     2705exports.array = true;
     2706exports.string = true;
     2707exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
     2708exports.nodebuffer = typeof Buffer !== "undefined";
     2709// contains true if JSZip can read/generate Uint8Array, false otherwise.
     2710exports.uint8array = typeof Uint8Array !== "undefined";
     2711
     2712if (typeof ArrayBuffer === "undefined") {
     2713    exports.blob = false;
     2714}
     2715else {
     2716    var buffer = new ArrayBuffer(0);
     2717    try {
     2718        exports.blob = new Blob([buffer], {
     2719            type: "application/zip"
     2720        }).size === 0;
     2721    }
     2722    catch (e) {
     2723        try {
     2724            var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
     2725            var builder = new Builder();
     2726            builder.append(buffer);
     2727            exports.blob = builder.getBlob('application/zip').size === 0;
     2728        }
     2729        catch (e) {
     2730            exports.blob = false;
     2731        }
     2732    }
     2733}
     2734
     2735try {
     2736    exports.nodestream = !!require('readable-stream').Readable;
     2737} catch(e) {
     2738    exports.nodestream = false;
     2739}
     2740
     2741},{"readable-stream":16}],31:[function(require,module,exports){
     2742'use strict';
     2743
     2744var utils = require('./utils');
     2745var support = require('./support');
     2746var nodejsUtils = require('./nodejsUtils');
     2747var GenericWorker = require('./stream/GenericWorker');
     2748
     2749/**
     2750 * The following functions come from pako, from pako/lib/utils/strings
     2751 * released under the MIT license, see pako https://github.com/nodeca/pako/
     2752 */
     2753
     2754// Table with utf8 lengths (calculated by first byte of sequence)
     2755// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
     2756// because max possible codepoint is 0x10ffff
     2757var _utf8len = new Array(256);
     2758for (var i=0; i<256; i++) {
     2759  _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);
     2760}
     2761_utf8len[254]=_utf8len[254]=1; // Invalid sequence start
     2762
     2763// convert string to array (typed, when possible)
     2764var string2buf = function (str) {
     2765    var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
     2766
     2767    // count binary size
     2768    for (m_pos = 0; m_pos < str_len; m_pos++) {
     2769        c = str.charCodeAt(m_pos);
     2770        if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
     2771            c2 = str.charCodeAt(m_pos+1);
     2772            if ((c2 & 0xfc00) === 0xdc00) {
     2773                c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
     2774                m_pos++;
     2775            }
     2776        }
     2777        buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
     2778    }
     2779
     2780    // allocate buffer
     2781    if (support.uint8array) {
     2782        buf = new Uint8Array(buf_len);
     2783    } else {
     2784        buf = new Array(buf_len);
     2785    }
     2786
     2787    // convert
     2788    for (i=0, m_pos = 0; i < buf_len; m_pos++) {
     2789        c = str.charCodeAt(m_pos);
     2790        if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
     2791            c2 = str.charCodeAt(m_pos+1);
     2792            if ((c2 & 0xfc00) === 0xdc00) {
     2793                c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
     2794                m_pos++;
     2795            }
     2796        }
     2797        if (c < 0x80) {
     2798            /* one byte */
     2799            buf[i++] = c;
     2800        } else if (c < 0x800) {
     2801            /* two bytes */
     2802            buf[i++] = 0xC0 | (c >>> 6);
     2803            buf[i++] = 0x80 | (c & 0x3f);
     2804        } else if (c < 0x10000) {
     2805            /* three bytes */
     2806            buf[i++] = 0xE0 | (c >>> 12);
     2807            buf[i++] = 0x80 | (c >>> 6 & 0x3f);
     2808            buf[i++] = 0x80 | (c & 0x3f);
     2809        } else {
     2810            /* four bytes */
     2811            buf[i++] = 0xf0 | (c >>> 18);
     2812            buf[i++] = 0x80 | (c >>> 12 & 0x3f);
     2813            buf[i++] = 0x80 | (c >>> 6 & 0x3f);
     2814            buf[i++] = 0x80 | (c & 0x3f);
     2815        }
     2816    }
     2817
     2818    return buf;
     2819};
     2820
     2821// Calculate max possible position in utf8 buffer,
     2822// that will not break sequence. If that's not possible
     2823// - (very small limits) return max size as is.
     2824//
     2825// buf[] - utf8 bytes array
     2826// max   - length limit (mandatory);
     2827var utf8border = function(buf, max) {
     2828    var pos;
     2829
     2830    max = max || buf.length;
     2831    if (max > buf.length) { max = buf.length; }
     2832
     2833    // go back from last position, until start of sequence found
     2834    pos = max-1;
     2835    while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
     2836
     2837    // Fuckup - very small and broken sequence,
     2838    // return max, because we should return something anyway.
     2839    if (pos < 0) { return max; }
     2840
     2841    // If we came to start of buffer - that means vuffer is too small,
     2842    // return max too.
     2843    if (pos === 0) { return max; }
     2844
     2845    return (pos + _utf8len[buf[pos]] > max) ? pos : max;
     2846};
     2847
     2848// convert array to string
     2849var buf2string = function (buf) {
     2850    var str, i, out, c, c_len;
     2851    var len = buf.length;
     2852
     2853    // Reserve max possible length (2 words per char)
     2854    // NB: by unknown reasons, Array is significantly faster for
     2855    //     String.fromCharCode.apply than Uint16Array.
     2856    var utf16buf = new Array(len*2);
     2857
     2858    for (out=0, i=0; i<len;) {
     2859        c = buf[i++];
     2860        // quick process ascii
     2861        if (c < 0x80) { utf16buf[out++] = c; continue; }
     2862
     2863        c_len = _utf8len[c];
     2864        // skip 5 & 6 byte codes
     2865        if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; }
     2866
     2867        // apply mask on first byte
     2868        c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
     2869        // join the rest
     2870        while (c_len > 1 && i < len) {
     2871            c = (c << 6) | (buf[i++] & 0x3f);
     2872            c_len--;
     2873        }
     2874
     2875        // terminated by end of string?
     2876        if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
     2877
     2878        if (c < 0x10000) {
     2879            utf16buf[out++] = c;
     2880        } else {
     2881            c -= 0x10000;
     2882            utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
     2883            utf16buf[out++] = 0xdc00 | (c & 0x3ff);
     2884        }
     2885    }
     2886
     2887    // shrinkBuf(utf16buf, out)
     2888    if (utf16buf.length !== out) {
     2889        if(utf16buf.subarray) {
     2890            utf16buf = utf16buf.subarray(0, out);
     2891        } else {
     2892            utf16buf.length = out;
     2893        }
     2894    }
     2895
     2896    // return String.fromCharCode.apply(null, utf16buf);
     2897    return utils.applyFromCharCode(utf16buf);
     2898};
     2899
     2900
     2901// That's all for the pako functions.
     2902
     2903
     2904/**
     2905 * Transform a javascript string into an array (typed if possible) of bytes,
     2906 * UTF-8 encoded.
     2907 * @param {String} str the string to encode
     2908 * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string.
     2909 */
     2910exports.utf8encode = function utf8encode(str) {
     2911    if (support.nodebuffer) {
     2912        return nodejsUtils.newBuffer(str, "utf-8");
     2913    }
     2914
     2915    return string2buf(str);
     2916};
     2917
     2918
     2919/**
     2920 * Transform a bytes array (or a representation) representing an UTF-8 encoded
     2921 * string into a javascript string.
     2922 * @param {Array|Uint8Array|Buffer} buf the data de decode
     2923 * @return {String} the decoded string.
     2924 */
     2925exports.utf8decode = function utf8decode(buf) {
     2926    if (support.nodebuffer) {
     2927        return utils.transformTo("nodebuffer", buf).toString("utf-8");
     2928    }
     2929
     2930    buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf);
     2931
     2932    return buf2string(buf);
     2933};
     2934
     2935/**
     2936 * A worker to decode utf8 encoded binary chunks into string chunks.
     2937 * @constructor
     2938 */
     2939function Utf8DecodeWorker() {
     2940    GenericWorker.call(this, "utf-8 decode");
     2941    // the last bytes if a chunk didn't end with a complete codepoint.
     2942    this.leftOver = null;
     2943}
     2944utils.inherits(Utf8DecodeWorker, GenericWorker);
     2945
     2946/**
     2947 * @see GenericWorker.processChunk
     2948 */
     2949Utf8DecodeWorker.prototype.processChunk = function (chunk) {
     2950
     2951    var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data);
     2952
     2953    // 1st step, re-use what's left of the previous chunk
     2954    if (this.leftOver && this.leftOver.length) {
     2955        if(support.uint8array) {
     2956            var previousData = data;
     2957            data = new Uint8Array(previousData.length + this.leftOver.length);
     2958            data.set(this.leftOver, 0);
     2959            data.set(previousData, this.leftOver.length);
     2960        } else {
     2961            data = this.leftOver.concat(data);
     2962        }
     2963        this.leftOver = null;
     2964    }
     2965
     2966    var nextBoundary = utf8border(data);
     2967    var usableData = data;
     2968    if (nextBoundary !== data.length) {
     2969        if (support.uint8array) {
     2970            usableData = data.subarray(0, nextBoundary);
     2971            this.leftOver = data.subarray(nextBoundary, data.length);
     2972        } else {
     2973            usableData = data.slice(0, nextBoundary);
     2974            this.leftOver = data.slice(nextBoundary, data.length);
     2975        }
     2976    }
     2977
     2978    this.push({
     2979        data : exports.utf8decode(usableData),
     2980        meta : chunk.meta
     2981    });
     2982};
     2983
     2984/**
     2985 * @see GenericWorker.flush
     2986 */
     2987Utf8DecodeWorker.prototype.flush = function () {
     2988    if(this.leftOver && this.leftOver.length) {
     2989        this.push({
     2990            data : exports.utf8decode(this.leftOver),
     2991            meta : {}
     2992        });
     2993        this.leftOver = null;
     2994    }
     2995};
     2996exports.Utf8DecodeWorker = Utf8DecodeWorker;
     2997
     2998/**
     2999 * A worker to endcode string chunks into utf8 encoded binary chunks.
     3000 * @constructor
     3001 */
     3002function Utf8EncodeWorker() {
     3003    GenericWorker.call(this, "utf-8 encode");
     3004}
     3005utils.inherits(Utf8EncodeWorker, GenericWorker);
     3006
     3007/**
     3008 * @see GenericWorker.processChunk
     3009 */
     3010Utf8EncodeWorker.prototype.processChunk = function (chunk) {
     3011    this.push({
     3012        data : exports.utf8encode(chunk.data),
     3013        meta : chunk.meta
     3014    });
     3015};
     3016exports.Utf8EncodeWorker = Utf8EncodeWorker;
     3017
     3018},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(require,module,exports){
     3019'use strict';
     3020
     3021var support = require('./support');
     3022var base64 = require('./base64');
     3023var nodejsUtils = require('./nodejsUtils');
     3024var setImmediate = require('core-js/library/fn/set-immediate');
     3025var external = require("./external");
     3026
     3027
     3028/**
     3029 * Convert a string that pass as a "binary string": it should represent a byte
     3030 * array but may have > 255 char codes. Be sure to take only the first byte
     3031 * and returns the byte array.
     3032 * @param {String} str the string to transform.
     3033 * @return {Array|Uint8Array} the string in a binary format.
     3034 */
     3035function string2binary(str) {
     3036    var result = null;
     3037    if (support.uint8array) {
     3038      result = new Uint8Array(str.length);
     3039    } else {
     3040      result = new Array(str.length);
     3041    }
     3042    return stringToArrayLike(str, result);
     3043}
     3044
     3045/**
     3046 * Create a new blob with the given content and the given type.
     3047 * @param {Array[String|ArrayBuffer]} parts the content to put in the blob. DO NOT use
     3048 * an Uint8Array because the stock browser of android 4 won't accept it (it
     3049 * will be silently converted to a string, "[object Uint8Array]").
     3050 * @param {String} type the mime type of the blob.
     3051 * @return {Blob} the created blob.
     3052 */
     3053exports.newBlob = function(parts, type) {
     3054    exports.checkSupport("blob");
     3055
     3056    try {
     3057        // Blob constructor
     3058        return new Blob(parts, {
     3059            type: type
     3060        });
     3061    }
     3062    catch (e) {
     3063
     3064        try {
     3065            // deprecated, browser only, old way
     3066            var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
     3067            var builder = new Builder();
     3068            for (var i = 0; i < parts.length; i++) {
     3069                builder.append(parts[i]);
     3070            }
     3071            return builder.getBlob(type);
     3072        }
     3073        catch (e) {
     3074
     3075            // well, fuck ?!
     3076            throw new Error("Bug : can't construct the Blob.");
     3077        }
     3078    }
     3079
     3080
     3081};
     3082/**
     3083 * The identity function.
     3084 * @param {Object} input the input.
     3085 * @return {Object} the same input.
     3086 */
     3087function identity(input) {
     3088    return input;
     3089}
     3090
     3091/**
     3092 * Fill in an array with a string.
     3093 * @param {String} str the string to use.
     3094 * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated).
     3095 * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array.
     3096 */
     3097function stringToArrayLike(str, array) {
     3098    for (var i = 0; i < str.length; ++i) {
     3099        array[i] = str.charCodeAt(i) & 0xFF;
     3100    }
     3101    return array;
     3102}
     3103
     3104/**
     3105 * An helper for the function arrayLikeToString.
     3106 * This contains static informations and functions that
     3107 * can be optimized by the browser JIT compiler.
     3108 */
     3109var arrayToStringHelper = {
     3110    /**
     3111     * Transform an array of int into a string, chunk by chunk.
     3112     * See the performances notes on arrayLikeToString.
     3113     * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
     3114     * @param {String} type the type of the array.
     3115     * @param {Integer} chunk the chunk size.
     3116     * @return {String} the resulting string.
     3117     * @throws Error if the chunk is too big for the stack.
     3118     */
     3119    stringifyByChunk: function(array, type, chunk) {
     3120        var result = [], k = 0, len = array.length;
     3121        // shortcut
     3122        if (len <= chunk) {
     3123            return String.fromCharCode.apply(null, array);
     3124        }
     3125        while (k < len) {
     3126            if (type === "array" || type === "nodebuffer") {
     3127                result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len))));
     3128            }
     3129            else {
     3130                result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len))));
     3131            }
     3132            k += chunk;
     3133        }
     3134        return result.join("");
     3135    },
     3136    /**
     3137     * Call String.fromCharCode on every item in the array.
     3138     * This is the naive implementation, which generate A LOT of intermediate string.
     3139     * This should be used when everything else fail.
     3140     * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
     3141     * @return {String} the result.
     3142     */
     3143    stringifyByChar: function(array){
     3144        var resultStr = "";
     3145        for(var i = 0; i < array.length; i++) {
     3146            resultStr += String.fromCharCode(array[i]);
     3147        }
     3148        return resultStr;
     3149    },
     3150    applyCanBeUsed : {
     3151        /**
     3152         * true if the browser accepts to use String.fromCharCode on Uint8Array
     3153         */
     3154        uint8array : (function () {
     3155            try {
     3156                return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1;
     3157            } catch (e) {
     3158                return false;
     3159            }
     3160        })(),
     3161        /**
     3162         * true if the browser accepts to use String.fromCharCode on nodejs Buffer.
     3163         */
     3164        nodebuffer : (function () {
     3165            try {
     3166                return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.newBuffer(1)).length === 1;
     3167            } catch (e) {
     3168                return false;
     3169            }
     3170        })()
     3171    }
     3172};
     3173
     3174/**
     3175 * Transform an array-like object to a string.
     3176 * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
     3177 * @return {String} the result.
     3178 */
     3179function arrayLikeToString(array) {
     3180    // Performances notes :
     3181    // --------------------
     3182    // String.fromCharCode.apply(null, array) is the fastest, see
     3183    // see http://jsperf.com/converting-a-uint8array-to-a-string/2
     3184    // but the stack is limited (and we can get huge arrays !).
     3185    //
     3186    // result += String.fromCharCode(array[i]); generate too many strings !
     3187    //
     3188    // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2
     3189    // TODO : we now have workers that split the work. Do we still need that ?
     3190    var chunk = 65536,
     3191        type = exports.getTypeOf(array),
     3192        canUseApply = true;
     3193    if (type === "uint8array") {
     3194        canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array;
     3195    } else if (type === "nodebuffer") {
     3196        canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer;
     3197    }
     3198
     3199    if (canUseApply) {
     3200        while (chunk > 1) {
     3201            try {
     3202                return arrayToStringHelper.stringifyByChunk(array, type, chunk);
     3203            } catch (e) {
     3204                chunk = Math.floor(chunk / 2);
     3205            }
     3206        }
     3207    }
     3208
     3209    // no apply or chunk error : slow and painful algorithm
     3210    // default browser on android 4.*
     3211    return arrayToStringHelper.stringifyByChar(array);
     3212}
     3213
     3214exports.applyFromCharCode = arrayLikeToString;
     3215
     3216
     3217/**
     3218 * Copy the data from an array-like to an other array-like.
     3219 * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array.
     3220 * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated.
     3221 * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array.
     3222 */
     3223function arrayLikeToArrayLike(arrayFrom, arrayTo) {
     3224    for (var i = 0; i < arrayFrom.length; i++) {
     3225        arrayTo[i] = arrayFrom[i];
     3226    }
     3227    return arrayTo;
     3228}
     3229
     3230// a matrix containing functions to transform everything into everything.
     3231var transform = {};
     3232
     3233// string to ?
     3234transform["string"] = {
     3235    "string": identity,
     3236    "array": function(input) {
     3237        return stringToArrayLike(input, new Array(input.length));
     3238    },
     3239    "arraybuffer": function(input) {
     3240        return transform["string"]["uint8array"](input).buffer;
     3241    },
     3242    "uint8array": function(input) {
     3243        return stringToArrayLike(input, new Uint8Array(input.length));
     3244    },
     3245    "nodebuffer": function(input) {
     3246        return stringToArrayLike(input, nodejsUtils.newBuffer(input.length));
     3247    }
     3248};
     3249
     3250// array to ?
     3251transform["array"] = {
     3252    "string": arrayLikeToString,
     3253    "array": identity,
     3254    "arraybuffer": function(input) {
     3255        return (new Uint8Array(input)).buffer;
     3256    },
     3257    "uint8array": function(input) {
     3258        return new Uint8Array(input);
     3259    },
     3260    "nodebuffer": function(input) {
     3261        return nodejsUtils.newBuffer(input);
     3262    }
     3263};
     3264
     3265// arraybuffer to ?
     3266transform["arraybuffer"] = {
     3267    "string": function(input) {
     3268        return arrayLikeToString(new Uint8Array(input));
     3269    },
     3270    "array": function(input) {
     3271        return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));
     3272    },
     3273    "arraybuffer": identity,
     3274    "uint8array": function(input) {
     3275        return new Uint8Array(input);
     3276    },
     3277    "nodebuffer": function(input) {
     3278        return nodejsUtils.newBuffer(new Uint8Array(input));
     3279    }
     3280};
     3281
     3282// uint8array to ?
     3283transform["uint8array"] = {
     3284    "string": arrayLikeToString,
     3285    "array": function(input) {
     3286        return arrayLikeToArrayLike(input, new Array(input.length));
     3287    },
     3288    "arraybuffer": function(input) {
     3289        // copy the uint8array: DO NOT propagate the original ArrayBuffer, it
     3290        // can be way larger (the whole zip file for example).
     3291        var copy = new Uint8Array(input.length);
     3292        if (input.length) {
     3293            copy.set(input, 0);
     3294        }
     3295        return copy.buffer;
     3296    },
     3297    "uint8array": identity,
     3298    "nodebuffer": function(input) {
     3299        return nodejsUtils.newBuffer(input);
     3300    }
     3301};
     3302
     3303// nodebuffer to ?
     3304transform["nodebuffer"] = {
     3305    "string": arrayLikeToString,
     3306    "array": function(input) {
     3307        return arrayLikeToArrayLike(input, new Array(input.length));
     3308    },
     3309    "arraybuffer": function(input) {
     3310        return transform["nodebuffer"]["uint8array"](input).buffer;
     3311    },
     3312    "uint8array": function(input) {
     3313        return arrayLikeToArrayLike(input, new Uint8Array(input.length));
     3314    },
     3315    "nodebuffer": identity
     3316};
     3317
     3318/**
     3319 * Transform an input into any type.
     3320 * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer.
     3321 * If no output type is specified, the unmodified input will be returned.
     3322 * @param {String} outputType the output type.
     3323 * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert.
     3324 * @throws {Error} an Error if the browser doesn't support the requested output type.
     3325 */
     3326exports.transformTo = function(outputType, input) {
     3327    if (!input) {
     3328        // undefined, null, etc
     3329        // an empty string won't harm.
     3330        input = "";
     3331    }
     3332    if (!outputType) {
     3333        return input;
     3334    }
     3335    exports.checkSupport(outputType);
     3336    var inputType = exports.getTypeOf(input);
     3337    var result = transform[inputType][outputType](input);
     3338    return result;
     3339};
     3340
     3341/**
     3342 * Return the type of the input.
     3343 * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
     3344 * @param {Object} input the input to identify.
     3345 * @return {String} the (lowercase) type of the input.
     3346 */
     3347exports.getTypeOf = function(input) {
     3348    if (typeof input === "string") {
     3349        return "string";
     3350    }
     3351    if (Object.prototype.toString.call(input) === "[object Array]") {
     3352        return "array";
     3353    }
     3354    if (support.nodebuffer && nodejsUtils.isBuffer(input)) {
     3355        return "nodebuffer";
     3356    }
     3357    if (support.uint8array && input instanceof Uint8Array) {
     3358        return "uint8array";
     3359    }
     3360    if (support.arraybuffer && input instanceof ArrayBuffer) {
     3361        return "arraybuffer";
     3362    }
     3363};
     3364
     3365/**
     3366 * Throw an exception if the type is not supported.
     3367 * @param {String} type the type to check.
     3368 * @throws {Error} an Error if the browser doesn't support the requested type.
     3369 */
     3370exports.checkSupport = function(type) {
     3371    var supported = support[type.toLowerCase()];
     3372    if (!supported) {
     3373        throw new Error(type + " is not supported by this platform");
     3374    }
     3375};
     3376
     3377exports.MAX_VALUE_16BITS = 65535;
     3378exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1
     3379
     3380/**
     3381 * Prettify a string read as binary.
     3382 * @param {string} str the string to prettify.
     3383 * @return {string} a pretty string.
     3384 */
     3385exports.pretty = function(str) {
     3386    var res = '',
     3387        code, i;
     3388    for (i = 0; i < (str || "").length; i++) {
     3389        code = str.charCodeAt(i);
     3390        res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
     3391    }
     3392    return res;
     3393};
     3394
     3395/**
     3396 * Defer the call of a function.
     3397 * @param {Function} callback the function to call asynchronously.
     3398 * @param {Array} args the arguments to give to the callback.
     3399 */
     3400exports.delay = function(callback, args, self) {
     3401    setImmediate(function () {
     3402        callback.apply(self || null, args || []);
     3403    });
     3404};
     3405
     3406/**
     3407 * Extends a prototype with an other, without calling a constructor with
     3408 * side effects. Inspired by nodejs' `utils.inherits`
     3409 * @param {Function} ctor the constructor to augment
     3410 * @param {Function} superCtor the parent constructor to use
     3411 */
     3412exports.inherits = function (ctor, superCtor) {
     3413    var Obj = function() {};
     3414    Obj.prototype = superCtor.prototype;
     3415    ctor.prototype = new Obj();
     3416};
     3417
     3418/**
     3419 * Merge the objects passed as parameters into a new one.
     3420 * @private
     3421 * @param {...Object} var_args All objects to merge.
     3422 * @return {Object} a new object with the data of the others.
     3423 */
     3424exports.extend = function() {
     3425    var result = {}, i, attr;
     3426    for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
     3427        for (attr in arguments[i]) {
     3428            if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
     3429                result[attr] = arguments[i][attr];
     3430            }
     3431        }
     3432    }
     3433    return result;
     3434};
     3435
     3436/**
     3437 * Transform arbitrary content into a Promise.
     3438 * @param {String} name a name for the content being processed.
     3439 * @param {Object} inputData the content to process.
     3440 * @param {Boolean} isBinary true if the content is not an unicode string
     3441 * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character.
     3442 * @param {Boolean} isBase64 true if the string content is encoded with base64.
     3443 * @return {Promise} a promise in a format usable by JSZip.
     3444 */
     3445exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) {
     3446
     3447    // if inputData is already a promise, this flatten it.
     3448    var promise = external.Promise.resolve(inputData).then(function(data) {
     3449       
     3450       
     3451        var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1);
     3452
     3453        if (isBlob && typeof FileReader !== "undefined") {
     3454            return new external.Promise(function (resolve, reject) {
     3455                var reader = new FileReader();
     3456
     3457                reader.onload = function(e) {
     3458                    resolve(e.target.result);
     3459                };
     3460                reader.onerror = function(e) {
     3461                    reject(e.target.error);
     3462                };
     3463                reader.readAsArrayBuffer(data);
     3464            });
     3465        } else {
     3466            return data;
     3467        }
     3468    });
     3469
     3470    return promise.then(function(data) {
     3471        var dataType = exports.getTypeOf(data);
     3472
     3473        if (!dataType) {
     3474            return external.Promise.reject(
     3475                new Error("The data of '" + name + "' is in an unsupported format !")
     3476            );
     3477        }
     3478        // special case : it's way easier to work with Uint8Array than with ArrayBuffer
     3479        if (dataType === "arraybuffer") {
     3480            data = exports.transformTo("uint8array", data);
     3481        } else if (dataType === "string") {
     3482            if (isBase64) {
     3483                data = base64.decode(data);
     3484            }
     3485            else if (isBinary) {
     3486                // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask
     3487                if (isOptimizedBinaryString !== true) {
     3488                    // this is a string, not in a base64 format.
     3489                    // Be sure that this is a correct "binary string"
     3490                    data = string2binary(data);
     3491                }
     3492            }
     3493        }
     3494        return data;
     3495    });
     3496};
     3497
     3498},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"core-js/library/fn/set-immediate":36}],33:[function(require,module,exports){
     3499'use strict';
     3500var readerFor = require('./reader/readerFor');
     3501var utils = require('./utils');
     3502var sig = require('./signature');
     3503var ZipEntry = require('./zipEntry');
     3504var utf8 = require('./utf8');
     3505var support = require('./support');
     3506//  class ZipEntries {{{
     3507/**
     3508 * All the entries in the zip file.
     3509 * @constructor
     3510 * @param {Object} loadOptions Options for loading the stream.
     3511 */
     3512function ZipEntries(loadOptions) {
     3513    this.files = [];
     3514    this.loadOptions = loadOptions;
     3515}
     3516ZipEntries.prototype = {
     3517    /**
     3518     * Check that the reader is on the speficied signature.
     3519     * @param {string} expectedSignature the expected signature.
     3520     * @throws {Error} if it is an other signature.
     3521     */
     3522    checkSignature: function(expectedSignature) {
     3523        if (!this.reader.readAndCheckSignature(expectedSignature)) {
     3524            this.reader.index -= 4;
     3525            var signature = this.reader.readString(4);
     3526            throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");
     3527        }
     3528    },
     3529    /**
     3530     * Check if the given signature is at the given index.
     3531     * @param {number} askedIndex the index to check.
     3532     * @param {string} expectedSignature the signature to expect.
     3533     * @return {boolean} true if the signature is here, false otherwise.
     3534     */
     3535    isSignature: function(askedIndex, expectedSignature) {
     3536        var currentIndex = this.reader.index;
     3537        this.reader.setIndex(askedIndex);
     3538        var signature = this.reader.readString(4);
     3539        var result = signature === expectedSignature;
     3540        this.reader.setIndex(currentIndex);
     3541        return result;
     3542    },
     3543    /**
     3544     * Read the end of the central directory.
     3545     */
     3546    readBlockEndOfCentral: function() {
     3547        this.diskNumber = this.reader.readInt(2);
     3548        this.diskWithCentralDirStart = this.reader.readInt(2);
     3549        this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
     3550        this.centralDirRecords = this.reader.readInt(2);
     3551        this.centralDirSize = this.reader.readInt(4);
     3552        this.centralDirOffset = this.reader.readInt(4);
     3553
     3554        this.zipCommentLength = this.reader.readInt(2);
     3555        // warning : the encoding depends of the system locale
     3556        // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.
     3557        // On a windows machine, this field is encoded with the localized windows code page.
     3558        var zipComment = this.reader.readData(this.zipCommentLength);
     3559        var decodeParamType = support.uint8array ? "uint8array" : "array";
     3560        // To get consistent behavior with the generation part, we will assume that
     3561        // this is utf8 encoded unless specified otherwise.
     3562        var decodeContent = utils.transformTo(decodeParamType, zipComment);
     3563        this.zipComment = this.loadOptions.decodeFileName(decodeContent);
     3564    },
     3565    /**
     3566     * Read the end of the Zip 64 central directory.
     3567     * Not merged with the method readEndOfCentral :
     3568     * The end of central can coexist with its Zip64 brother,
     3569     * I don't want to read the wrong number of bytes !
     3570     */
     3571    readBlockZip64EndOfCentral: function() {
     3572        this.zip64EndOfCentralSize = this.reader.readInt(8);
     3573        this.reader.skip(4);
     3574        // this.versionMadeBy = this.reader.readString(2);
     3575        // this.versionNeeded = this.reader.readInt(2);
     3576        this.diskNumber = this.reader.readInt(4);
     3577        this.diskWithCentralDirStart = this.reader.readInt(4);
     3578        this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
     3579        this.centralDirRecords = this.reader.readInt(8);
     3580        this.centralDirSize = this.reader.readInt(8);
     3581        this.centralDirOffset = this.reader.readInt(8);
     3582
     3583        this.zip64ExtensibleData = {};
     3584        var extraDataSize = this.zip64EndOfCentralSize - 44,
     3585            index = 0,
     3586            extraFieldId,
     3587            extraFieldLength,
     3588            extraFieldValue;
     3589        while (index < extraDataSize) {
     3590            extraFieldId = this.reader.readInt(2);
     3591            extraFieldLength = this.reader.readInt(4);
     3592            extraFieldValue = this.reader.readData(extraFieldLength);
     3593            this.zip64ExtensibleData[extraFieldId] = {
     3594                id: extraFieldId,
     3595                length: extraFieldLength,
     3596                value: extraFieldValue
     3597            };
     3598        }
     3599    },
     3600    /**
     3601     * Read the end of the Zip 64 central directory locator.
     3602     */
     3603    readBlockZip64EndOfCentralLocator: function() {
     3604        this.diskWithZip64CentralDirStart = this.reader.readInt(4);
     3605        this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
     3606        this.disksCount = this.reader.readInt(4);
     3607        if (this.disksCount > 1) {
     3608            throw new Error("Multi-volumes zip are not supported");
     3609        }
     3610    },
     3611    /**
     3612     * Read the local files, based on the offset read in the central part.
     3613     */
     3614    readLocalFiles: function() {
     3615        var i, file;
     3616        for (i = 0; i < this.files.length; i++) {
     3617            file = this.files[i];
     3618            this.reader.setIndex(file.localHeaderOffset);
     3619            this.checkSignature(sig.LOCAL_FILE_HEADER);
     3620            file.readLocalPart(this.reader);
     3621            file.handleUTF8();
     3622            file.processAttributes();
     3623        }
     3624    },
     3625    /**
     3626     * Read the central directory.
     3627     */
     3628    readCentralDir: function() {
     3629        var file;
     3630
     3631        this.reader.setIndex(this.centralDirOffset);
     3632        while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) {
     3633            file = new ZipEntry({
     3634                zip64: this.zip64
     3635            }, this.loadOptions);
     3636            file.readCentralPart(this.reader);
     3637            this.files.push(file);
     3638        }
     3639
     3640        if (this.centralDirRecords !== this.files.length) {
     3641            if (this.centralDirRecords !== 0 && this.files.length === 0) {
     3642                // We expected some records but couldn't find ANY.
     3643                // This is really suspicious, as if something went wrong.
     3644                throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
     3645            } else {
     3646                // We found some records but not all.
     3647                // Something is wrong but we got something for the user: no error here.
     3648                // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length);
     3649            }
     3650        }
     3651    },
     3652    /**
     3653     * Read the end of central directory.
     3654     */
     3655    readEndOfCentral: function() {
     3656        var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);
     3657        if (offset < 0) {
     3658            // Check if the content is a truncated zip or complete garbage.
     3659            // A "LOCAL_FILE_HEADER" is not required at the beginning (auto
     3660            // extractible zip for example) but it can give a good hint.
     3661            // If an ajax request was used without responseType, we will also
     3662            // get unreadable data.
     3663            var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER);
     3664
     3665            if (isGarbage) {
     3666                throw new Error("Can't find end of central directory : is this a zip file ? " +
     3667                                "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");
     3668            } else {
     3669                throw new Error("Corrupted zip: can't find end of central directory");
     3670            }
     3671
     3672        }
     3673        this.reader.setIndex(offset);
     3674        var endOfCentralDirOffset = offset;
     3675        this.checkSignature(sig.CENTRAL_DIRECTORY_END);
     3676        this.readBlockEndOfCentral();
     3677
     3678
     3679        /* extract from the zip spec :
     3680            4)  If one of the fields in the end of central directory
     3681                record is too small to hold required data, the field
     3682                should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
     3683                ZIP64 format record should be created.
     3684            5)  The end of central directory record and the
     3685                Zip64 end of central directory locator record must
     3686                reside on the same disk when splitting or spanning
     3687                an archive.
     3688         */
     3689        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) {
     3690            this.zip64 = true;
     3691
     3692            /*
     3693            Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
     3694            the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents
     3695            all numbers as 64-bit double precision IEEE 754 floating point numbers.
     3696            So, we have 53bits for integers and bitwise operations treat everything as 32bits.
     3697            see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
     3698            and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
     3699            */
     3700
     3701            // should look for a zip64 EOCD locator
     3702            offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
     3703            if (offset < 0) {
     3704                throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");
     3705            }
     3706            this.reader.setIndex(offset);
     3707            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
     3708            this.readBlockZip64EndOfCentralLocator();
     3709
     3710            // now the zip64 EOCD record
     3711            if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) {
     3712                // console.warn("ZIP64 end of central directory not where expected.");
     3713                this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
     3714                if (this.relativeOffsetEndOfZip64CentralDir < 0) {
     3715                    throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");
     3716                }
     3717            }
     3718            this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
     3719            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
     3720            this.readBlockZip64EndOfCentral();
     3721        }
     3722
     3723        var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize;
     3724        if (this.zip64) {
     3725            expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator
     3726            expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize;
     3727        }
     3728
     3729        var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset;
     3730
     3731        if (extraBytes > 0) {
     3732            // console.warn(extraBytes, "extra bytes at beginning or within zipfile");
     3733            if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) {
     3734                // The offsets seem wrong, but we have something at the specified offset.
     3735                // So… we keep it.
     3736            } else {
     3737                // the offset is wrong, update the "zero" of the reader
     3738                // this happens if data has been prepended (crx files for example)
     3739                this.reader.zero = extraBytes;
     3740            }
     3741        } else if (extraBytes < 0) {
     3742            throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.");
     3743        }
     3744    },
     3745    prepareReader: function(data) {
     3746        this.reader = readerFor(data);
     3747    },
     3748    /**
     3749     * Read a zip file and create ZipEntries.
     3750     * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
     3751     */
     3752    load: function(data) {
     3753        this.prepareReader(data);
     3754        this.readEndOfCentral();
     3755        this.readCentralDir();
     3756        this.readLocalFiles();
     3757    }
     3758};
     3759// }}} end of ZipEntries
     3760module.exports = ZipEntries;
     3761
     3762},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(require,module,exports){
     3763'use strict';
     3764var readerFor = require('./reader/readerFor');
     3765var utils = require('./utils');
     3766var CompressedObject = require('./compressedObject');
     3767var crc32fn = require('./crc32');
     3768var utf8 = require('./utf8');
     3769var compressions = require('./compressions');
     3770var support = require('./support');
     3771
     3772var MADE_BY_DOS = 0x00;
     3773var MADE_BY_UNIX = 0x03;
     3774
     3775/**
     3776 * Find a compression registered in JSZip.
     3777 * @param {string} compressionMethod the method magic to find.
     3778 * @return {Object|null} the JSZip compression object, null if none found.
     3779 */
     3780var findCompression = function(compressionMethod) {
     3781    for (var method in compressions) {
     3782        if (!compressions.hasOwnProperty(method)) {
     3783            continue;
     3784        }
     3785        if (compressions[method].magic === compressionMethod) {
     3786            return compressions[method];
     3787        }
     3788    }
     3789    return null;
     3790};
     3791
     3792// class ZipEntry {{{
     3793/**
     3794 * An entry in the zip file.
     3795 * @constructor
     3796 * @param {Object} options Options of the current file.
     3797 * @param {Object} loadOptions Options for loading the stream.
     3798 */
     3799function ZipEntry(options, loadOptions) {
     3800    this.options = options;
     3801    this.loadOptions = loadOptions;
     3802}
     3803ZipEntry.prototype = {
     3804    /**
     3805     * say if the file is encrypted.
     3806     * @return {boolean} true if the file is encrypted, false otherwise.
     3807     */
     3808    isEncrypted: function() {
     3809        // bit 1 is set
     3810        return (this.bitFlag & 0x0001) === 0x0001;
     3811    },
     3812    /**
     3813     * say if the file has utf-8 filename/comment.
     3814     * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
     3815     */
     3816    useUTF8: function() {
     3817        // bit 11 is set
     3818        return (this.bitFlag & 0x0800) === 0x0800;
     3819    },
     3820    /**
     3821     * Read the local part of a zip file and add the info in this object.
     3822     * @param {DataReader} reader the reader to use.
     3823     */
     3824    readLocalPart: function(reader) {
     3825        var compression, localExtraFieldsLength;
     3826
     3827        // we already know everything from the central dir !
     3828        // If the central dir data are false, we are doomed.
     3829        // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.
     3830        // The less data we get here, the more reliable this should be.
     3831        // Let's skip the whole header and dash to the data !
     3832        reader.skip(22);
     3833        // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
     3834        // Strangely, the filename here is OK.
     3835        // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
     3836        // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
     3837        // Search "unzip mismatching "local" filename continuing with "central" filename version" on
     3838        // the internet.
     3839        //
     3840        // I think I see the logic here : the central directory is used to display
     3841        // content and the local directory is used to extract the files. Mixing / and \
     3842        // may be used to display \ to windows users and use / when extracting the files.
     3843        // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
     3844        this.fileNameLength = reader.readInt(2);
     3845        localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
     3846        // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding.
     3847        this.fileName = reader.readData(this.fileNameLength);
     3848        reader.skip(localExtraFieldsLength);
     3849
     3850        if (this.compressedSize === -1 || this.uncompressedSize === -1) {
     3851            throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)");
     3852        }
     3853
     3854        compression = findCompression(this.compressionMethod);
     3855        if (compression === null) { // no compression found
     3856            throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");
     3857        }
     3858        this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize));
     3859    },
     3860
     3861    /**
     3862     * Read the central part of a zip file and add the info in this object.
     3863     * @param {DataReader} reader the reader to use.
     3864     */
     3865    readCentralPart: function(reader) {
     3866        this.versionMadeBy = reader.readInt(2);
     3867        reader.skip(2);
     3868        // this.versionNeeded = reader.readInt(2);
     3869        this.bitFlag = reader.readInt(2);
     3870        this.compressionMethod = reader.readString(2);
     3871        this.date = reader.readDate();
     3872        this.crc32 = reader.readInt(4);
     3873        this.compressedSize = reader.readInt(4);
     3874        this.uncompressedSize = reader.readInt(4);
     3875        var fileNameLength = reader.readInt(2);
     3876        this.extraFieldsLength = reader.readInt(2);
     3877        this.fileCommentLength = reader.readInt(2);
     3878        this.diskNumberStart = reader.readInt(2);
     3879        this.internalFileAttributes = reader.readInt(2);
     3880        this.externalFileAttributes = reader.readInt(4);
     3881        this.localHeaderOffset = reader.readInt(4);
     3882
     3883        if (this.isEncrypted()) {
     3884            throw new Error("Encrypted zip are not supported");
     3885        }
     3886
     3887        // will be read in the local part, see the comments there
     3888        reader.skip(fileNameLength);
     3889        this.readExtraFields(reader);
     3890        this.parseZIP64ExtraField(reader);
     3891        this.fileComment = reader.readData(this.fileCommentLength);
     3892    },
     3893
     3894    /**
     3895     * Parse the external file attributes and get the unix/dos permissions.
     3896     */
     3897    processAttributes: function () {
     3898        this.unixPermissions = null;
     3899        this.dosPermissions = null;
     3900        var madeBy = this.versionMadeBy >> 8;
     3901
     3902        // Check if we have the DOS directory flag set.
     3903        // We look for it in the DOS and UNIX permissions
     3904        // but some unknown platform could set it as a compatibility flag.
     3905        this.dir = this.externalFileAttributes & 0x0010 ? true : false;
     3906
     3907        if(madeBy === MADE_BY_DOS) {
     3908            // first 6 bits (0 to 5)
     3909            this.dosPermissions = this.externalFileAttributes & 0x3F;
     3910        }
     3911
     3912        if(madeBy === MADE_BY_UNIX) {
     3913            this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF;
     3914            // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);
     3915        }
     3916
     3917        // fail safe : if the name ends with a / it probably means a folder
     3918        if (!this.dir && this.fileNameStr.slice(-1) === '/') {
     3919            this.dir = true;
     3920        }
     3921    },
     3922
     3923    /**
     3924     * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
     3925     * @param {DataReader} reader the reader to use.
     3926     */
     3927    parseZIP64ExtraField: function(reader) {
     3928
     3929        if (!this.extraFields[0x0001]) {
     3930            return;
     3931        }
     3932
     3933        // should be something, preparing the extra reader
     3934        var extraReader = readerFor(this.extraFields[0x0001].value);
     3935
     3936        // I really hope that these 64bits integer can fit in 32 bits integer, because js
     3937        // won't let us have more.
     3938        if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
     3939            this.uncompressedSize = extraReader.readInt(8);
     3940        }
     3941        if (this.compressedSize === utils.MAX_VALUE_32BITS) {
     3942            this.compressedSize = extraReader.readInt(8);
     3943        }
     3944        if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
     3945            this.localHeaderOffset = extraReader.readInt(8);
     3946        }
     3947        if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
     3948            this.diskNumberStart = extraReader.readInt(4);
     3949        }
     3950    },
     3951    /**
     3952     * Read the central part of a zip file and add the info in this object.
     3953     * @param {DataReader} reader the reader to use.
     3954     */
     3955    readExtraFields: function(reader) {
     3956        var end = reader.index + this.extraFieldsLength,
     3957            extraFieldId,
     3958            extraFieldLength,
     3959            extraFieldValue;
     3960
     3961        if (!this.extraFields) {
     3962            this.extraFields = {};
     3963        }
     3964
     3965        while (reader.index < end) {
     3966            extraFieldId = reader.readInt(2);
     3967            extraFieldLength = reader.readInt(2);
     3968            extraFieldValue = reader.readData(extraFieldLength);
     3969
     3970            this.extraFields[extraFieldId] = {
     3971                id: extraFieldId,
     3972                length: extraFieldLength,
     3973                value: extraFieldValue
     3974            };
     3975        }
     3976    },
     3977    /**
     3978     * Apply an UTF8 transformation if needed.
     3979     */
     3980    handleUTF8: function() {
     3981        var decodeParamType = support.uint8array ? "uint8array" : "array";
     3982        if (this.useUTF8()) {
     3983            this.fileNameStr = utf8.utf8decode(this.fileName);
     3984            this.fileCommentStr = utf8.utf8decode(this.fileComment);
     3985        } else {
     3986            var upath = this.findExtraFieldUnicodePath();
     3987            if (upath !== null) {
     3988                this.fileNameStr = upath;
     3989            } else {
     3990                // ASCII text or unsupported code page
     3991                var fileNameByteArray =  utils.transformTo(decodeParamType, this.fileName);
     3992                this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);
     3993            }
     3994
     3995            var ucomment = this.findExtraFieldUnicodeComment();
     3996            if (ucomment !== null) {
     3997                this.fileCommentStr = ucomment;
     3998            } else {
     3999                // ASCII text or unsupported code page
     4000                var commentByteArray =  utils.transformTo(decodeParamType, this.fileComment);
     4001                this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);
     4002            }
     4003        }
     4004    },
     4005
     4006    /**
     4007     * Find the unicode path declared in the extra field, if any.
     4008     * @return {String} the unicode path, null otherwise.
     4009     */
     4010    findExtraFieldUnicodePath: function() {
     4011        var upathField = this.extraFields[0x7075];
     4012        if (upathField) {
     4013            var extraReader = readerFor(upathField.value);
     4014
     4015            // wrong version
     4016            if (extraReader.readInt(1) !== 1) {
     4017                return null;
     4018            }
     4019
     4020            // the crc of the filename changed, this field is out of date.
     4021            if (crc32fn(this.fileName) !== extraReader.readInt(4)) {
     4022                return null;
     4023            }
     4024
     4025            return utf8.utf8decode(extraReader.readData(upathField.length - 5));
     4026        }
     4027        return null;
     4028    },
     4029
     4030    /**
     4031     * Find the unicode comment declared in the extra field, if any.
     4032     * @return {String} the unicode comment, null otherwise.
     4033     */
     4034    findExtraFieldUnicodeComment: function() {
     4035        var ucommentField = this.extraFields[0x6375];
     4036        if (ucommentField) {
     4037            var extraReader = readerFor(ucommentField.value);
     4038
     4039            // wrong version
     4040            if (extraReader.readInt(1) !== 1) {
     4041                return null;
     4042            }
     4043
     4044            // the crc of the comment changed, this field is out of date.
     4045            if (crc32fn(this.fileComment) !== extraReader.readInt(4)) {
     4046                return null;
     4047            }
     4048
     4049            return utf8.utf8decode(extraReader.readData(ucommentField.length - 5));
     4050        }
     4051        return null;
     4052    }
     4053};
     4054module.exports = ZipEntry;
     4055
     4056},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(require,module,exports){
     4057'use strict';
     4058
     4059var StreamHelper = require('./stream/StreamHelper');
     4060var DataWorker = require('./stream/DataWorker');
     4061var utf8 = require('./utf8');
     4062var CompressedObject = require('./compressedObject');
     4063var GenericWorker = require('./stream/GenericWorker');
     4064
     4065/**
     4066 * A simple object representing a file in the zip file.
     4067 * @constructor
     4068 * @param {string} name the name of the file
     4069 * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
     4070 * @param {Object} options the options of the file
     4071 */
     4072var ZipObject = function(name, data, options) {
     4073    this.name = name;
     4074    this.dir = options.dir;
     4075    this.date = options.date;
     4076    this.comment = options.comment;
     4077    this.unixPermissions = options.unixPermissions;
     4078    this.dosPermissions = options.dosPermissions;
     4079
     4080    this._data = data;
     4081    this._dataBinary = options.binary;
     4082    // keep only the compression
     4083    this.options = {
     4084        compression : options.compression,
     4085        compressionOptions : options.compressionOptions
     4086    };
     4087};
     4088
     4089ZipObject.prototype = {
     4090    /**
     4091     * Create an internal stream for the content of this object.
     4092     * @param {String} type the type of each chunk.
     4093     * @return StreamHelper the stream.
     4094     */
     4095    internalStream: function (type) {
     4096        var outputType = type.toLowerCase();
     4097        var askUnicodeString = outputType === "string" || outputType === "text";
     4098        if (outputType === "binarystring" || outputType === "text") {
     4099            outputType = "string";
     4100        }
     4101        var result = this._decompressWorker();
     4102
     4103        var isUnicodeString = !this._dataBinary;
     4104
     4105        if (isUnicodeString && !askUnicodeString) {
     4106            result = result.pipe(new utf8.Utf8EncodeWorker());
     4107        }
     4108        if (!isUnicodeString && askUnicodeString) {
     4109            result = result.pipe(new utf8.Utf8DecodeWorker());
     4110        }
     4111
     4112        return new StreamHelper(result, outputType, "");
     4113    },
     4114
     4115    /**
     4116     * Prepare the content in the asked type.
     4117     * @param {String} type the type of the result.
     4118     * @param {Function} onUpdate a function to call on each internal update.
     4119     * @return Promise the promise of the result.
     4120     */
     4121    async: function (type, onUpdate) {
     4122        return this.internalStream(type).accumulate(onUpdate);
     4123    },
     4124
     4125    /**
     4126     * Prepare the content as a nodejs stream.
     4127     * @param {String} type the type of each chunk.
     4128     * @param {Function} onUpdate a function to call on each internal update.
     4129     * @return Stream the stream.
     4130     */
     4131    nodeStream: function (type, onUpdate) {
     4132        return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate);
     4133    },
     4134
     4135    /**
     4136     * Return a worker for the compressed content.
     4137     * @private
     4138     * @param {Object} compression the compression object to use.
     4139     * @param {Object} compressionOptions the options to use when compressing.
     4140     * @return Worker the worker.
     4141     */
     4142    _compressWorker: function (compression, compressionOptions) {
     4143        if (
     4144            this._data instanceof CompressedObject &&
     4145            this._data.compression.magic === compression.magic
     4146        ) {
     4147            return this._data.getCompressedWorker();
     4148        } else {
     4149            var result = this._decompressWorker();
     4150            if(!this._dataBinary) {
     4151                result = result.pipe(new utf8.Utf8EncodeWorker());
     4152            }
     4153            return CompressedObject.createWorkerFrom(result, compression, compressionOptions);
     4154        }
     4155    },
     4156    /**
     4157     * Return a worker for the decompressed content.
     4158     * @private
     4159     * @return Worker the worker.
     4160     */
     4161    _decompressWorker : function () {
     4162        if (this._data instanceof CompressedObject) {
     4163            return this._data.getContentWorker();
     4164        } else if (this._data instanceof GenericWorker) {
     4165            return this._data;
     4166        } else {
     4167            return new DataWorker(this._data);
     4168        }
     4169    }
     4170};
     4171
     4172var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"];
     4173var removedFn = function () {
     4174    throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
     4175};
     4176
     4177for(var i = 0; i < removedMethods.length; i++) {
     4178    ZipObject.prototype[removedMethods[i]] = removedFn;
     4179}
     4180module.exports = ZipObject;
     4181
     4182},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(require,module,exports){
     4183require('../modules/web.immediate');
     4184module.exports = require('../modules/_core').setImmediate;
     4185},{"../modules/_core":40,"../modules/web.immediate":56}],37:[function(require,module,exports){
     4186module.exports = function(it){
     4187  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
     4188  return it;
     4189};
     4190},{}],38:[function(require,module,exports){
     4191var isObject = require('./_is-object');
     4192module.exports = function(it){
     4193  if(!isObject(it))throw TypeError(it + ' is not an object!');
     4194  return it;
     4195};
     4196},{"./_is-object":51}],39:[function(require,module,exports){
     4197var toString = {}.toString;
     4198
     4199module.exports = function(it){
     4200  return toString.call(it).slice(8, -1);
     4201};
     4202},{}],40:[function(require,module,exports){
     4203var core = module.exports = {version: '2.3.0'};
     4204if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
     4205},{}],41:[function(require,module,exports){
     4206// optional / simple context binding
     4207var aFunction = require('./_a-function');
     4208module.exports = function(fn, that, length){
     4209  aFunction(fn);
     4210  if(that === undefined)return fn;
     4211  switch(length){
     4212    case 1: return function(a){
     4213      return fn.call(that, a);
     4214    };
     4215    case 2: return function(a, b){
     4216      return fn.call(that, a, b);
     4217    };
     4218    case 3: return function(a, b, c){
     4219      return fn.call(that, a, b, c);
     4220    };
     4221  }
     4222  return function(/* ...args */){
     4223    return fn.apply(that, arguments);
     4224  };
     4225};
     4226},{"./_a-function":37}],42:[function(require,module,exports){
     4227// Thank's IE8 for his funny defineProperty
     4228module.exports = !require('./_fails')(function(){
     4229  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
     4230});
     4231},{"./_fails":45}],43:[function(require,module,exports){
     4232var isObject = require('./_is-object')
     4233  , document = require('./_global').document
     4234  // in old IE typeof document.createElement is 'object'
     4235  , is = isObject(document) && isObject(document.createElement);
     4236module.exports = function(it){
     4237  return is ? document.createElement(it) : {};
     4238};
     4239},{"./_global":46,"./_is-object":51}],44:[function(require,module,exports){
     4240var global    = require('./_global')
     4241  , core      = require('./_core')
     4242  , ctx       = require('./_ctx')
     4243  , hide      = require('./_hide')
     4244  , PROTOTYPE = 'prototype';
     4245
     4246var $export = function(type, name, source){
     4247  var IS_FORCED = type & $export.F
     4248    , IS_GLOBAL = type & $export.G
     4249    , IS_STATIC = type & $export.S
     4250    , IS_PROTO  = type & $export.P
     4251    , IS_BIND   = type & $export.B
     4252    , IS_WRAP   = type & $export.W
     4253    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
     4254    , expProto  = exports[PROTOTYPE]
     4255    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
     4256    , key, own, out;
     4257  if(IS_GLOBAL)source = name;
     4258  for(key in source){
     4259    // contains in native
     4260    own = !IS_FORCED && target && target[key] !== undefined;
     4261    if(own && key in exports)continue;
     4262    // export native or passed
     4263    out = own ? target[key] : source[key];
     4264    // prevent global pollution for namespaces
     4265    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
     4266    // bind timers to global for call from export context
     4267    : IS_BIND && own ? ctx(out, global)
     4268    // wrap global constructors for prevent change them in library
     4269    : IS_WRAP && target[key] == out ? (function(C){
     4270      var F = function(a, b, c){
     4271        if(this instanceof C){
     4272          switch(arguments.length){
     4273            case 0: return new C;
     4274            case 1: return new C(a);
     4275            case 2: return new C(a, b);
     4276          } return new C(a, b, c);
     4277        } return C.apply(this, arguments);
     4278      };
     4279      F[PROTOTYPE] = C[PROTOTYPE];
     4280      return F;
     4281    // make static versions for prototype methods
     4282    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
     4283    // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
     4284    if(IS_PROTO){
     4285      (exports.virtual || (exports.virtual = {}))[key] = out;
     4286      // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
     4287      if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);
     4288    }
     4289  }
     4290};
     4291// type bitmap
     4292$export.F = 1;   // forced
     4293$export.G = 2;   // global
     4294$export.S = 4;   // static
     4295$export.P = 8;   // proto
     4296$export.B = 16;  // bind
     4297$export.W = 32;  // wrap
     4298$export.U = 64;  // safe
     4299$export.R = 128; // real proto method for `library`
     4300module.exports = $export;
     4301},{"./_core":40,"./_ctx":41,"./_global":46,"./_hide":47}],45:[function(require,module,exports){
     4302module.exports = function(exec){
     4303  try {
     4304    return !!exec();
     4305  } catch(e){
     4306    return true;
     4307  }
     4308};
     4309},{}],46:[function(require,module,exports){
     4310// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
     4311var global = module.exports = typeof window != 'undefined' && window.Math == Math
     4312  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
     4313if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
     4314},{}],47:[function(require,module,exports){
     4315var dP         = require('./_object-dp')
     4316  , createDesc = require('./_property-desc');
     4317module.exports = require('./_descriptors') ? function(object, key, value){
     4318  return dP.f(object, key, createDesc(1, value));
     4319} : function(object, key, value){
     4320  object[key] = value;
     4321  return object;
     4322};
     4323},{"./_descriptors":42,"./_object-dp":52,"./_property-desc":53}],48:[function(require,module,exports){
     4324module.exports = require('./_global').document && document.documentElement;
     4325},{"./_global":46}],49:[function(require,module,exports){
     4326module.exports = !require('./_descriptors') && !require('./_fails')(function(){
     4327  return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;
     4328});
     4329},{"./_descriptors":42,"./_dom-create":43,"./_fails":45}],50:[function(require,module,exports){
     4330// fast apply, http://jsperf.lnkit.com/fast-apply/5
     4331module.exports = function(fn, args, that){
     4332  var un = that === undefined;
     4333  switch(args.length){
     4334    case 0: return un ? fn()
     4335                      : fn.call(that);
     4336    case 1: return un ? fn(args[0])
     4337                      : fn.call(that, args[0]);
     4338    case 2: return un ? fn(args[0], args[1])
     4339                      : fn.call(that, args[0], args[1]);
     4340    case 3: return un ? fn(args[0], args[1], args[2])
     4341                      : fn.call(that, args[0], args[1], args[2]);
     4342    case 4: return un ? fn(args[0], args[1], args[2], args[3])
     4343                      : fn.call(that, args[0], args[1], args[2], args[3]);
     4344  } return              fn.apply(that, args);
     4345};
     4346},{}],51:[function(require,module,exports){
     4347module.exports = function(it){
     4348  return typeof it === 'object' ? it !== null : typeof it === 'function';
     4349};
     4350},{}],52:[function(require,module,exports){
     4351var anObject       = require('./_an-object')
     4352  , IE8_DOM_DEFINE = require('./_ie8-dom-define')
     4353  , toPrimitive    = require('./_to-primitive')
     4354  , dP             = Object.defineProperty;
     4355
     4356exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){
     4357  anObject(O);
     4358  P = toPrimitive(P, true);
     4359  anObject(Attributes);
     4360  if(IE8_DOM_DEFINE)try {
     4361    return dP(O, P, Attributes);
     4362  } catch(e){ /* empty */ }
     4363  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
     4364  if('value' in Attributes)O[P] = Attributes.value;
     4365  return O;
     4366};
     4367},{"./_an-object":38,"./_descriptors":42,"./_ie8-dom-define":49,"./_to-primitive":55}],53:[function(require,module,exports){
     4368module.exports = function(bitmap, value){
     4369  return {
     4370    enumerable  : !(bitmap & 1),
     4371    configurable: !(bitmap & 2),
     4372    writable    : !(bitmap & 4),
     4373    value       : value
     4374  };
     4375};
     4376},{}],54:[function(require,module,exports){
     4377var ctx                = require('./_ctx')
     4378  , invoke             = require('./_invoke')
     4379  , html               = require('./_html')
     4380  , cel                = require('./_dom-create')
     4381  , global             = require('./_global')
     4382  , process            = global.process
     4383  , setTask            = global.setImmediate
     4384  , clearTask          = global.clearImmediate
     4385  , MessageChannel     = global.MessageChannel
     4386  , counter            = 0
     4387  , queue              = {}
     4388  , ONREADYSTATECHANGE = 'onreadystatechange'
     4389  , defer, channel, port;
     4390var run = function(){
     4391  var id = +this;
     4392  if(queue.hasOwnProperty(id)){
     4393    var fn = queue[id];
     4394    delete queue[id];
     4395    fn();
     4396  }
     4397};
     4398var listener = function(event){
     4399  run.call(event.data);
     4400};
     4401// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
     4402if(!setTask || !clearTask){
     4403  setTask = function setImmediate(fn){
     4404    var args = [], i = 1;
     4405    while(arguments.length > i)args.push(arguments[i++]);
     4406    queue[++counter] = function(){
     4407      invoke(typeof fn == 'function' ? fn : Function(fn), args);
     4408    };
     4409    defer(counter);
     4410    return counter;
     4411  };
     4412  clearTask = function clearImmediate(id){
     4413    delete queue[id];
     4414  };
     4415  // Node.js 0.8-
     4416  if(require('./_cof')(process) == 'process'){
     4417    defer = function(id){
     4418      process.nextTick(ctx(run, id, 1));
     4419    };
     4420  // Browsers with MessageChannel, includes WebWorkers
     4421  } else if(MessageChannel){
     4422    channel = new MessageChannel;
     4423    port    = channel.port2;
     4424    channel.port1.onmessage = listener;
     4425    defer = ctx(port.postMessage, port, 1);
     4426  // Browsers with postMessage, skip WebWorkers
     4427  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
     4428  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
     4429    defer = function(id){
     4430      global.postMessage(id + '', '*');
     4431    };
     4432    global.addEventListener('message', listener, false);
     4433  // IE8-
     4434  } else if(ONREADYSTATECHANGE in cel('script')){
     4435    defer = function(id){
     4436      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
     4437        html.removeChild(this);
     4438        run.call(id);
     4439      };
     4440    };
     4441  // Rest old browsers
     4442  } else {
     4443    defer = function(id){
     4444      setTimeout(ctx(run, id, 1), 0);
     4445    };
     4446  }
     4447}
     4448module.exports = {
     4449  set:   setTask,
     4450  clear: clearTask
     4451};
     4452},{"./_cof":39,"./_ctx":41,"./_dom-create":43,"./_global":46,"./_html":48,"./_invoke":50}],55:[function(require,module,exports){
     4453// 7.1.1 ToPrimitive(input [, PreferredType])
     4454var isObject = require('./_is-object');
     4455// instead of the ES6 spec version, we didn't implement @@toPrimitive case
     4456// and the second argument - flag - preferred type is a string
     4457module.exports = function(it, S){
     4458  if(!isObject(it))return it;
     4459  var fn, val;
     4460  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
     4461  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
     4462  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
     4463  throw TypeError("Can't convert object to primitive value");
     4464};
     4465},{"./_is-object":51}],56:[function(require,module,exports){
     4466var $export = require('./_export')
     4467  , $task   = require('./_task');
     4468$export($export.G + $export.B, {
     4469  setImmediate:   $task.set,
     4470  clearImmediate: $task.clear
     4471});
     4472},{"./_export":44,"./_task":54}],57:[function(require,module,exports){
     4473(function (global){
     4474'use strict';
     4475var Mutation = global.MutationObserver || global.WebKitMutationObserver;
     4476
     4477var scheduleDrain;
     4478
     4479{
     4480  if (Mutation) {
     4481    var called = 0;
     4482    var observer = new Mutation(nextTick);
     4483    var element = global.document.createTextNode('');
     4484    observer.observe(element, {
     4485      characterData: true
     4486    });
     4487    scheduleDrain = function () {
     4488      element.data = (called = ++called % 2);
     4489    };
     4490  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
     4491    var channel = new global.MessageChannel();
     4492    channel.port1.onmessage = nextTick;
     4493    scheduleDrain = function () {
     4494      channel.port2.postMessage(0);
     4495    };
     4496  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
     4497    scheduleDrain = function () {
     4498
     4499      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
     4500      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
     4501      var scriptEl = global.document.createElement('script');
     4502      scriptEl.onreadystatechange = function () {
     4503        nextTick();
     4504
     4505        scriptEl.onreadystatechange = null;
     4506        scriptEl.parentNode.removeChild(scriptEl);
     4507        scriptEl = null;
     4508      };
     4509      global.document.documentElement.appendChild(scriptEl);
     4510    };
     4511  } else {
     4512    scheduleDrain = function () {
     4513      setTimeout(nextTick, 0);
     4514    };
     4515  }
     4516}
     4517
     4518var draining;
     4519var queue = [];
     4520//named nextTick for less confusing stack traces
     4521function nextTick() {
     4522  draining = true;
     4523  var i, oldQueue;
     4524  var len = queue.length;
     4525  while (len) {
     4526    oldQueue = queue;
     4527    queue = [];
     4528    i = -1;
     4529    while (++i < len) {
     4530      oldQueue[i]();
     4531    }
     4532    len = queue.length;
     4533  }
     4534  draining = false;
     4535}
     4536
     4537module.exports = immediate;
     4538function immediate(task) {
     4539  if (queue.push(task) === 1 && !draining) {
     4540    scheduleDrain();
     4541  }
     4542}
     4543
     4544}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
     4545},{}],58:[function(require,module,exports){
     4546'use strict';
     4547var immediate = require('immediate');
     4548
     4549/* istanbul ignore next */
     4550function INTERNAL() {}
     4551
     4552var handlers = {};
     4553
     4554var REJECTED = ['REJECTED'];
     4555var FULFILLED = ['FULFILLED'];
     4556var PENDING = ['PENDING'];
     4557
     4558module.exports = Promise;
     4559
     4560function Promise(resolver) {
     4561  if (typeof resolver !== 'function') {
     4562    throw new TypeError('resolver must be a function');
     4563  }
     4564  this.state = PENDING;
     4565  this.queue = [];
     4566  this.outcome = void 0;
     4567  if (resolver !== INTERNAL) {
     4568    safelyResolveThenable(this, resolver);
     4569  }
     4570}
     4571
     4572Promise.prototype["catch"] = function (onRejected) {
     4573  return this.then(null, onRejected);
     4574};
     4575Promise.prototype.then = function (onFulfilled, onRejected) {
     4576  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
     4577    typeof onRejected !== 'function' && this.state === REJECTED) {
     4578    return this;
     4579  }
     4580  var promise = new this.constructor(INTERNAL);
     4581  if (this.state !== PENDING) {
     4582    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
     4583    unwrap(promise, resolver, this.outcome);
     4584  } else {
     4585    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
     4586  }
     4587
     4588  return promise;
     4589};
     4590function QueueItem(promise, onFulfilled, onRejected) {
     4591  this.promise = promise;
     4592  if (typeof onFulfilled === 'function') {
     4593    this.onFulfilled = onFulfilled;
     4594    this.callFulfilled = this.otherCallFulfilled;
     4595  }
     4596  if (typeof onRejected === 'function') {
     4597    this.onRejected = onRejected;
     4598    this.callRejected = this.otherCallRejected;
     4599  }
     4600}
     4601QueueItem.prototype.callFulfilled = function (value) {
     4602  handlers.resolve(this.promise, value);
     4603};
     4604QueueItem.prototype.otherCallFulfilled = function (value) {
     4605  unwrap(this.promise, this.onFulfilled, value);
     4606};
     4607QueueItem.prototype.callRejected = function (value) {
     4608  handlers.reject(this.promise, value);
     4609};
     4610QueueItem.prototype.otherCallRejected = function (value) {
     4611  unwrap(this.promise, this.onRejected, value);
     4612};
     4613
     4614function unwrap(promise, func, value) {
     4615  immediate(function () {
     4616    var returnValue;
     4617    try {
     4618      returnValue = func(value);
     4619    } catch (e) {
     4620      return handlers.reject(promise, e);
     4621    }
     4622    if (returnValue === promise) {
     4623      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
     4624    } else {
     4625      handlers.resolve(promise, returnValue);
     4626    }
     4627  });
     4628}
     4629
     4630handlers.resolve = function (self, value) {
     4631  var result = tryCatch(getThen, value);
     4632  if (result.status === 'error') {
     4633    return handlers.reject(self, result.value);
     4634  }
     4635  var thenable = result.value;
     4636
     4637  if (thenable) {
     4638    safelyResolveThenable(self, thenable);
     4639  } else {
     4640    self.state = FULFILLED;
     4641    self.outcome = value;
     4642    var i = -1;
     4643    var len = self.queue.length;
     4644    while (++i < len) {
     4645      self.queue[i].callFulfilled(value);
     4646    }
     4647  }
     4648  return self;
     4649};
     4650handlers.reject = function (self, error) {
     4651  self.state = REJECTED;
     4652  self.outcome = error;
     4653  var i = -1;
     4654  var len = self.queue.length;
     4655  while (++i < len) {
     4656    self.queue[i].callRejected(error);
     4657  }
     4658  return self;
     4659};
     4660
     4661function getThen(obj) {
     4662  // Make sure we only access the accessor once as required by the spec
     4663  var then = obj && obj.then;
     4664  if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
     4665    return function appyThen() {
     4666      then.apply(obj, arguments);
     4667    };
     4668  }
     4669}
     4670
     4671function safelyResolveThenable(self, thenable) {
     4672  // Either fulfill, reject or reject with error
     4673  var called = false;
     4674  function onError(value) {
     4675    if (called) {
     4676      return;
     4677    }
     4678    called = true;
     4679    handlers.reject(self, value);
     4680  }
     4681
     4682  function onSuccess(value) {
     4683    if (called) {
     4684      return;
     4685    }
     4686    called = true;
     4687    handlers.resolve(self, value);
     4688  }
     4689
     4690  function tryToUnwrap() {
     4691    thenable(onSuccess, onError);
     4692  }
     4693
     4694  var result = tryCatch(tryToUnwrap);
     4695  if (result.status === 'error') {
     4696    onError(result.value);
     4697  }
     4698}
     4699
     4700function tryCatch(func, value) {
     4701  var out = {};
     4702  try {
     4703    out.value = func(value);
     4704    out.status = 'success';
     4705  } catch (e) {
     4706    out.status = 'error';
     4707    out.value = e;
     4708  }
     4709  return out;
     4710}
     4711
     4712Promise.resolve = resolve;
     4713function resolve(value) {
     4714  if (value instanceof this) {
     4715    return value;
     4716  }
     4717  return handlers.resolve(new this(INTERNAL), value);
     4718}
     4719
     4720Promise.reject = reject;
     4721function reject(reason) {
     4722  var promise = new this(INTERNAL);
     4723  return handlers.reject(promise, reason);
     4724}
     4725
     4726Promise.all = all;
     4727function all(iterable) {
     4728  var self = this;
     4729  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
     4730    return this.reject(new TypeError('must be an array'));
     4731  }
     4732
     4733  var len = iterable.length;
     4734  var called = false;
     4735  if (!len) {
     4736    return this.resolve([]);
     4737  }
     4738
     4739  var values = new Array(len);
     4740  var resolved = 0;
     4741  var i = -1;
     4742  var promise = new this(INTERNAL);
     4743
     4744  while (++i < len) {
     4745    allResolver(iterable[i], i);
     4746  }
     4747  return promise;
     4748  function allResolver(value, i) {
     4749    self.resolve(value).then(resolveFromAll, function (error) {
     4750      if (!called) {
     4751        called = true;
     4752        handlers.reject(promise, error);
     4753      }
     4754    });
     4755    function resolveFromAll(outValue) {
     4756      values[i] = outValue;
     4757      if (++resolved === len && !called) {
     4758        called = true;
     4759        handlers.resolve(promise, values);
     4760      }
     4761    }
     4762  }
     4763}
     4764
     4765Promise.race = race;
     4766function race(iterable) {
     4767  var self = this;
     4768  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
     4769    return this.reject(new TypeError('must be an array'));
     4770  }
     4771
     4772  var len = iterable.length;
     4773  var called = false;
     4774  if (!len) {
     4775    return this.resolve([]);
     4776  }
     4777
     4778  var i = -1;
     4779  var promise = new this(INTERNAL);
     4780
     4781  while (++i < len) {
     4782    resolver(iterable[i]);
     4783  }
     4784  return promise;
     4785  function resolver(value) {
     4786    self.resolve(value).then(function (response) {
     4787      if (!called) {
     4788        called = true;
     4789        handlers.resolve(promise, response);
     4790      }
     4791    }, function (error) {
     4792      if (!called) {
     4793        called = true;
     4794        handlers.reject(promise, error);
     4795      }
     4796    });
     4797  }
     4798}
     4799
     4800},{"immediate":57}],59:[function(require,module,exports){
     4801// Top level file is just a mixin of submodules & constants
     4802'use strict';
     4803
     4804var assign    = require('./lib/utils/common').assign;
     4805
     4806var deflate   = require('./lib/deflate');
     4807var inflate   = require('./lib/inflate');
     4808var constants = require('./lib/zlib/constants');
     4809
     4810var pako = {};
     4811
     4812assign(pako, deflate, inflate, constants);
     4813
     4814module.exports = pako;
     4815
     4816},{"./lib/deflate":60,"./lib/inflate":61,"./lib/utils/common":62,"./lib/zlib/constants":65}],60:[function(require,module,exports){
     4817'use strict';
     4818
     4819
     4820var zlib_deflate = require('./zlib/deflate');
     4821var utils        = require('./utils/common');
     4822var strings      = require('./utils/strings');
     4823var msg          = require('./zlib/messages');
     4824var ZStream      = require('./zlib/zstream');
     4825
     4826var toString = Object.prototype.toString;
     4827
     4828/* Public constants ==========================================================*/
     4829/* ===========================================================================*/
     4830
     4831var Z_NO_FLUSH      = 0;
     4832var Z_FINISH        = 4;
     4833
     4834var Z_OK            = 0;
     4835var Z_STREAM_END    = 1;
     4836var Z_SYNC_FLUSH    = 2;
     4837
     4838var Z_DEFAULT_COMPRESSION = -1;
     4839
     4840var Z_DEFAULT_STRATEGY    = 0;
     4841
     4842var Z_DEFLATED  = 8;
     4843
     4844/* ===========================================================================*/
     4845
     4846
     4847/**
     4848 * class Deflate
     4849 *
     4850 * Generic JS-style wrapper for zlib calls. If you don't need
     4851 * streaming behaviour - use more simple functions: [[deflate]],
     4852 * [[deflateRaw]] and [[gzip]].
     4853 **/
     4854
     4855/* internal
     4856 * Deflate.chunks -> Array
     4857 *
     4858 * Chunks of output data, if [[Deflate#onData]] not overriden.
     4859 **/
     4860
     4861/**
     4862 * Deflate.result -> Uint8Array|Array
     4863 *
     4864 * Compressed result, generated by default [[Deflate#onData]]
     4865 * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
     4866 * (call [[Deflate#push]] with `Z_FINISH` / `true` param)  or if you
     4867 * push a chunk with explicit flush (call [[Deflate#push]] with
     4868 * `Z_SYNC_FLUSH` param).
     4869 **/
     4870
     4871/**
     4872 * Deflate.err -> Number
     4873 *
     4874 * Error code after deflate finished. 0 (Z_OK) on success.
     4875 * You will not need it in real life, because deflate errors
     4876 * are possible only on wrong options or bad `onData` / `onEnd`
     4877 * custom handlers.
     4878 **/
     4879
     4880/**
     4881 * Deflate.msg -> String
     4882 *
     4883 * Error message, if [[Deflate.err]] != 0
     4884 **/
     4885
     4886
     4887/**
     4888 * new Deflate(options)
     4889 * - options (Object): zlib deflate options.
     4890 *
     4891 * Creates new deflator instance with specified params. Throws exception
     4892 * on bad params. Supported options:
     4893 *
     4894 * - `level`
     4895 * - `windowBits`
     4896 * - `memLevel`
     4897 * - `strategy`
     4898 * - `dictionary`
     4899 *
     4900 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
     4901 * for more information on these.
     4902 *
     4903 * Additional options, for internal needs:
     4904 *
     4905 * - `chunkSize` - size of generated data chunks (16K by default)
     4906 * - `raw` (Boolean) - do raw deflate
     4907 * - `gzip` (Boolean) - create gzip wrapper
     4908 * - `to` (String) - if equal to 'string', then result will be "binary string"
     4909 *    (each char code [0..255])
     4910 * - `header` (Object) - custom header for gzip
     4911 *   - `text` (Boolean) - true if compressed data believed to be text
     4912 *   - `time` (Number) - modification time, unix timestamp
     4913 *   - `os` (Number) - operation system code
     4914 *   - `extra` (Array) - array of bytes with extra data (max 65536)
     4915 *   - `name` (String) - file name (binary string)
     4916 *   - `comment` (String) - comment (binary string)
     4917 *   - `hcrc` (Boolean) - true if header crc should be added
     4918 *
     4919 * ##### Example:
     4920 *
     4921 * ```javascript
     4922 * var pako = require('pako')
     4923 *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
     4924 *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
     4925 *
     4926 * var deflate = new pako.Deflate({ level: 3});
     4927 *
     4928 * deflate.push(chunk1, false);
     4929 * deflate.push(chunk2, true);  // true -> last chunk
     4930 *
     4931 * if (deflate.err) { throw new Error(deflate.err); }
     4932 *
     4933 * console.log(deflate.result);
     4934 * ```
     4935 **/
     4936function Deflate(options) {
     4937  if (!(this instanceof Deflate)) return new Deflate(options);
     4938
     4939  this.options = utils.assign({
     4940    level: Z_DEFAULT_COMPRESSION,
     4941    method: Z_DEFLATED,
     4942    chunkSize: 16384,
     4943    windowBits: 15,
     4944    memLevel: 8,
     4945    strategy: Z_DEFAULT_STRATEGY,
     4946    to: ''
     4947  }, options || {});
     4948
     4949  var opt = this.options;
     4950
     4951  if (opt.raw && (opt.windowBits > 0)) {
     4952    opt.windowBits = -opt.windowBits;
     4953  }
     4954
     4955  else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
     4956    opt.windowBits += 16;
     4957  }
     4958
     4959  this.err    = 0;      // error code, if happens (0 = Z_OK)
     4960  this.msg    = '';     // error message
     4961  this.ended  = false;  // used to avoid multiple onEnd() calls
     4962  this.chunks = [];     // chunks of compressed data
     4963
     4964  this.strm = new ZStream();
     4965  this.strm.avail_out = 0;
     4966
     4967  var status = zlib_deflate.deflateInit2(
     4968    this.strm,
     4969    opt.level,
     4970    opt.method,
     4971    opt.windowBits,
     4972    opt.memLevel,
     4973    opt.strategy
     4974  );
     4975
     4976  if (status !== Z_OK) {
     4977    throw new Error(msg[status]);
     4978  }
     4979
     4980  if (opt.header) {
     4981    zlib_deflate.deflateSetHeader(this.strm, opt.header);
     4982  }
     4983
     4984  if (opt.dictionary) {
     4985    var dict;
     4986    // Convert data if needed
     4987    if (typeof opt.dictionary === 'string') {
     4988      // If we need to compress text, change encoding to utf8.
     4989      dict = strings.string2buf(opt.dictionary);
     4990    } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
     4991      dict = new Uint8Array(opt.dictionary);
     4992    } else {
     4993      dict = opt.dictionary;
     4994    }
     4995
     4996    status = zlib_deflate.deflateSetDictionary(this.strm, dict);
     4997
     4998    if (status !== Z_OK) {
     4999      throw new Error(msg[status]);
     5000    }
     5001
     5002    this._dict_set = true;
     5003  }
     5004}
     5005
     5006/**
     5007 * Deflate#push(data[, mode]) -> Boolean
     5008 * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
     5009 *   converted to utf8 byte sequence.
     5010 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
     5011 *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH.
     5012 *
     5013 * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
     5014 * new compressed chunks. Returns `true` on success. The last data block must have
     5015 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
     5016 * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
     5017 * can use mode Z_SYNC_FLUSH, keeping the compression context.
     5018 *
     5019 * On fail call [[Deflate#onEnd]] with error code and return false.
     5020 *
     5021 * We strongly recommend to use `Uint8Array` on input for best speed (output
     5022 * array format is detected automatically). Also, don't skip last param and always
     5023 * use the same type in your code (boolean or number). That will improve JS speed.
     5024 *
     5025 * For regular `Array`-s make sure all elements are [0..255].
     5026 *
     5027 * ##### Example
     5028 *
     5029 * ```javascript
     5030 * push(chunk, false); // push one of data chunks
     5031 * ...
     5032 * push(chunk, true);  // push last chunk
     5033 * ```
     5034 **/
     5035Deflate.prototype.push = function (data, mode) {
     5036  var strm = this.strm;
     5037  var chunkSize = this.options.chunkSize;
     5038  var status, _mode;
     5039
     5040  if (this.ended) { return false; }
     5041
     5042  _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
     5043
     5044  // Convert data if needed
     5045  if (typeof data === 'string') {
     5046    // If we need to compress text, change encoding to utf8.
     5047    strm.input = strings.string2buf(data);
     5048  } else if (toString.call(data) === '[object ArrayBuffer]') {
     5049    strm.input = new Uint8Array(data);
     5050  } else {
     5051    strm.input = data;
     5052  }
     5053
     5054  strm.next_in = 0;
     5055  strm.avail_in = strm.input.length;
     5056
     5057  do {
     5058    if (strm.avail_out === 0) {
     5059      strm.output = new utils.Buf8(chunkSize);
     5060      strm.next_out = 0;
     5061      strm.avail_out = chunkSize;
     5062    }
     5063    status = zlib_deflate.deflate(strm, _mode);    /* no bad return value */
     5064
     5065    if (status !== Z_STREAM_END && status !== Z_OK) {
     5066      this.onEnd(status);
     5067      this.ended = true;
     5068      return false;
     5069    }
     5070    if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
     5071      if (this.options.to === 'string') {
     5072        this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
     5073      } else {
     5074        this.onData(utils.shrinkBuf(strm.output, strm.next_out));
     5075      }
     5076    }
     5077  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
     5078
     5079  // Finalize on the last chunk.
     5080  if (_mode === Z_FINISH) {
     5081    status = zlib_deflate.deflateEnd(this.strm);
     5082    this.onEnd(status);
     5083    this.ended = true;
     5084    return status === Z_OK;
     5085  }
     5086
     5087  // callback interim results if Z_SYNC_FLUSH.
     5088  if (_mode === Z_SYNC_FLUSH) {
     5089    this.onEnd(Z_OK);
     5090    strm.avail_out = 0;
     5091    return true;
     5092  }
     5093
     5094  return true;
     5095};
     5096
     5097
     5098/**
     5099 * Deflate#onData(chunk) -> Void
     5100 * - chunk (Uint8Array|Array|String): ouput data. Type of array depends
     5101 *   on js engine support. When string output requested, each chunk
     5102 *   will be string.
     5103 *
     5104 * By default, stores data blocks in `chunks[]` property and glue
     5105 * those in `onEnd`. Override this handler, if you need another behaviour.
     5106 **/
     5107Deflate.prototype.onData = function (chunk) {
     5108  this.chunks.push(chunk);
     5109};
     5110
     5111
     5112/**
     5113 * Deflate#onEnd(status) -> Void
     5114 * - status (Number): deflate status. 0 (Z_OK) on success,
     5115 *   other if not.
     5116 *
     5117 * Called once after you tell deflate that the input stream is
     5118 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
     5119 * or if an error happened. By default - join collected chunks,
     5120 * free memory and fill `results` / `err` properties.
     5121 **/
     5122Deflate.prototype.onEnd = function (status) {
     5123  // On success - join
     5124  if (status === Z_OK) {
     5125    if (this.options.to === 'string') {
     5126      this.result = this.chunks.join('');
     5127    } else {
     5128      this.result = utils.flattenChunks(this.chunks);
     5129    }
     5130  }
     5131  this.chunks = [];
     5132  this.err = status;
     5133  this.msg = this.strm.msg;
     5134};
     5135
     5136
     5137/**
     5138 * deflate(data[, options]) -> Uint8Array|Array|String
     5139 * - data (Uint8Array|Array|String): input data to compress.
     5140 * - options (Object): zlib deflate options.
     5141 *
     5142 * Compress `data` with deflate algorithm and `options`.
     5143 *
     5144 * Supported options are:
     5145 *
     5146 * - level
     5147 * - windowBits
     5148 * - memLevel
     5149 * - strategy
     5150 * - dictionary
     5151 *
     5152 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
     5153 * for more information on these.
     5154 *
     5155 * Sugar (options):
     5156 *
     5157 * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
     5158 *   negative windowBits implicitly.
     5159 * - `to` (String) - if equal to 'string', then result will be "binary string"
     5160 *    (each char code [0..255])
     5161 *
     5162 * ##### Example:
     5163 *
     5164 * ```javascript
     5165 * var pako = require('pako')
     5166 *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
     5167 *
     5168 * console.log(pako.deflate(data));
     5169 * ```
     5170 **/
     5171function deflate(input, options) {
     5172  var deflator = new Deflate(options);
     5173
     5174  deflator.push(input, true);
     5175
     5176  // That will never happens, if you don't cheat with options :)
     5177  if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
     5178
     5179  return deflator.result;
     5180}
     5181
     5182
     5183/**
     5184 * deflateRaw(data[, options]) -> Uint8Array|Array|String
     5185 * - data (Uint8Array|Array|String): input data to compress.
     5186 * - options (Object): zlib deflate options.
     5187 *
     5188 * The same as [[deflate]], but creates raw data, without wrapper
     5189 * (header and adler32 crc).
     5190 **/
     5191function deflateRaw(input, options) {
     5192  options = options || {};
     5193  options.raw = true;
     5194  return deflate(input, options);
     5195}
     5196
     5197
     5198/**
     5199 * gzip(data[, options]) -> Uint8Array|Array|String
     5200 * - data (Uint8Array|Array|String): input data to compress.
     5201 * - options (Object): zlib deflate options.
     5202 *
     5203 * The same as [[deflate]], but create gzip wrapper instead of
     5204 * deflate one.
     5205 **/
     5206function gzip(input, options) {
     5207  options = options || {};
     5208  options.gzip = true;
     5209  return deflate(input, options);
     5210}
     5211
     5212
     5213exports.Deflate = Deflate;
     5214exports.deflate = deflate;
     5215exports.deflateRaw = deflateRaw;
     5216exports.gzip = gzip;
     5217
     5218},{"./utils/common":62,"./utils/strings":63,"./zlib/deflate":67,"./zlib/messages":72,"./zlib/zstream":74}],61:[function(require,module,exports){
     5219'use strict';
     5220
     5221
     5222var zlib_inflate = require('./zlib/inflate');
     5223var utils        = require('./utils/common');
     5224var strings      = require('./utils/strings');
     5225var c            = require('./zlib/constants');
     5226var msg          = require('./zlib/messages');
     5227var ZStream      = require('./zlib/zstream');
     5228var GZheader     = require('./zlib/gzheader');
     5229
     5230var toString = Object.prototype.toString;
     5231
     5232/**
     5233 * class Inflate
     5234 *
     5235 * Generic JS-style wrapper for zlib calls. If you don't need
     5236 * streaming behaviour - use more simple functions: [[inflate]]
     5237 * and [[inflateRaw]].
     5238 **/
     5239
     5240/* internal
     5241 * inflate.chunks -> Array
     5242 *
     5243 * Chunks of output data, if [[Inflate#onData]] not overriden.
     5244 **/
     5245
     5246/**
     5247 * Inflate.result -> Uint8Array|Array|String
     5248 *
     5249 * Uncompressed result, generated by default [[Inflate#onData]]
     5250 * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
     5251 * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
     5252 * push a chunk with explicit flush (call [[Inflate#push]] with
     5253 * `Z_SYNC_FLUSH` param).
     5254 **/
     5255
     5256/**
     5257 * Inflate.err -> Number
     5258 *
     5259 * Error code after inflate finished. 0 (Z_OK) on success.
     5260 * Should be checked if broken data possible.
     5261 **/
     5262
     5263/**
     5264 * Inflate.msg -> String
     5265 *
     5266 * Error message, if [[Inflate.err]] != 0
     5267 **/
     5268
     5269
     5270/**
     5271 * new Inflate(options)
     5272 * - options (Object): zlib inflate options.
     5273 *
     5274 * Creates new inflator instance with specified params. Throws exception
     5275 * on bad params. Supported options:
     5276 *
     5277 * - `windowBits`
     5278 * - `dictionary`
     5279 *
     5280 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
     5281 * for more information on these.
     5282 *
     5283 * Additional options, for internal needs:
     5284 *
     5285 * - `chunkSize` - size of generated data chunks (16K by default)
     5286 * - `raw` (Boolean) - do raw inflate
     5287 * - `to` (String) - if equal to 'string', then result will be converted
     5288 *   from utf8 to utf16 (javascript) string. When string output requested,
     5289 *   chunk length can differ from `chunkSize`, depending on content.
     5290 *
     5291 * By default, when no options set, autodetect deflate/gzip data format via
     5292 * wrapper header.
     5293 *
     5294 * ##### Example:
     5295 *
     5296 * ```javascript
     5297 * var pako = require('pako')
     5298 *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
     5299 *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
     5300 *
     5301 * var inflate = new pako.Inflate({ level: 3});
     5302 *
     5303 * inflate.push(chunk1, false);
     5304 * inflate.push(chunk2, true);  // true -> last chunk
     5305 *
     5306 * if (inflate.err) { throw new Error(inflate.err); }
     5307 *
     5308 * console.log(inflate.result);
     5309 * ```
     5310 **/
     5311function Inflate(options) {
     5312  if (!(this instanceof Inflate)) return new Inflate(options);
     5313
     5314  this.options = utils.assign({
     5315    chunkSize: 16384,
     5316    windowBits: 0,
     5317    to: ''
     5318  }, options || {});
     5319
     5320  var opt = this.options;
     5321
     5322  // Force window size for `raw` data, if not set directly,
     5323  // because we have no header for autodetect.
     5324  if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
     5325    opt.windowBits = -opt.windowBits;
     5326    if (opt.windowBits === 0) { opt.windowBits = -15; }
     5327  }
     5328
     5329  // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
     5330  if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
     5331      !(options && options.windowBits)) {
     5332    opt.windowBits += 32;
     5333  }
     5334
     5335  // Gzip header has no info about windows size, we can do autodetect only
     5336  // for deflate. So, if window size not set, force it to max when gzip possible
     5337  if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
     5338    // bit 3 (16) -> gzipped data
     5339    // bit 4 (32) -> autodetect gzip/deflate
     5340    if ((opt.windowBits & 15) === 0) {
     5341      opt.windowBits |= 15;
     5342    }
     5343  }
     5344
     5345  this.err    = 0;      // error code, if happens (0 = Z_OK)
     5346  this.msg    = '';     // error message
     5347  this.ended  = false;  // used to avoid multiple onEnd() calls
     5348  this.chunks = [];     // chunks of compressed data
     5349
     5350  this.strm   = new ZStream();
     5351  this.strm.avail_out = 0;
     5352
     5353  var status  = zlib_inflate.inflateInit2(
     5354    this.strm,
     5355    opt.windowBits
     5356  );
     5357
     5358  if (status !== c.Z_OK) {
     5359    throw new Error(msg[status]);
     5360  }
     5361
     5362  this.header = new GZheader();
     5363
     5364  zlib_inflate.inflateGetHeader(this.strm, this.header);
     5365}
     5366
     5367/**
     5368 * Inflate#push(data[, mode]) -> Boolean
     5369 * - data (Uint8Array|Array|ArrayBuffer|String): input data
     5370 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
     5371 *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH.
     5372 *
     5373 * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
     5374 * new output chunks. Returns `true` on success. The last data block must have
     5375 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
     5376 * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
     5377 * can use mode Z_SYNC_FLUSH, keeping the decompression context.
     5378 *
     5379 * On fail call [[Inflate#onEnd]] with error code and return false.
     5380 *
     5381 * We strongly recommend to use `Uint8Array` on input for best speed (output
     5382 * format is detected automatically). Also, don't skip last param and always
     5383 * use the same type in your code (boolean or number). That will improve JS speed.
     5384 *
     5385 * For regular `Array`-s make sure all elements are [0..255].
     5386 *
     5387 * ##### Example
     5388 *
     5389 * ```javascript
     5390 * push(chunk, false); // push one of data chunks
     5391 * ...
     5392 * push(chunk, true);  // push last chunk
     5393 * ```
     5394 **/
     5395Inflate.prototype.push = function (data, mode) {
     5396  var strm = this.strm;
     5397  var chunkSize = this.options.chunkSize;
     5398  var dictionary = this.options.dictionary;
     5399  var status, _mode;
     5400  var next_out_utf8, tail, utf8str;
     5401  var dict;
     5402
     5403  // Flag to properly process Z_BUF_ERROR on testing inflate call
     5404  // when we check that all output data was flushed.
     5405  var allowBufError = false;
     5406
     5407  if (this.ended) { return false; }
     5408  _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
     5409
     5410  // Convert data if needed
     5411  if (typeof data === 'string') {
     5412    // Only binary strings can be decompressed on practice
     5413    strm.input = strings.binstring2buf(data);
     5414  } else if (toString.call(data) === '[object ArrayBuffer]') {
     5415    strm.input = new Uint8Array(data);
     5416  } else {
     5417    strm.input = data;
     5418  }
     5419
     5420  strm.next_in = 0;
     5421  strm.avail_in = strm.input.length;
     5422
     5423  do {
     5424    if (strm.avail_out === 0) {
     5425      strm.output = new utils.Buf8(chunkSize);
     5426      strm.next_out = 0;
     5427      strm.avail_out = chunkSize;
     5428    }
     5429
     5430    status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);    /* no bad return value */
     5431
     5432    if (status === c.Z_NEED_DICT && dictionary) {
     5433      // Convert data if needed
     5434      if (typeof dictionary === 'string') {
     5435        dict = strings.string2buf(dictionary);
     5436      } else if (toString.call(dictionary) === '[object ArrayBuffer]') {
     5437        dict = new Uint8Array(dictionary);
     5438      } else {
     5439        dict = dictionary;
     5440      }
     5441
     5442      status = zlib_inflate.inflateSetDictionary(this.strm, dict);
     5443
     5444    }
     5445
     5446    if (status === c.Z_BUF_ERROR && allowBufError === true) {
     5447      status = c.Z_OK;
     5448      allowBufError = false;
     5449    }
     5450
     5451    if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
     5452      this.onEnd(status);
     5453      this.ended = true;
     5454      return false;
     5455    }
     5456
     5457    if (strm.next_out) {
     5458      if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {
     5459
     5460        if (this.options.to === 'string') {
     5461
     5462          next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
     5463
     5464          tail = strm.next_out - next_out_utf8;
     5465          utf8str = strings.buf2string(strm.output, next_out_utf8);
     5466
     5467          // move tail
     5468          strm.next_out = tail;
     5469          strm.avail_out = chunkSize - tail;
     5470          if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
     5471
     5472          this.onData(utf8str);
     5473
     5474        } else {
     5475          this.onData(utils.shrinkBuf(strm.output, strm.next_out));
     5476        }
     5477      }
     5478    }
     5479
     5480    // When no more input data, we should check that internal inflate buffers
     5481    // are flushed. The only way to do it when avail_out = 0 - run one more
     5482    // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
     5483    // Here we set flag to process this error properly.
     5484    //
     5485    // NOTE. Deflate does not return error in this case and does not needs such
     5486    // logic.
     5487    if (strm.avail_in === 0 && strm.avail_out === 0) {
     5488      allowBufError = true;
     5489    }
     5490
     5491  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);
     5492
     5493  if (status === c.Z_STREAM_END) {
     5494    _mode = c.Z_FINISH;
     5495  }
     5496
     5497  // Finalize on the last chunk.
     5498  if (_mode === c.Z_FINISH) {
     5499    status = zlib_inflate.inflateEnd(this.strm);
     5500    this.onEnd(status);
     5501    this.ended = true;
     5502    return status === c.Z_OK;
     5503  }
     5504
     5505  // callback interim results if Z_SYNC_FLUSH.
     5506  if (_mode === c.Z_SYNC_FLUSH) {
     5507    this.onEnd(c.Z_OK);
     5508    strm.avail_out = 0;
     5509    return true;
     5510  }
     5511
     5512  return true;
     5513};
     5514
     5515
     5516/**
     5517 * Inflate#onData(chunk) -> Void
     5518 * - chunk (Uint8Array|Array|String): ouput data. Type of array depends
     5519 *   on js engine support. When string output requested, each chunk
     5520 *   will be string.
     5521 *
     5522 * By default, stores data blocks in `chunks[]` property and glue
     5523 * those in `onEnd`. Override this handler, if you need another behaviour.
     5524 **/
     5525Inflate.prototype.onData = function (chunk) {
     5526  this.chunks.push(chunk);
     5527};
     5528
     5529
     5530/**
     5531 * Inflate#onEnd(status) -> Void
     5532 * - status (Number): inflate status. 0 (Z_OK) on success,
     5533 *   other if not.
     5534 *
     5535 * Called either after you tell inflate that the input stream is
     5536 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
     5537 * or if an error happened. By default - join collected chunks,
     5538 * free memory and fill `results` / `err` properties.
     5539 **/
     5540Inflate.prototype.onEnd = function (status) {
     5541  // On success - join
     5542  if (status === c.Z_OK) {
     5543    if (this.options.to === 'string') {
     5544      // Glue & convert here, until we teach pako to send
     5545      // utf8 alligned strings to onData
     5546      this.result = this.chunks.join('');
     5547    } else {
     5548      this.result = utils.flattenChunks(this.chunks);
     5549    }
     5550  }
     5551  this.chunks = [];
     5552  this.err = status;
     5553  this.msg = this.strm.msg;
     5554};
     5555
     5556
     5557/**
     5558 * inflate(data[, options]) -> Uint8Array|Array|String
     5559 * - data (Uint8Array|Array|String): input data to decompress.
     5560 * - options (Object): zlib inflate options.
     5561 *
     5562 * Decompress `data` with inflate/ungzip and `options`. Autodetect
     5563 * format via wrapper header by default. That's why we don't provide
     5564 * separate `ungzip` method.
     5565 *
     5566 * Supported options are:
     5567 *
     5568 * - windowBits
     5569 *
     5570 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
     5571 * for more information.
     5572 *
     5573 * Sugar (options):
     5574 *
     5575 * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
     5576 *   negative windowBits implicitly.
     5577 * - `to` (String) - if equal to 'string', then result will be converted
     5578 *   from utf8 to utf16 (javascript) string. When string output requested,
     5579 *   chunk length can differ from `chunkSize`, depending on content.
     5580 *
     5581 *
     5582 * ##### Example:
     5583 *
     5584 * ```javascript
     5585 * var pako = require('pako')
     5586 *   , input = pako.deflate([1,2,3,4,5,6,7,8,9])
     5587 *   , output;
     5588 *
     5589 * try {
     5590 *   output = pako.inflate(input);
     5591 * } catch (err)
     5592 *   console.log(err);
     5593 * }
     5594 * ```
     5595 **/
     5596function inflate(input, options) {
     5597  var inflator = new Inflate(options);
     5598
     5599  inflator.push(input, true);
     5600
     5601  // That will never happens, if you don't cheat with options :)
     5602  if (inflator.err) { throw inflator.msg || msg[inflator.err]; }
     5603
     5604  return inflator.result;
     5605}
     5606
     5607
     5608/**
     5609 * inflateRaw(data[, options]) -> Uint8Array|Array|String
     5610 * - data (Uint8Array|Array|String): input data to decompress.
     5611 * - options (Object): zlib inflate options.
     5612 *
     5613 * The same as [[inflate]], but creates raw data, without wrapper
     5614 * (header and adler32 crc).
     5615 **/
     5616function inflateRaw(input, options) {
     5617  options = options || {};
     5618  options.raw = true;
     5619  return inflate(input, options);
     5620}
     5621
     5622
     5623/**
     5624 * ungzip(data[, options]) -> Uint8Array|Array|String
     5625 * - data (Uint8Array|Array|String): input data to decompress.
     5626 * - options (Object): zlib inflate options.
     5627 *
     5628 * Just shortcut to [[inflate]], because it autodetects format
     5629 * by header.content. Done for convenience.
     5630 **/
     5631
     5632
     5633exports.Inflate = Inflate;
     5634exports.inflate = inflate;
     5635exports.inflateRaw = inflateRaw;
     5636exports.ungzip  = inflate;
     5637
     5638},{"./utils/common":62,"./utils/strings":63,"./zlib/constants":65,"./zlib/gzheader":68,"./zlib/inflate":70,"./zlib/messages":72,"./zlib/zstream":74}],62:[function(require,module,exports){
     5639'use strict';
     5640
     5641
     5642var TYPED_OK =  (typeof Uint8Array !== 'undefined') &&
     5643                (typeof Uint16Array !== 'undefined') &&
     5644                (typeof Int32Array !== 'undefined');
     5645
     5646
     5647exports.assign = function (obj /*from1, from2, from3, ...*/) {
     5648  var sources = Array.prototype.slice.call(arguments, 1);
     5649  while (sources.length) {
     5650    var source = sources.shift();
     5651    if (!source) { continue; }
     5652
     5653    if (typeof source !== 'object') {
     5654      throw new TypeError(source + 'must be non-object');
     5655    }
     5656
     5657    for (var p in source) {
     5658      if (source.hasOwnProperty(p)) {
     5659        obj[p] = source[p];
     5660      }
     5661    }
     5662  }
     5663
     5664  return obj;
     5665};
     5666
     5667
     5668// reduce buffer size, avoiding mem copy
     5669exports.shrinkBuf = function (buf, size) {
     5670  if (buf.length === size) { return buf; }
     5671  if (buf.subarray) { return buf.subarray(0, size); }
     5672  buf.length = size;
     5673  return buf;
     5674};
     5675
     5676
     5677var fnTyped = {
     5678  arraySet: function (dest, src, src_offs, len, dest_offs) {
     5679    if (src.subarray && dest.subarray) {
     5680      dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
     5681      return;
     5682    }
     5683    // Fallback to ordinary array
     5684    for (var i = 0; i < len; i++) {
     5685      dest[dest_offs + i] = src[src_offs + i];
     5686    }
     5687  },
     5688  // Join array of chunks to single array.
     5689  flattenChunks: function (chunks) {
     5690    var i, l, len, pos, chunk, result;
     5691
     5692    // calculate data length
     5693    len = 0;
     5694    for (i = 0, l = chunks.length; i < l; i++) {
     5695      len += chunks[i].length;
     5696    }
     5697
     5698    // join chunks
     5699    result = new Uint8Array(len);
     5700    pos = 0;
     5701    for (i = 0, l = chunks.length; i < l; i++) {
     5702      chunk = chunks[i];
     5703      result.set(chunk, pos);
     5704      pos += chunk.length;
     5705    }
     5706
     5707    return result;
     5708  }
     5709};
     5710
     5711var fnUntyped = {
     5712  arraySet: function (dest, src, src_offs, len, dest_offs) {
     5713    for (var i = 0; i < len; i++) {
     5714      dest[dest_offs + i] = src[src_offs + i];
     5715    }
     5716  },
     5717  // Join array of chunks to single array.
     5718  flattenChunks: function (chunks) {
     5719    return [].concat.apply([], chunks);
     5720  }
     5721};
     5722
     5723
     5724// Enable/Disable typed arrays use, for testing
     5725//
     5726exports.setTyped = function (on) {
     5727  if (on) {
     5728    exports.Buf8  = Uint8Array;
     5729    exports.Buf16 = Uint16Array;
     5730    exports.Buf32 = Int32Array;
     5731    exports.assign(exports, fnTyped);
     5732  } else {
     5733    exports.Buf8  = Array;
     5734    exports.Buf16 = Array;
     5735    exports.Buf32 = Array;
     5736    exports.assign(exports, fnUntyped);
     5737  }
     5738};
     5739
     5740exports.setTyped(TYPED_OK);
     5741
     5742},{}],63:[function(require,module,exports){
     5743// String encode/decode helpers
     5744'use strict';
     5745
     5746
     5747var utils = require('./common');
     5748
     5749
     5750// Quick check if we can use fast array to bin string conversion
     5751//
     5752// - apply(Array) can fail on Android 2.2
     5753// - apply(Uint8Array) can fail on iOS 5.1 Safary
     5754//
     5755var STR_APPLY_OK = true;
     5756var STR_APPLY_UIA_OK = true;
     5757
     5758try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; }
     5759try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }
     5760
     5761
     5762// Table with utf8 lengths (calculated by first byte of sequence)
     5763// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
     5764// because max possible codepoint is 0x10ffff
     5765var _utf8len = new utils.Buf8(256);
     5766for (var q = 0; q < 256; q++) {
     5767  _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);
     5768}
     5769_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
     5770
     5771
     5772// convert string to array (typed, when possible)
     5773exports.string2buf = function (str) {
     5774  var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
     5775
     5776  // count binary size
     5777  for (m_pos = 0; m_pos < str_len; m_pos++) {
     5778    c = str.charCodeAt(m_pos);
     5779