├── README.md ├── assets ├── greek-helmet-thumb.png ├── greek-helmet.jpg ├── jules-thumb.png ├── jules.jpg ├── window-thumb.png ├── window.jpg ├── wood-thumb.png ├── wood.jpg ├── yamasa-maneki-neko-thumb.png └── yamasa-maneki-neko.jpg ├── css └── styles.css ├── index.html ├── js ├── LensBlurDepthExtractor.js ├── ShaderLoader.js ├── StackBlur.js ├── THREE.OBJExporter.js ├── three.min.js └── zip │ ├── deflate.js │ ├── inflate.js │ ├── mime-types.js │ ├── zip-ext.js │ ├── zip-fs.js │ └── zip.js └── shaders ├── particle-fs.glsl └── particle-vs.glsl /README.md: -------------------------------------------------------------------------------- 1 | Depth Player for Android Lens Blur images 2 | ============= 3 | 4 | This is the code for the depth player here http://www.clicktorelease.com/code/depth-player, which is a tool to reconstruct scenes in 3D taken with the Android Lens Blur camera, using [LensBlurDepthExtractor.js](https://github.com/spite/android-lens-blur-depth-extractor) 5 | 6 | It correctly converts depth information from the depth image into a 3D set of points that can be visualized as point cloud, wireframe mesh or solid mesh. The mesh is textured with the pre-blurred version of the image. There's option to export a .obj version of the reconstructed mesh, and an uploader to [SketchFab](http://www.sketchfab.com). 7 | 8 | Read about this in [Creating Android Lens Blur Depth Viewer](http://www.clicktorelease.com/blog/creating-android-lens-blur-depth-viewer). 9 | 10 | **Demo: http://www.clicktorelease.com/code/depth-player** 11 | 12 | Credits 13 | ------- 14 | 15 | Coded using [three.js](http://www.threejs.org), [zip.js](http://gildas-lormeau.github.io/zip.js), [StackBlur](http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html), [LensBlurDepthExtractor.js](https://github.com/spite/android-lens-blur-depth-extractor) and a modified version of THREE.OBJExporter.js to export models. 16 | 17 | Images are all by me, taken with a Nexus5. 18 | License 19 | ------- 20 | 21 | MIT licensed 22 | 23 | Copyright (C) 2014 Jaume Sanchez Elias http://twitter.com/thespite 24 | 25 | http://www.clicktorelease.com -------------------------------------------------------------------------------- /assets/greek-helmet-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/greek-helmet-thumb.png -------------------------------------------------------------------------------- /assets/greek-helmet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/greek-helmet.jpg -------------------------------------------------------------------------------- /assets/jules-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/jules-thumb.png -------------------------------------------------------------------------------- /assets/jules.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/jules.jpg -------------------------------------------------------------------------------- /assets/window-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/window-thumb.png -------------------------------------------------------------------------------- /assets/window.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/window.jpg -------------------------------------------------------------------------------- /assets/wood-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/wood-thumb.png -------------------------------------------------------------------------------- /assets/wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/wood.jpg -------------------------------------------------------------------------------- /assets/yamasa-maneki-neko-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/yamasa-maneki-neko-thumb.png -------------------------------------------------------------------------------- /assets/yamasa-maneki-neko.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/depth-player/3907aafe855ccfe8fbb44c5a670e5bda0c6d3e7c/assets/yamasa-maneki-neko.jpg -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | *{ 2 | font-family: 'roboto condensed', tahoma; 3 | font-size:13px; 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | text-shadow: 0 -1px 0 rgba( 0,0,0, .6); 8 | } 9 | body { 10 | color: #ffffff; 11 | text-align: left; 12 | font-weight: 100; 13 | background-color: #111; 14 | margin: 0px; 15 | overflow: hidden; 16 | background: #7d7e7d; /* Old browsers */ 17 | background: -moz-radial-gradient(center, ellipse cover, #7d7e7d 0%, #0e0e0e 100%); /* FF3.6+ */ 18 | background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#7d7e7d), color-stop(100%,#0e0e0e)); /* Chrome,Safari4+ */ 19 | background: -webkit-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* Chrome10+,Safari5.1+ */ 20 | background: -o-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* Opera 12+ */ 21 | background: -ms-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* IE10+ */ 22 | background: radial-gradient(ellipse at center, #7d7e7d 0%,#0e0e0e 100%); /* W3C */ 23 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7d7e7d', endColorstr='#0e0e0e',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */ 24 | } 25 | a{ pointer-events: auto;} 26 | h1{ font-size: 16px;} 27 | a.inside{ color: #fff; font-style: normal; text-decoration: none; background-color: rgba( 255,255,255,.1); padding: 3px;} 28 | a.inside:hover{ background-color: rgba( 255,255,255,.4);} 29 | .rs-base{ display: none;} 30 | #uploadFile{ } 31 | .title{ position: absolute; left: 10px; top: 10px ; z-index: 100; right: 60%;} 32 | #log{ position: absolute; width: 600px; top: 10px; right: 10px; bottom: 10px; overflow: scroll; color: #eee; word-wrap:break-word; display :none;} 33 | #container{ position: absolute; left: 0; top: 0; right: 0; bottom: 0 ;} 34 | #loading{ position: absolute; left: 0; width: 100%; right: 0; height: 50px; background-color: rgba( 0,0,0,.6); color: white; text-align: center; line-height: 50px; transition: opacity 250ms ease-out; opacity: 1; pointer-events: none; z-index: 200;} 35 | #loading p{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; text-align: center; line-height: 50px; z-index: 300;} 36 | #message{ position: absolute; left: 0; top: 0; width: 100%; right: 0; height: 60px; background-color: rgba( 0,0,0,.6); color: white; text-align: center; line-height: 50px; transition: opacity 250ms ease-out; opacity: 0; pointer-events: none; z-index: 200;} 37 | #message p{ position: absolute; left: 0; top: 10px; right: 0; text-align: center; line-height: 1em;} 38 | #message a.close{ position: absolute; left: 50%; bottom: 10px; width: 20em; margin-left: -10em; text-align: center; line-height: 1em; pointer-events: auto; padding: 5px;} 39 | #progress{ position: absolute; left: 0; top: 0; bottom: 0; background-color: #b70000; transition: width 100ms ease-out;} 40 | #tools{ width: 350px;} 41 | #panel{ padding: 20px; border-left: 10px solid rgba( 0, 0, 0, .2 );} 42 | #panel p{ clear:both; padding: 5px 0; font-style: italic;} 43 | #panel ul{ font-style: italic;} 44 | #panel div{ padding-top: 10px; padding-bottom: 10px; border-top: 1px solid rgba( 255,255,255,.2 ); border-bottom: 1px solid rgba( 0, 0, 0, .2 );} 45 | .custom-file-input { 46 | color: transparent; 47 | width: 100%; 48 | } 49 | .custom-file-input::-webkit-file-upload-button { 50 | visibility: hidden; 51 | } 52 | .custom-file-input::before { 53 | content: 'Select a Lens Blur image'; 54 | } 55 | .custom-file-input::before, .button{ 56 | color: black; 57 | display: inline-block; 58 | background: -webkit-linear-gradient(top, #e9e9e9, #c9c9c9); 59 | background: -moz-linear-gradient(top, #e9e9e9, #c9c9c9); 60 | border: 1px solid #999; 61 | border-radius: 3px; 62 | padding: 5px 8px; 63 | outline: none; 64 | white-space: nowrap; 65 | -webkit-user-select: none; 66 | cursor: pointer; 67 | text-shadow: 1px 1px #fff; 68 | font-weight: 700; 69 | font-size: 10pt; 70 | text-decoration: none; 71 | font-weight: 600; 72 | font-size: 12px; 73 | margin-bottom: 5px; 74 | } 75 | .custom-file-input::before:hover, .button:hover{ 76 | background: -webkit-linear-gradient(top, #ffffff, #dddddd); 77 | background: -moz-linear-gradient(top, #ffffff, #dddddd); 78 | color: #000; 79 | text-shadow: 0 1px 0 rgba( 255,255,255,.6); 80 | } 81 | .custom-file-input:hover::before { 82 | border-color: black; 83 | } 84 | .custom-file-input:active { 85 | outline: 0; 86 | } 87 | .custom-file-input:active::before { 88 | background: -webkit-linear-gradient(top, #e3e3e3, #f9f9f9); 89 | } 90 | #imageList{ list-style-type: none ; float:left;} 91 | #imageList li{ width: 64px; height: 64px; float: left; background-size: cover; background-position: 50% 50%; cursor: pointer; border: 4px solid white; margin-right: 1px;} 92 | .selector{ width: 350px;} 93 | .selector p{ margin: 5px 0;} 94 | .selector ul{ float: left; } 95 | .ui{ transition: opacity 250ms ease-out } 96 | .hidden{ pointer-events:none; opacity: 0;} 97 | #panel{ position: absolute; right: 0; top: 0; bottom: 0; width: 380px; overflow: auto; background-color: rgba( 255, 158, 54, .4 ); z-index: 10;} 98 | #panel ul{ list-style-type: none; padding: 10px 0;} 99 | #panel li{ position: relative; padding: 3px 0;} 100 | #panel li input{ position: absolute; width: 50%; right: 40px;} 101 | #panel li span{ position: absolute; right: 0; padding: 0 5px;} 102 | h1.title{ position: absolute; left: 10px; top: 10px;} 103 | span.error{ color: #b70000;} 104 | @media only screen 105 | and (max-width: 640px) { 106 | body{ font-size: 11px; line-height: 1.5em;} 107 | h1{ margin-bottom: .5em;} 108 | .title{ right: 10px;} 109 | #panel{ position: absolute; left: 0; top: 50%; right: 0; bottom: 0; width: 100%; border-top: 10px solid rgba( 0, 0, 0, .2 ); border-left: none;} 110 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Depth data viewer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 26 | 27 |
28 |

29 |
30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 |
40 | 41 |
42 | 43 | Fork me on GitHub 44 | 45 |
46 |

About

47 |

Check out the GitHub project here:
android-lens-blur-depth-extractor.

48 |

Code by Jaume Sánchez @thespite using three.js
and Kinect code by @kcimc and @mrdoob. 49 |

50 |
51 |

Instructions

52 |

Upload a file captured with the new Android Lens Blur application, and see the model in 3D.

53 |

Click and drag to rotate, mousewheel to zoom / Touch and drag to rotate, pinch to zoom.

54 |
55 |
56 |

Source Lens Blur image

57 |

Select one of these images:

58 | 59 |

or upload your own:

60 | 61 |
62 |
63 |

Render mode

64 |

65 |
66 |
67 |

Actions

68 |

Download .obj Upload to Sketchfab

69 |
70 |
71 |

Settings

72 |

You'll have to reload the model for the changes to be effective.

73 |
80 | 81 |
82 | 83 |
84 | 85 |

Depth Data Viewer

86 | 87 |
88 |

Loading...

89 |
90 |
91 |
92 |

93 | Close 94 |
95 | 96 | 905 | 906 | 907 | 908 | -------------------------------------------------------------------------------- /js/LensBlurDepthExtractor.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | 'use strict'; 4 | 5 | var DepthReader = function() { 6 | 7 | this.focus = { 8 | blurAtInfinity: 0, 9 | focalDistance: 0, 10 | focalPoint: 0, 11 | focalPointX: 0, 12 | focalPointY: 0 13 | } 14 | this.image = { 15 | mime: '', 16 | data: null 17 | } 18 | this.depth = { 19 | format: '', 20 | near: 0, 21 | far: 0, 22 | mime: '', 23 | data: null 24 | } 25 | 26 | } 27 | 28 | function memcpy( dst, dstOffset, src, srcOffset, length ) { 29 | 30 | var dstU8 = new Uint8Array( dst, dstOffset, length ); 31 | var srcU8 = new Uint8Array( src, srcOffset, length ); 32 | dstU8.set( srcU8 ); 33 | 34 | }; 35 | 36 | function ab2str( buf ) { 37 | 38 | return String.fromCharCode.apply( null, new Uint8Array( buf ) ); 39 | 40 | }; 41 | 42 | function matchAttribute( id, str ) { 43 | 44 | var re = new RegExp( id + '="([\\S]*)"', 'gmi' ); 45 | var m = re.exec( str ); 46 | if( m ) return m[ 1 ]; 47 | return null; 48 | 49 | }; 50 | 51 | DepthReader.prototype.parseFile = function( arrayBuffer, onSuccess, onError ) { 52 | 53 | var byteArray = new Uint8Array( arrayBuffer ), 54 | str = ''; 55 | 56 | if( byteArray[ 0 ] === 0xff && byteArray[ 1 ] === 0xd8 ) { 57 | 58 | var boundaries = []; 59 | for (var i = 0; i < byteArray.byteLength; i++) { 60 | if( byteArray[ i ] === 0xff && byteArray[ i + 1 ] === 0xe1 ) { 61 | boundaries.push( i ); 62 | i++; 63 | } 64 | } 65 | boundaries.push( byteArray.byteLength ); 66 | 67 | for( var j = 0; j < boundaries.length - 1; j++ ) { 68 | 69 | if( byteArray[ boundaries[ j ] ] == 0xff && byteArray[ boundaries[ j ] + 1 ] == 0xe1 ) { 70 | 71 | var length = byteArray[ boundaries[ j ] + 2 ] * 256 + byteArray[ boundaries[ j ] + 3 ]; 72 | 73 | var offset = 79; 74 | if( offset > length ) offset = 0; 75 | length += 2; 76 | 77 | var tmp = new ArrayBuffer( length - offset ); 78 | memcpy( tmp, 0, arrayBuffer, boundaries[ j ] + offset, length - offset); 79 | var tmpStr = ab2str( tmp ); 80 | str += tmpStr; 81 | 82 | } 83 | 84 | } 85 | 86 | this.focus.blurAtInfinity = matchAttribute( 'GFocus:BlurAtInfinity', str ); 87 | this.focus.focalDistance = matchAttribute( 'GFocus:focalDistance', str ); 88 | this.focus.focalPoint = matchAttribute( 'GFocus:focalPoint', str ); 89 | this.focus.focalPointX = matchAttribute( 'GFocus:focalPointX', str ); 90 | this.focus.focalPointY = matchAttribute( 'GFocus:focalPointY', str ); 91 | 92 | this.image.mime = matchAttribute( 'GImage:Mime', str ); 93 | this.image.data = matchAttribute( 'GImage:Data', str ); 94 | 95 | this.depth.format = matchAttribute( 'GDepth:Format', str ); 96 | this.depth.near = matchAttribute( 'GDepth:Near', str ); 97 | this.depth.far = matchAttribute( 'GDepth:Far', str ); 98 | this.depth.mime = matchAttribute( 'GDepth:Mime', str ); 99 | this.depth.data = matchAttribute( 'GDepth:Data', str ); 100 | 101 | if( this.depth.data === null ) { 102 | if( onError ) onError( 'No depth data found' ); 103 | return; 104 | } 105 | 106 | if( onSuccess ) onSuccess(); 107 | 108 | } else { 109 | if( onError ) onError( 'File is not a JPEG' ); 110 | } 111 | 112 | }; 113 | 114 | DepthReader.prototype.loadFile = function( file, onSuccess, onError ) { 115 | 116 | var xhr = new XMLHttpRequest(); 117 | xhr.open( 'get', file ); 118 | xhr.responseType = 'arraybuffer'; 119 | var self = this; 120 | xhr.onload = function() { 121 | self.parseFile( this.response, onSuccess, onError ); 122 | }; 123 | xhr.send( null ); 124 | 125 | }; 126 | 127 | window.DepthReader = DepthReader; 128 | 129 | } )(); -------------------------------------------------------------------------------- /js/ShaderLoader.js: -------------------------------------------------------------------------------- 1 | var ShaderLoader = function() { 2 | 3 | this.loaded = 0; 4 | this.toLoad = 0; 5 | this.shaders = {}; 6 | this.queue = []; 7 | this.onLoadedCallback = function(){}; 8 | 9 | } 10 | 11 | ShaderLoader.prototype.add = function( id, name ) { 12 | 13 | this.toLoad++; 14 | this.shaders[ id ] = { 15 | id: id, 16 | name: name, 17 | content: '', 18 | loaded: false 19 | } 20 | this.queue.push( this.shaders[ id ] ); 21 | 22 | } 23 | 24 | ShaderLoader.prototype.processQueue = function() { 25 | 26 | var shader = this.queue.pop(); 27 | 28 | var oReq = new XMLHttpRequest(); 29 | oReq.onload = function() { 30 | this.loaded++; 31 | shader.content = oReq.responseText; 32 | if( this.loaded != this.toLoad ) { 33 | this.processQueue(); 34 | } else { 35 | this.onLoadedCallback(); 36 | } 37 | }.bind( this ); 38 | oReq.open( 'get', shader.name, true ); 39 | oReq.send(); 40 | 41 | } 42 | 43 | ShaderLoader.prototype.load = function() { 44 | 45 | this.processQueue(); 46 | 47 | } 48 | 49 | ShaderLoader.prototype.onLoaded = function( callback ) { 50 | 51 | if( this.loaded == this.toLoad ) callback(); 52 | else this.onLoadedCallback = callback; 53 | 54 | } 55 | 56 | ShaderLoader.prototype.get = function( id ) { 57 | 58 | function ShaderLoaderGetException( message ) { 59 | this.message = 'Cannot find shader "' + id + '".'; 60 | this.name = "ShaderLoaderGetException"; 61 | this.toString = function() { 62 | return this.message 63 | }; 64 | } 65 | 66 | var s = this.shaders[ id ]; 67 | if( !s ) { 68 | throw new ShaderLoaderGetException( id ); 69 | return; 70 | } 71 | 72 | return s.content; 73 | 74 | } -------------------------------------------------------------------------------- /js/StackBlur.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | StackBlur - a fast almost Gaussian Blur For Canvas 4 | 5 | Version: 0.5 6 | Author: Mario Klingemann 7 | Contact: mario@quasimondo.com 8 | Website: http://www.quasimondo.com/StackBlurForCanvas 9 | Twitter: @quasimondo 10 | 11 | In case you find this class useful - especially in commercial projects - 12 | I am not totally unhappy for a small donation to my PayPal account 13 | mario@quasimondo.de 14 | 15 | Or support me on flattr: 16 | https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript 17 | 18 | Copyright (c) 2010 Mario Klingemann 19 | 20 | Permission is hereby granted, free of charge, to any person 21 | obtaining a copy of this software and associated documentation 22 | files (the "Software"), to deal in the Software without 23 | restriction, including without limitation the rights to use, 24 | copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the 26 | Software is furnished to do so, subject to the following 27 | conditions: 28 | 29 | The above copyright notice and this permission notice shall be 30 | included in all copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 34 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 36 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 37 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 38 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 39 | OTHER DEALINGS IN THE SOFTWARE. 40 | */ 41 | 42 | var mul_table = [ 43 | 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 44 | 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 45 | 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 46 | 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 47 | 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 48 | 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 49 | 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 50 | 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 51 | 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 52 | 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 53 | 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 54 | 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 55 | 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 56 | 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 57 | 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 58 | 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; 59 | 60 | 61 | var shg_table = [ 62 | 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 63 | 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 64 | 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 65 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 66 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 67 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 68 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 69 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 70 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 71 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 72 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 73 | 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 74 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 75 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 76 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 77 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; 78 | 79 | function stackBlurImage(imageID, canvasID, radius, blurAlphaChannel) { 80 | 81 | var img = document.getElementById(imageID); 82 | var w = img.naturalWidth; 83 | var h = img.naturalHeight; 84 | 85 | var canvas = document.getElementById(canvasID); 86 | 87 | canvas.style.width = w + "px"; 88 | canvas.style.height = h + "px"; 89 | canvas.width = w; 90 | canvas.height = h; 91 | 92 | var context = canvas.getContext("2d"); 93 | context.clearRect(0, 0, w, h); 94 | context.drawImage(img, 0, 0); 95 | 96 | if (isNaN(radius) || radius < 1) return; 97 | 98 | if (blurAlphaChannel) stackBlurCanvasRGBA(canvasID, 0, 0, w, h, radius); 99 | else stackBlurCanvasRGB(canvasID, 0, 0, w, h, radius); 100 | } 101 | 102 | 103 | function stackBlurCanvasRGBA(id, top_x, top_y, width, height, radius) { 104 | if (isNaN(radius) || radius < 1) return; 105 | radius |= 0; 106 | 107 | var canvas; 108 | if( typeof( id ) === 'string ') { 109 | canvas = document.getElementById(id); 110 | } else { 111 | canvas = id; 112 | } 113 | var context = canvas.getContext("2d"); 114 | var imageData; 115 | 116 | try { 117 | try { 118 | imageData = context.getImageData(top_x, top_y, width, height); 119 | } catch (e) { 120 | 121 | // NOTE: this part is supposedly only needed if you want to work with local files 122 | // so it might be okay to remove the whole try/catch block and just use 123 | // imageData = context.getImageData( top_x, top_y, width, height ); 124 | try { 125 | netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); 126 | imageData = context.getImageData(top_x, top_y, width, height); 127 | } catch (e) { 128 | alert("Cannot access local image"); 129 | throw new Error("unable to access local image data: " + e); 130 | return; 131 | } 132 | } 133 | } catch (e) { 134 | alert("Cannot access image"); 135 | throw new Error("unable to access image data: " + e); 136 | } 137 | 138 | var pixels = imageData.data; 139 | 140 | var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, 141 | r_out_sum, g_out_sum, b_out_sum, a_out_sum, 142 | r_in_sum, g_in_sum, b_in_sum, a_in_sum, 143 | pr, pg, pb, pa, rbs; 144 | 145 | var div = radius + radius + 1; 146 | var w4 = width << 2; 147 | var widthMinus1 = width - 1; 148 | var heightMinus1 = height - 1; 149 | var radiusPlus1 = radius + 1; 150 | var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; 151 | 152 | var stackStart = new BlurStack(); 153 | var stack = stackStart; 154 | for (i = 1; i < div; i++) { 155 | stack = stack.next = new BlurStack(); 156 | if (i == radiusPlus1) var stackEnd = stack; 157 | } 158 | stack.next = stackStart; 159 | var stackIn = null; 160 | var stackOut = null; 161 | 162 | yw = yi = 0; 163 | 164 | var mul_sum = mul_table[radius]; 165 | var shg_sum = shg_table[radius]; 166 | 167 | for (y = 0; y < height; y++) { 168 | r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; 169 | 170 | r_out_sum = radiusPlus1 * (pr = pixels[yi]); 171 | g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 172 | b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 173 | a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); 174 | 175 | r_sum += sumFactor * pr; 176 | g_sum += sumFactor * pg; 177 | b_sum += sumFactor * pb; 178 | a_sum += sumFactor * pa; 179 | 180 | stack = stackStart; 181 | 182 | for (i = 0; i < radiusPlus1; i++) { 183 | stack.r = pr; 184 | stack.g = pg; 185 | stack.b = pb; 186 | stack.a = pa; 187 | stack = stack.next; 188 | } 189 | 190 | for (i = 1; i < radiusPlus1; i++) { 191 | p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); 192 | r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i); 193 | g_sum += (stack.g = (pg = pixels[p + 1])) * rbs; 194 | b_sum += (stack.b = (pb = pixels[p + 2])) * rbs; 195 | a_sum += (stack.a = (pa = pixels[p + 3])) * rbs; 196 | 197 | r_in_sum += pr; 198 | g_in_sum += pg; 199 | b_in_sum += pb; 200 | a_in_sum += pa; 201 | 202 | stack = stack.next; 203 | } 204 | 205 | 206 | stackIn = stackStart; 207 | stackOut = stackEnd; 208 | for (x = 0; x < width; x++) { 209 | pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum; 210 | if (pa != 0) { 211 | pa = 255 / pa; 212 | pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; 213 | pixels[yi + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; 214 | pixels[yi + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; 215 | } else { 216 | pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; 217 | } 218 | 219 | r_sum -= r_out_sum; 220 | g_sum -= g_out_sum; 221 | b_sum -= b_out_sum; 222 | a_sum -= a_out_sum; 223 | 224 | r_out_sum -= stackIn.r; 225 | g_out_sum -= stackIn.g; 226 | b_out_sum -= stackIn.b; 227 | a_out_sum -= stackIn.a; 228 | 229 | p = (yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1)) << 2; 230 | 231 | r_in_sum += (stackIn.r = pixels[p]); 232 | g_in_sum += (stackIn.g = pixels[p + 1]); 233 | b_in_sum += (stackIn.b = pixels[p + 2]); 234 | a_in_sum += (stackIn.a = pixels[p + 3]); 235 | 236 | r_sum += r_in_sum; 237 | g_sum += g_in_sum; 238 | b_sum += b_in_sum; 239 | a_sum += a_in_sum; 240 | 241 | stackIn = stackIn.next; 242 | 243 | r_out_sum += (pr = stackOut.r); 244 | g_out_sum += (pg = stackOut.g); 245 | b_out_sum += (pb = stackOut.b); 246 | a_out_sum += (pa = stackOut.a); 247 | 248 | r_in_sum -= pr; 249 | g_in_sum -= pg; 250 | b_in_sum -= pb; 251 | a_in_sum -= pa; 252 | 253 | stackOut = stackOut.next; 254 | 255 | yi += 4; 256 | } 257 | yw += width; 258 | } 259 | 260 | 261 | for (x = 0; x < width; x++) { 262 | g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; 263 | 264 | yi = x << 2; 265 | r_out_sum = radiusPlus1 * (pr = pixels[yi]); 266 | g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 267 | b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 268 | a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); 269 | 270 | r_sum += sumFactor * pr; 271 | g_sum += sumFactor * pg; 272 | b_sum += sumFactor * pb; 273 | a_sum += sumFactor * pa; 274 | 275 | stack = stackStart; 276 | 277 | for (i = 0; i < radiusPlus1; i++) { 278 | stack.r = pr; 279 | stack.g = pg; 280 | stack.b = pb; 281 | stack.a = pa; 282 | stack = stack.next; 283 | } 284 | 285 | yp = width; 286 | 287 | for (i = 1; i <= radius; i++) { 288 | yi = (yp + x) << 2; 289 | 290 | r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i); 291 | g_sum += (stack.g = (pg = pixels[yi + 1])) * rbs; 292 | b_sum += (stack.b = (pb = pixels[yi + 2])) * rbs; 293 | a_sum += (stack.a = (pa = pixels[yi + 3])) * rbs; 294 | 295 | r_in_sum += pr; 296 | g_in_sum += pg; 297 | b_in_sum += pb; 298 | a_in_sum += pa; 299 | 300 | stack = stack.next; 301 | 302 | if (i < heightMinus1) { 303 | yp += width; 304 | } 305 | } 306 | 307 | yi = x; 308 | stackIn = stackStart; 309 | stackOut = stackEnd; 310 | for (y = 0; y < height; y++) { 311 | p = yi << 2; 312 | pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum; 313 | if (pa > 0) { 314 | pa = 255 / pa; 315 | pixels[p] = ((r_sum * mul_sum) >> shg_sum) * pa; 316 | pixels[p + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; 317 | pixels[p + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; 318 | } else { 319 | pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; 320 | } 321 | 322 | r_sum -= r_out_sum; 323 | g_sum -= g_out_sum; 324 | b_sum -= b_out_sum; 325 | a_sum -= a_out_sum; 326 | 327 | r_out_sum -= stackIn.r; 328 | g_out_sum -= stackIn.g; 329 | b_out_sum -= stackIn.b; 330 | a_out_sum -= stackIn.a; 331 | 332 | p = (x + (((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width)) << 2; 333 | 334 | r_sum += (r_in_sum += (stackIn.r = pixels[p])); 335 | g_sum += (g_in_sum += (stackIn.g = pixels[p + 1])); 336 | b_sum += (b_in_sum += (stackIn.b = pixels[p + 2])); 337 | a_sum += (a_in_sum += (stackIn.a = pixels[p + 3])); 338 | 339 | stackIn = stackIn.next; 340 | 341 | r_out_sum += (pr = stackOut.r); 342 | g_out_sum += (pg = stackOut.g); 343 | b_out_sum += (pb = stackOut.b); 344 | a_out_sum += (pa = stackOut.a); 345 | 346 | r_in_sum -= pr; 347 | g_in_sum -= pg; 348 | b_in_sum -= pb; 349 | a_in_sum -= pa; 350 | 351 | stackOut = stackOut.next; 352 | 353 | yi += width; 354 | } 355 | } 356 | 357 | context.putImageData(imageData, top_x, top_y); 358 | 359 | } 360 | 361 | 362 | function stackBlurCanvasRGB(id, top_x, top_y, width, height, radius) { 363 | if (isNaN(radius) || radius < 1) return; 364 | radius |= 0; 365 | 366 | var canvas; 367 | if( typeof( id ) === 'string ') { 368 | canvas = document.getElementById(id); 369 | } else { 370 | canvas = id; 371 | } 372 | var context = canvas.getContext("2d"); 373 | var imageData; 374 | 375 | try { 376 | try { 377 | imageData = context.getImageData(top_x, top_y, width, height); 378 | } catch (e) { 379 | 380 | // NOTE: this part is supposedly only needed if you want to work with local files 381 | // so it might be okay to remove the whole try/catch block and just use 382 | // imageData = context.getImageData( top_x, top_y, width, height ); 383 | try { 384 | netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); 385 | imageData = context.getImageData(top_x, top_y, width, height); 386 | } catch (e) { 387 | alert("Cannot access local image"); 388 | throw new Error("unable to access local image data: " + e); 389 | return; 390 | } 391 | } 392 | } catch (e) { 393 | alert("Cannot access image"); 394 | throw new Error("unable to access image data: " + e); 395 | } 396 | 397 | var pixels = imageData.data; 398 | 399 | var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, 400 | r_out_sum, g_out_sum, b_out_sum, 401 | r_in_sum, g_in_sum, b_in_sum, 402 | pr, pg, pb, rbs; 403 | 404 | var div = radius + radius + 1; 405 | var w4 = width << 2; 406 | var widthMinus1 = width - 1; 407 | var heightMinus1 = height - 1; 408 | var radiusPlus1 = radius + 1; 409 | var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; 410 | 411 | var stackStart = new BlurStack(); 412 | var stack = stackStart; 413 | for (i = 1; i < div; i++) { 414 | stack = stack.next = new BlurStack(); 415 | if (i == radiusPlus1) var stackEnd = stack; 416 | } 417 | stack.next = stackStart; 418 | var stackIn = null; 419 | var stackOut = null; 420 | 421 | yw = yi = 0; 422 | 423 | var mul_sum = mul_table[radius]; 424 | var shg_sum = shg_table[radius]; 425 | 426 | for (y = 0; y < height; y++) { 427 | r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0; 428 | 429 | r_out_sum = radiusPlus1 * (pr = pixels[yi]); 430 | g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 431 | b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 432 | 433 | r_sum += sumFactor * pr; 434 | g_sum += sumFactor * pg; 435 | b_sum += sumFactor * pb; 436 | 437 | stack = stackStart; 438 | 439 | for (i = 0; i < radiusPlus1; i++) { 440 | stack.r = pr; 441 | stack.g = pg; 442 | stack.b = pb; 443 | stack = stack.next; 444 | } 445 | 446 | for (i = 1; i < radiusPlus1; i++) { 447 | p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); 448 | r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i); 449 | g_sum += (stack.g = (pg = pixels[p + 1])) * rbs; 450 | b_sum += (stack.b = (pb = pixels[p + 2])) * rbs; 451 | 452 | r_in_sum += pr; 453 | g_in_sum += pg; 454 | b_in_sum += pb; 455 | 456 | stack = stack.next; 457 | } 458 | 459 | 460 | stackIn = stackStart; 461 | stackOut = stackEnd; 462 | for (x = 0; x < width; x++) { 463 | pixels[yi] = (r_sum * mul_sum) >> shg_sum; 464 | pixels[yi + 1] = (g_sum * mul_sum) >> shg_sum; 465 | pixels[yi + 2] = (b_sum * mul_sum) >> shg_sum; 466 | 467 | r_sum -= r_out_sum; 468 | g_sum -= g_out_sum; 469 | b_sum -= b_out_sum; 470 | 471 | r_out_sum -= stackIn.r; 472 | g_out_sum -= stackIn.g; 473 | b_out_sum -= stackIn.b; 474 | 475 | p = (yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1)) << 2; 476 | 477 | r_in_sum += (stackIn.r = pixels[p]); 478 | g_in_sum += (stackIn.g = pixels[p + 1]); 479 | b_in_sum += (stackIn.b = pixels[p + 2]); 480 | 481 | r_sum += r_in_sum; 482 | g_sum += g_in_sum; 483 | b_sum += b_in_sum; 484 | 485 | stackIn = stackIn.next; 486 | 487 | r_out_sum += (pr = stackOut.r); 488 | g_out_sum += (pg = stackOut.g); 489 | b_out_sum += (pb = stackOut.b); 490 | 491 | r_in_sum -= pr; 492 | g_in_sum -= pg; 493 | b_in_sum -= pb; 494 | 495 | stackOut = stackOut.next; 496 | 497 | yi += 4; 498 | } 499 | yw += width; 500 | } 501 | 502 | 503 | for (x = 0; x < width; x++) { 504 | g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0; 505 | 506 | yi = x << 2; 507 | r_out_sum = radiusPlus1 * (pr = pixels[yi]); 508 | g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 509 | b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 510 | 511 | r_sum += sumFactor * pr; 512 | g_sum += sumFactor * pg; 513 | b_sum += sumFactor * pb; 514 | 515 | stack = stackStart; 516 | 517 | for (i = 0; i < radiusPlus1; i++) { 518 | stack.r = pr; 519 | stack.g = pg; 520 | stack.b = pb; 521 | stack = stack.next; 522 | } 523 | 524 | yp = width; 525 | 526 | for (i = 1; i <= radius; i++) { 527 | yi = (yp + x) << 2; 528 | 529 | r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i); 530 | g_sum += (stack.g = (pg = pixels[yi + 1])) * rbs; 531 | b_sum += (stack.b = (pb = pixels[yi + 2])) * rbs; 532 | 533 | r_in_sum += pr; 534 | g_in_sum += pg; 535 | b_in_sum += pb; 536 | 537 | stack = stack.next; 538 | 539 | if (i < heightMinus1) { 540 | yp += width; 541 | } 542 | } 543 | 544 | yi = x; 545 | stackIn = stackStart; 546 | stackOut = stackEnd; 547 | for (y = 0; y < height; y++) { 548 | p = yi << 2; 549 | pixels[p] = (r_sum * mul_sum) >> shg_sum; 550 | pixels[p + 1] = (g_sum * mul_sum) >> shg_sum; 551 | pixels[p + 2] = (b_sum * mul_sum) >> shg_sum; 552 | 553 | r_sum -= r_out_sum; 554 | g_sum -= g_out_sum; 555 | b_sum -= b_out_sum; 556 | 557 | r_out_sum -= stackIn.r; 558 | g_out_sum -= stackIn.g; 559 | b_out_sum -= stackIn.b; 560 | 561 | p = (x + (((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width)) << 2; 562 | 563 | r_sum += (r_in_sum += (stackIn.r = pixels[p])); 564 | g_sum += (g_in_sum += (stackIn.g = pixels[p + 1])); 565 | b_sum += (b_in_sum += (stackIn.b = pixels[p + 2])); 566 | 567 | stackIn = stackIn.next; 568 | 569 | r_out_sum += (pr = stackOut.r); 570 | g_out_sum += (pg = stackOut.g); 571 | b_out_sum += (pb = stackOut.b); 572 | 573 | r_in_sum -= pr; 574 | g_in_sum -= pg; 575 | b_in_sum -= pb; 576 | 577 | stackOut = stackOut.next; 578 | 579 | yi += width; 580 | } 581 | } 582 | 583 | context.putImageData(imageData, top_x, top_y); 584 | 585 | } 586 | 587 | function BlurStack() { 588 | this.r = 0; 589 | this.g = 0; 590 | this.b = 0; 591 | this.a = 0; 592 | this.next = null; 593 | } -------------------------------------------------------------------------------- /js/THREE.OBJExporter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | THREE.OBJExporter = function () {}; 6 | 7 | THREE.OBJExporter.prototype = { 8 | 9 | constructor: THREE.OBJExporter, 10 | 11 | parse: function ( geometry, addMaterial ) { 12 | 13 | var output = ''; 14 | 15 | if( addMaterial ) output += 'mtllib model.mtl\ng default\n'; 16 | 17 | for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) { 18 | 19 | var vertex = geometry.vertices[ i ]; 20 | output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; 21 | 22 | } 23 | 24 | // uvs 25 | 26 | for ( var i = 0, l = geometry.faceVertexUvs[ 0 ].length; i < l; i ++ ) { 27 | 28 | var vertexUvs = geometry.faceVertexUvs[ 0 ][ i ]; 29 | 30 | for ( var j = 0; j < vertexUvs.length; j ++ ) { 31 | 32 | var uv = vertexUvs[ j ]; 33 | output += 'vt ' + uv.x + ' ' + uv.y + '\n'; 34 | 35 | } 36 | 37 | } 38 | 39 | // normals 40 | 41 | for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) { 42 | 43 | var normals = geometry.faces[ i ].vertexNormals; 44 | 45 | for ( var j = 0; j < normals.length; j ++ ) { 46 | 47 | var normal = normals[ j ]; 48 | output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; 49 | 50 | } 51 | 52 | } 53 | 54 | if( addMaterial ) output += 's off\ng Mesh\nusemtl initialShadingGroup\n'; 55 | 56 | // faces 57 | 58 | for ( var i = 0, j = 1, l = geometry.faces.length; i < l; i ++, j += 3 ) { 59 | 60 | var face = geometry.faces[ i ]; 61 | 62 | output += 'f '; 63 | output += ( face.a + 1 ) + '/' + ( j ) + '/' + ( j ) + ' '; 64 | output += ( face.b + 1 ) + '/' + ( j + 1 ) + '/' + ( j + 1 ) + ' '; 65 | output += ( face.c + 1 ) + '/' + ( j + 2 ) + '/' + ( j + 2 ) + '\n'; 66 | 67 | } 68 | 69 | return output; 70 | 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /js/zip/inflate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* 30 | * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc. 31 | * JZlib is based on zlib-1.1.3, so all credit should go authors 32 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 33 | * and contributors of zlib. 34 | */ 35 | 36 | (function(obj) { 37 | 38 | // Global 39 | var MAX_BITS = 15; 40 | 41 | var Z_OK = 0; 42 | var Z_STREAM_END = 1; 43 | var Z_NEED_DICT = 2; 44 | var Z_STREAM_ERROR = -2; 45 | var Z_DATA_ERROR = -3; 46 | var Z_MEM_ERROR = -4; 47 | var Z_BUF_ERROR = -5; 48 | 49 | var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 50 | 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ]; 51 | 52 | var MANY = 1440; 53 | 54 | // JZlib version : "1.0.2" 55 | var Z_NO_FLUSH = 0; 56 | var Z_FINISH = 4; 57 | 58 | // InfTree 59 | var fixed_bl = 9; 60 | var fixed_bd = 5; 61 | 62 | var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 63 | 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 64 | 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 65 | 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 66 | 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 67 | 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 68 | 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 69 | 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 70 | 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 71 | 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 72 | 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 73 | 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 74 | 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 75 | 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 76 | 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 77 | 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 78 | 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 79 | 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 80 | 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 81 | 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 82 | 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 83 | 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 84 | 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 85 | 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 86 | 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 87 | 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 88 | 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 89 | 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 90 | 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 91 | 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 92 | 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 93 | 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 94 | 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 95 | 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 96 | 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 97 | 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 98 | 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ]; 99 | var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 100 | 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 101 | 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ]; 102 | 103 | // Tables for deflate from PKZIP's appnote.txt. 104 | var cplens = [ // Copy lengths for literal codes 257..285 105 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ]; 106 | 107 | // see note #13 above about 258 108 | var cplext = [ // Extra bits for literal codes 257..285 109 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid 110 | ]; 111 | 112 | var cpdist = [ // Copy offsets for distance codes 0..29 113 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; 114 | 115 | var cpdext = [ // Extra bits for distance codes 116 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ]; 117 | 118 | // If BMAX needs to be larger than 16, then h and x[] should be uLong. 119 | var BMAX = 15; // maximum bit length of any code 120 | 121 | function InfTree() { 122 | var that = this; 123 | 124 | var hn; // hufts used in space 125 | var v; // work area for huft_build 126 | var c; // bit length count table 127 | var r; // table entry for structure assignment 128 | var u; // table stack 129 | var x; // bit offsets, then code stack 130 | 131 | function huft_build(b, // code lengths in bits (all assumed <= 132 | // BMAX) 133 | bindex, n, // number of codes (assumed <= 288) 134 | s, // number of simple-valued codes (0..s-1) 135 | d, // list of base values for non-simple codes 136 | e, // list of extra bits for non-simple codes 137 | t, // result: starting table 138 | m, // maximum lookup bits, returns actual 139 | hp,// space for trees 140 | hn,// hufts used in space 141 | v // working area: values in order of bit length 142 | ) { 143 | // Given a list of code lengths and a maximum table size, make a set of 144 | // tables to decode that set of codes. Return Z_OK on success, 145 | // Z_BUF_ERROR 146 | // if the given code set is incomplete (the tables are still built in 147 | // this 148 | // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set 149 | // of 150 | // lengths), or Z_MEM_ERROR if not enough memory. 151 | 152 | var a; // counter for codes of length k 153 | var f; // i repeats in table every f entries 154 | var g; // maximum code length 155 | var h; // table level 156 | var i; // counter, current code 157 | var j; // counter 158 | var k; // number of bits in current code 159 | var l; // bits per table (returned in m) 160 | var mask; // (1 << w) - 1, to avoid cc -O bug on HP 161 | var p; // pointer into c[], b[], or v[] 162 | var q; // points to current table 163 | var w; // bits before this table == (l * h) 164 | var xp; // pointer into x 165 | var y; // number of dummy codes added 166 | var z; // number of entries in current table 167 | 168 | // Generate counts for each bit length 169 | 170 | p = 0; 171 | i = n; 172 | do { 173 | c[b[bindex + p]]++; 174 | p++; 175 | i--; // assume all entries <= BMAX 176 | } while (i !== 0); 177 | 178 | if (c[0] == n) { // null input--all zero length codes 179 | t[0] = -1; 180 | m[0] = 0; 181 | return Z_OK; 182 | } 183 | 184 | // Find minimum and maximum length, bound *m by those 185 | l = m[0]; 186 | for (j = 1; j <= BMAX; j++) 187 | if (c[j] !== 0) 188 | break; 189 | k = j; // minimum code length 190 | if (l < j) { 191 | l = j; 192 | } 193 | for (i = BMAX; i !== 0; i--) { 194 | if (c[i] !== 0) 195 | break; 196 | } 197 | g = i; // maximum code length 198 | if (l > i) { 199 | l = i; 200 | } 201 | m[0] = l; 202 | 203 | // Adjust last length count to fill out codes, if needed 204 | for (y = 1 << j; j < i; j++, y <<= 1) { 205 | if ((y -= c[j]) < 0) { 206 | return Z_DATA_ERROR; 207 | } 208 | } 209 | if ((y -= c[i]) < 0) { 210 | return Z_DATA_ERROR; 211 | } 212 | c[i] += y; 213 | 214 | // Generate starting offsets into the value table for each length 215 | x[1] = j = 0; 216 | p = 1; 217 | xp = 2; 218 | while (--i !== 0) { // note that i == g from above 219 | x[xp] = (j += c[p]); 220 | xp++; 221 | p++; 222 | } 223 | 224 | // Make a table of values in order of bit lengths 225 | i = 0; 226 | p = 0; 227 | do { 228 | if ((j = b[bindex + p]) !== 0) { 229 | v[x[j]++] = i; 230 | } 231 | p++; 232 | } while (++i < n); 233 | n = x[g]; // set n to length of v 234 | 235 | // Generate the Huffman codes and for each, make the table entries 236 | x[0] = i = 0; // first Huffman code is zero 237 | p = 0; // grab values in bit order 238 | h = -1; // no tables yet--level -1 239 | w = -l; // bits decoded == (l * h) 240 | u[0] = 0; // just to keep compilers happy 241 | q = 0; // ditto 242 | z = 0; // ditto 243 | 244 | // go through the bit lengths (k already is bits in shortest code) 245 | for (; k <= g; k++) { 246 | a = c[k]; 247 | while (a-- !== 0) { 248 | // here i is the Huffman code of length k bits for value *p 249 | // make tables up to required level 250 | while (k > w + l) { 251 | h++; 252 | w += l; // previous table always l bits 253 | // compute minimum size table less than or equal to l bits 254 | z = g - w; 255 | z = (z > l) ? l : z; // table size upper limit 256 | if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table 257 | // too few codes for 258 | // k-w bit table 259 | f -= a + 1; // deduct codes from patterns left 260 | xp = k; 261 | if (j < z) { 262 | while (++j < z) { // try smaller tables up to z bits 263 | if ((f <<= 1) <= c[++xp]) 264 | break; // enough codes to use up j bits 265 | f -= c[xp]; // else deduct codes from patterns 266 | } 267 | } 268 | } 269 | z = 1 << j; // table entries for j-bit table 270 | 271 | // allocate new table 272 | if (hn[0] + z > MANY) { // (note: doesn't matter for fixed) 273 | return Z_DATA_ERROR; // overflow of MANY 274 | } 275 | u[h] = q = /* hp+ */hn[0]; // DEBUG 276 | hn[0] += z; 277 | 278 | // connect to last table, if there is one 279 | if (h !== 0) { 280 | x[h] = i; // save pattern for backing up 281 | r[0] = /* (byte) */j; // bits in this table 282 | r[1] = /* (byte) */l; // bits to dump before this table 283 | j = i >>> (w - l); 284 | r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table 285 | hp.set(r, (u[h - 1] + j) * 3); 286 | // to 287 | // last 288 | // table 289 | } else { 290 | t[0] = q; // first table is returned result 291 | } 292 | } 293 | 294 | // set up table entry in r 295 | r[1] = /* (byte) */(k - w); 296 | if (p >= n) { 297 | r[0] = 128 + 64; // out of values--invalid code 298 | } else if (v[p] < s) { 299 | r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is 300 | // end-of-block 301 | r[2] = v[p++]; // simple code is just the value 302 | } else { 303 | r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look 304 | // up in lists 305 | r[2] = d[v[p++] - s]; 306 | } 307 | 308 | // fill code-like entries with r 309 | f = 1 << (k - w); 310 | for (j = i >>> w; j < z; j += f) { 311 | hp.set(r, (q + j) * 3); 312 | } 313 | 314 | // backwards increment the k-bit code i 315 | for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) { 316 | i ^= j; 317 | } 318 | i ^= j; 319 | 320 | // backup over finished tables 321 | mask = (1 << w) - 1; // needed on HP, cc -O bug 322 | while ((i & mask) != x[h]) { 323 | h--; // don't need to update q 324 | w -= l; 325 | mask = (1 << w) - 1; 326 | } 327 | } 328 | } 329 | // Return Z_BUF_ERROR if we were given an incomplete table 330 | return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK; 331 | } 332 | 333 | function initWorkArea(vsize) { 334 | var i; 335 | if (!hn) { 336 | hn = []; // []; //new Array(1); 337 | v = []; // new Array(vsize); 338 | c = new Int32Array(BMAX + 1); // new Array(BMAX + 1); 339 | r = []; // new Array(3); 340 | u = new Int32Array(BMAX); // new Array(BMAX); 341 | x = new Int32Array(BMAX + 1); // new Array(BMAX + 1); 342 | } 343 | if (v.length < vsize) { 344 | v = []; // new Array(vsize); 345 | } 346 | for (i = 0; i < vsize; i++) { 347 | v[i] = 0; 348 | } 349 | for (i = 0; i < BMAX + 1; i++) { 350 | c[i] = 0; 351 | } 352 | for (i = 0; i < 3; i++) { 353 | r[i] = 0; 354 | } 355 | // for(int i=0; i 257)) { 412 | if (result == Z_DATA_ERROR) { 413 | z.msg = "oversubscribed distance tree"; 414 | } else if (result == Z_BUF_ERROR) { 415 | z.msg = "incomplete distance tree"; 416 | result = Z_DATA_ERROR; 417 | } else if (result != Z_MEM_ERROR) { 418 | z.msg = "empty distance tree with lengths"; 419 | result = Z_DATA_ERROR; 420 | } 421 | return result; 422 | } 423 | 424 | return Z_OK; 425 | }; 426 | 427 | } 428 | 429 | InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth 430 | bd, // distance desired/actual bit depth 431 | tl,// literal/length tree result 432 | td// distance tree result 433 | ) { 434 | bl[0] = fixed_bl; 435 | bd[0] = fixed_bd; 436 | tl[0] = fixed_tl; 437 | td[0] = fixed_td; 438 | return Z_OK; 439 | }; 440 | 441 | // InfCodes 442 | 443 | // waiting for "i:"=input, 444 | // "o:"=output, 445 | // "x:"=nothing 446 | var START = 0; // x: set up for LEN 447 | var LEN = 1; // i: get length/literal/eob next 448 | var LENEXT = 2; // i: getting length extra (have base) 449 | var DIST = 3; // i: get distance next 450 | var DISTEXT = 4;// i: getting distance extra 451 | var COPY = 5; // o: copying bytes in window, waiting 452 | // for space 453 | var LIT = 6; // o: got literal, waiting for output 454 | // space 455 | var WASH = 7; // o: got eob, possibly still output 456 | // waiting 457 | var END = 8; // x: got eob and all data flushed 458 | var BADCODE = 9;// x: got error 459 | 460 | function InfCodes() { 461 | var that = this; 462 | 463 | var mode; // current inflate_codes mode 464 | 465 | // mode dependent information 466 | var len = 0; 467 | 468 | var tree; // pointer into tree 469 | var tree_index = 0; 470 | var need = 0; // bits needed 471 | 472 | var lit = 0; 473 | 474 | // if EXT or COPY, where and how much 475 | var get = 0; // bits to get for extra 476 | var dist = 0; // distance back to copy from 477 | 478 | var lbits = 0; // ltree bits decoded per branch 479 | var dbits = 0; // dtree bits decoder per branch 480 | var ltree; // literal/length/eob tree 481 | var ltree_index = 0; // literal/length/eob tree 482 | var dtree; // distance tree 483 | var dtree_index = 0; // distance tree 484 | 485 | // Called with number of bytes left to write in window at least 258 486 | // (the maximum string length) and number of input bytes available 487 | // at least ten. The ten bytes are six bytes for the longest length/ 488 | // distance pair plus four bytes for overloading the bit buffer. 489 | 490 | function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) { 491 | var t; // temporary pointer 492 | var tp; // temporary pointer 493 | var tp_index; // temporary pointer 494 | var e; // extra bits or operation 495 | var b; // bit buffer 496 | var k; // bits in bit buffer 497 | var p; // input data pointer 498 | var n; // bytes available there 499 | var q; // output window write pointer 500 | var m; // bytes to end of window or read pointer 501 | var ml; // mask for literal/length tree 502 | var md; // mask for distance tree 503 | var c; // bytes to copy 504 | var d; // distance back to copy from 505 | var r; // copy source pointer 506 | 507 | var tp_index_t_3; // (tp_index+t)*3 508 | 509 | // load input, output, bit values 510 | p = z.next_in_index; 511 | n = z.avail_in; 512 | b = s.bitb; 513 | k = s.bitk; 514 | q = s.write; 515 | m = q < s.read ? s.read - q - 1 : s.end - q; 516 | 517 | // initialize masks 518 | ml = inflate_mask[bl]; 519 | md = inflate_mask[bd]; 520 | 521 | // do until not enough input or output space for fast loop 522 | do { // assume called with m >= 258 && n >= 10 523 | // get literal/length code 524 | while (k < (20)) { // max bits for literal/length code 525 | n--; 526 | b |= (z.read_byte(p++) & 0xff) << k; 527 | k += 8; 528 | } 529 | 530 | t = b & ml; 531 | tp = tl; 532 | tp_index = tl_index; 533 | tp_index_t_3 = (tp_index + t) * 3; 534 | if ((e = tp[tp_index_t_3]) === 0) { 535 | b >>= (tp[tp_index_t_3 + 1]); 536 | k -= (tp[tp_index_t_3 + 1]); 537 | 538 | s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2]; 539 | m--; 540 | continue; 541 | } 542 | do { 543 | 544 | b >>= (tp[tp_index_t_3 + 1]); 545 | k -= (tp[tp_index_t_3 + 1]); 546 | 547 | if ((e & 16) !== 0) { 548 | e &= 15; 549 | c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]); 550 | 551 | b >>= e; 552 | k -= e; 553 | 554 | // decode distance base of block to copy 555 | while (k < (15)) { // max bits for distance code 556 | n--; 557 | b |= (z.read_byte(p++) & 0xff) << k; 558 | k += 8; 559 | } 560 | 561 | t = b & md; 562 | tp = td; 563 | tp_index = td_index; 564 | tp_index_t_3 = (tp_index + t) * 3; 565 | e = tp[tp_index_t_3]; 566 | 567 | do { 568 | 569 | b >>= (tp[tp_index_t_3 + 1]); 570 | k -= (tp[tp_index_t_3 + 1]); 571 | 572 | if ((e & 16) !== 0) { 573 | // get extra bits to add to distance base 574 | e &= 15; 575 | while (k < (e)) { // get extra bits (up to 13) 576 | n--; 577 | b |= (z.read_byte(p++) & 0xff) << k; 578 | k += 8; 579 | } 580 | 581 | d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); 582 | 583 | b >>= (e); 584 | k -= (e); 585 | 586 | // do the copy 587 | m -= c; 588 | if (q >= d) { // offset before dest 589 | // just copy 590 | r = q - d; 591 | if (q - r > 0 && 2 > (q - r)) { 592 | s.window[q++] = s.window[r++]; // minimum 593 | // count is 594 | // three, 595 | s.window[q++] = s.window[r++]; // so unroll 596 | // loop a 597 | // little 598 | c -= 2; 599 | } else { 600 | s.window.set(s.window.subarray(r, r + 2), q); 601 | q += 2; 602 | r += 2; 603 | c -= 2; 604 | } 605 | } else { // else offset after destination 606 | r = q - d; 607 | do { 608 | r += s.end; // force pointer in window 609 | } while (r < 0); // covers invalid distances 610 | e = s.end - r; 611 | if (c > e) { // if source crosses, 612 | c -= e; // wrapped copy 613 | if (q - r > 0 && e > (q - r)) { 614 | do { 615 | s.window[q++] = s.window[r++]; 616 | } while (--e !== 0); 617 | } else { 618 | s.window.set(s.window.subarray(r, r + e), q); 619 | q += e; 620 | r += e; 621 | e = 0; 622 | } 623 | r = 0; // copy rest from start of window 624 | } 625 | 626 | } 627 | 628 | // copy all or what's left 629 | if (q - r > 0 && c > (q - r)) { 630 | do { 631 | s.window[q++] = s.window[r++]; 632 | } while (--c !== 0); 633 | } else { 634 | s.window.set(s.window.subarray(r, r + c), q); 635 | q += c; 636 | r += c; 637 | c = 0; 638 | } 639 | break; 640 | } else if ((e & 64) === 0) { 641 | t += tp[tp_index_t_3 + 2]; 642 | t += (b & inflate_mask[e]); 643 | tp_index_t_3 = (tp_index + t) * 3; 644 | e = tp[tp_index_t_3]; 645 | } else { 646 | z.msg = "invalid distance code"; 647 | 648 | c = z.avail_in - n; 649 | c = (k >> 3) < c ? k >> 3 : c; 650 | n += c; 651 | p -= c; 652 | k -= c << 3; 653 | 654 | s.bitb = b; 655 | s.bitk = k; 656 | z.avail_in = n; 657 | z.total_in += p - z.next_in_index; 658 | z.next_in_index = p; 659 | s.write = q; 660 | 661 | return Z_DATA_ERROR; 662 | } 663 | } while (true); 664 | break; 665 | } 666 | 667 | if ((e & 64) === 0) { 668 | t += tp[tp_index_t_3 + 2]; 669 | t += (b & inflate_mask[e]); 670 | tp_index_t_3 = (tp_index + t) * 3; 671 | if ((e = tp[tp_index_t_3]) === 0) { 672 | 673 | b >>= (tp[tp_index_t_3 + 1]); 674 | k -= (tp[tp_index_t_3 + 1]); 675 | 676 | s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2]; 677 | m--; 678 | break; 679 | } 680 | } else if ((e & 32) !== 0) { 681 | 682 | c = z.avail_in - n; 683 | c = (k >> 3) < c ? k >> 3 : c; 684 | n += c; 685 | p -= c; 686 | k -= c << 3; 687 | 688 | s.bitb = b; 689 | s.bitk = k; 690 | z.avail_in = n; 691 | z.total_in += p - z.next_in_index; 692 | z.next_in_index = p; 693 | s.write = q; 694 | 695 | return Z_STREAM_END; 696 | } else { 697 | z.msg = "invalid literal/length code"; 698 | 699 | c = z.avail_in - n; 700 | c = (k >> 3) < c ? k >> 3 : c; 701 | n += c; 702 | p -= c; 703 | k -= c << 3; 704 | 705 | s.bitb = b; 706 | s.bitk = k; 707 | z.avail_in = n; 708 | z.total_in += p - z.next_in_index; 709 | z.next_in_index = p; 710 | s.write = q; 711 | 712 | return Z_DATA_ERROR; 713 | } 714 | } while (true); 715 | } while (m >= 258 && n >= 10); 716 | 717 | // not enough input or output--restore pointers and return 718 | c = z.avail_in - n; 719 | c = (k >> 3) < c ? k >> 3 : c; 720 | n += c; 721 | p -= c; 722 | k -= c << 3; 723 | 724 | s.bitb = b; 725 | s.bitk = k; 726 | z.avail_in = n; 727 | z.total_in += p - z.next_in_index; 728 | z.next_in_index = p; 729 | s.write = q; 730 | 731 | return Z_OK; 732 | } 733 | 734 | that.init = function(bl, bd, tl, tl_index, td, td_index) { 735 | mode = START; 736 | lbits = /* (byte) */bl; 737 | dbits = /* (byte) */bd; 738 | ltree = tl; 739 | ltree_index = tl_index; 740 | dtree = td; 741 | dtree_index = td_index; 742 | tree = null; 743 | }; 744 | 745 | that.proc = function(s, z, r) { 746 | var j; // temporary storage 747 | var tindex; // temporary pointer 748 | var e; // extra bits or operation 749 | var b = 0; // bit buffer 750 | var k = 0; // bits in bit buffer 751 | var p = 0; // input data pointer 752 | var n; // bytes available there 753 | var q; // output window write pointer 754 | var m; // bytes to end of window or read pointer 755 | var f; // pointer to copy strings from 756 | 757 | // copy input/output information to locals (UPDATE macro restores) 758 | p = z.next_in_index; 759 | n = z.avail_in; 760 | b = s.bitb; 761 | k = s.bitk; 762 | q = s.write; 763 | m = q < s.read ? s.read - q - 1 : s.end - q; 764 | 765 | // process input and output based on current state 766 | while (true) { 767 | switch (mode) { 768 | // waiting for "i:"=input, "o:"=output, "x:"=nothing 769 | case START: // x: set up for LEN 770 | if (m >= 258 && n >= 10) { 771 | 772 | s.bitb = b; 773 | s.bitk = k; 774 | z.avail_in = n; 775 | z.total_in += p - z.next_in_index; 776 | z.next_in_index = p; 777 | s.write = q; 778 | r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); 779 | 780 | p = z.next_in_index; 781 | n = z.avail_in; 782 | b = s.bitb; 783 | k = s.bitk; 784 | q = s.write; 785 | m = q < s.read ? s.read - q - 1 : s.end - q; 786 | 787 | if (r != Z_OK) { 788 | mode = r == Z_STREAM_END ? WASH : BADCODE; 789 | break; 790 | } 791 | } 792 | need = lbits; 793 | tree = ltree; 794 | tree_index = ltree_index; 795 | 796 | mode = LEN; 797 | case LEN: // i: get length/literal/eob next 798 | j = need; 799 | 800 | while (k < (j)) { 801 | if (n !== 0) 802 | r = Z_OK; 803 | else { 804 | 805 | s.bitb = b; 806 | s.bitk = k; 807 | z.avail_in = n; 808 | z.total_in += p - z.next_in_index; 809 | z.next_in_index = p; 810 | s.write = q; 811 | return s.inflate_flush(z, r); 812 | } 813 | n--; 814 | b |= (z.read_byte(p++) & 0xff) << k; 815 | k += 8; 816 | } 817 | 818 | tindex = (tree_index + (b & inflate_mask[j])) * 3; 819 | 820 | b >>>= (tree[tindex + 1]); 821 | k -= (tree[tindex + 1]); 822 | 823 | e = tree[tindex]; 824 | 825 | if (e === 0) { // literal 826 | lit = tree[tindex + 2]; 827 | mode = LIT; 828 | break; 829 | } 830 | if ((e & 16) !== 0) { // length 831 | get = e & 15; 832 | len = tree[tindex + 2]; 833 | mode = LENEXT; 834 | break; 835 | } 836 | if ((e & 64) === 0) { // next table 837 | need = e; 838 | tree_index = tindex / 3 + tree[tindex + 2]; 839 | break; 840 | } 841 | if ((e & 32) !== 0) { // end of block 842 | mode = WASH; 843 | break; 844 | } 845 | mode = BADCODE; // invalid code 846 | z.msg = "invalid literal/length code"; 847 | r = Z_DATA_ERROR; 848 | 849 | s.bitb = b; 850 | s.bitk = k; 851 | z.avail_in = n; 852 | z.total_in += p - z.next_in_index; 853 | z.next_in_index = p; 854 | s.write = q; 855 | return s.inflate_flush(z, r); 856 | 857 | case LENEXT: // i: getting length extra (have base) 858 | j = get; 859 | 860 | while (k < (j)) { 861 | if (n !== 0) 862 | r = Z_OK; 863 | else { 864 | 865 | s.bitb = b; 866 | s.bitk = k; 867 | z.avail_in = n; 868 | z.total_in += p - z.next_in_index; 869 | z.next_in_index = p; 870 | s.write = q; 871 | return s.inflate_flush(z, r); 872 | } 873 | n--; 874 | b |= (z.read_byte(p++) & 0xff) << k; 875 | k += 8; 876 | } 877 | 878 | len += (b & inflate_mask[j]); 879 | 880 | b >>= j; 881 | k -= j; 882 | 883 | need = dbits; 884 | tree = dtree; 885 | tree_index = dtree_index; 886 | mode = DIST; 887 | case DIST: // i: get distance next 888 | j = need; 889 | 890 | while (k < (j)) { 891 | if (n !== 0) 892 | r = Z_OK; 893 | else { 894 | 895 | s.bitb = b; 896 | s.bitk = k; 897 | z.avail_in = n; 898 | z.total_in += p - z.next_in_index; 899 | z.next_in_index = p; 900 | s.write = q; 901 | return s.inflate_flush(z, r); 902 | } 903 | n--; 904 | b |= (z.read_byte(p++) & 0xff) << k; 905 | k += 8; 906 | } 907 | 908 | tindex = (tree_index + (b & inflate_mask[j])) * 3; 909 | 910 | b >>= tree[tindex + 1]; 911 | k -= tree[tindex + 1]; 912 | 913 | e = (tree[tindex]); 914 | if ((e & 16) !== 0) { // distance 915 | get = e & 15; 916 | dist = tree[tindex + 2]; 917 | mode = DISTEXT; 918 | break; 919 | } 920 | if ((e & 64) === 0) { // next table 921 | need = e; 922 | tree_index = tindex / 3 + tree[tindex + 2]; 923 | break; 924 | } 925 | mode = BADCODE; // invalid code 926 | z.msg = "invalid distance code"; 927 | r = Z_DATA_ERROR; 928 | 929 | s.bitb = b; 930 | s.bitk = k; 931 | z.avail_in = n; 932 | z.total_in += p - z.next_in_index; 933 | z.next_in_index = p; 934 | s.write = q; 935 | return s.inflate_flush(z, r); 936 | 937 | case DISTEXT: // i: getting distance extra 938 | j = get; 939 | 940 | while (k < (j)) { 941 | if (n !== 0) 942 | r = Z_OK; 943 | else { 944 | 945 | s.bitb = b; 946 | s.bitk = k; 947 | z.avail_in = n; 948 | z.total_in += p - z.next_in_index; 949 | z.next_in_index = p; 950 | s.write = q; 951 | return s.inflate_flush(z, r); 952 | } 953 | n--; 954 | b |= (z.read_byte(p++) & 0xff) << k; 955 | k += 8; 956 | } 957 | 958 | dist += (b & inflate_mask[j]); 959 | 960 | b >>= j; 961 | k -= j; 962 | 963 | mode = COPY; 964 | case COPY: // o: copying bytes in window, waiting for space 965 | f = q - dist; 966 | while (f < 0) { // modulo window size-"while" instead 967 | f += s.end; // of "if" handles invalid distances 968 | } 969 | while (len !== 0) { 970 | 971 | if (m === 0) { 972 | if (q == s.end && s.read !== 0) { 973 | q = 0; 974 | m = q < s.read ? s.read - q - 1 : s.end - q; 975 | } 976 | if (m === 0) { 977 | s.write = q; 978 | r = s.inflate_flush(z, r); 979 | q = s.write; 980 | m = q < s.read ? s.read - q - 1 : s.end - q; 981 | 982 | if (q == s.end && s.read !== 0) { 983 | q = 0; 984 | m = q < s.read ? s.read - q - 1 : s.end - q; 985 | } 986 | 987 | if (m === 0) { 988 | s.bitb = b; 989 | s.bitk = k; 990 | z.avail_in = n; 991 | z.total_in += p - z.next_in_index; 992 | z.next_in_index = p; 993 | s.write = q; 994 | return s.inflate_flush(z, r); 995 | } 996 | } 997 | } 998 | 999 | s.window[q++] = s.window[f++]; 1000 | m--; 1001 | 1002 | if (f == s.end) 1003 | f = 0; 1004 | len--; 1005 | } 1006 | mode = START; 1007 | break; 1008 | case LIT: // o: got literal, waiting for output space 1009 | if (m === 0) { 1010 | if (q == s.end && s.read !== 0) { 1011 | q = 0; 1012 | m = q < s.read ? s.read - q - 1 : s.end - q; 1013 | } 1014 | if (m === 0) { 1015 | s.write = q; 1016 | r = s.inflate_flush(z, r); 1017 | q = s.write; 1018 | m = q < s.read ? s.read - q - 1 : s.end - q; 1019 | 1020 | if (q == s.end && s.read !== 0) { 1021 | q = 0; 1022 | m = q < s.read ? s.read - q - 1 : s.end - q; 1023 | } 1024 | if (m === 0) { 1025 | s.bitb = b; 1026 | s.bitk = k; 1027 | z.avail_in = n; 1028 | z.total_in += p - z.next_in_index; 1029 | z.next_in_index = p; 1030 | s.write = q; 1031 | return s.inflate_flush(z, r); 1032 | } 1033 | } 1034 | } 1035 | r = Z_OK; 1036 | 1037 | s.window[q++] = /* (byte) */lit; 1038 | m--; 1039 | 1040 | mode = START; 1041 | break; 1042 | case WASH: // o: got eob, possibly more output 1043 | if (k > 7) { // return unused byte, if any 1044 | k -= 8; 1045 | n++; 1046 | p--; // can always return one 1047 | } 1048 | 1049 | s.write = q; 1050 | r = s.inflate_flush(z, r); 1051 | q = s.write; 1052 | m = q < s.read ? s.read - q - 1 : s.end - q; 1053 | 1054 | if (s.read != s.write) { 1055 | s.bitb = b; 1056 | s.bitk = k; 1057 | z.avail_in = n; 1058 | z.total_in += p - z.next_in_index; 1059 | z.next_in_index = p; 1060 | s.write = q; 1061 | return s.inflate_flush(z, r); 1062 | } 1063 | mode = END; 1064 | case END: 1065 | r = Z_STREAM_END; 1066 | s.bitb = b; 1067 | s.bitk = k; 1068 | z.avail_in = n; 1069 | z.total_in += p - z.next_in_index; 1070 | z.next_in_index = p; 1071 | s.write = q; 1072 | return s.inflate_flush(z, r); 1073 | 1074 | case BADCODE: // x: got error 1075 | 1076 | r = Z_DATA_ERROR; 1077 | 1078 | s.bitb = b; 1079 | s.bitk = k; 1080 | z.avail_in = n; 1081 | z.total_in += p - z.next_in_index; 1082 | z.next_in_index = p; 1083 | s.write = q; 1084 | return s.inflate_flush(z, r); 1085 | 1086 | default: 1087 | r = Z_STREAM_ERROR; 1088 | 1089 | s.bitb = b; 1090 | s.bitk = k; 1091 | z.avail_in = n; 1092 | z.total_in += p - z.next_in_index; 1093 | z.next_in_index = p; 1094 | s.write = q; 1095 | return s.inflate_flush(z, r); 1096 | } 1097 | } 1098 | }; 1099 | 1100 | that.free = function() { 1101 | // ZFREE(z, c); 1102 | }; 1103 | 1104 | } 1105 | 1106 | // InfBlocks 1107 | 1108 | // Table for deflate from PKZIP's appnote.txt. 1109 | var border = [ // Order of the bit length code lengths 1110 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; 1111 | 1112 | var TYPE = 0; // get type bits (3, including end bit) 1113 | var LENS = 1; // get lengths for stored 1114 | var STORED = 2;// processing stored block 1115 | var TABLE = 3; // get table lengths 1116 | var BTREE = 4; // get bit lengths tree for a dynamic 1117 | // block 1118 | var DTREE = 5; // get length, distance trees for a 1119 | // dynamic block 1120 | var CODES = 6; // processing fixed or dynamic block 1121 | var DRY = 7; // output remaining window bytes 1122 | var DONELOCKS = 8; // finished last block, done 1123 | var BADBLOCKS = 9; // ot a data error--stuck here 1124 | 1125 | function InfBlocks(z, w) { 1126 | var that = this; 1127 | 1128 | var mode = TYPE; // current inflate_block mode 1129 | 1130 | var left = 0; // if STORED, bytes left to copy 1131 | 1132 | var table = 0; // table lengths (14 bits) 1133 | var index = 0; // index into blens (or border) 1134 | var blens; // bit lengths of codes 1135 | var bb = [ 0 ]; // bit length tree depth 1136 | var tb = [ 0 ]; // bit length decoding tree 1137 | 1138 | var codes = new InfCodes(); // if CODES, current state 1139 | 1140 | var last = 0; // true if this block is the last block 1141 | 1142 | var hufts = new Int32Array(MANY * 3); // single malloc for tree space 1143 | var check = 0; // check on output 1144 | var inftree = new InfTree(); 1145 | 1146 | that.bitk = 0; // bits in bit buffer 1147 | that.bitb = 0; // bit buffer 1148 | that.window = new Uint8Array(w); // sliding window 1149 | that.end = w; // one byte after sliding window 1150 | that.read = 0; // window read pointer 1151 | that.write = 0; // window write pointer 1152 | 1153 | that.reset = function(z, c) { 1154 | if (c) 1155 | c[0] = check; 1156 | // if (mode == BTREE || mode == DTREE) { 1157 | // } 1158 | if (mode == CODES) { 1159 | codes.free(z); 1160 | } 1161 | mode = TYPE; 1162 | that.bitk = 0; 1163 | that.bitb = 0; 1164 | that.read = that.write = 0; 1165 | }; 1166 | 1167 | that.reset(z, null); 1168 | 1169 | // copy as much as possible from the sliding window to the output area 1170 | that.inflate_flush = function(z, r) { 1171 | var n; 1172 | var p; 1173 | var q; 1174 | 1175 | // local copies of source and destination pointers 1176 | p = z.next_out_index; 1177 | q = that.read; 1178 | 1179 | // compute number of bytes to copy as far as end of window 1180 | n = /* (int) */((q <= that.write ? that.write : that.end) - q); 1181 | if (n > z.avail_out) 1182 | n = z.avail_out; 1183 | if (n !== 0 && r == Z_BUF_ERROR) 1184 | r = Z_OK; 1185 | 1186 | // update counters 1187 | z.avail_out -= n; 1188 | z.total_out += n; 1189 | 1190 | // copy as far as end of window 1191 | z.next_out.set(that.window.subarray(q, q + n), p); 1192 | p += n; 1193 | q += n; 1194 | 1195 | // see if more to copy at beginning of window 1196 | if (q == that.end) { 1197 | // wrap pointers 1198 | q = 0; 1199 | if (that.write == that.end) 1200 | that.write = 0; 1201 | 1202 | // compute bytes to copy 1203 | n = that.write - q; 1204 | if (n > z.avail_out) 1205 | n = z.avail_out; 1206 | if (n !== 0 && r == Z_BUF_ERROR) 1207 | r = Z_OK; 1208 | 1209 | // update counters 1210 | z.avail_out -= n; 1211 | z.total_out += n; 1212 | 1213 | // copy 1214 | z.next_out.set(that.window.subarray(q, q + n), p); 1215 | p += n; 1216 | q += n; 1217 | } 1218 | 1219 | // update pointers 1220 | z.next_out_index = p; 1221 | that.read = q; 1222 | 1223 | // done 1224 | return r; 1225 | }; 1226 | 1227 | that.proc = function(z, r) { 1228 | var t; // temporary storage 1229 | var b; // bit buffer 1230 | var k; // bits in bit buffer 1231 | var p; // input data pointer 1232 | var n; // bytes available there 1233 | var q; // output window write pointer 1234 | var m; // bytes to end of window or read pointer 1235 | 1236 | var i; 1237 | 1238 | // copy input/output information to locals (UPDATE macro restores) 1239 | // { 1240 | p = z.next_in_index; 1241 | n = z.avail_in; 1242 | b = that.bitb; 1243 | k = that.bitk; 1244 | // } 1245 | // { 1246 | q = that.write; 1247 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1248 | // } 1249 | 1250 | // process input based on current state 1251 | // DEBUG dtree 1252 | while (true) { 1253 | switch (mode) { 1254 | case TYPE: 1255 | 1256 | while (k < (3)) { 1257 | if (n !== 0) { 1258 | r = Z_OK; 1259 | } else { 1260 | that.bitb = b; 1261 | that.bitk = k; 1262 | z.avail_in = n; 1263 | z.total_in += p - z.next_in_index; 1264 | z.next_in_index = p; 1265 | that.write = q; 1266 | return that.inflate_flush(z, r); 1267 | } 1268 | n--; 1269 | b |= (z.read_byte(p++) & 0xff) << k; 1270 | k += 8; 1271 | } 1272 | t = /* (int) */(b & 7); 1273 | last = t & 1; 1274 | 1275 | switch (t >>> 1) { 1276 | case 0: // stored 1277 | // { 1278 | b >>>= (3); 1279 | k -= (3); 1280 | // } 1281 | t = k & 7; // go to byte boundary 1282 | 1283 | // { 1284 | b >>>= (t); 1285 | k -= (t); 1286 | // } 1287 | mode = LENS; // get length of stored block 1288 | break; 1289 | case 1: // fixed 1290 | // { 1291 | var bl = []; // new Array(1); 1292 | var bd = []; // new Array(1); 1293 | var tl = [ [] ]; // new Array(1); 1294 | var td = [ [] ]; // new Array(1); 1295 | 1296 | InfTree.inflate_trees_fixed(bl, bd, tl, td); 1297 | codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); 1298 | // } 1299 | 1300 | // { 1301 | b >>>= (3); 1302 | k -= (3); 1303 | // } 1304 | 1305 | mode = CODES; 1306 | break; 1307 | case 2: // dynamic 1308 | 1309 | // { 1310 | b >>>= (3); 1311 | k -= (3); 1312 | // } 1313 | 1314 | mode = TABLE; 1315 | break; 1316 | case 3: // illegal 1317 | 1318 | // { 1319 | b >>>= (3); 1320 | k -= (3); 1321 | // } 1322 | mode = BADBLOCKS; 1323 | z.msg = "invalid block type"; 1324 | r = Z_DATA_ERROR; 1325 | 1326 | that.bitb = b; 1327 | that.bitk = k; 1328 | z.avail_in = n; 1329 | z.total_in += p - z.next_in_index; 1330 | z.next_in_index = p; 1331 | that.write = q; 1332 | return that.inflate_flush(z, r); 1333 | } 1334 | break; 1335 | case LENS: 1336 | 1337 | while (k < (32)) { 1338 | if (n !== 0) { 1339 | r = Z_OK; 1340 | } else { 1341 | that.bitb = b; 1342 | that.bitk = k; 1343 | z.avail_in = n; 1344 | z.total_in += p - z.next_in_index; 1345 | z.next_in_index = p; 1346 | that.write = q; 1347 | return that.inflate_flush(z, r); 1348 | } 1349 | n--; 1350 | b |= (z.read_byte(p++) & 0xff) << k; 1351 | k += 8; 1352 | } 1353 | 1354 | if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) { 1355 | mode = BADBLOCKS; 1356 | z.msg = "invalid stored block lengths"; 1357 | r = Z_DATA_ERROR; 1358 | 1359 | that.bitb = b; 1360 | that.bitk = k; 1361 | z.avail_in = n; 1362 | z.total_in += p - z.next_in_index; 1363 | z.next_in_index = p; 1364 | that.write = q; 1365 | return that.inflate_flush(z, r); 1366 | } 1367 | left = (b & 0xffff); 1368 | b = k = 0; // dump bits 1369 | mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE); 1370 | break; 1371 | case STORED: 1372 | if (n === 0) { 1373 | that.bitb = b; 1374 | that.bitk = k; 1375 | z.avail_in = n; 1376 | z.total_in += p - z.next_in_index; 1377 | z.next_in_index = p; 1378 | that.write = q; 1379 | return that.inflate_flush(z, r); 1380 | } 1381 | 1382 | if (m === 0) { 1383 | if (q == that.end && that.read !== 0) { 1384 | q = 0; 1385 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1386 | } 1387 | if (m === 0) { 1388 | that.write = q; 1389 | r = that.inflate_flush(z, r); 1390 | q = that.write; 1391 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1392 | if (q == that.end && that.read !== 0) { 1393 | q = 0; 1394 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1395 | } 1396 | if (m === 0) { 1397 | that.bitb = b; 1398 | that.bitk = k; 1399 | z.avail_in = n; 1400 | z.total_in += p - z.next_in_index; 1401 | z.next_in_index = p; 1402 | that.write = q; 1403 | return that.inflate_flush(z, r); 1404 | } 1405 | } 1406 | } 1407 | r = Z_OK; 1408 | 1409 | t = left; 1410 | if (t > n) 1411 | t = n; 1412 | if (t > m) 1413 | t = m; 1414 | that.window.set(z.read_buf(p, t), q); 1415 | p += t; 1416 | n -= t; 1417 | q += t; 1418 | m -= t; 1419 | if ((left -= t) !== 0) 1420 | break; 1421 | mode = last !== 0 ? DRY : TYPE; 1422 | break; 1423 | case TABLE: 1424 | 1425 | while (k < (14)) { 1426 | if (n !== 0) { 1427 | r = Z_OK; 1428 | } else { 1429 | that.bitb = b; 1430 | that.bitk = k; 1431 | z.avail_in = n; 1432 | z.total_in += p - z.next_in_index; 1433 | z.next_in_index = p; 1434 | that.write = q; 1435 | return that.inflate_flush(z, r); 1436 | } 1437 | 1438 | n--; 1439 | b |= (z.read_byte(p++) & 0xff) << k; 1440 | k += 8; 1441 | } 1442 | 1443 | table = t = (b & 0x3fff); 1444 | if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { 1445 | mode = BADBLOCKS; 1446 | z.msg = "too many length or distance symbols"; 1447 | r = Z_DATA_ERROR; 1448 | 1449 | that.bitb = b; 1450 | that.bitk = k; 1451 | z.avail_in = n; 1452 | z.total_in += p - z.next_in_index; 1453 | z.next_in_index = p; 1454 | that.write = q; 1455 | return that.inflate_flush(z, r); 1456 | } 1457 | t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); 1458 | if (!blens || blens.length < t) { 1459 | blens = []; // new Array(t); 1460 | } else { 1461 | for (i = 0; i < t; i++) { 1462 | blens[i] = 0; 1463 | } 1464 | } 1465 | 1466 | // { 1467 | b >>>= (14); 1468 | k -= (14); 1469 | // } 1470 | 1471 | index = 0; 1472 | mode = BTREE; 1473 | case BTREE: 1474 | while (index < 4 + (table >>> 10)) { 1475 | while (k < (3)) { 1476 | if (n !== 0) { 1477 | r = Z_OK; 1478 | } else { 1479 | that.bitb = b; 1480 | that.bitk = k; 1481 | z.avail_in = n; 1482 | z.total_in += p - z.next_in_index; 1483 | z.next_in_index = p; 1484 | that.write = q; 1485 | return that.inflate_flush(z, r); 1486 | } 1487 | n--; 1488 | b |= (z.read_byte(p++) & 0xff) << k; 1489 | k += 8; 1490 | } 1491 | 1492 | blens[border[index++]] = b & 7; 1493 | 1494 | // { 1495 | b >>>= (3); 1496 | k -= (3); 1497 | // } 1498 | } 1499 | 1500 | while (index < 19) { 1501 | blens[border[index++]] = 0; 1502 | } 1503 | 1504 | bb[0] = 7; 1505 | t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); 1506 | if (t != Z_OK) { 1507 | r = t; 1508 | if (r == Z_DATA_ERROR) { 1509 | blens = null; 1510 | mode = BADBLOCKS; 1511 | } 1512 | 1513 | that.bitb = b; 1514 | that.bitk = k; 1515 | z.avail_in = n; 1516 | z.total_in += p - z.next_in_index; 1517 | z.next_in_index = p; 1518 | that.write = q; 1519 | return that.inflate_flush(z, r); 1520 | } 1521 | 1522 | index = 0; 1523 | mode = DTREE; 1524 | case DTREE: 1525 | while (true) { 1526 | t = table; 1527 | if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { 1528 | break; 1529 | } 1530 | 1531 | var j, c; 1532 | 1533 | t = bb[0]; 1534 | 1535 | while (k < (t)) { 1536 | if (n !== 0) { 1537 | r = Z_OK; 1538 | } else { 1539 | that.bitb = b; 1540 | that.bitk = k; 1541 | z.avail_in = n; 1542 | z.total_in += p - z.next_in_index; 1543 | z.next_in_index = p; 1544 | that.write = q; 1545 | return that.inflate_flush(z, r); 1546 | } 1547 | n--; 1548 | b |= (z.read_byte(p++) & 0xff) << k; 1549 | k += 8; 1550 | } 1551 | 1552 | // if (tb[0] == -1) { 1553 | // System.err.println("null..."); 1554 | // } 1555 | 1556 | t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; 1557 | c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; 1558 | 1559 | if (c < 16) { 1560 | b >>>= (t); 1561 | k -= (t); 1562 | blens[index++] = c; 1563 | } else { // c == 16..18 1564 | i = c == 18 ? 7 : c - 14; 1565 | j = c == 18 ? 11 : 3; 1566 | 1567 | while (k < (t + i)) { 1568 | if (n !== 0) { 1569 | r = Z_OK; 1570 | } else { 1571 | that.bitb = b; 1572 | that.bitk = k; 1573 | z.avail_in = n; 1574 | z.total_in += p - z.next_in_index; 1575 | z.next_in_index = p; 1576 | that.write = q; 1577 | return that.inflate_flush(z, r); 1578 | } 1579 | n--; 1580 | b |= (z.read_byte(p++) & 0xff) << k; 1581 | k += 8; 1582 | } 1583 | 1584 | b >>>= (t); 1585 | k -= (t); 1586 | 1587 | j += (b & inflate_mask[i]); 1588 | 1589 | b >>>= (i); 1590 | k -= (i); 1591 | 1592 | i = index; 1593 | t = table; 1594 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { 1595 | blens = null; 1596 | mode = BADBLOCKS; 1597 | z.msg = "invalid bit length repeat"; 1598 | r = Z_DATA_ERROR; 1599 | 1600 | that.bitb = b; 1601 | that.bitk = k; 1602 | z.avail_in = n; 1603 | z.total_in += p - z.next_in_index; 1604 | z.next_in_index = p; 1605 | that.write = q; 1606 | return that.inflate_flush(z, r); 1607 | } 1608 | 1609 | c = c == 16 ? blens[i - 1] : 0; 1610 | do { 1611 | blens[i++] = c; 1612 | } while (--j !== 0); 1613 | index = i; 1614 | } 1615 | } 1616 | 1617 | tb[0] = -1; 1618 | // { 1619 | var bl_ = []; // new Array(1); 1620 | var bd_ = []; // new Array(1); 1621 | var tl_ = []; // new Array(1); 1622 | var td_ = []; // new Array(1); 1623 | bl_[0] = 9; // must be <= 9 for lookahead assumptions 1624 | bd_[0] = 6; // must be <= 9 for lookahead assumptions 1625 | 1626 | t = table; 1627 | t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z); 1628 | 1629 | if (t != Z_OK) { 1630 | if (t == Z_DATA_ERROR) { 1631 | blens = null; 1632 | mode = BADBLOCKS; 1633 | } 1634 | r = t; 1635 | 1636 | that.bitb = b; 1637 | that.bitk = k; 1638 | z.avail_in = n; 1639 | z.total_in += p - z.next_in_index; 1640 | z.next_in_index = p; 1641 | that.write = q; 1642 | return that.inflate_flush(z, r); 1643 | } 1644 | codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0]); 1645 | // } 1646 | mode = CODES; 1647 | case CODES: 1648 | that.bitb = b; 1649 | that.bitk = k; 1650 | z.avail_in = n; 1651 | z.total_in += p - z.next_in_index; 1652 | z.next_in_index = p; 1653 | that.write = q; 1654 | 1655 | if ((r = codes.proc(that, z, r)) != Z_STREAM_END) { 1656 | return that.inflate_flush(z, r); 1657 | } 1658 | r = Z_OK; 1659 | codes.free(z); 1660 | 1661 | p = z.next_in_index; 1662 | n = z.avail_in; 1663 | b = that.bitb; 1664 | k = that.bitk; 1665 | q = that.write; 1666 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1667 | 1668 | if (last === 0) { 1669 | mode = TYPE; 1670 | break; 1671 | } 1672 | mode = DRY; 1673 | case DRY: 1674 | that.write = q; 1675 | r = that.inflate_flush(z, r); 1676 | q = that.write; 1677 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1678 | if (that.read != that.write) { 1679 | that.bitb = b; 1680 | that.bitk = k; 1681 | z.avail_in = n; 1682 | z.total_in += p - z.next_in_index; 1683 | z.next_in_index = p; 1684 | that.write = q; 1685 | return that.inflate_flush(z, r); 1686 | } 1687 | mode = DONELOCKS; 1688 | case DONELOCKS: 1689 | r = Z_STREAM_END; 1690 | 1691 | that.bitb = b; 1692 | that.bitk = k; 1693 | z.avail_in = n; 1694 | z.total_in += p - z.next_in_index; 1695 | z.next_in_index = p; 1696 | that.write = q; 1697 | return that.inflate_flush(z, r); 1698 | case BADBLOCKS: 1699 | r = Z_DATA_ERROR; 1700 | 1701 | that.bitb = b; 1702 | that.bitk = k; 1703 | z.avail_in = n; 1704 | z.total_in += p - z.next_in_index; 1705 | z.next_in_index = p; 1706 | that.write = q; 1707 | return that.inflate_flush(z, r); 1708 | 1709 | default: 1710 | r = Z_STREAM_ERROR; 1711 | 1712 | that.bitb = b; 1713 | that.bitk = k; 1714 | z.avail_in = n; 1715 | z.total_in += p - z.next_in_index; 1716 | z.next_in_index = p; 1717 | that.write = q; 1718 | return that.inflate_flush(z, r); 1719 | } 1720 | } 1721 | }; 1722 | 1723 | that.free = function(z) { 1724 | that.reset(z, null); 1725 | that.window = null; 1726 | hufts = null; 1727 | // ZFREE(z, s); 1728 | }; 1729 | 1730 | that.set_dictionary = function(d, start, n) { 1731 | that.window.set(d.subarray(start, start + n), 0); 1732 | that.read = that.write = n; 1733 | }; 1734 | 1735 | // Returns true if inflate is currently at the end of a block generated 1736 | // by Z_SYNC_FLUSH or Z_FULL_FLUSH. 1737 | that.sync_point = function() { 1738 | return mode == LENS ? 1 : 0; 1739 | }; 1740 | 1741 | } 1742 | 1743 | // Inflate 1744 | 1745 | // preset dictionary flag in zlib header 1746 | var PRESET_DICT = 0x20; 1747 | 1748 | var Z_DEFLATED = 8; 1749 | 1750 | var METHOD = 0; // waiting for method byte 1751 | var FLAG = 1; // waiting for flag byte 1752 | var DICT4 = 2; // four dictionary check bytes to go 1753 | var DICT3 = 3; // three dictionary check bytes to go 1754 | var DICT2 = 4; // two dictionary check bytes to go 1755 | var DICT1 = 5; // one dictionary check byte to go 1756 | var DICT0 = 6; // waiting for inflateSetDictionary 1757 | var BLOCKS = 7; // decompressing blocks 1758 | var DONE = 12; // finished check, done 1759 | var BAD = 13; // got an error--stay here 1760 | 1761 | var mark = [ 0, 0, 0xff, 0xff ]; 1762 | 1763 | function Inflate() { 1764 | var that = this; 1765 | 1766 | that.mode = 0; // current inflate mode 1767 | 1768 | // mode dependent information 1769 | that.method = 0; // if FLAGS, method byte 1770 | 1771 | // if CHECK, check values to compare 1772 | that.was = [ 0 ]; // new Array(1); // computed check value 1773 | that.need = 0; // stream check value 1774 | 1775 | // if BAD, inflateSync's marker bytes count 1776 | that.marker = 0; 1777 | 1778 | // mode independent information 1779 | that.wbits = 0; // log2(window size) (8..15, defaults to 15) 1780 | 1781 | // this.blocks; // current inflate_blocks state 1782 | 1783 | function inflateReset(z) { 1784 | if (!z || !z.istate) 1785 | return Z_STREAM_ERROR; 1786 | 1787 | z.total_in = z.total_out = 0; 1788 | z.msg = null; 1789 | z.istate.mode = BLOCKS; 1790 | z.istate.blocks.reset(z, null); 1791 | return Z_OK; 1792 | } 1793 | 1794 | that.inflateEnd = function(z) { 1795 | if (that.blocks) 1796 | that.blocks.free(z); 1797 | that.blocks = null; 1798 | // ZFREE(z, z->state); 1799 | return Z_OK; 1800 | }; 1801 | 1802 | that.inflateInit = function(z, w) { 1803 | z.msg = null; 1804 | that.blocks = null; 1805 | 1806 | // set window size 1807 | if (w < 8 || w > 15) { 1808 | that.inflateEnd(z); 1809 | return Z_STREAM_ERROR; 1810 | } 1811 | that.wbits = w; 1812 | 1813 | z.istate.blocks = new InfBlocks(z, 1 << w); 1814 | 1815 | // reset state 1816 | inflateReset(z); 1817 | return Z_OK; 1818 | }; 1819 | 1820 | that.inflate = function(z, f) { 1821 | var r; 1822 | var b; 1823 | 1824 | if (!z || !z.istate || !z.next_in) 1825 | return Z_STREAM_ERROR; 1826 | f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 1827 | r = Z_BUF_ERROR; 1828 | while (true) { 1829 | // System.out.println("mode: "+z.istate.mode); 1830 | switch (z.istate.mode) { 1831 | case METHOD: 1832 | 1833 | if (z.avail_in === 0) 1834 | return r; 1835 | r = f; 1836 | 1837 | z.avail_in--; 1838 | z.total_in++; 1839 | if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) { 1840 | z.istate.mode = BAD; 1841 | z.msg = "unknown compression method"; 1842 | z.istate.marker = 5; // can't try inflateSync 1843 | break; 1844 | } 1845 | if ((z.istate.method >> 4) + 8 > z.istate.wbits) { 1846 | z.istate.mode = BAD; 1847 | z.msg = "invalid window size"; 1848 | z.istate.marker = 5; // can't try inflateSync 1849 | break; 1850 | } 1851 | z.istate.mode = FLAG; 1852 | case FLAG: 1853 | 1854 | if (z.avail_in === 0) 1855 | return r; 1856 | r = f; 1857 | 1858 | z.avail_in--; 1859 | z.total_in++; 1860 | b = (z.read_byte(z.next_in_index++)) & 0xff; 1861 | 1862 | if ((((z.istate.method << 8) + b) % 31) !== 0) { 1863 | z.istate.mode = BAD; 1864 | z.msg = "incorrect header check"; 1865 | z.istate.marker = 5; // can't try inflateSync 1866 | break; 1867 | } 1868 | 1869 | if ((b & PRESET_DICT) === 0) { 1870 | z.istate.mode = BLOCKS; 1871 | break; 1872 | } 1873 | z.istate.mode = DICT4; 1874 | case DICT4: 1875 | 1876 | if (z.avail_in === 0) 1877 | return r; 1878 | r = f; 1879 | 1880 | z.avail_in--; 1881 | z.total_in++; 1882 | z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000; 1883 | z.istate.mode = DICT3; 1884 | case DICT3: 1885 | 1886 | if (z.avail_in === 0) 1887 | return r; 1888 | r = f; 1889 | 1890 | z.avail_in--; 1891 | z.total_in++; 1892 | z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000; 1893 | z.istate.mode = DICT2; 1894 | case DICT2: 1895 | 1896 | if (z.avail_in === 0) 1897 | return r; 1898 | r = f; 1899 | 1900 | z.avail_in--; 1901 | z.total_in++; 1902 | z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00; 1903 | z.istate.mode = DICT1; 1904 | case DICT1: 1905 | 1906 | if (z.avail_in === 0) 1907 | return r; 1908 | r = f; 1909 | 1910 | z.avail_in--; 1911 | z.total_in++; 1912 | z.istate.need += (z.read_byte(z.next_in_index++) & 0xff); 1913 | z.istate.mode = DICT0; 1914 | return Z_NEED_DICT; 1915 | case DICT0: 1916 | z.istate.mode = BAD; 1917 | z.msg = "need dictionary"; 1918 | z.istate.marker = 0; // can try inflateSync 1919 | return Z_STREAM_ERROR; 1920 | case BLOCKS: 1921 | 1922 | r = z.istate.blocks.proc(z, r); 1923 | if (r == Z_DATA_ERROR) { 1924 | z.istate.mode = BAD; 1925 | z.istate.marker = 0; // can try inflateSync 1926 | break; 1927 | } 1928 | if (r == Z_OK) { 1929 | r = f; 1930 | } 1931 | if (r != Z_STREAM_END) { 1932 | return r; 1933 | } 1934 | r = f; 1935 | z.istate.blocks.reset(z, z.istate.was); 1936 | z.istate.mode = DONE; 1937 | case DONE: 1938 | return Z_STREAM_END; 1939 | case BAD: 1940 | return Z_DATA_ERROR; 1941 | default: 1942 | return Z_STREAM_ERROR; 1943 | } 1944 | } 1945 | }; 1946 | 1947 | that.inflateSetDictionary = function(z, dictionary, dictLength) { 1948 | var index = 0; 1949 | var length = dictLength; 1950 | if (!z || !z.istate || z.istate.mode != DICT0) 1951 | return Z_STREAM_ERROR; 1952 | 1953 | if (length >= (1 << z.istate.wbits)) { 1954 | length = (1 << z.istate.wbits) - 1; 1955 | index = dictLength - length; 1956 | } 1957 | z.istate.blocks.set_dictionary(dictionary, index, length); 1958 | z.istate.mode = BLOCKS; 1959 | return Z_OK; 1960 | }; 1961 | 1962 | that.inflateSync = function(z) { 1963 | var n; // number of bytes to look at 1964 | var p; // pointer to bytes 1965 | var m; // number of marker bytes found in a row 1966 | var r, w; // temporaries to save total_in and total_out 1967 | 1968 | // set up 1969 | if (!z || !z.istate) 1970 | return Z_STREAM_ERROR; 1971 | if (z.istate.mode != BAD) { 1972 | z.istate.mode = BAD; 1973 | z.istate.marker = 0; 1974 | } 1975 | if ((n = z.avail_in) === 0) 1976 | return Z_BUF_ERROR; 1977 | p = z.next_in_index; 1978 | m = z.istate.marker; 1979 | 1980 | // search 1981 | while (n !== 0 && m < 4) { 1982 | if (z.read_byte(p) == mark[m]) { 1983 | m++; 1984 | } else if (z.read_byte(p) !== 0) { 1985 | m = 0; 1986 | } else { 1987 | m = 4 - m; 1988 | } 1989 | p++; 1990 | n--; 1991 | } 1992 | 1993 | // restore 1994 | z.total_in += p - z.next_in_index; 1995 | z.next_in_index = p; 1996 | z.avail_in = n; 1997 | z.istate.marker = m; 1998 | 1999 | // return no joy or set up to restart on a new block 2000 | if (m != 4) { 2001 | return Z_DATA_ERROR; 2002 | } 2003 | r = z.total_in; 2004 | w = z.total_out; 2005 | inflateReset(z); 2006 | z.total_in = r; 2007 | z.total_out = w; 2008 | z.istate.mode = BLOCKS; 2009 | return Z_OK; 2010 | }; 2011 | 2012 | // Returns true if inflate is currently at the end of a block generated 2013 | // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 2014 | // implementation to provide an additional safety check. PPP uses 2015 | // Z_SYNC_FLUSH 2016 | // but removes the length bytes of the resulting empty stored block. When 2017 | // decompressing, PPP checks that at the end of input packet, inflate is 2018 | // waiting for these length bytes. 2019 | that.inflateSyncPoint = function(z) { 2020 | if (!z || !z.istate || !z.istate.blocks) 2021 | return Z_STREAM_ERROR; 2022 | return z.istate.blocks.sync_point(); 2023 | }; 2024 | } 2025 | 2026 | // ZStream 2027 | 2028 | function ZStream() { 2029 | } 2030 | 2031 | ZStream.prototype = { 2032 | inflateInit : function(bits) { 2033 | var that = this; 2034 | that.istate = new Inflate(); 2035 | if (!bits) 2036 | bits = MAX_BITS; 2037 | return that.istate.inflateInit(that, bits); 2038 | }, 2039 | 2040 | inflate : function(f) { 2041 | var that = this; 2042 | if (!that.istate) 2043 | return Z_STREAM_ERROR; 2044 | return that.istate.inflate(that, f); 2045 | }, 2046 | 2047 | inflateEnd : function() { 2048 | var that = this; 2049 | if (!that.istate) 2050 | return Z_STREAM_ERROR; 2051 | var ret = that.istate.inflateEnd(that); 2052 | that.istate = null; 2053 | return ret; 2054 | }, 2055 | 2056 | inflateSync : function() { 2057 | var that = this; 2058 | if (!that.istate) 2059 | return Z_STREAM_ERROR; 2060 | return that.istate.inflateSync(that); 2061 | }, 2062 | inflateSetDictionary : function(dictionary, dictLength) { 2063 | var that = this; 2064 | if (!that.istate) 2065 | return Z_STREAM_ERROR; 2066 | return that.istate.inflateSetDictionary(that, dictionary, dictLength); 2067 | }, 2068 | read_byte : function(start) { 2069 | var that = this; 2070 | return that.next_in.subarray(start, start + 1)[0]; 2071 | }, 2072 | read_buf : function(start, size) { 2073 | var that = this; 2074 | return that.next_in.subarray(start, start + size); 2075 | } 2076 | }; 2077 | 2078 | // Inflater 2079 | 2080 | function Inflater() { 2081 | var that = this; 2082 | var z = new ZStream(); 2083 | var bufsize = 512; 2084 | var flush = Z_NO_FLUSH; 2085 | var buf = new Uint8Array(bufsize); 2086 | var nomoreinput = false; 2087 | 2088 | z.inflateInit(); 2089 | z.next_out = buf; 2090 | 2091 | that.append = function(data, onprogress) { 2092 | var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array; 2093 | if (data.length === 0) 2094 | return; 2095 | z.next_in_index = 0; 2096 | z.next_in = data; 2097 | z.avail_in = data.length; 2098 | do { 2099 | z.next_out_index = 0; 2100 | z.avail_out = bufsize; 2101 | if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it 2102 | z.next_in_index = 0; 2103 | nomoreinput = true; 2104 | } 2105 | err = z.inflate(flush); 2106 | if (nomoreinput && (err == Z_BUF_ERROR)) 2107 | return -1; 2108 | if (err != Z_OK && err != Z_STREAM_END) 2109 | throw "inflating: " + z.msg; 2110 | if ((nomoreinput || err == Z_STREAM_END) && (z.avail_in == data.length)) 2111 | return -1; 2112 | if (z.next_out_index) 2113 | if (z.next_out_index == bufsize) 2114 | buffers.push(new Uint8Array(buf)); 2115 | else 2116 | buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index))); 2117 | bufferSize += z.next_out_index; 2118 | if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) { 2119 | onprogress(z.next_in_index); 2120 | lastIndex = z.next_in_index; 2121 | } 2122 | } while (z.avail_in > 0 || z.avail_out === 0); 2123 | array = new Uint8Array(bufferSize); 2124 | buffers.forEach(function(chunk) { 2125 | array.set(chunk, bufferIndex); 2126 | bufferIndex += chunk.length; 2127 | }); 2128 | return array; 2129 | }; 2130 | that.flush = function() { 2131 | z.inflateEnd(); 2132 | }; 2133 | } 2134 | 2135 | var inflater; 2136 | 2137 | if (obj.zip) 2138 | obj.zip.Inflater = Inflater; 2139 | else { 2140 | inflater = new Inflater(); 2141 | obj.addEventListener("message", function(event) { 2142 | var message = event.data; 2143 | 2144 | if (message.append) 2145 | obj.postMessage({ 2146 | onappend : true, 2147 | data : inflater.append(message.data, function(current) { 2148 | obj.postMessage({ 2149 | progress : true, 2150 | current : current 2151 | }); 2152 | }) 2153 | }); 2154 | if (message.flush) { 2155 | inflater.flush(); 2156 | obj.postMessage({ 2157 | onflush : true 2158 | }); 2159 | } 2160 | }, false); 2161 | } 2162 | 2163 | })(this); 2164 | -------------------------------------------------------------------------------- /js/zip/mime-types.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | (function() { 30 | var table = { 31 | "application" : { 32 | "andrew-inset" : "ez", 33 | "annodex" : "anx", 34 | "atom+xml" : "atom", 35 | "atomcat+xml" : "atomcat", 36 | "atomserv+xml" : "atomsrv", 37 | "bbolin" : "lin", 38 | "cap" : [ "cap", "pcap" ], 39 | "cu-seeme" : "cu", 40 | "davmount+xml" : "davmount", 41 | "dsptype" : "tsp", 42 | "ecmascript" : [ "es", "ecma" ], 43 | "futuresplash" : "spl", 44 | "hta" : "hta", 45 | "java-archive" : "jar", 46 | "java-serialized-object" : "ser", 47 | "java-vm" : "class", 48 | "javascript" : "js", 49 | "m3g" : "m3g", 50 | "mac-binhex40" : "hqx", 51 | "mathematica" : [ "nb", "ma", "mb" ], 52 | "msaccess" : "mdb", 53 | "msword" : [ "doc", "dot" ], 54 | "mxf" : "mxf", 55 | "oda" : "oda", 56 | "ogg" : "ogx", 57 | "pdf" : "pdf", 58 | "pgp-keys" : "key", 59 | "pgp-signature" : [ "asc", "sig" ], 60 | "pics-rules" : "prf", 61 | "postscript" : [ "ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3" ], 62 | "rar" : "rar", 63 | "rdf+xml" : "rdf", 64 | "rss+xml" : "rss", 65 | "rtf" : "rtf", 66 | "smil" : [ "smi", "smil" ], 67 | "xhtml+xml" : [ "xhtml", "xht" ], 68 | "xml" : [ "xml", "xsl", "xsd" ], 69 | "xspf+xml" : "xspf", 70 | "zip" : "zip", 71 | "vnd.android.package-archive" : "apk", 72 | "vnd.cinderella" : "cdy", 73 | "vnd.google-earth.kml+xml" : "kml", 74 | "vnd.google-earth.kmz" : "kmz", 75 | "vnd.mozilla.xul+xml" : "xul", 76 | "vnd.ms-excel" : [ "xls", "xlb", "xlt", "xlm", "xla", "xlc", "xlw" ], 77 | "vnd.ms-pki.seccat" : "cat", 78 | "vnd.ms-pki.stl" : "stl", 79 | "vnd.ms-powerpoint" : [ "ppt", "pps", "pot" ], 80 | "vnd.oasis.opendocument.chart" : "odc", 81 | "vnd.oasis.opendocument.database" : "odb", 82 | "vnd.oasis.opendocument.formula" : "odf", 83 | "vnd.oasis.opendocument.graphics" : "odg", 84 | "vnd.oasis.opendocument.graphics-template" : "otg", 85 | "vnd.oasis.opendocument.image" : "odi", 86 | "vnd.oasis.opendocument.presentation" : "odp", 87 | "vnd.oasis.opendocument.presentation-template" : "otp", 88 | "vnd.oasis.opendocument.spreadsheet" : "ods", 89 | "vnd.oasis.opendocument.spreadsheet-template" : "ots", 90 | "vnd.oasis.opendocument.text" : "odt", 91 | "vnd.oasis.opendocument.text-master" : "odm", 92 | "vnd.oasis.opendocument.text-template" : "ott", 93 | "vnd.oasis.opendocument.text-web" : "oth", 94 | "vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "xlsx", 95 | "vnd.openxmlformats-officedocument.spreadsheetml.template" : "xltx", 96 | "vnd.openxmlformats-officedocument.presentationml.presentation" : "pptx", 97 | "vnd.openxmlformats-officedocument.presentationml.slideshow" : "ppsx", 98 | "vnd.openxmlformats-officedocument.presentationml.template" : "potx", 99 | "vnd.openxmlformats-officedocument.wordprocessingml.document" : "docx", 100 | "vnd.openxmlformats-officedocument.wordprocessingml.template" : "dotx", 101 | "vnd.smaf" : "mmf", 102 | "vnd.stardivision.calc" : "sdc", 103 | "vnd.stardivision.chart" : "sds", 104 | "vnd.stardivision.draw" : "sda", 105 | "vnd.stardivision.impress" : "sdd", 106 | "vnd.stardivision.math" : [ "sdf", "smf" ], 107 | "vnd.stardivision.writer" : [ "sdw", "vor" ], 108 | "vnd.stardivision.writer-global" : "sgl", 109 | "vnd.sun.xml.calc" : "sxc", 110 | "vnd.sun.xml.calc.template" : "stc", 111 | "vnd.sun.xml.draw" : "sxd", 112 | "vnd.sun.xml.draw.template" : "std", 113 | "vnd.sun.xml.impress" : "sxi", 114 | "vnd.sun.xml.impress.template" : "sti", 115 | "vnd.sun.xml.math" : "sxm", 116 | "vnd.sun.xml.writer" : "sxw", 117 | "vnd.sun.xml.writer.global" : "sxg", 118 | "vnd.sun.xml.writer.template" : "stw", 119 | "vnd.symbian.install" : [ "sis", "sisx" ], 120 | "vnd.visio" : [ "vsd", "vst", "vss", "vsw" ], 121 | "vnd.wap.wbxml" : "wbxml", 122 | "vnd.wap.wmlc" : "wmlc", 123 | "vnd.wap.wmlscriptc" : "wmlsc", 124 | "vnd.wordperfect" : "wpd", 125 | "vnd.wordperfect5.1" : "wp5", 126 | "x-123" : "wk", 127 | "x-7z-compressed" : "7z", 128 | "x-abiword" : "abw", 129 | "x-apple-diskimage" : "dmg", 130 | "x-bcpio" : "bcpio", 131 | "x-bittorrent" : "torrent", 132 | "x-cbr" : [ "cbr", "cba", "cbt", "cb7" ], 133 | "x-cbz" : "cbz", 134 | "x-cdf" : [ "cdf", "cda" ], 135 | "x-cdlink" : "vcd", 136 | "x-chess-pgn" : "pgn", 137 | "x-cpio" : "cpio", 138 | "x-csh" : "csh", 139 | "x-debian-package" : [ "deb", "udeb" ], 140 | "x-director" : [ "dcr", "dir", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa" ], 141 | "x-dms" : "dms", 142 | "x-doom" : "wad", 143 | "x-dvi" : "dvi", 144 | "x-httpd-eruby" : "rhtml", 145 | "x-font" : "pcf.Z", 146 | "x-freemind" : "mm", 147 | "x-gnumeric" : "gnumeric", 148 | "x-go-sgf" : "sgf", 149 | "x-graphing-calculator" : "gcf", 150 | "x-gtar" : [ "gtar", "taz" ], 151 | "x-hdf" : "hdf", 152 | "x-httpd-php" : [ "phtml", "pht", "php" ], 153 | "x-httpd-php-source" : "phps", 154 | "x-httpd-php3" : "php3", 155 | "x-httpd-php3-preprocessed" : "php3p", 156 | "x-httpd-php4" : "php4", 157 | "x-httpd-php5" : "php5", 158 | "x-ica" : "ica", 159 | "x-info" : "info", 160 | "x-internet-signup" : [ "ins", "isp" ], 161 | "x-iphone" : "iii", 162 | "x-iso9660-image" : "iso", 163 | "x-java-jnlp-file" : "jnlp", 164 | "x-jmol" : "jmz", 165 | "x-killustrator" : "kil", 166 | "x-koan" : [ "skp", "skd", "skt", "skm" ], 167 | "x-kpresenter" : [ "kpr", "kpt" ], 168 | "x-kword" : [ "kwd", "kwt" ], 169 | "x-latex" : "latex", 170 | "x-lha" : "lha", 171 | "x-lyx" : "lyx", 172 | "x-lzh" : "lzh", 173 | "x-lzx" : "lzx", 174 | "x-maker" : [ "frm", "maker", "frame", "fm", "fb", "book", "fbdoc" ], 175 | "x-ms-wmd" : "wmd", 176 | "x-ms-wmz" : "wmz", 177 | "x-msdos-program" : [ "com", "exe", "bat", "dll" ], 178 | "x-msi" : "msi", 179 | "x-netcdf" : [ "nc", "cdf" ], 180 | "x-ns-proxy-autoconfig" : [ "pac", "dat" ], 181 | "x-nwc" : "nwc", 182 | "x-object" : "o", 183 | "x-oz-application" : "oza", 184 | "x-pkcs7-certreqresp" : "p7r", 185 | "x-python-code" : [ "pyc", "pyo" ], 186 | "x-qgis" : [ "qgs", "shp", "shx" ], 187 | "x-quicktimeplayer" : "qtl", 188 | "x-redhat-package-manager" : "rpm", 189 | "x-ruby" : "rb", 190 | "x-sh" : "sh", 191 | "x-shar" : "shar", 192 | "x-shockwave-flash" : [ "swf", "swfl" ], 193 | "x-silverlight" : "scr", 194 | "x-stuffit" : "sit", 195 | "x-sv4cpio" : "sv4cpio", 196 | "x-sv4crc" : "sv4crc", 197 | "x-tar" : "tar", 198 | "x-tcl" : "tcl", 199 | "x-tex-gf" : "gf", 200 | "x-tex-pk" : "pk", 201 | "x-texinfo" : [ "texinfo", "texi" ], 202 | "x-trash" : [ "~", "%", "bak", "old", "sik" ], 203 | "x-troff" : [ "t", "tr", "roff" ], 204 | "x-troff-man" : "man", 205 | "x-troff-me" : "me", 206 | "x-troff-ms" : "ms", 207 | "x-ustar" : "ustar", 208 | "x-wais-source" : "src", 209 | "x-wingz" : "wz", 210 | "x-x509-ca-cert" : [ "crt", "der", "cer" ], 211 | "x-xcf" : "xcf", 212 | "x-xfig" : "fig", 213 | "x-xpinstall" : "xpi", 214 | "applixware" : "aw", 215 | "atomsvc+xml" : "atomsvc", 216 | "ccxml+xml" : "ccxml", 217 | "cdmi-capability" : "cdmia", 218 | "cdmi-container" : "cdmic", 219 | "cdmi-domain" : "cdmid", 220 | "cdmi-object" : "cdmio", 221 | "cdmi-queue" : "cdmiq", 222 | "docbook+xml" : "dbk", 223 | "dssc+der" : "dssc", 224 | "dssc+xml" : "xdssc", 225 | "emma+xml" : "emma", 226 | "epub+zip" : "epub", 227 | "exi" : "exi", 228 | "font-tdpfr" : "pfr", 229 | "gml+xml" : "gml", 230 | "gpx+xml" : "gpx", 231 | "gxf" : "gxf", 232 | "hyperstudio" : "stk", 233 | "inkml+xml" : [ "ink", "inkml" ], 234 | "ipfix" : "ipfix", 235 | "json" : "json", 236 | "jsonml+json" : "jsonml", 237 | "lost+xml" : "lostxml", 238 | "mads+xml" : "mads", 239 | "marc" : "mrc", 240 | "marcxml+xml" : "mrcx", 241 | "mathml+xml" : "mathml", 242 | "mbox" : "mbox", 243 | "mediaservercontrol+xml" : "mscml", 244 | "metalink+xml" : "metalink", 245 | "metalink4+xml" : "meta4", 246 | "mets+xml" : "mets", 247 | "mods+xml" : "mods", 248 | "mp21" : [ "m21", "mp21" ], 249 | "mp4" : "mp4s", 250 | "oebps-package+xml" : "opf", 251 | "omdoc+xml" : "omdoc", 252 | "onenote" : [ "onetoc", "onetoc2", "onetmp", "onepkg" ], 253 | "oxps" : "oxps", 254 | "patch-ops-error+xml" : "xer", 255 | "pgp-encrypted" : "pgp", 256 | "pkcs10" : "p10", 257 | "pkcs7-mime" : [ "p7m", "p7c" ], 258 | "pkcs7-signature" : "p7s", 259 | "pkcs8" : "p8", 260 | "pkix-attr-cert" : "ac", 261 | "pkix-crl" : "crl", 262 | "pkix-pkipath" : "pkipath", 263 | "pkixcmp" : "pki", 264 | "pls+xml" : "pls", 265 | "prs.cww" : "cww", 266 | "pskc+xml" : "pskcxml", 267 | "reginfo+xml" : "rif", 268 | "relax-ng-compact-syntax" : "rnc", 269 | "resource-lists+xml" : "rl", 270 | "resource-lists-diff+xml" : "rld", 271 | "rls-services+xml" : "rs", 272 | "rpki-ghostbusters" : "gbr", 273 | "rpki-manifest" : "mft", 274 | "rpki-roa" : "roa", 275 | "rsd+xml" : "rsd", 276 | "sbml+xml" : "sbml", 277 | "scvp-cv-request" : "scq", 278 | "scvp-cv-response" : "scs", 279 | "scvp-vp-request" : "spq", 280 | "scvp-vp-response" : "spp", 281 | "sdp" : "sdp", 282 | "set-payment-initiation" : "setpay", 283 | "set-registration-initiation" : "setreg", 284 | "shf+xml" : "shf", 285 | "sparql-query" : "rq", 286 | "sparql-results+xml" : "srx", 287 | "srgs" : "gram", 288 | "srgs+xml" : "grxml", 289 | "sru+xml" : "sru", 290 | "ssdl+xml" : "ssdl", 291 | "ssml+xml" : "ssml", 292 | "tei+xml" : [ "tei", "teicorpus" ], 293 | "thraud+xml" : "tfi", 294 | "timestamped-data" : "tsd", 295 | "vnd.3gpp.pic-bw-large" : "plb", 296 | "vnd.3gpp.pic-bw-small" : "psb", 297 | "vnd.3gpp.pic-bw-var" : "pvb", 298 | "vnd.3gpp2.tcap" : "tcap", 299 | "vnd.3m.post-it-notes" : "pwn", 300 | "vnd.accpac.simply.aso" : "aso", 301 | "vnd.accpac.simply.imp" : "imp", 302 | "vnd.acucobol" : "acu", 303 | "vnd.acucorp" : [ "atc", "acutc" ], 304 | "vnd.adobe.air-application-installer-package+zip" : "air", 305 | "vnd.adobe.formscentral.fcdt" : "fcdt", 306 | "vnd.adobe.fxp" : [ "fxp", "fxpl" ], 307 | "vnd.adobe.xdp+xml" : "xdp", 308 | "vnd.adobe.xfdf" : "xfdf", 309 | "vnd.ahead.space" : "ahead", 310 | "vnd.airzip.filesecure.azf" : "azf", 311 | "vnd.airzip.filesecure.azs" : "azs", 312 | "vnd.amazon.ebook" : "azw", 313 | "vnd.americandynamics.acc" : "acc", 314 | "vnd.amiga.ami" : "ami", 315 | "vnd.anser-web-certificate-issue-initiation" : "cii", 316 | "vnd.anser-web-funds-transfer-initiation" : "fti", 317 | "vnd.antix.game-component" : "atx", 318 | "vnd.apple.installer+xml" : "mpkg", 319 | "vnd.apple.mpegurl" : "m3u8", 320 | "vnd.aristanetworks.swi" : "swi", 321 | "vnd.astraea-software.iota" : "iota", 322 | "vnd.audiograph" : "aep", 323 | "vnd.blueice.multipass" : "mpm", 324 | "vnd.bmi" : "bmi", 325 | "vnd.businessobjects" : "rep", 326 | "vnd.chemdraw+xml" : "cdxml", 327 | "vnd.chipnuts.karaoke-mmd" : "mmd", 328 | "vnd.claymore" : "cla", 329 | "vnd.cloanto.rp9" : "rp9", 330 | "vnd.clonk.c4group" : [ "c4g", "c4d", "c4f", "c4p", "c4u" ], 331 | "vnd.cluetrust.cartomobile-config" : "c11amc", 332 | "vnd.cluetrust.cartomobile-config-pkg" : "c11amz", 333 | "vnd.commonspace" : "csp", 334 | "vnd.contact.cmsg" : "cdbcmsg", 335 | "vnd.cosmocaller" : "cmc", 336 | "vnd.crick.clicker" : "clkx", 337 | "vnd.crick.clicker.keyboard" : "clkk", 338 | "vnd.crick.clicker.palette" : "clkp", 339 | "vnd.crick.clicker.template" : "clkt", 340 | "vnd.crick.clicker.wordbank" : "clkw", 341 | "vnd.criticaltools.wbs+xml" : "wbs", 342 | "vnd.ctc-posml" : "pml", 343 | "vnd.cups-ppd" : "ppd", 344 | "vnd.curl.car" : "car", 345 | "vnd.curl.pcurl" : "pcurl", 346 | "vnd.dart" : "dart", 347 | "vnd.data-vision.rdz" : "rdz", 348 | "vnd.dece.data" : [ "uvf", "uvvf", "uvd", "uvvd" ], 349 | "vnd.dece.ttml+xml" : [ "uvt", "uvvt" ], 350 | "vnd.dece.unspecified" : [ "uvx", "uvvx" ], 351 | "vnd.dece.zip" : [ "uvz", "uvvz" ], 352 | "vnd.denovo.fcselayout-link" : "fe_launch", 353 | "vnd.dna" : "dna", 354 | "vnd.dolby.mlp" : "mlp", 355 | "vnd.dpgraph" : "dpg", 356 | "vnd.dreamfactory" : "dfac", 357 | "vnd.ds-keypoint" : "kpxx", 358 | "vnd.dvb.ait" : "ait", 359 | "vnd.dvb.service" : "svc", 360 | "vnd.dynageo" : "geo", 361 | "vnd.ecowin.chart" : "mag", 362 | "vnd.enliven" : "nml", 363 | "vnd.epson.esf" : "esf", 364 | "vnd.epson.msf" : "msf", 365 | "vnd.epson.quickanime" : "qam", 366 | "vnd.epson.salt" : "slt", 367 | "vnd.epson.ssf" : "ssf", 368 | "vnd.eszigno3+xml" : [ "es3", "et3" ], 369 | "vnd.ezpix-album" : "ez2", 370 | "vnd.ezpix-package" : "ez3", 371 | "vnd.fdf" : "fdf", 372 | "vnd.fdsn.mseed" : "mseed", 373 | "vnd.fdsn.seed" : [ "seed", "dataless" ], 374 | "vnd.flographit" : "gph", 375 | "vnd.fluxtime.clip" : "ftc", 376 | "vnd.framemaker" : [ "fm", "frame", "maker", "book" ], 377 | "vnd.frogans.fnc" : "fnc", 378 | "vnd.frogans.ltf" : "ltf", 379 | "vnd.fsc.weblaunch" : "fsc", 380 | "vnd.fujitsu.oasys" : "oas", 381 | "vnd.fujitsu.oasys2" : "oa2", 382 | "vnd.fujitsu.oasys3" : "oa3", 383 | "vnd.fujitsu.oasysgp" : "fg5", 384 | "vnd.fujitsu.oasysprs" : "bh2", 385 | "vnd.fujixerox.ddd" : "ddd", 386 | "vnd.fujixerox.docuworks" : "xdw", 387 | "vnd.fujixerox.docuworks.binder" : "xbd", 388 | "vnd.fuzzysheet" : "fzs", 389 | "vnd.genomatix.tuxedo" : "txd", 390 | "vnd.geogebra.file" : "ggb", 391 | "vnd.geogebra.tool" : "ggt", 392 | "vnd.geometry-explorer" : [ "gex", "gre" ], 393 | "vnd.geonext" : "gxt", 394 | "vnd.geoplan" : "g2w", 395 | "vnd.geospace" : "g3w", 396 | "vnd.gmx" : "gmx", 397 | "vnd.grafeq" : [ "gqf", "gqs" ], 398 | "vnd.groove-account" : "gac", 399 | "vnd.groove-help" : "ghf", 400 | "vnd.groove-identity-message" : "gim", 401 | "vnd.groove-injector" : "grv", 402 | "vnd.groove-tool-message" : "gtm", 403 | "vnd.groove-tool-template" : "tpl", 404 | "vnd.groove-vcard" : "vcg", 405 | "vnd.hal+xml" : "hal", 406 | "vnd.handheld-entertainment+xml" : "zmm", 407 | "vnd.hbci" : "hbci", 408 | "vnd.hhe.lesson-player" : "les", 409 | "vnd.hp-hpgl" : "hpgl", 410 | "vnd.hp-hpid" : "hpid", 411 | "vnd.hp-hps" : "hps", 412 | "vnd.hp-jlyt" : "jlt", 413 | "vnd.hp-pcl" : "pcl", 414 | "vnd.hp-pclxl" : "pclxl", 415 | "vnd.hydrostatix.sof-data" : "sfd-hdstx", 416 | "vnd.ibm.minipay" : "mpy", 417 | "vnd.ibm.modcap" : [ "afp", "listafp", "list3820" ], 418 | "vnd.ibm.rights-management" : "irm", 419 | "vnd.ibm.secure-container" : "sc", 420 | "vnd.iccprofile" : [ "icc", "icm" ], 421 | "vnd.igloader" : "igl", 422 | "vnd.immervision-ivp" : "ivp", 423 | "vnd.immervision-ivu" : "ivu", 424 | "vnd.insors.igm" : "igm", 425 | "vnd.intercon.formnet" : [ "xpw", "xpx" ], 426 | "vnd.intergeo" : "i2g", 427 | "vnd.intu.qbo" : "qbo", 428 | "vnd.intu.qfx" : "qfx", 429 | "vnd.ipunplugged.rcprofile" : "rcprofile", 430 | "vnd.irepository.package+xml" : "irp", 431 | "vnd.is-xpr" : "xpr", 432 | "vnd.isac.fcs" : "fcs", 433 | "vnd.jam" : "jam", 434 | "vnd.jcp.javame.midlet-rms" : "rms", 435 | "vnd.jisp" : "jisp", 436 | "vnd.joost.joda-archive" : "joda", 437 | "vnd.kahootz" : [ "ktz", "ktr" ], 438 | "vnd.kde.karbon" : "karbon", 439 | "vnd.kde.kchart" : "chrt", 440 | "vnd.kde.kformula" : "kfo", 441 | "vnd.kde.kivio" : "flw", 442 | "vnd.kde.kontour" : "kon", 443 | "vnd.kde.kpresenter" : [ "kpr", "kpt" ], 444 | "vnd.kde.kspread" : "ksp", 445 | "vnd.kde.kword" : [ "kwd", "kwt" ], 446 | "vnd.kenameaapp" : "htke", 447 | "vnd.kidspiration" : "kia", 448 | "vnd.kinar" : [ "kne", "knp" ], 449 | "vnd.koan" : [ "skp", "skd", "skt", "skm" ], 450 | "vnd.kodak-descriptor" : "sse", 451 | "vnd.las.las+xml" : "lasxml", 452 | "vnd.llamagraphics.life-balance.desktop" : "lbd", 453 | "vnd.llamagraphics.life-balance.exchange+xml" : "lbe", 454 | "vnd.lotus-1-2-3" : "123", 455 | "vnd.lotus-approach" : "apr", 456 | "vnd.lotus-freelance" : "pre", 457 | "vnd.lotus-notes" : "nsf", 458 | "vnd.lotus-organizer" : "org", 459 | "vnd.lotus-screencam" : "scm", 460 | "vnd.lotus-wordpro" : "lwp", 461 | "vnd.macports.portpkg" : "portpkg", 462 | "vnd.mcd" : "mcd", 463 | "vnd.medcalcdata" : "mc1", 464 | "vnd.mediastation.cdkey" : "cdkey", 465 | "vnd.mfer" : "mwf", 466 | "vnd.mfmp" : "mfm", 467 | "vnd.micrografx.flo" : "flo", 468 | "vnd.micrografx.igx" : "igx", 469 | "vnd.mif" : "mif", 470 | "vnd.mobius.daf" : "daf", 471 | "vnd.mobius.dis" : "dis", 472 | "vnd.mobius.mbk" : "mbk", 473 | "vnd.mobius.mqy" : "mqy", 474 | "vnd.mobius.msl" : "msl", 475 | "vnd.mobius.plc" : "plc", 476 | "vnd.mobius.txf" : "txf", 477 | "vnd.mophun.application" : "mpn", 478 | "vnd.mophun.certificate" : "mpc", 479 | "vnd.ms-artgalry" : "cil", 480 | "vnd.ms-cab-compressed" : "cab", 481 | "vnd.ms-excel.addin.macroenabled.12" : "xlam", 482 | "vnd.ms-excel.sheet.binary.macroenabled.12" : "xlsb", 483 | "vnd.ms-excel.sheet.macroenabled.12" : "xlsm", 484 | "vnd.ms-excel.template.macroenabled.12" : "xltm", 485 | "vnd.ms-fontobject" : "eot", 486 | "vnd.ms-htmlhelp" : "chm", 487 | "vnd.ms-ims" : "ims", 488 | "vnd.ms-lrm" : "lrm", 489 | "vnd.ms-officetheme" : "thmx", 490 | "vnd.ms-powerpoint.addin.macroenabled.12" : "ppam", 491 | "vnd.ms-powerpoint.presentation.macroenabled.12" : "pptm", 492 | "vnd.ms-powerpoint.slide.macroenabled.12" : "sldm", 493 | "vnd.ms-powerpoint.slideshow.macroenabled.12" : "ppsm", 494 | "vnd.ms-powerpoint.template.macroenabled.12" : "potm", 495 | "vnd.ms-project" : [ "mpp", "mpt" ], 496 | "vnd.ms-word.document.macroenabled.12" : "docm", 497 | "vnd.ms-word.template.macroenabled.12" : "dotm", 498 | "vnd.ms-works" : [ "wps", "wks", "wcm", "wdb" ], 499 | "vnd.ms-wpl" : "wpl", 500 | "vnd.ms-xpsdocument" : "xps", 501 | "vnd.mseq" : "mseq", 502 | "vnd.musician" : "mus", 503 | "vnd.muvee.style" : "msty", 504 | "vnd.mynfc" : "taglet", 505 | "vnd.neurolanguage.nlu" : "nlu", 506 | "vnd.nitf" : [ "ntf", "nitf" ], 507 | "vnd.noblenet-directory" : "nnd", 508 | "vnd.noblenet-sealer" : "nns", 509 | "vnd.noblenet-web" : "nnw", 510 | "vnd.nokia.n-gage.data" : "ngdat", 511 | "vnd.nokia.n-gage.symbian.install" : "n-gage", 512 | "vnd.nokia.radio-preset" : "rpst", 513 | "vnd.nokia.radio-presets" : "rpss", 514 | "vnd.novadigm.edm" : "edm", 515 | "vnd.novadigm.edx" : "edx", 516 | "vnd.novadigm.ext" : "ext", 517 | "vnd.oasis.opendocument.chart-template" : "otc", 518 | "vnd.oasis.opendocument.formula-template" : "odft", 519 | "vnd.oasis.opendocument.image-template" : "oti", 520 | "vnd.olpc-sugar" : "xo", 521 | "vnd.oma.dd2+xml" : "dd2", 522 | "vnd.openofficeorg.extension" : "oxt", 523 | "vnd.openxmlformats-officedocument.presentationml.slide" : "sldx", 524 | "vnd.osgeo.mapguide.package" : "mgp", 525 | "vnd.osgi.dp" : "dp", 526 | "vnd.osgi.subsystem" : "esa", 527 | "vnd.palm" : [ "pdb", "pqa", "oprc" ], 528 | "vnd.pawaafile" : "paw", 529 | "vnd.pg.format" : "str", 530 | "vnd.pg.osasli" : "ei6", 531 | "vnd.picsel" : "efif", 532 | "vnd.pmi.widget" : "wg", 533 | "vnd.pocketlearn" : "plf", 534 | "vnd.powerbuilder6" : "pbd", 535 | "vnd.previewsystems.box" : "box", 536 | "vnd.proteus.magazine" : "mgz", 537 | "vnd.publishare-delta-tree" : "qps", 538 | "vnd.pvi.ptid1" : "ptid", 539 | "vnd.quark.quarkxpress" : [ "qxd", "qxt", "qwd", "qwt", "qxl", "qxb" ], 540 | "vnd.realvnc.bed" : "bed", 541 | "vnd.recordare.musicxml" : "mxl", 542 | "vnd.recordare.musicxml+xml" : "musicxml", 543 | "vnd.rig.cryptonote" : "cryptonote", 544 | "vnd.rn-realmedia" : "rm", 545 | "vnd.rn-realmedia-vbr" : "rmvb", 546 | "vnd.route66.link66+xml" : "link66", 547 | "vnd.sailingtracker.track" : "st", 548 | "vnd.seemail" : "see", 549 | "vnd.sema" : "sema", 550 | "vnd.semd" : "semd", 551 | "vnd.semf" : "semf", 552 | "vnd.shana.informed.formdata" : "ifm", 553 | "vnd.shana.informed.formtemplate" : "itp", 554 | "vnd.shana.informed.interchange" : "iif", 555 | "vnd.shana.informed.package" : "ipk", 556 | "vnd.simtech-mindmapper" : [ "twd", "twds" ], 557 | "vnd.smart.teacher" : "teacher", 558 | "vnd.solent.sdkm+xml" : [ "sdkm", "sdkd" ], 559 | "vnd.spotfire.dxp" : "dxp", 560 | "vnd.spotfire.sfs" : "sfs", 561 | "vnd.stepmania.package" : "smzip", 562 | "vnd.stepmania.stepchart" : "sm", 563 | "vnd.sus-calendar" : [ "sus", "susp" ], 564 | "vnd.svd" : "svd", 565 | "vnd.syncml+xml" : "xsm", 566 | "vnd.syncml.dm+wbxml" : "bdm", 567 | "vnd.syncml.dm+xml" : "xdm", 568 | "vnd.tao.intent-module-archive" : "tao", 569 | "vnd.tcpdump.pcap" : [ "pcap", "cap", "dmp" ], 570 | "vnd.tmobile-livetv" : "tmo", 571 | "vnd.trid.tpt" : "tpt", 572 | "vnd.triscape.mxs" : "mxs", 573 | "vnd.trueapp" : "tra", 574 | "vnd.ufdl" : [ "ufd", "ufdl" ], 575 | "vnd.uiq.theme" : "utz", 576 | "vnd.umajin" : "umj", 577 | "vnd.unity" : "unityweb", 578 | "vnd.uoml+xml" : "uoml", 579 | "vnd.vcx" : "vcx", 580 | "vnd.visionary" : "vis", 581 | "vnd.vsf" : "vsf", 582 | "vnd.webturbo" : "wtb", 583 | "vnd.wolfram.player" : "nbp", 584 | "vnd.wqd" : "wqd", 585 | "vnd.wt.stf" : "stf", 586 | "vnd.xara" : "xar", 587 | "vnd.xfdl" : "xfdl", 588 | "vnd.yamaha.hv-dic" : "hvd", 589 | "vnd.yamaha.hv-script" : "hvs", 590 | "vnd.yamaha.hv-voice" : "hvp", 591 | "vnd.yamaha.openscoreformat" : "osf", 592 | "vnd.yamaha.openscoreformat.osfpvg+xml" : "osfpvg", 593 | "vnd.yamaha.smaf-audio" : "saf", 594 | "vnd.yamaha.smaf-phrase" : "spf", 595 | "vnd.yellowriver-custom-menu" : "cmp", 596 | "vnd.zul" : [ "zir", "zirz" ], 597 | "vnd.zzazz.deck+xml" : "zaz", 598 | "voicexml+xml" : "vxml", 599 | "widget" : "wgt", 600 | "winhlp" : "hlp", 601 | "wsdl+xml" : "wsdl", 602 | "wspolicy+xml" : "wspolicy", 603 | "x-ace-compressed" : "ace", 604 | "x-authorware-bin" : [ "aab", "x32", "u32", "vox" ], 605 | "x-authorware-map" : "aam", 606 | "x-authorware-seg" : "aas", 607 | "x-blorb" : [ "blb", "blorb" ], 608 | "x-bzip" : "bz", 609 | "x-bzip2" : [ "bz2", "boz" ], 610 | "x-cfs-compressed" : "cfs", 611 | "x-chat" : "chat", 612 | "x-conference" : "nsc", 613 | "x-dgc-compressed" : "dgc", 614 | "x-dtbncx+xml" : "ncx", 615 | "x-dtbook+xml" : "dtb", 616 | "x-dtbresource+xml" : "res", 617 | "x-eva" : "eva", 618 | "x-font-bdf" : "bdf", 619 | "x-font-ghostscript" : "gsf", 620 | "x-font-linux-psf" : "psf", 621 | "x-font-otf" : "otf", 622 | "x-font-pcf" : "pcf", 623 | "x-font-snf" : "snf", 624 | "x-font-ttf" : [ "ttf", "ttc" ], 625 | "x-font-type1" : [ "pfa", "pfb", "pfm", "afm" ], 626 | "x-font-woff" : "woff", 627 | "x-freearc" : "arc", 628 | "x-gca-compressed" : "gca", 629 | "x-glulx" : "ulx", 630 | "x-gramps-xml" : "gramps", 631 | "x-install-instructions" : "install", 632 | "x-lzh-compressed" : [ "lzh", "lha" ], 633 | "x-mie" : "mie", 634 | "x-mobipocket-ebook" : [ "prc", "mobi" ], 635 | "x-ms-application" : "application", 636 | "x-ms-shortcut" : "lnk", 637 | "x-ms-xbap" : "xbap", 638 | "x-msbinder" : "obd", 639 | "x-mscardfile" : "crd", 640 | "x-msclip" : "clp", 641 | "x-msdownload" : [ "exe", "dll", "com", "bat", "msi" ], 642 | "x-msmediaview" : [ "mvb", "m13", "m14" ], 643 | "x-msmetafile" : [ "wmf", "wmz", "emf", "emz" ], 644 | "x-msmoney" : "mny", 645 | "x-mspublisher" : "pub", 646 | "x-msschedule" : "scd", 647 | "x-msterminal" : "trm", 648 | "x-mswrite" : "wri", 649 | "x-nzb" : "nzb", 650 | "x-pkcs12" : [ "p12", "pfx" ], 651 | "x-pkcs7-certificates" : [ "p7b", "spc" ], 652 | "x-research-info-systems" : "ris", 653 | "x-silverlight-app" : "xap", 654 | "x-sql" : "sql", 655 | "x-stuffitx" : "sitx", 656 | "x-subrip" : "srt", 657 | "x-t3vm-image" : "t3", 658 | "x-tads" : "gam", 659 | "x-tex" : "tex", 660 | "x-tex-tfm" : "tfm", 661 | "x-tgif" : "obj", 662 | "x-xliff+xml" : "xlf", 663 | "x-xz" : "xz", 664 | "x-zmachine" : [ "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8" ], 665 | "xaml+xml" : "xaml", 666 | "xcap-diff+xml" : "xdf", 667 | "xenc+xml" : "xenc", 668 | "xml-dtd" : "dtd", 669 | "xop+xml" : "xop", 670 | "xproc+xml" : "xpl", 671 | "xslt+xml" : "xslt", 672 | "xv+xml" : [ "mxml", "xhvml", "xvml", "xvm" ], 673 | "yang" : "yang", 674 | "yin+xml" : "yin", 675 | "envoy" : "evy", 676 | "fractals" : "fif", 677 | "internet-property-stream" : "acx", 678 | "olescript" : "axs", 679 | "vnd.ms-outlook" : "msg", 680 | "vnd.ms-pkicertstore" : "sst", 681 | "x-compress" : "z", 682 | "x-compressed" : "tgz", 683 | "x-gzip" : "gz", 684 | "x-perfmon" : [ "pma", "pmc", "pml", "pmr", "pmw" ], 685 | "x-pkcs7-mime" : [ "p7c", "p7m" ], 686 | "ynd.ms-pkipko" : "pko" 687 | }, 688 | "audio" : { 689 | "amr" : "amr", 690 | "amr-wb" : "awb", 691 | "annodex" : "axa", 692 | "basic" : [ "au", "snd" ], 693 | "flac" : "flac", 694 | "midi" : [ "mid", "midi", "kar", "rmi" ], 695 | "mpeg" : [ "mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a" ], 696 | "mpegurl" : "m3u", 697 | "ogg" : [ "oga", "ogg", "spx" ], 698 | "prs.sid" : "sid", 699 | "x-aiff" : [ "aif", "aiff", "aifc" ], 700 | "x-gsm" : "gsm", 701 | "x-ms-wma" : "wma", 702 | "x-ms-wax" : "wax", 703 | "x-pn-realaudio" : "ram", 704 | "x-realaudio" : "ra", 705 | "x-sd2" : "sd2", 706 | "x-wav" : "wav", 707 | "adpcm" : "adp", 708 | "mp4" : "mp4a", 709 | "s3m" : "s3m", 710 | "silk" : "sil", 711 | "vnd.dece.audio" : [ "uva", "uvva" ], 712 | "vnd.digital-winds" : "eol", 713 | "vnd.dra" : "dra", 714 | "vnd.dts" : "dts", 715 | "vnd.dts.hd" : "dtshd", 716 | "vnd.lucent.voice" : "lvp", 717 | "vnd.ms-playready.media.pya" : "pya", 718 | "vnd.nuera.ecelp4800" : "ecelp4800", 719 | "vnd.nuera.ecelp7470" : "ecelp7470", 720 | "vnd.nuera.ecelp9600" : "ecelp9600", 721 | "vnd.rip" : "rip", 722 | "webm" : "weba", 723 | "x-aac" : "aac", 724 | "x-caf" : "caf", 725 | "x-matroska" : "mka", 726 | "x-pn-realaudio-plugin" : "rmp", 727 | "xm" : "xm", 728 | "mid" : [ "mid", "rmi" ] 729 | }, 730 | "chemical" : { 731 | "x-alchemy" : "alc", 732 | "x-cache" : [ "cac", "cache" ], 733 | "x-cache-csf" : "csf", 734 | "x-cactvs-binary" : [ "cbin", "cascii", "ctab" ], 735 | "x-cdx" : "cdx", 736 | "x-chem3d" : "c3d", 737 | "x-cif" : "cif", 738 | "x-cmdf" : "cmdf", 739 | "x-cml" : "cml", 740 | "x-compass" : "cpa", 741 | "x-crossfire" : "bsd", 742 | "x-csml" : [ "csml", "csm" ], 743 | "x-ctx" : "ctx", 744 | "x-cxf" : [ "cxf", "cef" ], 745 | "x-embl-dl-nucleotide" : [ "emb", "embl" ], 746 | "x-gamess-input" : [ "inp", "gam", "gamin" ], 747 | "x-gaussian-checkpoint" : [ "fch", "fchk" ], 748 | "x-gaussian-cube" : "cub", 749 | "x-gaussian-input" : [ "gau", "gjc", "gjf" ], 750 | "x-gaussian-log" : "gal", 751 | "x-gcg8-sequence" : "gcg", 752 | "x-genbank" : "gen", 753 | "x-hin" : "hin", 754 | "x-isostar" : [ "istr", "ist" ], 755 | "x-jcamp-dx" : [ "jdx", "dx" ], 756 | "x-kinemage" : "kin", 757 | "x-macmolecule" : "mcm", 758 | "x-macromodel-input" : [ "mmd", "mmod" ], 759 | "x-mdl-molfile" : "mol", 760 | "x-mdl-rdfile" : "rd", 761 | "x-mdl-rxnfile" : "rxn", 762 | "x-mdl-sdfile" : [ "sd", "sdf" ], 763 | "x-mdl-tgf" : "tgf", 764 | "x-mmcif" : "mcif", 765 | "x-mol2" : "mol2", 766 | "x-molconn-Z" : "b", 767 | "x-mopac-graph" : "gpt", 768 | "x-mopac-input" : [ "mop", "mopcrt", "mpc", "zmt" ], 769 | "x-mopac-out" : "moo", 770 | "x-ncbi-asn1" : "asn", 771 | "x-ncbi-asn1-ascii" : [ "prt", "ent" ], 772 | "x-ncbi-asn1-binary" : [ "val", "aso" ], 773 | "x-pdb" : [ "pdb", "ent" ], 774 | "x-rosdal" : "ros", 775 | "x-swissprot" : "sw", 776 | "x-vamas-iso14976" : "vms", 777 | "x-vmd" : "vmd", 778 | "x-xtel" : "xtel", 779 | "x-xyz" : "xyz" 780 | }, 781 | "image" : { 782 | "gif" : "gif", 783 | "ief" : "ief", 784 | "jpeg" : [ "jpeg", "jpg", "jpe" ], 785 | "pcx" : "pcx", 786 | "png" : "png", 787 | "svg+xml" : [ "svg", "svgz" ], 788 | "tiff" : [ "tiff", "tif" ], 789 | "vnd.djvu" : [ "djvu", "djv" ], 790 | "vnd.wap.wbmp" : "wbmp", 791 | "x-canon-cr2" : "cr2", 792 | "x-canon-crw" : "crw", 793 | "x-cmu-raster" : "ras", 794 | "x-coreldraw" : "cdr", 795 | "x-coreldrawpattern" : "pat", 796 | "x-coreldrawtemplate" : "cdt", 797 | "x-corelphotopaint" : "cpt", 798 | "x-epson-erf" : "erf", 799 | "x-icon" : "ico", 800 | "x-jg" : "art", 801 | "x-jng" : "jng", 802 | "x-nikon-nef" : "nef", 803 | "x-olympus-orf" : "orf", 804 | "x-photoshop" : "psd", 805 | "x-portable-anymap" : "pnm", 806 | "x-portable-bitmap" : "pbm", 807 | "x-portable-graymap" : "pgm", 808 | "x-portable-pixmap" : "ppm", 809 | "x-rgb" : "rgb", 810 | "x-xbitmap" : "xbm", 811 | "x-xpixmap" : "xpm", 812 | "x-xwindowdump" : "xwd", 813 | "bmp" : "bmp", 814 | "cgm" : "cgm", 815 | "g3fax" : "g3", 816 | "ktx" : "ktx", 817 | "prs.btif" : "btif", 818 | "sgi" : "sgi", 819 | "vnd.dece.graphic" : [ "uvi", "uvvi", "uvg", "uvvg" ], 820 | "vnd.dwg" : "dwg", 821 | "vnd.dxf" : "dxf", 822 | "vnd.fastbidsheet" : "fbs", 823 | "vnd.fpx" : "fpx", 824 | "vnd.fst" : "fst", 825 | "vnd.fujixerox.edmics-mmr" : "mmr", 826 | "vnd.fujixerox.edmics-rlc" : "rlc", 827 | "vnd.ms-modi" : "mdi", 828 | "vnd.ms-photo" : "wdp", 829 | "vnd.net-fpx" : "npx", 830 | "vnd.xiff" : "xif", 831 | "webp" : "webp", 832 | "x-3ds" : "3ds", 833 | "x-cmx" : "cmx", 834 | "x-freehand" : [ "fh", "fhc", "fh4", "fh5", "fh7" ], 835 | "x-pict" : [ "pic", "pct" ], 836 | "x-tga" : "tga", 837 | "cis-cod" : "cod", 838 | "pipeg" : "jfif" 839 | }, 840 | "message" : { 841 | "rfc822" : [ "eml", "mime", "mht", "mhtml", "nws" ] 842 | }, 843 | "model" : { 844 | "iges" : [ "igs", "iges" ], 845 | "mesh" : [ "msh", "mesh", "silo" ], 846 | "vrml" : [ "wrl", "vrml" ], 847 | "x3d+vrml" : [ "x3dv", "x3dvz" ], 848 | "x3d+xml" : [ "x3d", "x3dz" ], 849 | "x3d+binary" : [ "x3db", "x3dbz" ], 850 | "vnd.collada+xml" : "dae", 851 | "vnd.dwf" : "dwf", 852 | "vnd.gdl" : "gdl", 853 | "vnd.gtw" : "gtw", 854 | "vnd.mts" : "mts", 855 | "vnd.vtu" : "vtu" 856 | }, 857 | "text" : { 858 | "cache-manifest" : [ "manifest", "appcache" ], 859 | "calendar" : [ "ics", "icz", "ifb" ], 860 | "css" : "css", 861 | "csv" : "csv", 862 | "h323" : "323", 863 | "html" : [ "html", "htm", "shtml", "stm" ], 864 | "iuls" : "uls", 865 | "mathml" : "mml", 866 | "plain" : [ "txt", "text", "brf", "conf", "def", "list", "log", "in", "bas" ], 867 | "richtext" : "rtx", 868 | "scriptlet" : [ "sct", "wsc" ], 869 | "texmacs" : [ "tm", "ts" ], 870 | "tab-separated-values" : "tsv", 871 | "vnd.sun.j2me.app-descriptor" : "jad", 872 | "vnd.wap.wml" : "wml", 873 | "vnd.wap.wmlscript" : "wmls", 874 | "x-bibtex" : "bib", 875 | "x-boo" : "boo", 876 | "x-c++hdr" : [ "h++", "hpp", "hxx", "hh" ], 877 | "x-c++src" : [ "c++", "cpp", "cxx", "cc" ], 878 | "x-component" : "htc", 879 | "x-dsrc" : "d", 880 | "x-diff" : [ "diff", "patch" ], 881 | "x-haskell" : "hs", 882 | "x-java" : "java", 883 | "x-literate-haskell" : "lhs", 884 | "x-moc" : "moc", 885 | "x-pascal" : [ "p", "pas" ], 886 | "x-pcs-gcd" : "gcd", 887 | "x-perl" : [ "pl", "pm" ], 888 | "x-python" : "py", 889 | "x-scala" : "scala", 890 | "x-setext" : "etx", 891 | "x-tcl" : [ "tcl", "tk" ], 892 | "x-tex" : [ "tex", "ltx", "sty", "cls" ], 893 | "x-vcalendar" : "vcs", 894 | "x-vcard" : "vcf", 895 | "n3" : "n3", 896 | "prs.lines.tag" : "dsc", 897 | "sgml" : [ "sgml", "sgm" ], 898 | "troff" : [ "t", "tr", "roff", "man", "me", "ms" ], 899 | "turtle" : "ttl", 900 | "uri-list" : [ "uri", "uris", "urls" ], 901 | "vcard" : "vcard", 902 | "vnd.curl" : "curl", 903 | "vnd.curl.dcurl" : "dcurl", 904 | "vnd.curl.scurl" : "scurl", 905 | "vnd.curl.mcurl" : "mcurl", 906 | "vnd.dvb.subtitle" : "sub", 907 | "vnd.fly" : "fly", 908 | "vnd.fmi.flexstor" : "flx", 909 | "vnd.graphviz" : "gv", 910 | "vnd.in3d.3dml" : "3dml", 911 | "vnd.in3d.spot" : "spot", 912 | "x-asm" : [ "s", "asm" ], 913 | "x-c" : [ "c", "cc", "cxx", "cpp", "h", "hh", "dic" ], 914 | "x-fortran" : [ "f", "for", "f77", "f90" ], 915 | "x-opml" : "opml", 916 | "x-nfo" : "nfo", 917 | "x-sfv" : "sfv", 918 | "x-uuencode" : "uu", 919 | "webviewhtml" : "htt" 920 | }, 921 | "video" : { 922 | "3gpp" : "3gp", 923 | "annodex" : "axv", 924 | "dl" : "dl", 925 | "dv" : [ "dif", "dv" ], 926 | "fli" : "fli", 927 | "gl" : "gl", 928 | "mpeg" : [ "mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2" ], 929 | "mp4" : [ "mp4", "mp4v", "mpg4" ], 930 | "quicktime" : [ "qt", "mov" ], 931 | "ogg" : "ogv", 932 | "vnd.mpegurl" : [ "mxu", "m4u" ], 933 | "x-flv" : "flv", 934 | "x-la-asf" : [ "lsf", "lsx" ], 935 | "x-mng" : "mng", 936 | "x-ms-asf" : [ "asf", "asx", "asr" ], 937 | "x-ms-wm" : "wm", 938 | "x-ms-wmv" : "wmv", 939 | "x-ms-wmx" : "wmx", 940 | "x-ms-wvx" : "wvx", 941 | "x-msvideo" : "avi", 942 | "x-sgi-movie" : "movie", 943 | "x-matroska" : [ "mpv", "mkv", "mk3d", "mks" ], 944 | "3gpp2" : "3g2", 945 | "h261" : "h261", 946 | "h263" : "h263", 947 | "h264" : "h264", 948 | "jpeg" : "jpgv", 949 | "jpm" : [ "jpm", "jpgm" ], 950 | "mj2" : [ "mj2", "mjp2" ], 951 | "vnd.dece.hd" : [ "uvh", "uvvh" ], 952 | "vnd.dece.mobile" : [ "uvm", "uvvm" ], 953 | "vnd.dece.pd" : [ "uvp", "uvvp" ], 954 | "vnd.dece.sd" : [ "uvs", "uvvs" ], 955 | "vnd.dece.video" : [ "uvv", "uvvv" ], 956 | "vnd.dvb.file" : "dvb", 957 | "vnd.fvt" : "fvt", 958 | "vnd.ms-playready.media.pyv" : "pyv", 959 | "vnd.uvvu.mp4" : [ "uvu", "uvvu" ], 960 | "vnd.vivo" : "viv", 961 | "webm" : "webm", 962 | "x-f4v" : "f4v", 963 | "x-m4v" : "m4v", 964 | "x-ms-vob" : "vob", 965 | "x-smv" : "smv" 966 | }, 967 | "x-conference" : { 968 | "x-cooltalk" : "ice" 969 | }, 970 | "x-world" : { 971 | "x-vrml" : [ "vrm", "vrml", "wrl", "flr", "wrz", "xaf", "xof" ] 972 | } 973 | }; 974 | 975 | var mimeTypes = (function() { 976 | var type, subtype, val, index, mimeTypes = {}; 977 | for (type in table) { 978 | if (table.hasOwnProperty(type)) { 979 | for (subtype in table[type]) { 980 | if (table[type].hasOwnProperty(subtype)) { 981 | val = table[type][subtype]; 982 | if (typeof val == "string") { 983 | mimeTypes[val] = type + "/" + subtype; 984 | } else { 985 | for (index = 0; index < val.length; index++) { 986 | mimeTypes[val[index]] = type + "/" + subtype; 987 | } 988 | } 989 | } 990 | } 991 | } 992 | } 993 | return mimeTypes; 994 | })(); 995 | 996 | zip.getMimeType = function(filename) { 997 | var defaultValue = "application/octet-stream"; 998 | return filename && mimeTypes[filename.split(".").pop().toLowerCase()] || defaultValue; 999 | }; 1000 | 1001 | })(); 1002 | -------------------------------------------------------------------------------- /js/zip/zip-ext.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | (function() { 30 | 31 | var ERR_HTTP_RANGE = "HTTP Range not supported."; 32 | 33 | var Reader = zip.Reader; 34 | var Writer = zip.Writer; 35 | 36 | var ZipDirectoryEntry; 37 | 38 | var appendABViewSupported; 39 | try { 40 | appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0; 41 | } catch (e) { 42 | } 43 | 44 | function HttpReader(url) { 45 | var that = this; 46 | 47 | function getData(callback, onerror) { 48 | var request; 49 | if (!that.data) { 50 | request = new XMLHttpRequest(); 51 | request.addEventListener("load", function() { 52 | if (!that.size) 53 | that.size = Number(request.getResponseHeader("Content-Length")); 54 | that.data = new Uint8Array(request.response); 55 | callback(); 56 | }, false); 57 | request.addEventListener("error", onerror, false); 58 | request.open("GET", url); 59 | request.responseType = "arraybuffer"; 60 | request.send(); 61 | } else 62 | callback(); 63 | } 64 | 65 | function init(callback, onerror) { 66 | var request = new XMLHttpRequest(); 67 | request.addEventListener("load", function() { 68 | that.size = Number(request.getResponseHeader("Content-Length")); 69 | callback(); 70 | }, false); 71 | request.addEventListener("error", onerror, false); 72 | request.open("HEAD", url); 73 | request.send(); 74 | } 75 | 76 | function readUint8Array(index, length, callback, onerror) { 77 | getData(function() { 78 | callback(new Uint8Array(that.data.subarray(index, index + length))); 79 | }, onerror); 80 | } 81 | 82 | that.size = 0; 83 | that.init = init; 84 | that.readUint8Array = readUint8Array; 85 | } 86 | HttpReader.prototype = new Reader(); 87 | HttpReader.prototype.constructor = HttpReader; 88 | 89 | function HttpRangeReader(url) { 90 | var that = this; 91 | 92 | function init(callback, onerror) { 93 | var request = new XMLHttpRequest(); 94 | request.addEventListener("load", function() { 95 | that.size = Number(request.getResponseHeader("Content-Length")); 96 | if (request.getResponseHeader("Accept-Ranges") == "bytes") 97 | callback(); 98 | else 99 | onerror(ERR_HTTP_RANGE); 100 | }, false); 101 | request.addEventListener("error", onerror, false); 102 | request.open("HEAD", url); 103 | request.send(); 104 | } 105 | 106 | function readArrayBuffer(index, length, callback, onerror) { 107 | var request = new XMLHttpRequest(); 108 | request.open("GET", url); 109 | request.responseType = "arraybuffer"; 110 | request.setRequestHeader("Range", "bytes=" + index + "-" + (index + length - 1)); 111 | request.addEventListener("load", function() { 112 | callback(request.response); 113 | }, false); 114 | request.addEventListener("error", onerror, false); 115 | request.send(); 116 | } 117 | 118 | function readUint8Array(index, length, callback, onerror) { 119 | readArrayBuffer(index, length, function(arraybuffer) { 120 | callback(new Uint8Array(arraybuffer)); 121 | }, onerror); 122 | } 123 | 124 | that.size = 0; 125 | that.init = init; 126 | that.readUint8Array = readUint8Array; 127 | } 128 | HttpRangeReader.prototype = new Reader(); 129 | HttpRangeReader.prototype.constructor = HttpRangeReader; 130 | 131 | function ArrayBufferReader(arrayBuffer) { 132 | var that = this; 133 | 134 | function init(callback, onerror) { 135 | that.size = arrayBuffer.byteLength; 136 | callback(); 137 | } 138 | 139 | function readUint8Array(index, length, callback, onerror) { 140 | callback(new Uint8Array(arrayBuffer.slice(index, index + length))); 141 | } 142 | 143 | that.size = 0; 144 | that.init = init; 145 | that.readUint8Array = readUint8Array; 146 | } 147 | ArrayBufferReader.prototype = new Reader(); 148 | ArrayBufferReader.prototype.constructor = ArrayBufferReader; 149 | 150 | function ArrayBufferWriter() { 151 | var array, that = this; 152 | 153 | function init(callback, onerror) { 154 | array = new Uint8Array(); 155 | callback(); 156 | } 157 | 158 | function writeUint8Array(arr, callback, onerror) { 159 | var tmpArray = new Uint8Array(array.length + arr.length); 160 | tmpArray.set(array); 161 | tmpArray.set(arr, array.length); 162 | array = tmpArray; 163 | callback(); 164 | } 165 | 166 | function getData(callback) { 167 | callback(array.buffer); 168 | } 169 | 170 | that.init = init; 171 | that.writeUint8Array = writeUint8Array; 172 | that.getData = getData; 173 | } 174 | ArrayBufferWriter.prototype = new Writer(); 175 | ArrayBufferWriter.prototype.constructor = ArrayBufferWriter; 176 | 177 | function FileWriter(fileEntry, contentType) { 178 | var writer, that = this; 179 | 180 | function init(callback, onerror) { 181 | fileEntry.createWriter(function(fileWriter) { 182 | writer = fileWriter; 183 | callback(); 184 | }, onerror); 185 | } 186 | 187 | function writeUint8Array(array, callback, onerror) { 188 | var blob = new Blob([ appendABViewSupported ? array : array.buffer ], { 189 | type : contentType 190 | }); 191 | writer.onwrite = function() { 192 | writer.onwrite = null; 193 | callback(); 194 | }; 195 | writer.onerror = onerror; 196 | writer.write(blob); 197 | } 198 | 199 | function getData(callback) { 200 | fileEntry.file(callback); 201 | } 202 | 203 | that.init = init; 204 | that.writeUint8Array = writeUint8Array; 205 | that.getData = getData; 206 | } 207 | FileWriter.prototype = new Writer(); 208 | FileWriter.prototype.constructor = FileWriter; 209 | 210 | zip.FileWriter = FileWriter; 211 | zip.HttpReader = HttpReader; 212 | zip.HttpRangeReader = HttpRangeReader; 213 | zip.ArrayBufferReader = ArrayBufferReader; 214 | zip.ArrayBufferWriter = ArrayBufferWriter; 215 | 216 | if (zip.fs) { 217 | ZipDirectoryEntry = zip.fs.ZipDirectoryEntry; 218 | ZipDirectoryEntry.prototype.addHttpContent = function(name, URL, useRangeHeader) { 219 | function addChild(parent, name, params, directory) { 220 | if (parent.directory) 221 | return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new zip.fs.ZipFileEntry(parent.fs, name, params, parent); 222 | else 223 | throw "Parent entry is not a directory."; 224 | } 225 | 226 | return addChild(this, name, { 227 | data : URL, 228 | Reader : useRangeHeader ? HttpRangeReader : HttpReader 229 | }); 230 | }; 231 | ZipDirectoryEntry.prototype.importHttpContent = function(URL, useRangeHeader, onend, onerror) { 232 | this.importZip(useRangeHeader ? new HttpRangeReader(URL) : new HttpReader(URL), onend, onerror); 233 | }; 234 | zip.fs.FS.prototype.importHttpContent = function(URL, useRangeHeader, onend, onerror) { 235 | this.entries = []; 236 | this.root = new ZipDirectoryEntry(this); 237 | this.root.importHttpContent(URL, useRangeHeader, onend, onerror); 238 | }; 239 | } 240 | 241 | })(); 242 | -------------------------------------------------------------------------------- /js/zip/zip-fs.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | (function() { 30 | 31 | var CHUNK_SIZE = 512 * 1024; 32 | 33 | var TextWriter = zip.TextWriter, // 34 | BlobWriter = zip.BlobWriter, // 35 | Data64URIWriter = zip.Data64URIWriter, // 36 | Reader = zip.Reader, // 37 | TextReader = zip.TextReader, // 38 | BlobReader = zip.BlobReader, // 39 | Data64URIReader = zip.Data64URIReader, // 40 | createReader = zip.createReader, // 41 | createWriter = zip.createWriter; 42 | 43 | function ZipBlobReader(entry) { 44 | var that = this, blobReader; 45 | 46 | function init(callback) { 47 | this.size = entry.uncompressedSize; 48 | callback(); 49 | } 50 | 51 | function getData(callback) { 52 | if (that.data) 53 | callback(); 54 | else 55 | entry.getData(new BlobWriter(), function(data) { 56 | that.data = data; 57 | blobReader = new BlobReader(data); 58 | callback(); 59 | }, null, that.checkCrc32); 60 | } 61 | 62 | function readUint8Array(index, length, callback, onerror) { 63 | getData(function() { 64 | blobReader.readUint8Array(index, length, callback, onerror); 65 | }, onerror); 66 | } 67 | 68 | that.size = 0; 69 | that.init = init; 70 | that.readUint8Array = readUint8Array; 71 | } 72 | ZipBlobReader.prototype = new Reader(); 73 | ZipBlobReader.prototype.constructor = ZipBlobReader; 74 | ZipBlobReader.prototype.checkCrc32 = false; 75 | 76 | function getTotalSize(entry) { 77 | var size = 0; 78 | 79 | function process(entry) { 80 | size += entry.uncompressedSize || 0; 81 | entry.children.forEach(process); 82 | } 83 | 84 | process(entry); 85 | return size; 86 | } 87 | 88 | function initReaders(entry, onend, onerror) { 89 | var index = 0; 90 | 91 | function next() { 92 | index++; 93 | if (index < entry.children.length) 94 | process(entry.children[index]); 95 | else 96 | onend(); 97 | } 98 | 99 | function process(child) { 100 | if (child.directory) 101 | initReaders(child, next, onerror); 102 | else { 103 | child.reader = new child.Reader(child.data, onerror); 104 | child.reader.init(function() { 105 | child.uncompressedSize = child.reader.size; 106 | next(); 107 | }); 108 | } 109 | } 110 | 111 | if (entry.children.length) 112 | process(entry.children[index]); 113 | else 114 | onend(); 115 | } 116 | 117 | function detach(entry) { 118 | var children = entry.parent.children; 119 | children.forEach(function(child, index) { 120 | if (child.id == entry.id) 121 | children.splice(index, 1); 122 | }); 123 | } 124 | 125 | function exportZip(zipWriter, entry, onend, onprogress, totalSize) { 126 | var currentIndex = 0; 127 | 128 | function process(zipWriter, entry, onend, onprogress, totalSize) { 129 | var childIndex = 0; 130 | 131 | function exportChild() { 132 | var child = entry.children[childIndex]; 133 | if (child) 134 | zipWriter.add(child.getFullname(), child.reader, function() { 135 | currentIndex += child.uncompressedSize || 0; 136 | process(zipWriter, child, function() { 137 | childIndex++; 138 | exportChild(); 139 | }, onprogress, totalSize); 140 | }, function(index) { 141 | if (onprogress) 142 | onprogress(currentIndex + index, totalSize); 143 | }, { 144 | directory : child.directory, 145 | version : child.zipVersion 146 | }); 147 | else 148 | onend(); 149 | } 150 | 151 | exportChild(); 152 | } 153 | 154 | process(zipWriter, entry, onend, onprogress, totalSize); 155 | } 156 | 157 | function addFileEntry(zipEntry, fileEntry, onend, onerror) { 158 | function getChildren(fileEntry, callback) { 159 | if (fileEntry.isDirectory) 160 | fileEntry.createReader().readEntries(callback); 161 | if (fileEntry.isFile) 162 | callback([]); 163 | } 164 | 165 | function process(zipEntry, fileEntry, onend) { 166 | getChildren(fileEntry, function(children) { 167 | var childIndex = 0; 168 | 169 | function addChild(child) { 170 | function nextChild(childFileEntry) { 171 | process(childFileEntry, child, function() { 172 | childIndex++; 173 | processChild(); 174 | }); 175 | } 176 | 177 | if (child.isDirectory) 178 | nextChild(zipEntry.addDirectory(child.name)); 179 | if (child.isFile) 180 | child.file(function(file) { 181 | var childZipEntry = zipEntry.addBlob(child.name, file); 182 | childZipEntry.uncompressedSize = file.size; 183 | nextChild(childZipEntry); 184 | }, onerror); 185 | } 186 | 187 | function processChild() { 188 | var child = children[childIndex]; 189 | if (child) 190 | addChild(child); 191 | else 192 | onend(); 193 | } 194 | 195 | processChild(); 196 | }); 197 | } 198 | 199 | if (fileEntry.isDirectory) 200 | process(zipEntry, fileEntry, onend); 201 | else 202 | fileEntry.file(function(file) { 203 | zipEntry.addBlob(fileEntry.name, file); 204 | onend(); 205 | }, onerror); 206 | } 207 | 208 | function getFileEntry(fileEntry, entry, onend, onprogress, onerror, totalSize, checkCrc32) { 209 | var currentIndex = 0; 210 | 211 | function process(fileEntry, entry, onend, onprogress, onerror, totalSize) { 212 | var childIndex = 0; 213 | 214 | function addChild(child) { 215 | function nextChild(childFileEntry) { 216 | currentIndex += child.uncompressedSize || 0; 217 | process(childFileEntry, child, function() { 218 | childIndex++; 219 | processChild(); 220 | }, onprogress, onerror, totalSize); 221 | } 222 | 223 | if (child.directory) 224 | fileEntry.getDirectory(child.name, { 225 | create : true 226 | }, nextChild, onerror); 227 | else 228 | fileEntry.getFile(child.name, { 229 | create : true 230 | }, function(file) { 231 | child.getData(new zip.FileWriter(file, zip.getMimeType(child.name)), nextChild, function(index) { 232 | if (onprogress) 233 | onprogress(currentIndex + index, totalSize); 234 | }, checkCrc32); 235 | }, onerror); 236 | } 237 | 238 | function processChild() { 239 | var child = entry.children[childIndex]; 240 | if (child) 241 | addChild(child); 242 | else 243 | onend(); 244 | } 245 | 246 | processChild(); 247 | } 248 | 249 | if (entry.directory) 250 | process(fileEntry, entry, onend, onprogress, onerror, totalSize); 251 | else 252 | entry.getData(new zip.FileWriter(fileEntry, zip.getMimeType(entry.name)), onend, onprogress, checkCrc32); 253 | } 254 | 255 | function resetFS(fs) { 256 | fs.entries = []; 257 | fs.root = new ZipDirectoryEntry(fs); 258 | } 259 | 260 | function bufferedCopy(reader, writer, onend, onprogress, onerror) { 261 | var chunkIndex = 0; 262 | 263 | function stepCopy() { 264 | var index = chunkIndex * CHUNK_SIZE; 265 | if (onprogress) 266 | onprogress(index, reader.size); 267 | if (index < reader.size) 268 | reader.readUint8Array(index, Math.min(CHUNK_SIZE, reader.size - index), function(array) { 269 | writer.writeUint8Array(new Uint8Array(array), function() { 270 | chunkIndex++; 271 | stepCopy(); 272 | }); 273 | }, onerror); 274 | else 275 | writer.getData(onend); 276 | } 277 | 278 | stepCopy(); 279 | } 280 | 281 | function getEntryData(writer, onend, onprogress, onerror) { 282 | var that = this; 283 | if (!writer || (writer.constructor == that.Writer && that.data)) 284 | onend(that.data); 285 | else { 286 | if (!that.reader) 287 | that.reader = new that.Reader(that.data, onerror); 288 | that.reader.init(function() { 289 | writer.init(function() { 290 | bufferedCopy(that.reader, writer, onend, onprogress, onerror); 291 | }, onerror); 292 | }); 293 | } 294 | } 295 | 296 | function addChild(parent, name, params, directory) { 297 | if (parent.directory) 298 | return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent); 299 | else 300 | throw "Parent entry is not a directory."; 301 | } 302 | 303 | function ZipEntry() { 304 | } 305 | 306 | ZipEntry.prototype = { 307 | init : function(fs, name, params, parent) { 308 | var that = this; 309 | if (fs.root && parent && parent.getChildByName(name)) 310 | throw "Entry filename already exists."; 311 | if (!params) 312 | params = {}; 313 | that.fs = fs; 314 | that.name = name; 315 | that.id = fs.entries.length; 316 | that.parent = parent; 317 | that.children = []; 318 | that.zipVersion = params.zipVersion || 0x14; 319 | that.uncompressedSize = 0; 320 | fs.entries.push(that); 321 | if (parent) 322 | that.parent.children.push(that); 323 | }, 324 | getFileEntry : function(fileEntry, onend, onprogress, onerror, checkCrc32) { 325 | var that = this; 326 | initReaders(that, function() { 327 | getFileEntry(fileEntry, that, onend, onprogress, onerror, getTotalSize(that), checkCrc32); 328 | }, onerror); 329 | }, 330 | moveTo : function(target) { 331 | var that = this; 332 | if (target.directory) { 333 | if (!target.isDescendantOf(that)) { 334 | if (that != target) { 335 | if (target.getChildByName(that.name)) 336 | throw "Entry filename already exists."; 337 | detach(that); 338 | that.parent = target; 339 | target.children.push(that); 340 | } 341 | } else 342 | throw "Entry is a ancestor of target entry."; 343 | } else 344 | throw "Target entry is not a directory."; 345 | }, 346 | getFullname : function() { 347 | var that = this, fullname = that.name, entry = that.parent; 348 | while (entry) { 349 | fullname = (entry.name ? entry.name + "/" : "") + fullname; 350 | entry = entry.parent; 351 | } 352 | return fullname; 353 | }, 354 | isDescendantOf : function(ancestor) { 355 | var entry = this.parent; 356 | while (entry && entry.id != ancestor.id) 357 | entry = entry.parent; 358 | return !!entry; 359 | } 360 | }; 361 | ZipEntry.prototype.constructor = ZipEntry; 362 | 363 | var ZipFileEntryProto; 364 | 365 | function ZipFileEntry(fs, name, params, parent) { 366 | var that = this; 367 | ZipEntry.prototype.init.call(that, fs, name, params, parent); 368 | that.Reader = params.Reader; 369 | that.Writer = params.Writer; 370 | that.data = params.data; 371 | that.getData = params.getData || getEntryData; 372 | } 373 | 374 | ZipFileEntry.prototype = ZipFileEntryProto = new ZipEntry(); 375 | ZipFileEntryProto.constructor = ZipFileEntry; 376 | ZipFileEntryProto.getText = function(onend, onprogress, checkCrc32, encoding) { 377 | this.getData(new TextWriter(encoding), onend, onprogress, checkCrc32); 378 | }; 379 | ZipFileEntryProto.getBlob = function(mimeType, onend, onprogress, checkCrc32) { 380 | this.getData(new BlobWriter(mimeType), onend, onprogress, checkCrc32); 381 | }; 382 | ZipFileEntryProto.getData64URI = function(mimeType, onend, onprogress, checkCrc32) { 383 | this.getData(new Data64URIWriter(mimeType), onend, onprogress, checkCrc32); 384 | }; 385 | 386 | var ZipDirectoryEntryProto; 387 | 388 | function ZipDirectoryEntry(fs, name, params, parent) { 389 | var that = this; 390 | ZipEntry.prototype.init.call(that, fs, name, params, parent); 391 | that.directory = true; 392 | } 393 | 394 | ZipDirectoryEntry.prototype = ZipDirectoryEntryProto = new ZipEntry(); 395 | ZipDirectoryEntryProto.constructor = ZipDirectoryEntry; 396 | ZipDirectoryEntryProto.addDirectory = function(name) { 397 | return addChild(this, name, null, true); 398 | }; 399 | ZipDirectoryEntryProto.addText = function(name, text) { 400 | return addChild(this, name, { 401 | data : text, 402 | Reader : TextReader, 403 | Writer : TextWriter 404 | }); 405 | }; 406 | ZipDirectoryEntryProto.addBlob = function(name, blob) { 407 | return addChild(this, name, { 408 | data : blob, 409 | Reader : BlobReader, 410 | Writer : BlobWriter 411 | }); 412 | }; 413 | ZipDirectoryEntryProto.addData64URI = function(name, dataURI) { 414 | return addChild(this, name, { 415 | data : dataURI, 416 | Reader : Data64URIReader, 417 | Writer : Data64URIWriter 418 | }); 419 | }; 420 | ZipDirectoryEntryProto.addFileEntry = function(fileEntry, onend, onerror) { 421 | addFileEntry(this, fileEntry, onend, onerror); 422 | }; 423 | ZipDirectoryEntryProto.addData = function(name, params) { 424 | return addChild(this, name, params); 425 | }; 426 | ZipDirectoryEntryProto.importBlob = function(blob, onend, onerror) { 427 | this.importZip(new BlobReader(blob), onend, onerror); 428 | }; 429 | ZipDirectoryEntryProto.importText = function(text, onend, onerror) { 430 | this.importZip(new TextReader(text), onend, onerror); 431 | }; 432 | ZipDirectoryEntryProto.importData64URI = function(dataURI, onend, onerror) { 433 | this.importZip(new Data64URIReader(dataURI), onend, onerror); 434 | }; 435 | ZipDirectoryEntryProto.exportBlob = function(onend, onprogress, onerror) { 436 | this.exportZip(new BlobWriter("application/zip"), onend, onprogress, onerror); 437 | }; 438 | ZipDirectoryEntryProto.exportText = function(onend, onprogress, onerror) { 439 | this.exportZip(new TextWriter(), onend, onprogress, onerror); 440 | }; 441 | ZipDirectoryEntryProto.exportFileEntry = function(fileEntry, onend, onprogress, onerror) { 442 | this.exportZip(new zip.FileWriter(fileEntry, "application/zip"), onend, onprogress, onerror); 443 | }; 444 | ZipDirectoryEntryProto.exportData64URI = function(onend, onprogress, onerror) { 445 | this.exportZip(new Data64URIWriter("application/zip"), onend, onprogress, onerror); 446 | }; 447 | ZipDirectoryEntryProto.importZip = function(reader, onend, onerror) { 448 | var that = this; 449 | createReader(reader, function(zipReader) { 450 | zipReader.getEntries(function(entries) { 451 | entries.forEach(function(entry) { 452 | var parent = that, path = entry.filename.split("/"), name = path.pop(); 453 | path.forEach(function(pathPart) { 454 | parent = parent.getChildByName(pathPart) || new ZipDirectoryEntry(that.fs, pathPart, null, parent); 455 | }); 456 | if (!entry.directory) 457 | addChild(parent, name, { 458 | data : entry, 459 | Reader : ZipBlobReader 460 | }); 461 | }); 462 | onend(); 463 | }); 464 | }, onerror); 465 | }; 466 | ZipDirectoryEntryProto.exportZip = function(writer, onend, onprogress, onerror) { 467 | var that = this; 468 | initReaders(that, function() { 469 | createWriter(writer, function(zipWriter) { 470 | exportZip(zipWriter, that, function() { 471 | zipWriter.close(onend); 472 | }, onprogress, getTotalSize(that)); 473 | }, onerror); 474 | }, onerror); 475 | }; 476 | ZipDirectoryEntryProto.getChildByName = function(name) { 477 | var childIndex, child, that = this; 478 | for (childIndex = 0; childIndex < that.children.length; childIndex++) { 479 | child = that.children[childIndex]; 480 | if (child.name == name) 481 | return child; 482 | } 483 | }; 484 | 485 | function FS() { 486 | resetFS(this); 487 | } 488 | FS.prototype = { 489 | remove : function(entry) { 490 | detach(entry); 491 | this.entries[entry.id] = null; 492 | }, 493 | find : function(fullname) { 494 | var index, path = fullname.split("/"), node = this.root; 495 | for (index = 0; node && index < path.length; index++) 496 | node = node.getChildByName(path[index]); 497 | return node; 498 | }, 499 | getById : function(id) { 500 | return this.entries[id]; 501 | }, 502 | importBlob : function(blob, onend, onerror) { 503 | resetFS(this); 504 | this.root.importBlob(blob, onend, onerror); 505 | }, 506 | importText : function(text, onend, onerror) { 507 | resetFS(this); 508 | this.root.importText(text, onend, onerror); 509 | }, 510 | importData64URI : function(dataURI, onend, onerror) { 511 | resetFS(this); 512 | this.root.importData64URI(dataURI, onend, onerror); 513 | }, 514 | exportBlob : function(onend, onprogress, onerror) { 515 | this.root.exportBlob(onend, onprogress, onerror); 516 | }, 517 | exportText : function(onend, onprogress, onerror) { 518 | this.root.exportText(onend, onprogress, onerror); 519 | }, 520 | exportFileEntry : function(fileEntry, onend, onprogress, onerror) { 521 | this.root.exportFileEntry(fileEntry, onend, onprogress, onerror); 522 | }, 523 | exportData64URI : function(onend, onprogress, onerror) { 524 | this.root.exportData64URI(onend, onprogress, onerror); 525 | } 526 | }; 527 | 528 | zip.fs = { 529 | FS : FS, 530 | ZipDirectoryEntry : ZipDirectoryEntry, 531 | ZipFileEntry : ZipFileEntry 532 | }; 533 | 534 | zip.getMimeType = function() { 535 | return "application/octet-stream"; 536 | }; 537 | 538 | })(); 539 | -------------------------------------------------------------------------------- /js/zip/zip.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | (function(obj) { 30 | 31 | var ERR_BAD_FORMAT = "File format is not recognized."; 32 | var ERR_ENCRYPTED = "File contains encrypted entry."; 33 | var ERR_ZIP64 = "File is using Zip64 (4gb+ file size)."; 34 | var ERR_READ = "Error while reading zip file."; 35 | var ERR_WRITE = "Error while writing zip file."; 36 | var ERR_WRITE_DATA = "Error while writing file data."; 37 | var ERR_READ_DATA = "Error while reading file data."; 38 | var ERR_DUPLICATED_NAME = "File already exists."; 39 | var CHUNK_SIZE = 512 * 1024; 40 | 41 | var INFLATE_JS = "inflate.js"; 42 | var DEFLATE_JS = "deflate.js"; 43 | 44 | var TEXT_PLAIN = "text/plain"; 45 | 46 | var MESSAGE_EVENT = "message"; 47 | 48 | var appendABViewSupported; 49 | try { 50 | appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0; 51 | } catch (e) { 52 | } 53 | 54 | function Crc32() { 55 | var crc = -1, that = this; 56 | that.append = function(data) { 57 | var offset, table = that.table; 58 | for (offset = 0; offset < data.length; offset++) 59 | crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; 60 | }; 61 | that.get = function() { 62 | return ~crc; 63 | }; 64 | } 65 | Crc32.prototype.table = (function() { 66 | var i, j, t, table = []; 67 | for (i = 0; i < 256; i++) { 68 | t = i; 69 | for (j = 0; j < 8; j++) 70 | if (t & 1) 71 | t = (t >>> 1) ^ 0xEDB88320; 72 | else 73 | t = t >>> 1; 74 | table[i] = t; 75 | } 76 | return table; 77 | })(); 78 | 79 | function blobSlice(blob, index, length) { 80 | if (blob.slice) 81 | return blob.slice(index, index + length); 82 | else if (blob.webkitSlice) 83 | return blob.webkitSlice(index, index + length); 84 | else if (blob.mozSlice) 85 | return blob.mozSlice(index, index + length); 86 | else if (blob.msSlice) 87 | return blob.msSlice(index, index + length); 88 | } 89 | 90 | function getDataHelper(byteLength, bytes) { 91 | var dataBuffer, dataArray; 92 | dataBuffer = new ArrayBuffer(byteLength); 93 | dataArray = new Uint8Array(dataBuffer); 94 | if (bytes) 95 | dataArray.set(bytes, 0); 96 | return { 97 | buffer : dataBuffer, 98 | array : dataArray, 99 | view : new DataView(dataBuffer) 100 | }; 101 | } 102 | 103 | // Readers 104 | function Reader() { 105 | } 106 | 107 | function TextReader(text) { 108 | var that = this, blobReader; 109 | 110 | function init(callback, onerror) { 111 | var blob = new Blob([ text ], { 112 | type : TEXT_PLAIN 113 | }); 114 | blobReader = new BlobReader(blob); 115 | blobReader.init(function() { 116 | that.size = blobReader.size; 117 | callback(); 118 | }, onerror); 119 | } 120 | 121 | function readUint8Array(index, length, callback, onerror) { 122 | blobReader.readUint8Array(index, length, callback, onerror); 123 | } 124 | 125 | that.size = 0; 126 | that.init = init; 127 | that.readUint8Array = readUint8Array; 128 | } 129 | TextReader.prototype = new Reader(); 130 | TextReader.prototype.constructor = TextReader; 131 | 132 | function Data64URIReader(dataURI) { 133 | var that = this, dataStart; 134 | 135 | function init(callback) { 136 | var dataEnd = dataURI.length; 137 | while (dataURI.charAt(dataEnd - 1) == "=") 138 | dataEnd--; 139 | dataStart = dataURI.indexOf(",") + 1; 140 | that.size = Math.floor((dataEnd - dataStart) * 0.75); 141 | callback(); 142 | } 143 | 144 | function readUint8Array(index, length, callback) { 145 | var i, data = getDataHelper(length); 146 | var start = Math.floor(index / 3) * 4; 147 | var end = Math.ceil((index + length) / 3) * 4; 148 | var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart)); 149 | var delta = index - Math.floor(start / 4) * 3; 150 | for (i = delta; i < delta + length; i++) 151 | data.array[i - delta] = bytes.charCodeAt(i); 152 | callback(data.array); 153 | } 154 | 155 | that.size = 0; 156 | that.init = init; 157 | that.readUint8Array = readUint8Array; 158 | } 159 | Data64URIReader.prototype = new Reader(); 160 | Data64URIReader.prototype.constructor = Data64URIReader; 161 | 162 | function BlobReader(blob) { 163 | var that = this; 164 | 165 | function init(callback) { 166 | this.size = blob.size; 167 | callback(); 168 | } 169 | 170 | function readUint8Array(index, length, callback, onerror) { 171 | var reader = new FileReader(); 172 | reader.onload = function(e) { 173 | callback(new Uint8Array(e.target.result)); 174 | }; 175 | reader.onerror = onerror; 176 | reader.readAsArrayBuffer(blobSlice(blob, index, length)); 177 | } 178 | 179 | that.size = 0; 180 | that.init = init; 181 | that.readUint8Array = readUint8Array; 182 | } 183 | BlobReader.prototype = new Reader(); 184 | BlobReader.prototype.constructor = BlobReader; 185 | 186 | // Writers 187 | 188 | function Writer() { 189 | } 190 | Writer.prototype.getData = function(callback) { 191 | callback(this.data); 192 | }; 193 | 194 | function TextWriter(encoding) { 195 | var that = this, blob; 196 | 197 | function init(callback) { 198 | blob = new Blob([], { 199 | type : TEXT_PLAIN 200 | }); 201 | callback(); 202 | } 203 | 204 | function writeUint8Array(array, callback) { 205 | blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { 206 | type : TEXT_PLAIN 207 | }); 208 | callback(); 209 | } 210 | 211 | function getData(callback, onerror) { 212 | var reader = new FileReader(); 213 | reader.onload = function(e) { 214 | callback(e.target.result); 215 | }; 216 | reader.onerror = onerror; 217 | reader.readAsText(blob, encoding); 218 | } 219 | 220 | that.init = init; 221 | that.writeUint8Array = writeUint8Array; 222 | that.getData = getData; 223 | } 224 | TextWriter.prototype = new Writer(); 225 | TextWriter.prototype.constructor = TextWriter; 226 | 227 | function Data64URIWriter(contentType) { 228 | var that = this, data = "", pending = ""; 229 | 230 | function init(callback) { 231 | data += "data:" + (contentType || "") + ";base64,"; 232 | callback(); 233 | } 234 | 235 | function writeUint8Array(array, callback) { 236 | var i, delta = pending.length, dataString = pending; 237 | pending = ""; 238 | for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++) 239 | dataString += String.fromCharCode(array[i]); 240 | for (; i < array.length; i++) 241 | pending += String.fromCharCode(array[i]); 242 | if (dataString.length > 2) 243 | data += obj.btoa(dataString); 244 | else 245 | pending = dataString; 246 | callback(); 247 | } 248 | 249 | function getData(callback) { 250 | callback(data + obj.btoa(pending)); 251 | } 252 | 253 | that.init = init; 254 | that.writeUint8Array = writeUint8Array; 255 | that.getData = getData; 256 | } 257 | Data64URIWriter.prototype = new Writer(); 258 | Data64URIWriter.prototype.constructor = Data64URIWriter; 259 | 260 | function BlobWriter(contentType) { 261 | var blob, that = this; 262 | 263 | function init(callback) { 264 | blob = new Blob([], { 265 | type : contentType 266 | }); 267 | callback(); 268 | } 269 | 270 | function writeUint8Array(array, callback) { 271 | blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { 272 | type : contentType 273 | }); 274 | callback(); 275 | } 276 | 277 | function getData(callback) { 278 | callback(blob); 279 | } 280 | 281 | that.init = init; 282 | that.writeUint8Array = writeUint8Array; 283 | that.getData = getData; 284 | } 285 | BlobWriter.prototype = new Writer(); 286 | BlobWriter.prototype.constructor = BlobWriter; 287 | 288 | // inflate/deflate core functions 289 | 290 | function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { 291 | var chunkIndex = 0, index, outputSize; 292 | 293 | function onflush() { 294 | worker.removeEventListener(MESSAGE_EVENT, onmessage, false); 295 | onend(outputSize); 296 | } 297 | 298 | function onmessage(event) { 299 | var message = event.data, data = message.data; 300 | 301 | if (message.onappend) { 302 | outputSize += data.length; 303 | writer.writeUint8Array(data, function() { 304 | onappend(false, data); 305 | step(); 306 | }, onwriteerror); 307 | } 308 | if (message.onflush) 309 | if (data) { 310 | outputSize += data.length; 311 | writer.writeUint8Array(data, function() { 312 | onappend(false, data); 313 | onflush(); 314 | }, onwriteerror); 315 | } else 316 | onflush(); 317 | if (message.progress && onprogress) 318 | onprogress(index + message.current, size); 319 | } 320 | 321 | function step() { 322 | index = chunkIndex * CHUNK_SIZE; 323 | if (index < size) 324 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { 325 | worker.postMessage({ 326 | append : true, 327 | data : array 328 | }); 329 | chunkIndex++; 330 | if (onprogress) 331 | onprogress(index, size); 332 | onappend(true, array); 333 | }, onreaderror); 334 | else 335 | worker.postMessage({ 336 | flush : true 337 | }); 338 | } 339 | 340 | outputSize = 0; 341 | worker.addEventListener(MESSAGE_EVENT, onmessage, false); 342 | step(); 343 | } 344 | 345 | function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { 346 | var chunkIndex = 0, index, outputSize = 0; 347 | 348 | function step() { 349 | var outputData; 350 | index = chunkIndex * CHUNK_SIZE; 351 | if (index < size) 352 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) { 353 | var outputData = process.append(inputData, function() { 354 | if (onprogress) 355 | onprogress(offset + index, size); 356 | }); 357 | outputSize += outputData.length; 358 | onappend(true, inputData); 359 | writer.writeUint8Array(outputData, function() { 360 | onappend(false, outputData); 361 | chunkIndex++; 362 | setTimeout(step, 1); 363 | }, onwriteerror); 364 | if (onprogress) 365 | onprogress(index, size); 366 | }, onreaderror); 367 | else { 368 | outputData = process.flush(); 369 | if (outputData) { 370 | outputSize += outputData.length; 371 | writer.writeUint8Array(outputData, function() { 372 | onappend(false, outputData); 373 | onend(outputSize); 374 | }, onwriteerror); 375 | } else 376 | onend(outputSize); 377 | } 378 | } 379 | 380 | step(); 381 | } 382 | 383 | function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { 384 | var worker, crc32 = new Crc32(); 385 | 386 | function oninflateappend(sending, array) { 387 | if (computeCrc32 && !sending) 388 | crc32.append(array); 389 | } 390 | 391 | function oninflateend(outputSize) { 392 | onend(outputSize, crc32.get()); 393 | } 394 | 395 | if (obj.zip.useWebWorkers) { 396 | worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS); 397 | launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); 398 | } else 399 | launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); 400 | return worker; 401 | } 402 | 403 | function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) { 404 | var worker, crc32 = new Crc32(); 405 | 406 | function ondeflateappend(sending, array) { 407 | if (sending) 408 | crc32.append(array); 409 | } 410 | 411 | function ondeflateend(outputSize) { 412 | onend(outputSize, crc32.get()); 413 | } 414 | 415 | function onmessage() { 416 | worker.removeEventListener(MESSAGE_EVENT, onmessage, false); 417 | launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); 418 | } 419 | 420 | if (obj.zip.useWebWorkers) { 421 | worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS); 422 | worker.addEventListener(MESSAGE_EVENT, onmessage, false); 423 | worker.postMessage({ 424 | init : true, 425 | level : level 426 | }); 427 | } else 428 | launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); 429 | return worker; 430 | } 431 | 432 | function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { 433 | var chunkIndex = 0, crc32 = new Crc32(); 434 | 435 | function step() { 436 | var index = chunkIndex * CHUNK_SIZE; 437 | if (index < size) 438 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { 439 | if (computeCrc32) 440 | crc32.append(array); 441 | if (onprogress) 442 | onprogress(index, size, array); 443 | writer.writeUint8Array(array, function() { 444 | chunkIndex++; 445 | step(); 446 | }, onwriteerror); 447 | }, onreaderror); 448 | else 449 | onend(size, crc32.get()); 450 | } 451 | 452 | step(); 453 | } 454 | 455 | // ZipReader 456 | 457 | function decodeASCII(str) { 458 | var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', 459 | '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', 460 | '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', 461 | '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6', 462 | '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3', 463 | '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE', 464 | '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE', 465 | '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7', 466 | '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ]; 467 | for (i = 0; i < str.length; i++) { 468 | charCode = str.charCodeAt(i) & 0xFF; 469 | if (charCode > 127) 470 | out += extendedASCII[charCode - 128]; 471 | else 472 | out += String.fromCharCode(charCode); 473 | } 474 | return out; 475 | } 476 | 477 | function decodeUTF8(string) { 478 | return decodeURIComponent(escape(string)); 479 | } 480 | 481 | function getString(bytes) { 482 | var i, str = ""; 483 | for (i = 0; i < bytes.length; i++) 484 | str += String.fromCharCode(bytes[i]); 485 | return str; 486 | } 487 | 488 | function getDate(timeRaw) { 489 | var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; 490 | try { 491 | return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, 492 | (time & 0x001F) * 2, 0); 493 | } catch (e) { 494 | } 495 | } 496 | 497 | function readCommonHeader(entry, data, index, centralDirectory, onerror) { 498 | entry.version = data.view.getUint16(index, true); 499 | entry.bitFlag = data.view.getUint16(index + 2, true); 500 | entry.compressionMethod = data.view.getUint16(index + 4, true); 501 | entry.lastModDateRaw = data.view.getUint32(index + 6, true); 502 | entry.lastModDate = getDate(entry.lastModDateRaw); 503 | if ((entry.bitFlag & 0x01) === 0x01) { 504 | onerror(ERR_ENCRYPTED); 505 | return; 506 | } 507 | if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) { 508 | entry.crc32 = data.view.getUint32(index + 10, true); 509 | entry.compressedSize = data.view.getUint32(index + 14, true); 510 | entry.uncompressedSize = data.view.getUint32(index + 18, true); 511 | } 512 | if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) { 513 | onerror(ERR_ZIP64); 514 | return; 515 | } 516 | entry.filenameLength = data.view.getUint16(index + 22, true); 517 | entry.extraFieldLength = data.view.getUint16(index + 24, true); 518 | } 519 | 520 | function createZipReader(reader, onerror) { 521 | function Entry() { 522 | } 523 | 524 | Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) { 525 | var that = this, worker; 526 | 527 | function terminate(callback, param) { 528 | if (worker) 529 | worker.terminate(); 530 | worker = null; 531 | if (callback) 532 | callback(param); 533 | } 534 | 535 | function testCrc32(crc32) { 536 | var dataCrc32 = getDataHelper(4); 537 | dataCrc32.view.setUint32(0, crc32); 538 | return that.crc32 == dataCrc32.view.getUint32(0); 539 | } 540 | 541 | function getWriterData(uncompressedSize, crc32) { 542 | if (checkCrc32 && !testCrc32(crc32)) 543 | onreaderror(); 544 | else 545 | writer.getData(function(data) { 546 | terminate(onend, data); 547 | }); 548 | } 549 | 550 | function onreaderror() { 551 | terminate(onerror, ERR_READ_DATA); 552 | } 553 | 554 | function onwriteerror() { 555 | terminate(onerror, ERR_WRITE_DATA); 556 | } 557 | 558 | reader.readUint8Array(that.offset, 30, function(bytes) { 559 | var data = getDataHelper(bytes.length, bytes), dataOffset; 560 | if (data.view.getUint32(0) != 0x504b0304) { 561 | onerror(ERR_BAD_FORMAT); 562 | return; 563 | } 564 | readCommonHeader(that, data, 4, false, onerror); 565 | dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength; 566 | writer.init(function() { 567 | if (that.compressionMethod === 0) 568 | copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); 569 | else 570 | worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); 571 | }, onwriteerror); 572 | }, onreaderror); 573 | }; 574 | 575 | function seekEOCDR(offset, entriesCallback) { 576 | reader.readUint8Array(reader.size - offset, offset, function(bytes) { 577 | var dataView = getDataHelper(bytes.length, bytes).view; 578 | if (dataView.getUint32(0) != 0x504b0506) { 579 | seekEOCDR(offset + 1, entriesCallback); 580 | } else { 581 | entriesCallback(dataView); 582 | } 583 | }, function() { 584 | onerror(ERR_READ); 585 | }); 586 | } 587 | 588 | return { 589 | getEntries : function(callback) { 590 | if (reader.size < 22) { 591 | onerror(ERR_BAD_FORMAT); 592 | return; 593 | } 594 | // look for End of central directory record 595 | seekEOCDR(22, function(dataView) { 596 | var datalength, fileslength; 597 | datalength = dataView.getUint32(16, true); 598 | fileslength = dataView.getUint16(8, true); 599 | reader.readUint8Array(datalength, reader.size - datalength, function(bytes) { 600 | var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes); 601 | for (i = 0; i < fileslength; i++) { 602 | entry = new Entry(); 603 | if (data.view.getUint32(index) != 0x504b0102) { 604 | onerror(ERR_BAD_FORMAT); 605 | return; 606 | } 607 | readCommonHeader(entry, data, index + 6, true, onerror); 608 | entry.commentLength = data.view.getUint16(index + 32, true); 609 | entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10); 610 | entry.offset = data.view.getUint32(index + 42, true); 611 | filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength)); 612 | entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename); 613 | if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/") 614 | entry.directory = true; 615 | comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46 616 | + entry.filenameLength + entry.extraFieldLength + entry.commentLength)); 617 | entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment); 618 | entries.push(entry); 619 | index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength; 620 | } 621 | callback(entries); 622 | }, function() { 623 | onerror(ERR_READ); 624 | }); 625 | }); 626 | }, 627 | close : function(callback) { 628 | if (callback) 629 | callback(); 630 | } 631 | }; 632 | } 633 | 634 | // ZipWriter 635 | 636 | function encodeUTF8(string) { 637 | return unescape(encodeURIComponent(string)); 638 | } 639 | 640 | function getBytes(str) { 641 | var i, array = []; 642 | for (i = 0; i < str.length; i++) 643 | array.push(str.charCodeAt(i)); 644 | return array; 645 | } 646 | 647 | function createZipWriter(writer, onerror, dontDeflate) { 648 | var worker, files = {}, filenames = [], datalength = 0; 649 | 650 | function terminate(callback, message) { 651 | if (worker) 652 | worker.terminate(); 653 | worker = null; 654 | if (callback) 655 | callback(message); 656 | } 657 | 658 | function onwriteerror() { 659 | terminate(onerror, ERR_WRITE); 660 | } 661 | 662 | function onreaderror() { 663 | terminate(onerror, ERR_READ_DATA); 664 | } 665 | 666 | return { 667 | add : function(name, reader, onend, onprogress, options) { 668 | var header, filename, date; 669 | 670 | function writeHeader(callback) { 671 | var data; 672 | date = options.lastModDate || new Date(); 673 | header = getDataHelper(26); 674 | files[name] = { 675 | headerArray : header.array, 676 | directory : options.directory, 677 | filename : filename, 678 | offset : datalength, 679 | comment : getBytes(encodeUTF8(options.comment || "")) 680 | }; 681 | header.view.setUint32(0, 0x14000808); 682 | if (options.version) 683 | header.view.setUint8(0, options.version); 684 | if (!dontDeflate && options.level !== 0 && !options.directory) 685 | header.view.setUint16(4, 0x0800); 686 | header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true); 687 | header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true); 688 | header.view.setUint16(22, filename.length, true); 689 | data = getDataHelper(30 + filename.length); 690 | data.view.setUint32(0, 0x504b0304); 691 | data.array.set(header.array, 4); 692 | data.array.set(filename, 30); 693 | datalength += data.array.length; 694 | writer.writeUint8Array(data.array, callback, onwriteerror); 695 | } 696 | 697 | function writeFooter(compressedLength, crc32) { 698 | var footer = getDataHelper(16); 699 | datalength += compressedLength || 0; 700 | footer.view.setUint32(0, 0x504b0708); 701 | if (typeof crc32 != "undefined") { 702 | header.view.setUint32(10, crc32, true); 703 | footer.view.setUint32(4, crc32, true); 704 | } 705 | if (reader) { 706 | footer.view.setUint32(8, compressedLength, true); 707 | header.view.setUint32(14, compressedLength, true); 708 | footer.view.setUint32(12, reader.size, true); 709 | header.view.setUint32(18, reader.size, true); 710 | } 711 | writer.writeUint8Array(footer.array, function() { 712 | datalength += 16; 713 | terminate(onend); 714 | }, onwriteerror); 715 | } 716 | 717 | function writeFile() { 718 | options = options || {}; 719 | name = name.trim(); 720 | if (options.directory && name.charAt(name.length - 1) != "/") 721 | name += "/"; 722 | if (files.hasOwnProperty(name)) { 723 | onerror(ERR_DUPLICATED_NAME); 724 | return; 725 | } 726 | filename = getBytes(encodeUTF8(name)); 727 | filenames.push(name); 728 | writeHeader(function() { 729 | if (reader) 730 | if (dontDeflate || options.level === 0) 731 | copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror); 732 | else 733 | worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror); 734 | else 735 | writeFooter(); 736 | }, onwriteerror); 737 | } 738 | 739 | if (reader) 740 | reader.init(writeFile, onreaderror); 741 | else 742 | writeFile(); 743 | }, 744 | close : function(callback) { 745 | var data, length = 0, index = 0, indexFilename, file; 746 | for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { 747 | file = files[filenames[indexFilename]]; 748 | length += 46 + file.filename.length + file.comment.length; 749 | } 750 | data = getDataHelper(length + 22); 751 | for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { 752 | file = files[filenames[indexFilename]]; 753 | data.view.setUint32(index, 0x504b0102); 754 | data.view.setUint16(index + 4, 0x1400); 755 | data.array.set(file.headerArray, index + 6); 756 | data.view.setUint16(index + 32, file.comment.length, true); 757 | if (file.directory) 758 | data.view.setUint8(index + 38, 0x10); 759 | data.view.setUint32(index + 42, file.offset, true); 760 | data.array.set(file.filename, index + 46); 761 | data.array.set(file.comment, index + 46 + file.filename.length); 762 | index += 46 + file.filename.length + file.comment.length; 763 | } 764 | data.view.setUint32(index, 0x504b0506); 765 | data.view.setUint16(index + 8, filenames.length, true); 766 | data.view.setUint16(index + 10, filenames.length, true); 767 | data.view.setUint32(index + 12, length, true); 768 | data.view.setUint32(index + 16, datalength, true); 769 | writer.writeUint8Array(data.array, function() { 770 | terminate(function() { 771 | writer.getData(callback); 772 | }); 773 | }, onwriteerror); 774 | } 775 | }; 776 | } 777 | 778 | obj.zip = { 779 | Reader : Reader, 780 | Writer : Writer, 781 | BlobReader : BlobReader, 782 | Data64URIReader : Data64URIReader, 783 | TextReader : TextReader, 784 | BlobWriter : BlobWriter, 785 | Data64URIWriter : Data64URIWriter, 786 | TextWriter : TextWriter, 787 | createReader : function(reader, callback, onerror) { 788 | reader.init(function() { 789 | callback(createZipReader(reader, onerror)); 790 | }, onerror); 791 | }, 792 | createWriter : function(writer, callback, onerror, dontDeflate) { 793 | writer.init(function() { 794 | callback(createZipWriter(writer, onerror, dontDeflate)); 795 | }, onerror); 796 | }, 797 | workerScriptsPath : "", 798 | useWebWorkers : true 799 | }; 800 | 801 | })(this); 802 | -------------------------------------------------------------------------------- /shaders/particle-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec3 vColor; 2 | 3 | void main() { 4 | 5 | gl_FragColor = vec4( vColor, 1. ); 6 | 7 | } -------------------------------------------------------------------------------- /shaders/particle-vs.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 customColor; 2 | 3 | uniform float size; 4 | uniform float displacement; 5 | 6 | varying vec3 vColor; 7 | 8 | void main() { 9 | 10 | vColor = customColor; 11 | 12 | vec4 p = vec4( position, 1. ); 13 | //p.z *= displacement; 14 | vec4 mvPosition = modelViewMatrix * p; 15 | 16 | gl_Position = projectionMatrix * mvPosition; 17 | 18 | gl_PointSize = size / gl_Position.z; 19 | 20 | } --------------------------------------------------------------------------------