├── js ├── thirdparty │ ├── jszip │ │ ├── .jshintignore │ │ ├── .gitignore │ │ ├── test │ │ │ ├── smile.gif │ │ │ ├── ref │ │ │ │ ├── all.zip │ │ │ │ ├── image.zip │ │ │ │ ├── store.zip │ │ │ │ ├── text.zip │ │ │ │ ├── utf8.zip │ │ │ │ ├── zip64.zip │ │ │ │ ├── deflate.zip │ │ │ │ ├── folder.zip │ │ │ │ ├── nested.zip │ │ │ │ ├── all.7zip.zip │ │ │ │ ├── backslash.zip │ │ │ │ ├── encrypted.zip │ │ │ │ ├── subfolder.zip │ │ │ │ ├── all.windows.zip │ │ │ │ ├── nested_zip64.zip │ │ │ │ ├── pile_of_poo.zip │ │ │ │ ├── utf8_in_name.zip │ │ │ │ ├── archive_comment.zip │ │ │ │ ├── data_descriptor.zip │ │ │ │ ├── invalid │ │ │ │ │ ├── crc32.zip │ │ │ │ │ ├── bad_offset.zip │ │ │ │ │ └── compression.zip │ │ │ │ ├── extra_attributes.zip │ │ │ │ ├── slashes_and_izarc.zip │ │ │ │ ├── winrar_utf8_in_name.zip │ │ │ │ ├── nested_data_descriptor.zip │ │ │ │ └── complex_files │ │ │ │ │ ├── AntarcticaTemps.ods │ │ │ │ │ ├── AntarcticaTemps.xlsx │ │ │ │ │ ├── Outlook2007_Calendar.xps │ │ │ │ │ └── Franz Kafka - The Metamorphosis.epub │ │ │ ├── browser-test-utils.js │ │ │ ├── node.js │ │ │ ├── index.html │ │ │ └── qunit-1.11.0.css │ │ ├── .npmignore │ │ ├── lib │ │ │ ├── nodeBuffer.js │ │ │ ├── defaults.js │ │ │ ├── signature.js │ │ │ ├── compressions.js │ │ │ ├── license_header.js │ │ │ ├── flate.js │ │ │ ├── nodeBufferReader.js │ │ │ ├── stringWriter.js │ │ │ ├── compressedObject.js │ │ │ ├── load.js │ │ │ ├── stringReader.js │ │ │ ├── uint8ArrayWriter.js │ │ │ ├── support.js │ │ │ ├── uint8ArrayReader.js │ │ │ ├── base64.js │ │ │ ├── index.js │ │ │ ├── deprecatedPublicUtils.js │ │ │ ├── dataReader.js │ │ │ ├── crc32.js │ │ │ ├── utf8.js │ │ │ ├── zipEntries.js │ │ │ └── utils.js │ │ ├── .jshintrc │ │ ├── component.json │ │ ├── documentation │ │ │ ├── api_jszip │ │ │ │ ├── constructor.md │ │ │ │ ├── constructor_load.md │ │ │ │ ├── support.md │ │ │ │ ├── folder_data.md │ │ │ │ ├── remove.md │ │ │ │ ├── folder_regex.md │ │ │ │ ├── filter.md │ │ │ │ ├── file_name.md │ │ │ │ ├── file_regex.md │ │ │ │ ├── generate.md │ │ │ │ ├── load.md │ │ │ │ └── file_data.md │ │ │ ├── api_jszip.md │ │ │ ├── css │ │ │ │ ├── main.css │ │ │ │ └── pygments.css │ │ │ ├── faq.md │ │ │ ├── examples │ │ │ │ ├── get-binary-files-ajax.html │ │ │ │ ├── downloader.html │ │ │ │ ├── download-zip-file.html │ │ │ │ ├── downloader.js │ │ │ │ └── read-local-file-api.html │ │ │ ├── upgrade_guide.md │ │ │ ├── api_zipobject.md │ │ │ ├── contributing.md │ │ │ ├── limitations.md │ │ │ ├── examples.md │ │ │ ├── howto │ │ │ │ ├── write_zip.md │ │ │ │ └── read_zip.md │ │ │ └── _layouts │ │ │ │ └── default.html │ │ ├── .travis.yml │ │ ├── bower.json │ │ ├── _config.yml │ │ ├── docs │ │ │ ├── references.txt │ │ │ └── ZIP spec.txt │ │ ├── README.markdown │ │ ├── package.json │ │ ├── CHANGES.md │ │ ├── Gruntfile.js │ │ ├── index.html │ │ └── vendor │ │ │ └── FileSaver.js │ ├── jquery.nodoubletapzoom.js │ ├── jquery-ajax-blob-arraybuffer.js │ ├── domReady.js │ └── jquery.powertip.min.js └── c64 │ ├── iec.js │ └── main.js ├── rom ├── basic.rom ├── game.bin ├── game.zip ├── sorex.d64 ├── test.d64 ├── truth.d64 ├── 1dnoise.d64 ├── 69uasr.d64 ├── kernal.rom ├── loadram.bin ├── raster2.d64 ├── 32bfuzzy.d64 ├── 6502test.bin ├── microture.d64 ├── testscreen.d64 ├── colorsplits.d64 └── game.asm ├── img └── cclicker.png ├── LICENSE ├── index.html ├── css ├── jquery.powertip-yellow.css └── index.css └── README.md /js/thirdparty/jszip/.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test 3 | -------------------------------------------------------------------------------- /rom/basic.rom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/basic.rom -------------------------------------------------------------------------------- /rom/game.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/game.bin -------------------------------------------------------------------------------- /rom/game.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/game.zip -------------------------------------------------------------------------------- /rom/sorex.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/sorex.d64 -------------------------------------------------------------------------------- /rom/test.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/test.d64 -------------------------------------------------------------------------------- /rom/truth.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/truth.d64 -------------------------------------------------------------------------------- /rom/1dnoise.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/1dnoise.d64 -------------------------------------------------------------------------------- /rom/69uasr.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/69uasr.d64 -------------------------------------------------------------------------------- /rom/kernal.rom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/kernal.rom -------------------------------------------------------------------------------- /rom/loadram.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/loadram.bin -------------------------------------------------------------------------------- /rom/raster2.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/raster2.d64 -------------------------------------------------------------------------------- /img/cclicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/img/cclicker.png -------------------------------------------------------------------------------- /js/thirdparty/jszip/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | node_modules 3 | sauce_connect.log 4 | .c9revisions -------------------------------------------------------------------------------- /rom/32bfuzzy.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/32bfuzzy.d64 -------------------------------------------------------------------------------- /rom/6502test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/6502test.bin -------------------------------------------------------------------------------- /rom/microture.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/microture.d64 -------------------------------------------------------------------------------- /rom/testscreen.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/testscreen.d64 -------------------------------------------------------------------------------- /rom/colorsplits.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/rom/colorsplits.d64 -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/smile.gif -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/all.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/all.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/image.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/image.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/store.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/store.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/text.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/text.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/utf8.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/utf8.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/zip64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/zip64.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/deflate.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/deflate.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/folder.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/folder.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/nested.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/nested.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/all.7zip.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/all.7zip.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/backslash.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/backslash.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/encrypted.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/encrypted.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/subfolder.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/subfolder.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/all.windows.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/all.windows.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/nested_zip64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/nested_zip64.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/pile_of_poo.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/pile_of_poo.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/utf8_in_name.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/utf8_in_name.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/archive_comment.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/archive_comment.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/data_descriptor.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/data_descriptor.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/invalid/crc32.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/invalid/crc32.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/extra_attributes.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/extra_attributes.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/slashes_and_izarc.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/slashes_and_izarc.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/invalid/bad_offset.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/invalid/bad_offset.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/invalid/compression.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/invalid/compression.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/winrar_utf8_in_name.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/winrar_utf8_in_name.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/nested_data_descriptor.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/nested_data_descriptor.zip -------------------------------------------------------------------------------- /js/thirdparty/jszip/.npmignore: -------------------------------------------------------------------------------- 1 | _config.yml 2 | bower.json 3 | component.json 4 | dist 5 | docs 6 | documentation 7 | Gruntfile.js 8 | index.html 9 | test 10 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/complex_files/AntarcticaTemps.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/complex_files/AntarcticaTemps.ods -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/complex_files/AntarcticaTemps.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/complex_files/AntarcticaTemps.xlsx -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/complex_files/Outlook2007_Calendar.xps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/complex_files/Outlook2007_Calendar.xps -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/ref/complex_files/Franz Kafka - The Metamorphosis.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Two9A/c64clicker/HEAD/js/thirdparty/jszip/test/ref/complex_files/Franz Kafka - The Metamorphosis.epub -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/nodeBuffer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(data, encoding){ 3 | return new Buffer(data, encoding); 4 | }; 5 | module.exports.test = function(b){ 6 | return Buffer.isBuffer(b); 7 | }; 8 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/browser-test-utils.js: -------------------------------------------------------------------------------- 1 | var JSZipTestUtils = { 2 | loadZipFile : function (name, callback) { 3 | JSZipUtils.getBinaryContent(name + "?_=" + ( new Date() ).getTime(), callback); 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/defaults.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.base64 = false; 3 | exports.binary = false; 4 | exports.dir = false; 5 | exports.createFolders = false; 6 | exports.date = null; 7 | exports.compression = null; 8 | exports.comment = null; 9 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "undef": true, 3 | "strict": true, 4 | "sub": true, 5 | 6 | "globals": { 7 | "TextEncoder": false, 8 | "TextDecoder": false 9 | }, 10 | "browser": true, 11 | "node": true 12 | } 13 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/node.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | 3 | global.JSZip = require("../lib/index"); 4 | 5 | global.JSZipTestUtils = { 6 | loadZipFile: function(name, callback) { 7 | fs.readFile(name, "binary", callback); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/signature.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.LOCAL_FILE_HEADER = "PK\x03\x04"; 3 | exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; 4 | exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; 5 | exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; 6 | exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; 7 | exports.DATA_DESCRIPTOR = "PK\x07\x08"; 8 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/compressions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.STORE = { 3 | magic: "\x00\x00", 4 | compress: function(content) { 5 | return content; // no compression 6 | }, 7 | uncompress: function(content) { 8 | return content; // no compression 9 | }, 10 | compressInputType: null, 11 | uncompressInputType: null 12 | }; 13 | exports.DEFLATE = require('./flate'); 14 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jszip", 3 | "repo": "Stuk/jszip", 4 | "description": "Create, read and edit .zip files with Javascript http://stuartk.com/jszip", 5 | "version": "2.4.0", 6 | "keywords": [ 7 | "zip", 8 | "deflate", 9 | "inflate" 10 | ], 11 | "main": "dist/jszip.js", 12 | "license": "MIT or GPLv3", 13 | "scripts": [ 14 | "dist/jszip.js" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/license_header.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | JSZip - A Javascript class for generating and reading zip files 4 | 5 | 6 | (c) 2009-2014 Stuart Knightley 7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. 8 | 9 | JSZip uses the library pako released under the MIT license : 10 | https://github.com/nodeca/pako/blob/master/LICENSE 11 | */ 12 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/constructor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "new JSZip() or JSZip()" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Create a new JSZip instance. 8 | 9 | __Arguments__ : None 10 | 11 | __Returns__ : A new JSZip. 12 | 13 | __Throws__ : Nothing. 14 | 15 | 16 | 17 | __Example__ 18 | 19 | ```js 20 | var zip = new JSZip(); 21 | // same as 22 | var zip = JSZip(); 23 | ``` 24 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/constructor_load.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "new JSZip(data [,options]) or JSZip(data [,options])" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | This is a shortcut for 8 | 9 | ```js 10 | var zip = new JSZip(); 11 | zip.load(data, options); 12 | ``` 13 | 14 | Please see the documentation of [load]({{site.baseurl}}/documentation/api_jszip/load.html). 15 | 16 | __Example__ 17 | 18 | ```js 19 | var zip = new JSZip(data, options); 20 | // same as 21 | var zip = JSZip(data, options); 22 | ``` 23 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | script: npm run $COMMAND 5 | env: 6 | matrix: 7 | - COMMAND=test-node 8 | - COMMAND=test-browser 9 | global: 10 | - secure: MhA8GHU42X3GWTUMaqdZVvarx4BMjhQCUGNi3kvuD/iCmKVb7gMwj4jbds7AcJdsCRsRk8bBGzZs/E7HidBJMPDa5DhgLKy9EV1s42JlHq8lVzbJeWIGgrtyJvhVUkGRy2OJjnDSgh3U6elkQmvDn74jreSQc6m/yGoPFF1nqq8= 11 | - secure: qREw6aUu2DnB+2reMuHgygSkumRiJvt7Z5Fz4uEVoraqbe65e4PGhtzypr9uIgCN43vxS2D5tAIeDbfid5VQrWFUQnrC9O5Z5qgVPsKN94zZ1tvYurXI4wRlAg58nNjkfGXWhLI3VUjjDTp5gYcMqgfe5hpEFYUPnUQkKGnaqAk= 12 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jszip", 3 | "version": "2.4.0", 4 | "homepage": "http://stuartk.com/jszip", 5 | "authors": [ 6 | "Stuart Knightley " 7 | ], 8 | "description": "Create, read and edit .zip files with Javascript http://stuartk.com/jszip", 9 | "main": "dist/jszip.js", 10 | "keywords": [ 11 | "zip", 12 | "deflate", 13 | "inflate" 14 | ], 15 | "license": "MIT or GPLv3", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/flate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); 3 | 4 | var pako = require("pako"); 5 | exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; 6 | exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; 7 | 8 | exports.magic = "\x08\x00"; 9 | exports.compress = function(input) { 10 | return pako.deflateRaw(input); 11 | }; 12 | exports.uncompress = function(input) { 13 | return pako.inflateRaw(input); 14 | }; 15 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/nodeBufferReader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var Uint8ArrayReader = require('./uint8ArrayReader'); 3 | 4 | function NodeBufferReader(data) { 5 | this.data = data; 6 | this.length = this.data.length; 7 | this.index = 0; 8 | } 9 | NodeBufferReader.prototype = new Uint8ArrayReader(); 10 | 11 | /** 12 | * @see DataReader.readData 13 | */ 14 | NodeBufferReader.prototype.readData = function(size) { 15 | this.checkOffset(size); 16 | var result = this.data.slice(this.index, this.index + size); 17 | this.index += size; 18 | return result; 19 | }; 20 | module.exports = NodeBufferReader; 21 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/_config.yml: -------------------------------------------------------------------------------- 1 | # will be overwritten by github, see https://help.github.com/articles/using-jekyll-with-pages 2 | safe: true 3 | lsi: false 4 | pygments: true 5 | source: ./ 6 | # /overwritten 7 | 8 | baseurl: /jszip 9 | 10 | layouts: ./documentation/_layouts 11 | permalink: none 12 | exclude: ['bin', 'README.md', 'node_modules'] 13 | 14 | markdown: redcarpet 15 | redcarpet: 16 | extensions: [ 17 | 'no_intra_emphasis', 18 | 'fenced_code_blocks', 19 | 'autolink', 20 | 'strikethrough', 21 | 'superscript', 22 | 'with_toc_data', 23 | 'tables', 24 | 'hardwrap' 25 | ] 26 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/docs/references.txt: -------------------------------------------------------------------------------- 1 | Zip format 2 | ---------- 3 | http://www.pkware.com/support/zip-application-note 4 | http://www.xxcopy.com/xxcopy06.htm 5 | 6 | Data URL 7 | -------- 8 | https://developer.mozilla.org/en/The_data_URL_scheme 9 | http://msdn.microsoft.com/en-us/library/cc848897(VS.85).aspx 10 | http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/ 11 | 12 | http://www.motobit.com/util/base64-decoder-encoder.asp 13 | 14 | Saving files 15 | ------------ 16 | http://msdn.microsoft.com/en-us/library/ms536676(VS.85).aspx 17 | http://msdn.microsoft.com/en-us/library/ms536419(VS.85).aspx 18 | http://msdn.microsoft.com/en-us/library/ms537418(VS.85).aspx 19 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "JSZip API" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | An instance of JSZip represents a set of files. You can add them, remove them, 8 | modify them. You can also import an existing zip file or generate one. 9 | 10 | ### Attributes 11 | 12 | attribute name | type | description 13 | ---------------------|-------------|------------- 14 | `files` | object | the [ZipObject]({{site.baseurl}}/documentation/api_zipobject.html)s inside the zip with the name as key. See [file(name)]({{site.baseurl}}/documentation/api_jszip/file_name.html). 15 | `comment` | string | the comment of the zip file. 16 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/support.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "JSZip.support" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | If the browser supports them, JSZip can take advantage of some "new" features : 8 | ArrayBuffer, Blob, Uint8Array. To know if JSZip can use them, you can check the 9 | JSZip.support object. It contains the following boolean properties : 10 | 11 | * `arraybuffer` : true if JSZip can read and generate ArrayBuffer, false otherwise. 12 | * `uint8array` : true if JSZip can read and generate Uint8Array, false otherwise. 13 | * `blob` : true if JSZip can generate Blob, false otherwise. 14 | * `nodebuffer` : true if JSZip can read and generate nodejs Buffer, false otherwise. 15 | 16 | 17 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/css/main.css: -------------------------------------------------------------------------------- 1 | ul.nav ul { 2 | list-style:none; 3 | margin: 0; 4 | padding: 0 0 0 25px; 5 | } 6 | 7 | #downloader_application form { 8 | margin-bottom: 10px; 9 | } 10 | 11 | #downloader_application ul { 12 | list-style-type: none; 13 | } 14 | 15 | .browser_support th { 16 | border-bottom-width: 3px !important; 17 | } 18 | 19 | .support_ie {border-bottom-color: #0275BA !important;} 20 | .support_ff {border-bottom-color: #DF7215 !important;} 21 | .support_sf {border-bottom-color: #43B3E9 !important;} 22 | .support_cr {border-bottom-color: #39B642 !important;} 23 | .support_op {border-bottom-color: #C42122 !important;} 24 | .support_nd {border-bottom-color: #8CC84B !important;} 25 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Frequently Asked Questions" 3 | layout: default 4 | section: main 5 | --- 6 | 7 | ### "Corrupted zip or bug : unexpected signature" 8 | 9 | If you are sure that the zip file is correct, that error often comes from a 10 | corrupted content. An ajax request, if not prepared correctly, will try to 11 | decode the binary content as a text and corrupt it. See 12 | [this page]({{site.baseurl}}/documentation/howto/read_zip.html). 13 | 14 | ### My browser crashes / becomes unresponsive / never finish the execution 15 | 16 | That happens if you try to handle to much data. If possible, try again with a 17 | small (some KB) zip file to see if your code is correct. See 18 | [this page]({{site.baseurl}}/documentation/limitations.html) for more 19 | informations. 20 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/stringWriter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var utils = require('./utils'); 4 | 5 | /** 6 | * An object to write any content to a string. 7 | * @constructor 8 | */ 9 | var StringWriter = function() { 10 | this.data = []; 11 | }; 12 | StringWriter.prototype = { 13 | /** 14 | * Append any content to the current string. 15 | * @param {Object} input the content to add. 16 | */ 17 | append: function(input) { 18 | input = utils.transformTo("string", input); 19 | this.data.push(input); 20 | }, 21 | /** 22 | * Finalize the construction an return the result. 23 | * @return {string} the generated string. 24 | */ 25 | finalize: function() { 26 | return this.data.join(""); 27 | } 28 | }; 29 | 30 | module.exports = StringWriter; 31 | -------------------------------------------------------------------------------- /js/thirdparty/jquery.nodoubletapzoom.js: -------------------------------------------------------------------------------- 1 | /* 2 | Prevent double-tap to zoom on touch-capable devices 3 | John Sundstrom, adapted by Wouter Konecny 4 | http://stackoverflow.com/questions/10614481 5 | */ 6 | (function($) { 7 | $.fn.nodoubletapzoom = function() { 8 | $(this).bind('touchstart', function preventZoom(e) { 9 | var t2 = e.timeStamp 10 | , t1 = $(this).data('lastTouch') || t2 11 | , dt = t2 - t1 12 | , fingers = e.originalEvent.touches.length; 13 | $(this).data('lastTouch', t2); 14 | if (!dt || dt > 500 || fingers > 1) return; // not double-tap 15 | 16 | e.preventDefault(); // double tap - prevent the zoom 17 | // also synthesize click events we just swallowed up 18 | $(this).trigger('click'); 19 | }); 20 | }; 21 | })(jQuery); 22 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/folder_data.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "folder(name)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Add a directory to the zip file. 8 | 9 | __Arguments__ 10 | 11 | name | type | description 12 | -----|--------|------------ 13 | name | string | the name of the directory. 14 | 15 | __Returns__ : A new JSZip (for chaining), with the new folder as root. 16 | 17 | __Throws__ : Nothing. 18 | 19 | 20 | 21 | __Example__ 22 | 23 | ```js 24 | zip.folder("images"); 25 | zip.folder("css").file("style.css", "body {background: #FF0000}"); 26 | // or specify an absolute path (using forward slashes) 27 | zip.file("css/font.css", "body {font-family: sans-serif}") 28 | 29 | // result : images/, css/, css/style.css, css/font.css 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/remove.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "remove(name)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Delete a file or folder (recursively). 8 | 9 | __Arguments__ 10 | 11 | name | type | description 12 | -----|--------|------------ 13 | name | string | the name of the file/folder to delete. 14 | 15 | __Returns__ : The current JSZip object. 16 | 17 | __Throws__ : Nothing. 18 | 19 | 23 | 24 | __Example__ 25 | 26 | ```js 27 | var zip = new JSZip(); 28 | zip.file("Hello.txt", "Hello World\n"); 29 | zip.file("temp.txt", "nothing").remove("temp.txt"); 30 | // result : Hello.txt 31 | 32 | zip.folder("css").file("style.css", "body {background: #FF0000}"); 33 | zip.remove("css"); 34 | //result : empty zip 35 | ``` 36 | 37 | 38 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/compressedObject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | function CompressedObject() { 3 | this.compressedSize = 0; 4 | this.uncompressedSize = 0; 5 | this.crc32 = 0; 6 | this.compressionMethod = null; 7 | this.compressedContent = null; 8 | } 9 | 10 | CompressedObject.prototype = { 11 | /** 12 | * Return the decompressed content in an unspecified format. 13 | * The format will depend on the decompressor. 14 | * @return {Object} the decompressed content. 15 | */ 16 | getContent: function() { 17 | return null; // see implementation 18 | }, 19 | /** 20 | * Return the compressed content in an unspecified format. 21 | * The format will depend on the compressed conten source. 22 | * @return {Object} the compressed content. 23 | */ 24 | getCompressedContent: function() { 25 | return null; // see implementation 26 | } 27 | }; 28 | module.exports = CompressedObject; 29 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/load.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var base64 = require('./base64'); 3 | var ZipEntries = require('./zipEntries'); 4 | module.exports = function(data, options) { 5 | var files, zipEntries, i, input; 6 | options = options || {}; 7 | if (options.base64) { 8 | data = base64.decode(data); 9 | } 10 | 11 | zipEntries = new ZipEntries(data, options); 12 | files = zipEntries.files; 13 | for (i = 0; i < files.length; i++) { 14 | input = files[i]; 15 | this.file(input.fileName, input.decompressed, { 16 | binary: true, 17 | optimizedBinaryString: true, 18 | date: input.date, 19 | dir: input.dir, 20 | comment : input.fileComment.length ? input.fileComment : null, 21 | createFolders: options.createFolders 22 | }); 23 | } 24 | if (zipEntries.zipComment.length) { 25 | this.comment = zipEntries.zipComment; 26 | } 27 | 28 | return this; 29 | }; 30 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/README.markdown: -------------------------------------------------------------------------------- 1 | JSZip 2 | ===== 3 | 4 | A library for creating, reading and editing .zip files with Javascript, with a 5 | lovely and simple API. 6 | 7 | See http://stuartk.com/jszip for all the documentation. 8 | 9 | ```javascript 10 | var zip = new JSZip(); 11 | 12 | zip.file("Hello.txt", "Hello World\n"); 13 | 14 | var img = zip.folder("images"); 15 | img.file("smile.gif", imgData, {base64: true}); 16 | 17 | var content = zip.generate({type:"blob"}); 18 | 19 | // see FileSaver.js 20 | saveAs(content, "example.zip"); 21 | 22 | /* 23 | Results in a zip containing 24 | Hello.txt 25 | images/ 26 | smile.gif 27 | */ 28 | ``` 29 | 30 | Test status 31 | ----------- 32 | 33 | [![Build Status](https://api.travis-ci.org/Stuk/jszip.svg?branch=master)](http://travis-ci.org/Stuk/jszip) 34 | 35 | [![Selenium Test Status](https://saucelabs.com/browser-matrix/jszip.svg)](https://saucelabs.com/u/jszip) 36 | 37 | License 38 | ------- 39 | 40 | JSZip is dual-licensed. You may use it under the MIT license *or* the GPLv3 41 | license. See [LICENSE.markdown](LICENSE.markdown). 42 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/stringReader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var DataReader = require('./dataReader'); 3 | var utils = require('./utils'); 4 | 5 | function StringReader(data, optimizedBinaryString) { 6 | this.data = data; 7 | if (!optimizedBinaryString) { 8 | this.data = utils.string2binary(this.data); 9 | } 10 | this.length = this.data.length; 11 | this.index = 0; 12 | } 13 | StringReader.prototype = new DataReader(); 14 | /** 15 | * @see DataReader.byteAt 16 | */ 17 | StringReader.prototype.byteAt = function(i) { 18 | return this.data.charCodeAt(i); 19 | }; 20 | /** 21 | * @see DataReader.lastIndexOfSignature 22 | */ 23 | StringReader.prototype.lastIndexOfSignature = function(sig) { 24 | return this.data.lastIndexOf(sig); 25 | }; 26 | /** 27 | * @see DataReader.readData 28 | */ 29 | StringReader.prototype.readData = function(size) { 30 | this.checkOffset(size); 31 | // this will work because the constructor applied the "& 0xff" mask. 32 | var result = this.data.slice(this.index, this.index + size); 33 | this.index += size; 34 | return result; 35 | }; 36 | module.exports = StringReader; 37 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/uint8ArrayWriter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var utils = require('./utils'); 4 | 5 | /** 6 | * An object to write any content to an Uint8Array. 7 | * @constructor 8 | * @param {number} length The length of the array. 9 | */ 10 | var Uint8ArrayWriter = function(length) { 11 | this.data = new Uint8Array(length); 12 | this.index = 0; 13 | }; 14 | Uint8ArrayWriter.prototype = { 15 | /** 16 | * Append any content to the current array. 17 | * @param {Object} input the content to add. 18 | */ 19 | append: function(input) { 20 | if (input.length !== 0) { 21 | // with an empty Uint8Array, Opera fails with a "Offset larger than array size" 22 | input = utils.transformTo("uint8array", input); 23 | this.data.set(input, this.index); 24 | this.index += input.length; 25 | } 26 | }, 27 | /** 28 | * Finalize the construction an return the result. 29 | * @return {Uint8Array} the generated array. 30 | */ 31 | finalize: function() { 32 | return this.data; 33 | } 34 | }; 35 | 36 | module.exports = Uint8ArrayWriter; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Two9A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/folder_regex.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "folder(regex)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Search a subdirectory in the current directory with a 8 | [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). 9 | The regex is tested against the relative path. 10 | 11 | __Arguments__ 12 | 13 | name | type | description 14 | ------|--------|------------ 15 | regex | RegExp | the regex to use. 16 | 17 | __Returns__ : An array of matching folders (an empty array if none matched). 18 | Each maching folder is an instance of [ZipObject]({{site.baseurl}}/documentation/api_zipobject.html). 19 | 20 | __Throws__ : Nothing. 21 | 22 | 26 | 27 | __Example__ 28 | 29 | ```js 30 | var zip = new JSZip(); 31 | zip.folder("home/Pierre/videos"); 32 | zip.folder("home/Pierre/photos"); 33 | zip.folder("home/Jean/videos"); 34 | zip.folder("home/Jean/photos"); 35 | 36 | zip.folder(/videos/); // array of size 2 37 | 38 | zip.folder("home/Jean").folder(/^vid/); // array of 1 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples/get-binary-files-ajax.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Get a file with an ajax call" 3 | layout: default 4 | section: example 5 | --- 6 | 7 |

Tip : check the source of the page !

8 | 9 |

With JSZipUtils

10 |
11 | 12 | 44 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/filter.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "filter(predicate)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Filter nested files/folders with the specified function. 8 | 9 | __Arguments__ 10 | 11 | name | type | description 12 | ----------|----------|------------ 13 | predicate | function | the predicate to use. 14 | 15 | The predicate has the following signature : `function (relativePath, file) {...}` : 16 | 17 | name | type | description 18 | -------------|-----------|------------ 19 | relativePath | string | the filename and its path, reliatively to the current folder. 20 | file | ZipObject | the file being tested. See [ZipObject]({{site.baseurl}}/documentation/api_zipobject.html). 21 | 22 | The predicate must return true if the file should be included, false otherwise. 23 | 24 | 25 | __Returns__ : An array of matching ZipObject. 26 | 27 | __Throws__ : Nothing. 28 | 29 | 30 | 31 | __Example__ 32 | 33 | ```js 34 | var zip = new JSZip().folder("dir"); 35 | zip.file("readme.txt", "content"); 36 | zip.filter(function (relativePath, file){ 37 | // relativePath == "readme.txt" 38 | // file = {name:"dir/readme.txt",options:{...},asText:function} 39 | return true/false; 40 | }); 41 | ``` 42 | 43 | 44 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/support.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.base64 = true; 3 | exports.array = true; 4 | exports.string = true; 5 | exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; 6 | // contains true if JSZip can read/generate nodejs Buffer, false otherwise. 7 | // Browserify will provide a Buffer implementation for browsers, which is 8 | // an augmented Uint8Array (i.e., can be used as either Buffer or U8). 9 | exports.nodebuffer = typeof Buffer !== "undefined"; 10 | // contains true if JSZip can read/generate Uint8Array, false otherwise. 11 | exports.uint8array = typeof Uint8Array !== "undefined"; 12 | 13 | if (typeof ArrayBuffer === "undefined") { 14 | exports.blob = false; 15 | } 16 | else { 17 | var buffer = new ArrayBuffer(0); 18 | try { 19 | exports.blob = new Blob([buffer], { 20 | type: "application/zip" 21 | }).size === 0; 22 | } 23 | catch (e) { 24 | try { 25 | var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; 26 | var builder = new Builder(); 27 | builder.append(buffer); 28 | exports.blob = builder.getBlob('application/zip').size === 0; 29 | } 30 | catch (e) { 31 | exports.blob = false; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/file_name.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "file(name)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Get a file with the specified name. You can specify folders 8 | in the name : the folder separator is a forward slash ("/"). 9 | 10 | __Arguments__ 11 | 12 | name | type | description 13 | -----|--------|------------- 14 | name | string | the name of the file. 15 | 16 | __Returns__ : An instance of [ZipObject]({{site.baseurl}}/documentation/api_zipobject.html) representing 17 | the file if any, `null` otherwise. 18 | 19 | __Throws__ : Nothing. 20 | 21 | 22 | 23 | __Examples__ 24 | 25 | ```js 26 | var zip = new JSZip(); 27 | zip.file("file.txt", "content"); 28 | 29 | zip.file("file.txt").name // "file.txt" 30 | zip.file("file.txt").asText() // "content" 31 | zip.file("file.txt").options.dir // false 32 | 33 | // utf8 example 34 | var zip = new JSZip(zipFromAjaxWithUTF8); 35 | zip.file("amount.txt").asText() // "€15" 36 | zip.file("amount.txt").asArrayBuffer() // an ArrayBuffer containing €15 encoded as utf8 37 | zip.file("amount.txt").asUint8Array() // an Uint8Array containing €15 encoded as utf8 38 | 39 | // with folders 40 | zip.folder("sub").file("file.txt", "content"); 41 | zip.file("sub/file.txt"); // the file 42 | // or 43 | zip.folder("sub").file("file.txt") // the file 44 | ``` 45 | 46 | 47 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jszip", 3 | "version": "2.4.0", 4 | "author": "Stuart Knightley ", 5 | "description": "Create, read and edit .zip files with Javascript http://stuartk.com/jszip", 6 | "scripts": { 7 | "test": "npm run test-node && npm run test-browser", 8 | "test-node": "cd test && qunit -c node.js -t test.js", 9 | "test-browser": "grunt build && grunt test", 10 | "lint": "grunt jshint" 11 | }, 12 | "contributors": [ 13 | { 14 | "name": "Franz Buchinger" 15 | }, 16 | { 17 | "name": "António Afonso" 18 | }, 19 | { 20 | "name": "David Duponchel" 21 | }, 22 | { 23 | "name": "yiminghe" 24 | } 25 | ], 26 | "main": "./lib/index", 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/Stuk/jszip.git" 30 | }, 31 | "keywords": [ 32 | "zip", 33 | "deflate", 34 | "inflate" 35 | ], 36 | "devDependencies": { 37 | "qunit": "~0.6.3", 38 | "grunt": "~0.4.1", 39 | "grunt-cli": "~0.1.9", 40 | "grunt-saucelabs": "~7.0.0", 41 | "grunt-contrib-connect": "~0.7.1", 42 | "jshint": "~2.5.1", 43 | "browserify": "~4.1.4", 44 | "grunt-browserify": "~2.1.0", 45 | "grunt-contrib-jshint": "~0.10.0", 46 | "grunt-contrib-uglify": "~0.4.0", 47 | "jszip-utils": "~0.0.2" 48 | }, 49 | "dependencies":{ 50 | "pako": "~0.2.5" 51 | }, 52 | "license": "MIT or GPLv3" 53 | } 54 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/uint8ArrayReader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var DataReader = require('./dataReader'); 3 | 4 | function Uint8ArrayReader(data) { 5 | if (data) { 6 | this.data = data; 7 | this.length = this.data.length; 8 | this.index = 0; 9 | } 10 | } 11 | Uint8ArrayReader.prototype = new DataReader(); 12 | /** 13 | * @see DataReader.byteAt 14 | */ 15 | Uint8ArrayReader.prototype.byteAt = function(i) { 16 | return this.data[i]; 17 | }; 18 | /** 19 | * @see DataReader.lastIndexOfSignature 20 | */ 21 | Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { 22 | var sig0 = sig.charCodeAt(0), 23 | sig1 = sig.charCodeAt(1), 24 | sig2 = sig.charCodeAt(2), 25 | sig3 = sig.charCodeAt(3); 26 | for (var i = this.length - 4; i >= 0; --i) { 27 | if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { 28 | return i; 29 | } 30 | } 31 | 32 | return -1; 33 | }; 34 | /** 35 | * @see DataReader.readData 36 | */ 37 | Uint8ArrayReader.prototype.readData = function(size) { 38 | this.checkOffset(size); 39 | if(size === 0) { 40 | // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. 41 | return new Uint8Array(0); 42 | } 43 | var result = this.data.subarray(this.index, this.index + size); 44 | this.index += size; 45 | return result; 46 | }; 47 | module.exports = Uint8ArrayReader; 48 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/file_regex.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "file(regex)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Search a file in the current folder and subfolders with a 8 | [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). 9 | The regex is tested against the relative filename. 10 | 11 | __Arguments__ 12 | 13 | name | type | description 14 | ------|--------|------------ 15 | regex | RegExp | the regex to use. 16 | 17 | __Returns__ : An array of matching files (an empty array if none matched). Each 18 | maching file is an instance of [ZipObject]({{site.baseurl}}/documentation/api_zipobject.html). 19 | 20 | __Throws__ : Nothing. 21 | 22 | 26 | 27 | __Example__ 28 | 29 | ```js 30 | var zip = new JSZip(); 31 | zip.file("file1.txt", "content"); 32 | zip.file("file2.txt", "content"); 33 | 34 | zip.file(/file/); // array of size 2 35 | 36 | // example with a relative path : 37 | var folder = zip.folder("sub"); 38 | folder 39 | .file("file3.txt", "content") // relative path from folder : file3.txt 40 | .file("file4.txt", "content"); // relative path from folder : file4.txt 41 | 42 | folder.file(/file/); // array of size 2 43 | folder.file(/^file/); // array of size 2, the relative paths start with file 44 | 45 | // arrays contain objects in the form: 46 | // {name: "file2.txt", dir: false, asText : function () {...}, ...} 47 | ``` 48 | 49 | 50 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples/downloader.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Mini app : Downloader" 3 | layout: default 4 | section: example 5 | --- 6 | 7 |

Tip : check the source of the page !

8 | 9 |

10 | This mini application let you choose the files you want in a list, download 11 | them, zip them and give the result to the user. 12 |

13 |

14 | This demo requires a recent browser, see 15 | the howto. 16 |

17 | 18 | 19 | 20 |
21 |

Please select your files

22 |
23 |
    24 |
  • 25 | 29 |
  • 30 |
  • 31 | 35 |
  • 36 |
  • 37 | 41 |
  • 42 |
  • 43 | 47 |
  • 48 |
49 | 50 | 51 |
52 | 53 |

54 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/upgrade_guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Upgrade Guide 3 | layout: default 4 | section: main 5 | --- 6 | 7 | ### From 2.2.2 to 2.3.0 8 | 9 | * On `ZipObject#options`, the attributes `date` and `dir` have been 10 | deprecated and are now on `ZipObject`. 11 | * On `ZipObject#options`, the attributes `base64` and `binary` have been 12 | deprecated. 13 | * `JSZip.base64`, `JSZip.prototype.crc32`, `JSZip.prototype.utf8decode`, 14 | `JSZip.prototype.utf8encode` and `JSZip.utils` have been deprecated. 15 | 16 | ```js 17 | // deprecated 18 | zip.file("test.txt").options.date 19 | zip.file("test.txt").options.dir 20 | // new API 21 | zip.file("test.txt").date 22 | zip.file("test.txt").dir 23 | ``` 24 | 25 | 26 | ### From 2.0.0 to 2.1.0 27 | 28 | * The packaging changed : instead of loading jszip.js, jszip-load.js, 29 | jszip-inflate.js, jszip-deflate.js, just include dist/jszip.js or 30 | dist/jszip.min.js. 31 | For AMD loader users : JSZip now registers itself. You just have to put the 32 | file at the right place or configure your loader. 33 | 34 | 35 | ### From 1.x to 2.x 36 | 37 | * `JSZipBase64` has been renamed to `JSZip.base64`. 38 | * The `data` attribute doesn't exist anymore : 39 | use the getters `asText()`, `asBinary()`, etc 40 | * The compression/decompression methods now give their input type with the 41 | `compressInputType` and `uncompressInputType` attributes. 42 | 43 | Example for the data attribute : 44 | 45 | ```js 46 | // before 47 | zip.file("test.txt").data; 48 | zip.files["test.txt"].data; 49 | zip.file("image.png").data; 50 | zip.files["image.png"].data; 51 | 52 | // after 53 | zip.file("test.txt").asText(); 54 | zip.files["test.txt"].asText(); 55 | zip.file("image.png").asBinary(); 56 | zip.files["image.png"].asBinary(); 57 | ``` 58 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples/download-zip-file.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Download the generated zip file" 3 | layout: default 4 | section: example 5 | --- 6 | 7 |

Tip : check the source of the page !

8 |

The FileSaver API

9 |
10 | Works on firefox, chrome , opera >= 15 and IE >= 10 (but NOT in compatibility view).
11 | 12 |
13 |

The data URL

14 |
15 | Does not work in IE, has restrictions on the length.
16 | 17 |
18 | 60 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/base64.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // private property 3 | var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 4 | 5 | 6 | // public method for encoding 7 | exports.encode = function(input, utf8) { 8 | var output = ""; 9 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 10 | var i = 0; 11 | 12 | while (i < input.length) { 13 | 14 | chr1 = input.charCodeAt(i++); 15 | chr2 = input.charCodeAt(i++); 16 | chr3 = input.charCodeAt(i++); 17 | 18 | enc1 = chr1 >> 2; 19 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 20 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 21 | enc4 = chr3 & 63; 22 | 23 | if (isNaN(chr2)) { 24 | enc3 = enc4 = 64; 25 | } 26 | else if (isNaN(chr3)) { 27 | enc4 = 64; 28 | } 29 | 30 | output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); 31 | 32 | } 33 | 34 | return output; 35 | }; 36 | 37 | // public method for decoding 38 | exports.decode = function(input, utf8) { 39 | var output = ""; 40 | var chr1, chr2, chr3; 41 | var enc1, enc2, enc3, enc4; 42 | var i = 0; 43 | 44 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 45 | 46 | while (i < input.length) { 47 | 48 | enc1 = _keyStr.indexOf(input.charAt(i++)); 49 | enc2 = _keyStr.indexOf(input.charAt(i++)); 50 | enc3 = _keyStr.indexOf(input.charAt(i++)); 51 | enc4 = _keyStr.indexOf(input.charAt(i++)); 52 | 53 | chr1 = (enc1 << 2) | (enc2 >> 4); 54 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 55 | chr3 = ((enc3 & 3) << 6) | enc4; 56 | 57 | output = output + String.fromCharCode(chr1); 58 | 59 | if (enc3 != 64) { 60 | output = output + String.fromCharCode(chr2); 61 | } 62 | if (enc4 != 64) { 63 | output = output + String.fromCharCode(chr3); 64 | } 65 | 66 | } 67 | 68 | return output; 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /js/c64/iec.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | return { 3 | lines: {}, 4 | devices: [], 5 | 6 | register: function(device) { 7 | if (!this.lines[device]) { 8 | this.devices.push(device); 9 | } 10 | this.lines[device] = { 11 | ATN: false, 12 | CLK: false, 13 | DATA: false 14 | }; 15 | }, 16 | log: function(device, str) { 17 | if (this.owner.game.debug) { 18 | console.log('[IEC] {'+this.owner.CPU.clock+'} Device '+device+' '+str); 19 | } 20 | }, 21 | pulldown: function(device, line) { 22 | if (!this.lines[device][line]) { 23 | this.log(device, 'pulling down '+line); 24 | } 25 | this.lines[device][line] = true; 26 | }, 27 | release: function(device, line) { 28 | if (this.lines[device][line]) { 29 | this.log(device, 'releasing '+line); 30 | } 31 | this.lines[device][line] = false; 32 | }, 33 | check: function(line) { 34 | for (var i = 0; i < this.devices.length; i++) { 35 | if (this.lines[this.devices[i]][line]) { 36 | return true; 37 | } 38 | } 39 | return false; 40 | }, 41 | getState: function() { 42 | return $.extend({}, this.lines); 43 | }, 44 | setState: function(state) { 45 | this.lines = $.extend({}, state); 46 | }, 47 | signal: function(line) { 48 | if (line == 'RESET') { 49 | this.owner.DISK.reset(); 50 | } 51 | }, 52 | reset: function() { 53 | var i; 54 | this.lines = {}; 55 | for (i in this.devices) { 56 | this.register(this.devices[i]); 57 | } 58 | }, 59 | init: function() { 60 | this.lines = {}; 61 | } 62 | }; 63 | }); 64 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_zipobject.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ZipObject API" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | This represents an entry in the zip file. If the entry comes from an existing 8 | archive previously [loaded]({{site.baseurl}}/documentation/api_jszip/load.html), the content 9 | will be automatically decompressed/converted first. 10 | 11 | ### Attributes 12 | 13 | attribute name | type | description 14 | ----------------------------|-------------|------------- 15 | `name` | string | the absolute path of the file 16 | `dir` | boolean | true if this is a directory 17 | `date` | date | the last modification date 18 | `comment` | string | the comment for this file 19 | `options` | object | the options of the file. The available options are : 20 | `options.base64` | boolean | **Deprecated**, see [file(name, data [,options])]({{site.baseurl}}/documentation/api_jszip/file_data.html) 21 | `options.binary` | boolean | **Deprecated**, see [file(name, data [,options])]({{site.baseurl}}/documentation/api_jszip/file_data.html) 22 | `options.dir` | boolean | **Deprecated**, use `dir`. True if this is a directory 23 | `options.date` | date | **Deprecated**, use `date`. See [file(name, data [,options])]({{site.baseurl}}/documentation/api_jszip/file_data.html) 24 | `options.compression` | compression | see [file(name, data [,options])]({{site.baseurl}}/documentation/api_jszip/file_data.html) 25 | 26 | 27 | ### Getters 28 | 29 | method | return type | description 30 | ------------------|---------------|------------- 31 | `asText()` | string | the content as an unicode string. 32 | `asBinary()` | string | the content as binary string. 33 | `asArrayBuffer()` | ArrayBuffer | need a [compatible browser]({{site.baseurl}}/documentation/api_jszip/support.html). 34 | `asUint8Array()` | Uint8Array | need a [compatible browser]({{site.baseurl}}/documentation/api_jszip/support.html). 35 | `asNodeBuffer()` | nodejs Buffer | need [nodejs]({{site.baseurl}}/documentation/api_jszip/support.html). 36 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contributing 3 | layout: default 4 | section: main 5 | --- 6 | 7 | 8 | ### Download the sources 9 | 10 | You should create a [Github](https://github.com/) account and 11 | [fork the repository](https://help.github.com/articles/fork-a-repo) (you will 12 | need one to create the pull request). 13 | 14 | If you just want the get the source code, you can use git and do 15 | `git clone https://github.com/Stuk/jszip.git` to get the sources. You can also 16 | download the latest sources [here](https://github.com/Stuk/jszip/archive/master.zip). 17 | 18 | ### Building the project 19 | 20 | #### Code 21 | 22 | The dependencies are handled by npm, the first step is to run 23 | `npm install` to get the dependencies. 24 | JSZip uses Grunt to handle the build, [see here to install its CLI](http://gruntjs.com/getting-started). 25 | 26 | Here are the interesting build commands : 27 | 28 | * `grunt` will generate the final js file in dist/ and the minified version. 29 | * `npm run test-node` will run the tests in nodejs. 30 | * `npm run test-browser` will the tests in some browsers using SauceLabs, see 31 | below. 32 | * `npm run test` will run the tests in nodejs and in the browser. 33 | * `npm run lint` will use jshint the check the source code. 34 | 35 | #### Documentation 36 | 37 | The documentation uses jekyll on gh-pages. To render the documentation, you 38 | need to [install jekyll](http://jekyllrb.com/docs/installation/) and then run 39 | `jekyll serve --baseurl ''`. 40 | 41 | ### Testing the project 42 | 43 | To test JSZip in nodejs, use `npm run test-node`. 44 | 45 | To test JSZip in a browser, you can open the file `test/index.html` in the 46 | browser you want to test. Don't forget to update the dist/ files with `grunt`. 47 | 48 | You can also test JSZip in a lot of browsers at once with 49 | [SauceLabs](https://saucelabs.com/). You will need a SauceLabs account and two 50 | variables into your environment. On linux, just use 51 | 52 | ```bash 53 | export SAUCE_USERNAME=your-saucelabs-username 54 | export SAUCE_ACCESS_KEY=your-saucelabs-access-key 55 | ``` 56 | 57 | before running the `npm run test-browser` command. 58 | 59 | ### Merging the changes 60 | 61 | If you have tested bug fixes or new features, you can open a 62 | [pull request](https://help.github.com/articles/using-pull-requests) on Github. 63 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var base64 = require('./base64'); 4 | 5 | /** 6 | Usage: 7 | zip = new JSZip(); 8 | zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); 9 | zip.folder("images").file("smile.gif", base64Data, {base64: true}); 10 | zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); 11 | zip.remove("tempfile"); 12 | 13 | base64zip = zip.generate(); 14 | 15 | **/ 16 | 17 | /** 18 | * Representation a of zip file in js 19 | * @constructor 20 | * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). 21 | * @param {Object=} options the options for creating this objects (optional). 22 | */ 23 | function JSZip(data, options) { 24 | // if this constructor is used without `new`, it adds `new` before itself: 25 | if(!(this instanceof JSZip)) return new JSZip(data, options); 26 | 27 | // object containing the files : 28 | // { 29 | // "folder/" : {...}, 30 | // "folder/data.txt" : {...} 31 | // } 32 | this.files = {}; 33 | 34 | this.comment = null; 35 | 36 | // Where we are in the hierarchy 37 | this.root = ""; 38 | if (data) { 39 | this.load(data, options); 40 | } 41 | this.clone = function() { 42 | var newObj = new JSZip(); 43 | for (var i in this) { 44 | if (typeof this[i] !== "function") { 45 | newObj[i] = this[i]; 46 | } 47 | } 48 | return newObj; 49 | }; 50 | } 51 | JSZip.prototype = require('./object'); 52 | JSZip.prototype.load = require('./load'); 53 | JSZip.support = require('./support'); 54 | JSZip.defaults = require('./defaults'); 55 | 56 | /** 57 | * @deprecated 58 | * This namespace will be removed in a future version without replacement. 59 | */ 60 | JSZip.utils = require('./deprecatedPublicUtils'); 61 | 62 | JSZip.base64 = { 63 | /** 64 | * @deprecated 65 | * This method will be removed in a future version without replacement. 66 | */ 67 | encode : function(input) { 68 | return base64.encode(input); 69 | }, 70 | /** 71 | * @deprecated 72 | * This method will be removed in a future version without replacement. 73 | */ 74 | decode : function(input) { 75 | return base64.decode(input); 76 | } 77 | }; 78 | JSZip.compressions = require('./compressions'); 79 | module.exports = JSZip; 80 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSZip Testing 6 | 7 | 8 | 9 | 10 | 11 | 47 | 48 | 49 | 52 | 55 | 56 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
71 |
72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Commodore Clicker 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Commodore Clicker

12 |
13 |

Render the screen of a Commodore 64 pixel by pixel, and unleash the graphical prowess of the greatest computer of the 80s!

14 |

Purchase oscillators to kick-start the computer's clock, using the pixels you've built up; buy upgrades to power up your clicking, and to start special graphical effects.

15 | This is not a full simulation of a C64. Not yet, anyways. 16 |
17 |
18 |
19 |
20 |
U
21 |
L
22 |
R
23 |
D
24 |
Fire
25 |
26 |
 
27 |
 
28 |
Reticulating splines...
29 |
30 |
31 | 48 |
49 | 50 |
51 |
52 | 58 |
    59 |
  • Frame: , raster:
  • 60 |
  • Clock speed:
  • 61 |
  • Rendering:
  • 62 |
63 |
Hard Reset
64 |
65 |
66 |
67 | Developed by Imran Nazar, 2014. Now on GitHub. 68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples/downloader.js: -------------------------------------------------------------------------------- 1 | jQuery(function ($) { 2 | "use strict"; 3 | 4 | /** 5 | * Reset the message. 6 | */ 7 | function resetMessage () { 8 | $("#result") 9 | .removeClass() 10 | .text(""); 11 | } 12 | /** 13 | * show a successful message. 14 | * @param {String} text the text to show. 15 | */ 16 | function showMessage(text) { 17 | resetMessage(); 18 | $("#result") 19 | .addClass("alert alert-success") 20 | .text(text); 21 | } 22 | /** 23 | * show an error message. 24 | * @param {String} text the text to show. 25 | */ 26 | function showError(text) { 27 | resetMessage(); 28 | $("#result") 29 | .addClass("alert alert-danger") 30 | .text(text); 31 | } 32 | 33 | /** 34 | * Fetch the content, add it to the JSZip object 35 | * and use a jQuery deferred to hold the result. 36 | * @param {String} url the url of the content to fetch. 37 | * @param {String} filename the filename to use in the JSZip object. 38 | * @param {JSZip} zip the JSZip instance. 39 | * @return {jQuery.Deferred} the deferred containing the data. 40 | */ 41 | function deferredAddZip(url, filename, zip) { 42 | var deferred = $.Deferred(); 43 | JSZipUtils.getBinaryContent(url, function (err, data) { 44 | if(err) { 45 | deferred.reject(err); 46 | } else { 47 | zip.file(filename, data, {binary:true}); 48 | deferred.resolve(data); 49 | } 50 | }); 51 | return deferred; 52 | } 53 | 54 | if(!JSZip.support.blob) { 55 | showError("This demo works only with a recent browser !"); 56 | return; 57 | } 58 | 59 | var $form = $("#download_form").on("submit", function () { 60 | 61 | resetMessage(); 62 | 63 | var zip = new JSZip(); 64 | var deferreds = []; 65 | 66 | // find every checked item 67 | $(this).find(":checked").each(function () { 68 | var $this = $(this); 69 | var url = $this.data("url"); 70 | var filename = url.replace(/.*\//g, ""); 71 | deferreds.push(deferredAddZip(url, filename, zip)); 72 | }); 73 | 74 | // when everything has been downloaded, we can trigger the dl 75 | $.when.apply($, deferreds).done(function () { 76 | var blob = zip.generate({type:"blob"}); 77 | 78 | // see FileSaver.js 79 | saveAs(blob, "example.zip"); 80 | 81 | showMessage("done !"); 82 | }).fail(function (err) { 83 | showError(err); 84 | }); 85 | return false; 86 | }); 87 | }); 88 | 89 | // vim: set shiftwidth=4 softtabstop=4: 90 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/docs/ZIP spec.txt: -------------------------------------------------------------------------------- 1 | Here are the notes I made while working through the ZIP file specification. 2 | 3 | For each file: 4 | 5 | local file header signature 4 bytes (0x04034b50) 6 | version needed to extract 2 bytes 7 | general purpose bit flag 2 bytes 8 | compression method 2 bytes 9 | last mod file time 2 bytes 10 | last mod file date 2 bytes 11 | crc-32 4 bytes 12 | compressed size 4 bytes 13 | uncompressed size 4 bytes 14 | file name length 2 bytes 15 | extra field length 2 bytes 16 | 17 | |sig |v |g |c |t |d |crc |csz |usz |n |x | 18 | PK.. ## 00 00 ?? ?? xxxx ???? ???? ?? 00 19 | 20 | 21 | Central directory: 22 | 23 | central file header signature 4 bytes (0x02014b50) 24 | version made by 2 bytes 25 | version needed to extract 2 bytes * 26 | general purpose bit flag 2 bytes * 27 | compression method 2 bytes * 28 | last mod file time 2 bytes * 29 | last mod file date 2 bytes * 30 | crc-32 4 bytes * 31 | compressed size 4 bytes * 32 | uncompressed size 4 bytes * 33 | file name length 2 bytes * 34 | extra field length 2 bytes * 35 | file comment length 2 bytes 36 | disk number start 2 bytes 37 | internal file attributes 2 bytes 38 | external file attributes 4 bytes 39 | relative offset of local header 4 bytes 40 | 41 | file name (variable size) 42 | extra field (variable size) 43 | file comment (variable size) 44 | 45 | |sig |vm|vx|g |c |d |t |crc |csz |usz |n |x |cm|dn|ia|xa |roff| 46 | PK.. ## ## 00 00 ?? ?? xxxx ???? ???? ?? 00 00 00 00 xxxx ???? 47 | 48 | End of central directory: 49 | 50 | end of central dir signature 4 bytes (0x06054b50) 51 | number of this disk 2 bytes 52 | number of the disk with the 53 | start of the central directory 2 bytes 54 | total number of entries in the 55 | central directory on this disk 2 bytes 56 | total number of entries in 57 | the central directory 2 bytes 58 | size of the central directory 4 bytes 59 | offset of start of central 60 | directory with respect to 61 | the starting disk number 4 bytes 62 | .ZIP file comment length 2 bytes 63 | .ZIP file comment (variable size) 64 | 65 | |sig |n1|n2|e |ne|size|off |cm| 66 | PK.. 00 00 ?? ?? ???? ???? 00 67 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/generate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "generate(options)" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Generates the complete zip file. 8 | 9 | __Arguments__ 10 | 11 | name | type | default | description 12 | --------------------|---------|---------|------------ 13 | options | object | | the options to generate the zip file : 14 | options.base64 | boolean | false | **deprecated**, use `type` instead. If `type` is not used, set to `false` to get the result as a raw byte string, `true` to encode it as base64. 15 | options.compression | string | `STORE` (no compression) | the default file compression method to use. Available methods are `STORE` and `DEFLATE`. You can also provide your own compression method. 16 | options.type | string | `base64` | The type of zip to return, see below for the other types. 17 | options.comment | string | | The comment to use for the zip file. 18 | 19 | Possible values for `type` : 20 | 21 | * `base64` (default) : the result will be a string, the binary in a base64 form. 22 | * `string` : the result will be a string in "binary" form, using 1 byte per char (2 bytes). 23 | * `uint8array` : the result will be a Uint8Array containing the zip. This requires a compatible browser. 24 | * `arraybuffer` : the result will be a ArrayBuffer containing the zip. This requires a compatible browser. 25 | * `blob` : the result will be a Blob containing the zip. This requires a compatible browser. 26 | * `nodebuffer` : the result will be a nodejs Buffer containing the zip. This requires nodejs. 27 | 28 | Note : when using type = "uint8array", "arraybuffer" or "blob", be sure to 29 | check if the browser supports it (you can use [`JSZip.support`]({{site.baseurl}}/documentation/api_jszip/support.html)). 30 | 31 | Note for the `comment` option : the zip format has no flag or field to give the 32 | encoding of this field and JSZip will use UTF-8. With non ASCII characters you 33 | might get encoding issues if the file archiver doesn't use UTF-8 to decode the 34 | comment. 35 | 36 | If not set, JSZip will use the field `comment` on its `options`. 37 | 38 | __Returns__ : The generated zip file. 39 | 40 | __Throws__ : An exception if the asked `type` is not available in the browser, 41 | see [JSZip.support]({{site.baseurl}}/documentation/api_jszip/support.html). 42 | 43 | 44 | 45 | __Example__ 46 | 47 | ```js 48 | var content = zip.generate({type:"blob"}); 49 | // see FileSaver.js 50 | saveAs(content, "hello.zip"); 51 | ``` 52 | 53 | ```js 54 | var content = zip.generate({type:"base64"}); 55 | location.href="data:application/zip;base64,"+content; 56 | ``` 57 | 58 | ```js 59 | var content = zip.generate({type:"nodebuffer"}); 60 | require("fs").writeFile("hello.zip", content, function(err){/*...*/}); 61 | ``` 62 | 63 | 64 | -------------------------------------------------------------------------------- /css/jquery.powertip-yellow.css: -------------------------------------------------------------------------------- 1 | /* PowerTip Plugin */ 2 | #powerTip { 3 | cursor: default; 4 | background-color: #ffffb4; 5 | -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15), 0 2px 1px rgba(255, 255, 255, 0.8) inset, 0 -2px 2px #fafa6e inset; 6 | -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15), 0 2px 1px rgba(255, 255, 255, 0.8) inset, 0 -2px 2px #fafa6e inset; 7 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15), 0 2px 1px rgba(255, 255, 255, 0.8) inset, 0 -2px 2px #fafa6e inset; 8 | border: 1px solid #fafa50; 9 | border-radius: 6px; 10 | color: #000000; 11 | display: none; 12 | padding: 10px; 13 | position: absolute; 14 | max-width: 90%; 15 | z-index: 2147483647; 16 | } 17 | #powerTip:before { 18 | content: ""; 19 | position: absolute; 20 | } 21 | #powerTip.n:before, #powerTip.s:before { 22 | border-right: 5px solid transparent; 23 | border-left: 5px solid transparent; 24 | left: 50%; 25 | margin-left: -5px; 26 | } 27 | #powerTip.e:before, #powerTip.w:before { 28 | border-bottom: 5px solid transparent; 29 | border-top: 5px solid transparent; 30 | margin-top: -5px; 31 | top: 50%; 32 | } 33 | #powerTip.n:before { 34 | border-top: 10px solid #fafa50; 35 | border-top: 10px solid rgba(250, 250, 80, 0.8); 36 | bottom: -10px; 37 | } 38 | #powerTip.e:before { 39 | border-right: 10px solid #fafa50; 40 | border-right: 10px solid rgba(250, 250, 80, 0.8); 41 | left: -10px; 42 | } 43 | #powerTip.s:before { 44 | border-bottom: 10px solid #fafa50; 45 | border-bottom: 10px solid rgba(250, 250, 80, 0.8); 46 | top: -10px; 47 | } 48 | #powerTip.w:before { 49 | border-left: 10px solid #fafa50; 50 | border-left: 10px solid rgba(250, 250, 80, 0.8); 51 | right: -10px; 52 | } 53 | #powerTip.ne:before, #powerTip.se:before { 54 | border-right: 10px solid transparent; 55 | border-left: 0; 56 | left: 10px; 57 | } 58 | #powerTip.nw:before, #powerTip.sw:before { 59 | border-left: 10px solid transparent; 60 | border-right: 0; 61 | right: 10px; 62 | } 63 | #powerTip.ne:before, #powerTip.nw:before { 64 | border-top: 10px solid #fafa50; 65 | border-top: 10px solid rgba(250, 250, 80, 0.8); 66 | bottom: -10px; 67 | } 68 | #powerTip.se:before, #powerTip.sw:before { 69 | border-bottom: 10px solid #fafa50; 70 | border-bottom: 10px solid rgba(250, 250, 80, 0.8); 71 | top: -10px; 72 | } 73 | #powerTip.nw-alt:before, #powerTip.ne-alt:before, 74 | #powerTip.sw-alt:before, #powerTip.se-alt:before { 75 | border-top: 10px solid #fafa50; 76 | border-top: 10px solid rgba(250, 250, 80, 0.8); 77 | bottom: -10px; 78 | border-left: 5px solid transparent; 79 | border-right: 5px solid transparent; 80 | left: 10px; 81 | } 82 | #powerTip.ne-alt:before { 83 | left: auto; 84 | right: 10px; 85 | } 86 | #powerTip.sw-alt:before, #powerTip.se-alt:before { 87 | border-top: none; 88 | border-bottom: 10px solid #fafa50; 89 | border-bottom: 10px solid rgba(250, 250, 80, 0.8); 90 | bottom: auto; 91 | top: -10px; 92 | } 93 | #powerTip.se-alt:before { 94 | left: auto; 95 | right: 10px; 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Commodore Clicker 2 | ================= 3 | 4 | A JavaScript incremental game which drives the clock of a Commodore 64 emulation. Or at least, that's the eventual goal. 5 | [Play the game here.](http://c64clicker.com/) 6 | 7 | Usage 8 | ----- 9 | 10 | The emulated C64 boots into the incremental game, but this can be interrupted in the usual manner of hitting Run/Stop + Restore. After interruption, the game can be restarted using the statement: SYS 49152 11 | 12 | A joystick is plugged into port 2 of the C64, and its directions are mapped to the arrow keys. The joystick is used in-game to allow movement of the sprite. Alt is the Fire key, but this is not used in-game at this time. 13 | 14 | The keyboard corresponds to that of a British C64, and is mapped in similar fashion to VICE's mapping. The following keys are non-obvious mappings: 15 | 16 | * F1, F2, F3, F4 are mapped to the C64's F1, F3, F5, F7. Shift-F1 is the C64's F2, and so on. 17 | * Escape is Run/Stop; F8 is Restore. 18 | * Tab is the C64's Control; the host's Control maps to the Commodore key. 19 | 20 | Key map entries not mentioned here are documented in the CIA emulation. 21 | 22 | Credits 23 | ------- 24 | 25 | Libraries included: 26 | 27 | * [BigInteger, by Matthew Crumley and John Tobey](http://silentmatt.com/biginteger/) 28 | * [jQuery.PowerTip, by Steven Benner](http://stevenbenner.github.com/jquery-powertip/) 29 | * [Require.js, by the Dojo Foundation](http://github.com/jrburke/requirejs) 30 | * [jQuery-Ajax-Blob-ArrayBuffer, by Christopher Keefer](https://gist.github.com/SaneMethod/7548768) 31 | * [JSZip, by Stuart Knightley](https://github.com/Stuk/jszip) 32 | * And, of course, jQuery. 33 | 34 | Test ROMs included: 35 | 36 | * [Klaus Dormann's 6502 functional tests](https://github.com/redline6561/cl-6502/blob/b0087903/tests/6502_functional_test.a65) 37 | 38 | Resources that have been infinitely useful: 39 | 40 | * [The C64 memory map](http://sta.c64.org/cbm64mem.html) 41 | * [The VIC-II For Beginners series, by actraiser, 2013](http://dustlayer.com/vic-ii/2013/4/22/when-visibility-matters) 42 | * ["The MOS 6567/6569 video controller and its application in the Commodore 64", by Christian Bauer, 1996](http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt) 43 | * ["Documentation for the NMOS 65xx instruction set", by John West and Marko Makela, 1994](http://www.zimmers.net/anonftp/pub/cbm/documents/chipdata/64doc) 44 | * [6502 opcode matrix, by Graham/Oxyron, 2012](http://www.oxyron.de/html/opcodes02.html) 45 | * [Opcode pseudocode from VICE, compiled at Nesdev](http://nesdev.com/6502.txt) 46 | * ["Internals of BRK/IRQ/NMI/RESET on a MOS 6502", by Michael Steil, 2010](http://www.pagetable.com/?p=410) 47 | * [CIA register map, on the C64 Wiki](http://www.c64-wiki.com/index.php/CIA) 48 | * [Kernal/BASIC disassembly, by Marko Makela, 1994](http://www.ffd2.com/fridge/docs/c64-diss.html) 49 | * ["How the VIC/64 Serial Bus Works", by Jim Butterfield, 1983](ftp://ftp.zimmers.net/pub/cbm/programming/serial-bus.pdf) 50 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/load.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "load(data [, options])" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Read an existing zip and merge the data in the current JSZip 8 | object at the current folder level. This technique has some limitations, see 9 | [here]({{site.baseurl}}/documentation/limitations.html). 10 | 11 | __Arguments__ 12 | 13 | name | type | description 14 | -------------------|--------|------------ 15 | data | String/ArrayBuffer/Uint8Array/Buffer | the zip file 16 | options | object | the options to load the zip file 17 | 18 | Content of `options` : 19 | 20 | name | type | default | description 21 | ------------------------------|---------|---------|------------ 22 | options.base64 | boolean | false | set to `true` if the data is base64 encoded, `false` for binary. 23 | options.checkCRC32 | boolean | false | set to `true` if the read data should be checked against its CRC32. 24 | options.optimizedBinaryString | boolean | false | set to true if (and only if) the input is a string and has already been prepared with a 0xFF mask. 25 | options.createFolders | boolean | false | set to true to create folders in the file path automatically. Leaving it false will result in only virtual folders (i.e. folders that merely represent part of the file path) being created. 26 | 27 | You shouldn't update the data given to this method : it is kept as it so any 28 | update will impact the stored data. 29 | 30 | Zip features supported by this method : 31 | 32 | * Compression (DEFLATE supported) 33 | * zip with data descriptor 34 | * ZIP64 35 | * UTF8 in file name, UTF8 in file content 36 | 37 | Zip features not (yet) supported : 38 | 39 | * password protected zip 40 | * multi-volume zip 41 | 42 | __Returns__ : The current JSZip object. 43 | 44 | __Throws__ : An exception if the loaded data is not valid zip data or if it 45 | uses features (multi volume, password protected, etc). 46 | 47 | 58 | 59 | __Example__ 60 | 61 | ```js 62 | var zip = new JSZip(); 63 | zip.load(zipDataFromXHR); 64 | ``` 65 | 66 | ```js 67 | require("fs").readFile("hello.zip", function (err, data) { 68 | if (err) throw err; 69 | var zip = new JSZip(); 70 | zip.load(data); 71 | } 72 | ``` 73 | 74 | Using sub folders : 75 | 76 | ```js 77 | var zip = new JSZip(); 78 | zip.folder("subfolder").load(data); 79 | // the content of data will be loaded in subfolder/ 80 | ``` 81 | 82 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples/read-local-file-api.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Reading a local file with the File API" 3 | layout: default 4 | section: example 5 | --- 6 | 7 |

Choose the local(s) zip file(s)

8 |

Note : your browser will process the zip file, don't choose a file too big !

9 |
10 | 11 | 14 | 15 | 19 | 20 | 88 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/deprecatedPublicUtils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var utils = require('./utils'); 3 | 4 | /** 5 | * @deprecated 6 | * This function will be removed in a future version without replacement. 7 | */ 8 | exports.string2binary = function(str) { 9 | return utils.string2binary(str); 10 | }; 11 | 12 | /** 13 | * @deprecated 14 | * This function will be removed in a future version without replacement. 15 | */ 16 | exports.string2Uint8Array = function(str) { 17 | return utils.transformTo("uint8array", str); 18 | }; 19 | 20 | /** 21 | * @deprecated 22 | * This function will be removed in a future version without replacement. 23 | */ 24 | exports.uint8Array2String = function(array) { 25 | return utils.transformTo("string", array); 26 | }; 27 | 28 | /** 29 | * @deprecated 30 | * This function will be removed in a future version without replacement. 31 | */ 32 | exports.string2Blob = function(str) { 33 | var buffer = utils.transformTo("arraybuffer", str); 34 | return utils.arrayBuffer2Blob(buffer); 35 | }; 36 | 37 | /** 38 | * @deprecated 39 | * This function will be removed in a future version without replacement. 40 | */ 41 | exports.arrayBuffer2Blob = function(buffer) { 42 | return utils.arrayBuffer2Blob(buffer); 43 | }; 44 | 45 | /** 46 | * @deprecated 47 | * This function will be removed in a future version without replacement. 48 | */ 49 | exports.transformTo = function(outputType, input) { 50 | return utils.transformTo(outputType, input); 51 | }; 52 | 53 | /** 54 | * @deprecated 55 | * This function will be removed in a future version without replacement. 56 | */ 57 | exports.getTypeOf = function(input) { 58 | return utils.getTypeOf(input); 59 | }; 60 | 61 | /** 62 | * @deprecated 63 | * This function will be removed in a future version without replacement. 64 | */ 65 | exports.checkSupport = function(type) { 66 | return utils.checkSupport(type); 67 | }; 68 | 69 | /** 70 | * @deprecated 71 | * This value will be removed in a future version without replacement. 72 | */ 73 | exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; 74 | 75 | /** 76 | * @deprecated 77 | * This value will be removed in a future version without replacement. 78 | */ 79 | exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; 80 | 81 | 82 | /** 83 | * @deprecated 84 | * This function will be removed in a future version without replacement. 85 | */ 86 | exports.pretty = function(str) { 87 | return utils.pretty(str); 88 | }; 89 | 90 | /** 91 | * @deprecated 92 | * This function will be removed in a future version without replacement. 93 | */ 94 | exports.findCompression = function(compressionMethod) { 95 | return utils.findCompression(compressionMethod); 96 | }; 97 | 98 | /** 99 | * @deprecated 100 | * This function will be removed in a future version without replacement. 101 | */ 102 | exports.isRegExp = function (object) { 103 | return utils.isRegExp(object); 104 | }; 105 | 106 | -------------------------------------------------------------------------------- /js/thirdparty/jquery-ajax-blob-arraybuffer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Register ajax transports for blob send/recieve and array buffer send/receive via XMLHttpRequest Level 2 3 | * within the comfortable framework of the jquery ajax request, with full support for promises. 4 | * 5 | * Notice the +* in the dataType string? The + indicates we want this transport to be prepended to the list 6 | * of potential transports (so it gets first dibs if the request passes the conditions within to provide the 7 | * ajax transport, preventing the standard transport from hogging the request), and the * indicates that 8 | * potentially any request with any dataType might want to use the transports provided herein. 9 | * 10 | * Remember to specify 'processData:false' in the ajax options when attempting to send a blob or arraybuffer - 11 | * otherwise jquery will try (and fail) to convert the blob or buffer into a query string. 12 | */ 13 | $.ajaxTransport("+*", function(options, originalOptions, jqXHR){ 14 | // Test for the conditions that mean we can/want to send/receive blobs or arraybuffers - we need XMLHttpRequest 15 | // level 2 (so feature-detect against window.FormData), feature detect against window.Blob or window.ArrayBuffer, 16 | // and then check to see if the dataType is blob/arraybuffer or the data itself is a Blob/ArrayBuffer 17 | if (window.FormData && ((options.dataType && (options.dataType == 'blob' || options.dataType == 'arraybuffer')) 18 | || (options.data && ((window.Blob && options.data instanceof Blob) 19 | || (window.ArrayBuffer && options.data instanceof ArrayBuffer))) 20 | )) 21 | { 22 | return { 23 | /** 24 | * Return a transport capable of sending and/or receiving blobs - in this case, we instantiate 25 | * a new XMLHttpRequest and use it to actually perform the request, and funnel the result back 26 | * into the jquery complete callback (such as the success function, done blocks, etc.) 27 | * 28 | * @param headers 29 | * @param completeCallback 30 | */ 31 | send: function(headers, completeCallback){ 32 | var xhr = new XMLHttpRequest(), 33 | url = options.url || window.location.href, 34 | type = options.type || 'GET', 35 | dataType = options.dataType || 'text', 36 | data = options.data || null, 37 | async = options.async || true; 38 | 39 | xhr.addEventListener('load', function(){ 40 | var res = {}; 41 | 42 | res[dataType] = xhr.response; 43 | completeCallback(xhr.status, xhr.statusText, res, xhr.getAllResponseHeaders()); 44 | }); 45 | 46 | xhr.open(type, url, async); 47 | xhr.responseType = dataType; 48 | xhr.send(data); 49 | }, 50 | abort: function(){ 51 | jqXHR.abort(); 52 | } 53 | }; 54 | } 55 | }); 56 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/limitations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Limitations of JSZip" 3 | layout: default 4 | section: limitations 5 | fullpage: true 6 | --- 7 | 8 | ### Not supported features 9 | 10 | All the features of zip files are not supported. Classic zip files will work 11 | but encrypted zip, multi-volume, etc are not supported and the load() method 12 | will throw an `Error`. 13 | 14 | 15 | ### ZIP64 and 32bit integers 16 | 17 | ZIP64 files can be loaded, but only if the zip file is not "too big". ZIP64 uses 64bits integers 18 | but Javascript represents all numbers as 19 | [64-bit double precision IEEE 754 floating point numbers](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf) 20 | (see section 8.5). So, we have 53bits for integers and 21 | [bitwise operations treat everything as 32bits](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators). 22 | So if all the 64bits integers can fit into 32 bits integers, everything will be 23 | fine. If it's not the case, you will have other problems anyway (see next 24 | limitation). 25 | 26 | ### Performance issues 27 | 28 | An other limitation comes from the browser (and the machine running the 29 | browser). A compressed zip file of 10MB is "easily" opened by firefox / chrome 30 | / opera / IE10+ but will crash older IE. Also keep in mind that strings in 31 | javascript are encoded in UTF-16 : a 10MB ascii text file will take 20MB of 32 | memory. 33 | 34 | If you're having performance issues, please consider the following : 35 | 36 | * Don't use IE <= 9. Everything is better with typed arrays. 37 | * Use typed arrays (Uint8Array, ArrayBuffer, etc) if possible : 38 | * If you generate a zip file, you should use `type:"uint8array"` 39 | (or blob, arraybuffer, nodebuffer). 40 | * If you load the file from an ajax call, ask your XHR an ArrayBuffer. 41 | Loading a string is asking for troubles. 42 | * Don't use compression (see below). 43 | * If you want to get the content of an ASCII file as a string, consider using 44 | `asBinary()` instead of `asText()`. The transformation 45 | "binary string" -> "unicode string" is a consuming process. 46 | 47 | Note about compression : 48 | When reading a file, JSZip will store the content without decompressing it. 49 | When generating a compressed file, JSZip will reuse if possible compressed 50 | content : 51 | 52 | * If you read a zip file compressed with DEFLATE and call `generate` with the 53 | DEFLATE compression, JSZip won't call the compression algorithms (same with 54 | STORE everywhere.) 55 | * If you read a zip file compressed with DEFLATE and call `generate` with the 56 | STORE compression, JSZip will have to decompress everything. 57 | 58 | On IE <=9, typed arrays are not supported and the compression algorithm 59 | will fallback on arrays. In that case, JSZip needs to convert the binary string 60 | into an array, DEFLATE it and convert the result into a binary string. 61 | You don't want that to happen. 62 | 63 | ### The output zip will differ from the input zip 64 | 65 | Reading and generating a zip file won't give you back the same file. 66 | Some data are discarded (file metadata) and other are added (subfolders). 67 | 68 | ### Encodings support 69 | 70 | JSZip only supports utf8 : if the names of the files inside the zip are not in 71 | utf8 (or ASCII), they won't be interpreted correctly. If the content is a text 72 | not encoded with utf8 (or ASCII), the `asText()` method won't decode it 73 | correctly. 74 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/css/pygments.css: -------------------------------------------------------------------------------- 1 | /* Generated with : 2 | * pygmentize -S default -f html > pygments.css 3 | */ 4 | .hll { background-color: #ffffcc } 5 | .c { color: #408080; font-style: italic } /* Comment */ 6 | .err { border: 1px solid #FF0000 } /* Error */ 7 | .k { color: #008000; font-weight: bold } /* Keyword */ 8 | .o { color: #666666 } /* Operator */ 9 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 10 | .cp { color: #BC7A00 } /* Comment.Preproc */ 11 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ 12 | .cs { color: #408080; font-style: italic } /* Comment.Special */ 13 | .gd { color: #A00000 } /* Generic.Deleted */ 14 | .ge { font-style: italic } /* Generic.Emph */ 15 | .gr { color: #FF0000 } /* Generic.Error */ 16 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 17 | .gi { color: #00A000 } /* Generic.Inserted */ 18 | .go { color: #888888 } /* Generic.Output */ 19 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 20 | .gs { font-weight: bold } /* Generic.Strong */ 21 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 22 | .gt { color: #0044DD } /* Generic.Traceback */ 23 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 24 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 25 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 26 | .kp { color: #008000 } /* Keyword.Pseudo */ 27 | .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 28 | .kt { color: #B00040 } /* Keyword.Type */ 29 | .m { color: #666666 } /* Literal.Number */ 30 | .s { color: #BA2121 } /* Literal.String */ 31 | .na { color: #7D9029 } /* Name.Attribute */ 32 | .nb { color: #008000 } /* Name.Builtin */ 33 | .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 34 | .no { color: #880000 } /* Name.Constant */ 35 | .nd { color: #AA22FF } /* Name.Decorator */ 36 | .ni { color: #999999; font-weight: bold } /* Name.Entity */ 37 | .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 38 | .nf { color: #0000FF } /* Name.Function */ 39 | .nl { color: #A0A000 } /* Name.Label */ 40 | .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 41 | .nt { color: #008000; font-weight: bold } /* Name.Tag */ 42 | .nv { color: #19177C } /* Name.Variable */ 43 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 44 | .w { color: #bbbbbb } /* Text.Whitespace */ 45 | .mf { color: #666666 } /* Literal.Number.Float */ 46 | .mh { color: #666666 } /* Literal.Number.Hex */ 47 | .mi { color: #666666 } /* Literal.Number.Integer */ 48 | .mo { color: #666666 } /* Literal.Number.Oct */ 49 | .sb { color: #BA2121 } /* Literal.String.Backtick */ 50 | .sc { color: #BA2121 } /* Literal.String.Char */ 51 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 52 | .s2 { color: #BA2121 } /* Literal.String.Double */ 53 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 54 | .sh { color: #BA2121 } /* Literal.String.Heredoc */ 55 | .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 56 | .sx { color: #008000 } /* Literal.String.Other */ 57 | .sr { color: #BB6688 } /* Literal.String.Regex */ 58 | .s1 { color: #BA2121 } /* Literal.String.Single */ 59 | .ss { color: #19177C } /* Literal.String.Symbol */ 60 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ 61 | .vc { color: #19177C } /* Name.Variable.Class */ 62 | .vg { color: #19177C } /* Name.Variable.Global */ 63 | .vi { color: #19177C } /* Name.Variable.Instance */ 64 | .il { color: #666666 } /* Literal.Number.Integer.Long */ 65 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/api_jszip/file_data.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "file(name, data [,options])" 3 | layout: default 4 | section: api 5 | --- 6 | 7 | __Description__ : Add (or update) a file to the zip file. 8 | 9 | __Arguments__ 10 | 11 | name | type | description 12 | --------------------|---------|------------ 13 | name | string | the name of the file. You can specify folders in the name : the folder separator is a forward slash ("/"). 14 | data | String/ArrayBuffer/Uint8Array/Buffer | the content of the file. 15 | options | object | the options. 16 | 17 | Content of `options` : 18 | 19 | name | type | default | description 20 | ------------|---------|---------|------------ 21 | base64 | boolean | `false` | set to `true` if the data is base64 encoded. For example image data from a `` element. Plain text and HTML do not need this option. 22 | binary | boolean | `false` | set to `true` if the data should be treated as raw content, `false` if this is a text. If base64 is used, this defaults to `true`, if the data is not a string, this will be set to `true`. 23 | date | date | the current date | the last modification date. 24 | compression | string | null | If set, specifies compression method to use for this specific file. If not, the default file compression will be used, see [generate(options)]({{site.baseurl}}/documentation/api_jszip/generate.html). 25 | comment | string | null | The comment for this file. 26 | optimizedBinaryString | boolean | `false` | Set to true if (and only if) the input is a "binary string" and has already been prepared with a 0xFF mask. 27 | createFolders | boolean | `false` | Set to true if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file. 28 | 29 | You shouldn't update the data given to this method : it is kept as it so any 30 | update will impact the stored data. 31 | 32 | __Returns__ : The current JSZip object, for chaining. 33 | 34 | __Throws__ : An exception if the data is not in a supported format. 35 | 36 | 42 | 43 | __Example__ 44 | 45 | ```js 46 | zip.file("Hello.txt", "Hello World\n"); 47 | 48 | // base64 49 | zip.file("smile.gif", "R0lGODdhBQAFAIACAAAAAP/eACwAAAAABQAFAAACCIwPkWerClIBADs=", {base64: true}); 50 | // from an ajax call with xhr.responseType = 'arraybuffer' 51 | zip.file("smile.gif", arraybufferFromXhr); 52 | // or on nodejs 53 | zip.file("smile.gif", fs.readFileSync("smile.gif")); 54 | 55 | zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); 56 | zip.file("folder/file.txt", "file in folder"); 57 | 58 | zip.file("animals.txt", "dog,platypus\n").file("people.txt", "james,sebastian\n"); 59 | 60 | // result : Hello.txt, smile.gif, Xmas.txt, animals.txt, people.txt, 61 | // folder/, folder/file.txt 62 | // In the above case, the "folder" folder will not have a 'D'irectory attribute or Method property. The 63 | // folder only exists as part of the path to "file.txt". 64 | 65 | zip.file("folder/file.txt", "file in folder", {createFolders: true}); 66 | // In this case, the "folder" folder WILL have a 'D'irectory attribute and a Method property of "store". 67 | // It will exist whether or not "file.txt" is present. 68 | ``` 69 | 70 | 71 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/CHANGES.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Changelog 3 | layout: default 4 | section: main 5 | --- 6 | 7 | ### v2.4.0 2014-07-24 8 | - update pako to 0.2.5 (see [#156](https://github.com/Stuk/jszip/issues/156)). 9 | - make JSZip work in a Firefox addon context (see [#151](https://github.com/Stuk/jszip/issues/151)). 10 | - add an option (`createFolders`) to control the subfolder generation (see [#154](https://github.com/Stuk/jszip/issues/154)). 11 | - allow `Buffer` polyfill in the browser (see [#139](https://github.com/Stuk/jszip/issues/139)). 12 | 13 | ### v2.3.0 2014-06-18 14 | - don't generate subfolders (see [#130](https://github.com/Stuk/jszip/issues/130)). 15 | - add comment support (see [#134](https://github.com/Stuk/jszip/issues/134)). 16 | - on `ZipObject#options`, the attributes `date` and `dir` have been deprecated and are now on `ZipObject` (see [the upgrade guide](http://stuk.github.io/jszip/documentation/upgrade_guide.html)). 17 | - on `ZipObject#options`, the attributes `base64` and `binary` have been deprecated (see [the upgrade guide](http://stuk.github.io/jszip/documentation/upgrade_guide.html)). 18 | - deprecate internal functions exposed in the public API (see [#123](https://github.com/Stuk/jszip/issues/123)). 19 | - improve UTF-8 support (see [#142](https://github.com/Stuk/jszip/issues/142)). 20 | 21 | ### v2.2.2, 2014-05-01 22 | - update pako to v0.2.1, fix an error when decompressing some files (see [#126](https://github.com/Stuk/jszip/issues/126)). 23 | 24 | ### v2.2.1, 2014-04-23 25 | - fix unreadable generated file on Windows 8 (see [#112](https://github.com/Stuk/jszip/issues/112)). 26 | - replace zlibjs with pako. 27 | 28 | ### v2.2.0, 2014-02-25 29 | - make the `new` operator optional before the `JSZip` constructor (see [#93](https://github.com/Stuk/jszip/pull/93)). 30 | - update zlibjs to v0.2.0. 31 | 32 | ### v2.1.1, 2014-02-13 33 | - use the npm package for zlib.js instead of the github url. 34 | 35 | ### v2.1.0, 2014-02-06 36 | - split the files and use Browserify to generate the final file (see [#74](https://github.com/Stuk/jszip/pull/74)) 37 | - packaging change : instead of 4 files (jszip.js, jszip-load.js, jszip-inflate.js, jszip-deflate.js) we now have 2 files : dist/jszip.js and dist/jszip.min.js 38 | - add component/bower support 39 | - rename variable: 'byte' is a reserved word (see [#76](https://github.com/Stuk/jszip/pull/76)) 40 | - add support for the unicode path extra field (see [#82](https://github.com/Stuk/jszip/pull/82)) 41 | - ensure that the generated files have a header with the licenses (see [#80](https://github.com/Stuk/jszip/pull/80)) 42 | 43 | # v2.0.0, 2013-10-20 44 | 45 | - `JSZipBase64` has been renamed to `JSZip.base64`. 46 | - The `data` attribute on the object returned by `zip.file(name)` has been removed. Use `asText()`, `asBinary()`, `asUint8Array()`, `asArrayBuffer()` or `asNodeBuffer()`. 47 | 48 | - [Fix issue with Android browser](https://github.com/Stuk/jszip/pull/60) 49 | 50 | - The compression/decompression methods now give their input type with the `compressInputType` and `uncompressInputType` attributes. 51 | - Lazily decompress data when needed and [improve performance in general](https://github.com/Stuk/jszip/pull/56) 52 | - [Add support for `Buffer` in Node.js](https://github.com/Stuk/jszip/pull/57). 53 | - Package for CommonJS/npm. 54 | 55 | ### v1.0.1, 2013-03-04 56 | 57 | - Fixed an issue when generating a compressed zip file with empty files or folders, see #33. 58 | - With bad data (null or undefined), asText/asBinary/asUint8Array/asArrayBuffer methods now return an empty string, see #36. 59 | 60 | # v1.0.0, 2013-02-14 61 | 62 | - First release after a long period without version. 63 | 64 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/examples.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to use JSZip" 3 | layout: default 4 | section: example 5 | --- 6 | 7 | An instance of JSZip represents a set of files. You can add them, remove them, 8 | modify them. You can also import an existing zip file or generate one. 9 | 10 | ### Getting the object 11 | 12 | #### In a browser 13 | 14 | For a browser, there are two interesting files : `dist/jszip.js` and 15 | `dist/jszip.min.js` (include just one). 16 | 17 | If you use an AMD loader (RequireJS for example) JSZip will register itself : 18 | you just have to put the js file at the right place, or configure the loader 19 | (see [here for RequireJS](http://requirejs.org/docs/api.html#config-paths)). 20 | 21 | Without any loader, JSZip will declare in the global scope a variable named `JSZip`. 22 | 23 | #### In nodejs 24 | 25 | In nodejs, you can `require` it : 26 | 27 | ```js 28 | var JSZip = require("jszip"); 29 | ``` 30 | 31 | ### Basic manipulations 32 | 33 | The first step is to create an instance of JSZip : 34 | 35 | ```js 36 | var zip = new JSZip(); 37 | ``` 38 | 39 | On this instance, we can add (and update) files and folders with 40 | `.file(name, content)` and `.folder(name)`. 41 | They return the current JSZip instance so you can chain the calls. 42 | 43 | ```js 44 | // create a file 45 | zip.file("hello.txt", "Hello[p my)6cxsw2q"); 46 | // oops, cat on keyboard. Fixing ! 47 | zip.file("hello.txt", "Hello World\n"); 48 | 49 | // create a file and a folder 50 | zip.file("nested/hello.txt", "Hello World\n"); 51 | // same as 52 | zip.folder("nested").file("hello.txt", "Hello World\n"); 53 | ``` 54 | 55 | With `.folder(name)`, the returned object has a different root : if you add files 56 | on this object, you will put them in the created subfolder. This is just a 57 | view, the added files will also be in the "root" object. 58 | 59 | ```js 60 | var photoZip = zip.folder("photos"); 61 | // this call will create photos/README 62 | photoZip.file("README", "a folder with photos"); 63 | ``` 64 | 65 | You can access the file content with `.file(name)` and 66 | [its getters]({{site.baseurl}}/documentation/api_zipobject.html) : 67 | 68 | ```js 69 | zip.file("hello.txt").asText(); // "Hello World\n" 70 | 71 | if (JSZip.support.uint8array) { 72 | zip.file("hello.txt").asUint8Array(); // Uint8Array { 0=72, 1=101, 2=108, more...} 73 | } 74 | ``` 75 | 76 | You can also remove files or folders with `.remove(name)` : 77 | 78 | ```js 79 | zip.remove("photos/README"); 80 | zip.remove("photos"); 81 | // same as 82 | zip.remove("photos"); // by removing the folder, you also remove its content. 83 | ``` 84 | 85 | ### Generate a zip file 86 | 87 | With `.generate(options)` you can generate a zip file (not a real file but its 88 | representation in memory). Check 89 | [this page]({{site.baseurl}}/documentation/howto/write_zip.html) for more 90 | informations on how to write / give the file to the user. 91 | 92 | ```js 93 | var content = null; 94 | if (JSZip.support.uint8array) { 95 | content = zip.generate({type : "uint8array"}); 96 | } else { 97 | content = zip.generate({type : "string"}); 98 | } 99 | ``` 100 | 101 | ### Read a zip file 102 | 103 | With `.load(data)` you can load a zip file. Check 104 | [this page]({{site.baseurl}}/documentation/howto/read_zip.html) to see how to 105 | do properly (it's more tricky that it seems). 106 | 107 | ```js 108 | var new_zip = new JSZip(); 109 | // more files ! 110 | new_zip.load(content); 111 | 112 | // you now have every files contained in the loaded zip 113 | new_zip.file("hello.txt").asText(); // "Hello World\n" 114 | ``` 115 | 116 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/howto/write_zip.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to write a file / give it to the user" 3 | layout: default 4 | section: example 5 | --- 6 | 7 | ### In the browser 8 | 9 | With only javascript, this part won't work in old browsers, including IE < 10. 10 | For those browsers, you can use a flash polyfill, see below. 11 | 12 | You can also see this 13 | [example]({{site.baseurl}}/documentation/examples/download-zip-file.html). 14 | 15 | #### Blob URL / FileSaver 16 | 17 | With recent browsers, the easiest way is to use `saveAs` or a polyfill, see 18 | [FileSaver.js](https://github.com/eligrey/FileSaver.js) : 19 | 20 | ```js 21 | var blob = zip.generate({type:"blob"}); 22 | saveAs(blob, "hello.zip"); 23 | ``` 24 | 25 | Under the hood, the polyfill uses the native `saveAs` from the 26 | [FileSaver](http://www.w3.org/TR/file-writer-api/#the-filesaver-interface) API 27 | (on Chrome and IE10+) or use a [Blob URL](http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download) 28 | (on Firefox). 29 | 30 | 31 | #### Data URI 32 | 33 | For older browsers that support [data URI](http://caniuse.com/datauri), you can also 34 | do the following : 35 | 36 | ```js 37 | location.href="data:application/zip;base64," + zip.generate({type:"base64"}); 38 | ``` 39 | 40 | The biggest issue here is that the filenames are very awkward, Firefox 41 | generates filenames such as `a5sZQRsx.zip.part` (see bugs 42 | [367231](https://bugzilla.mozilla.org/show_bug.cgi?id=367231) and 43 | [532230](https://bugzilla.mozilla.org/show_bug.cgi?id=532230), and Safari 44 | isn't much better with just `Unknown`. 45 | 46 | Browser support and resulting filename : 47 | 48 | Opera | Firefox | Safari | Chrome | Internet Explorer 49 | -------|---------|--------|--------|------------------ 50 | "default.zip" | random alphanumeric with ".part" extension | "Unknown" (no extension) | "download.zip" on OSX and Linux, just "download" on Windows | No 51 | 52 | #### Downloadify 53 | 54 | [Downloadify](https://github.com/dcneiner/downloadify) uses a small Flash SWF 55 | to download files to a user's computer with a filename that you can choose. 56 | Doug Neiner has added the `dataType` option to allow you to pass a zip for 57 | downloading. Follow the [Downloadify demo](http://pixelgraphics.us/downloadify/test.html) 58 | with the following changes: 59 | 60 | ```js 61 | zip = new JSZip(); 62 | zip.file("Hello.", "hello.txt"); 63 | Downloadify.create('downloadify',{ 64 | ... 65 | data: function(){ 66 | return zip.generate({type:"base64"}); 67 | }, 68 | ... 69 | dataType: 'base64' 70 | }); 71 | ``` 72 | 73 | 76 | 77 | #### Deprecated google gears 78 | 79 | [Franz Buchinger](http://www.picurl.org/blog/author/franz/) has written a 80 | brilliant tutorial on [using JSZip with Google Gears](http://www.picurl.org/blog/2009/11/22/creating-zip-archives-with-gears) 81 | ([part 2](http://www.picurl.org/blog/2009/11/29/gearszipper-part2-adding-support-for-real-files-and-canvas-elements/)). 82 | If you want to let your Gears users download several files at once I really 83 | recommend having a look at some of his [examples](http://picurl.org/gears/zipper/). 84 | 85 | 86 | 87 | ### In nodejs 88 | 89 | JSZip can generate Buffers so you can do the following : 90 | 91 | ```js 92 | var fs = require("fs"); 93 | var JSZip = require("jszip"); 94 | 95 | var zip = new JSZip(); 96 | // zip.file("file", content); 97 | // ... and other manipulations 98 | 99 | var buffer = zip.generate({type:"nodebuffer"}); 100 | 101 | fs.writeFile("test.zip", buffer, function(err) { 102 | if (err) throw err; 103 | }); 104 | ``` 105 | 106 | 107 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/dataReader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var utils = require('./utils'); 3 | 4 | function DataReader(data) { 5 | this.data = null; // type : see implementation 6 | this.length = 0; 7 | this.index = 0; 8 | } 9 | DataReader.prototype = { 10 | /** 11 | * Check that the offset will not go too far. 12 | * @param {string} offset the additional offset to check. 13 | * @throws {Error} an Error if the offset is out of bounds. 14 | */ 15 | checkOffset: function(offset) { 16 | this.checkIndex(this.index + offset); 17 | }, 18 | /** 19 | * Check that the specifed index will not be too far. 20 | * @param {string} newIndex the index to check. 21 | * @throws {Error} an Error if the index is out of bounds. 22 | */ 23 | checkIndex: function(newIndex) { 24 | if (this.length < newIndex || newIndex < 0) { 25 | throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); 26 | } 27 | }, 28 | /** 29 | * Change the index. 30 | * @param {number} newIndex The new index. 31 | * @throws {Error} if the new index is out of the data. 32 | */ 33 | setIndex: function(newIndex) { 34 | this.checkIndex(newIndex); 35 | this.index = newIndex; 36 | }, 37 | /** 38 | * Skip the next n bytes. 39 | * @param {number} n the number of bytes to skip. 40 | * @throws {Error} if the new index is out of the data. 41 | */ 42 | skip: function(n) { 43 | this.setIndex(this.index + n); 44 | }, 45 | /** 46 | * Get the byte at the specified index. 47 | * @param {number} i the index to use. 48 | * @return {number} a byte. 49 | */ 50 | byteAt: function(i) { 51 | // see implementations 52 | }, 53 | /** 54 | * Get the next number with a given byte size. 55 | * @param {number} size the number of bytes to read. 56 | * @return {number} the corresponding number. 57 | */ 58 | readInt: function(size) { 59 | var result = 0, 60 | i; 61 | this.checkOffset(size); 62 | for (i = this.index + size - 1; i >= this.index; i--) { 63 | result = (result << 8) + this.byteAt(i); 64 | } 65 | this.index += size; 66 | return result; 67 | }, 68 | /** 69 | * Get the next string with a given byte size. 70 | * @param {number} size the number of bytes to read. 71 | * @return {string} the corresponding string. 72 | */ 73 | readString: function(size) { 74 | return utils.transformTo("string", this.readData(size)); 75 | }, 76 | /** 77 | * Get raw data without conversion, bytes. 78 | * @param {number} size the number of bytes to read. 79 | * @return {Object} the raw data, implementation specific. 80 | */ 81 | readData: function(size) { 82 | // see implementations 83 | }, 84 | /** 85 | * Find the last occurence of a zip signature (4 bytes). 86 | * @param {string} sig the signature to find. 87 | * @return {number} the index of the last occurence, -1 if not found. 88 | */ 89 | lastIndexOfSignature: function(sig) { 90 | // see implementations 91 | }, 92 | /** 93 | * Get the next date. 94 | * @return {Date} the date. 95 | */ 96 | readDate: function() { 97 | var dostime = this.readInt(4); 98 | return new Date( 99 | ((dostime >> 25) & 0x7f) + 1980, // year 100 | ((dostime >> 21) & 0x0f) - 1, // month 101 | (dostime >> 16) & 0x1f, // day 102 | (dostime >> 11) & 0x1f, // hour 103 | (dostime >> 5) & 0x3f, // minute 104 | (dostime & 0x1f) << 1); // second 105 | } 106 | }; 107 | module.exports = DataReader; 108 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*jshint node: true */ 2 | module.exports = function(grunt) { 3 | var browsers = [{ 4 | browserName: "iphone", 5 | platform: "OS X 10.8", 6 | version: "6" 7 | }, { 8 | browserName: "android", 9 | platform: "Linux", 10 | version: "4.0" 11 | }, { 12 | browserName: "firefox", 13 | platform: "XP" 14 | }, { 15 | browserName: "chrome", 16 | platform: "XP" 17 | }, { 18 | browserName: "internet explorer", 19 | platform: "WIN8", 20 | version: "10" 21 | }, { 22 | browserName: "internet explorer", 23 | platform: "VISTA", 24 | version: "9" 25 | }, { 26 | browserName: "internet explorer", 27 | platform: "Windows 7", 28 | version: "8" 29 | }, { 30 | browserName: "internet explorer", 31 | platform: "XP", 32 | version: "7" 33 | }, { 34 | browserName: "opera", 35 | platform: "Windows 2008", 36 | version: "12" 37 | }, { 38 | browserName: "safari", 39 | platform: "OS X 10.8", 40 | version: "6" 41 | }]; 42 | 43 | var tags = []; 44 | if (process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST != "false") { 45 | tags.push("pr" + process.env.TRAVIS_PULL_REQUEST); 46 | } else if (process.env.TRAVIS_BRANCH) { 47 | tags.push(process.env.TRAVIS_BRANCH); 48 | } 49 | 50 | grunt.initConfig({ 51 | connect: { 52 | server: { 53 | options: { 54 | base: "", 55 | port: 9999 56 | } 57 | } 58 | }, 59 | 'saucelabs-qunit': { 60 | all: { 61 | options: { 62 | urls: ["http://127.0.0.1:9999/test/index.html"], 63 | tunnelTimeout: 5, 64 | build: process.env.TRAVIS_JOB_ID, 65 | concurrency: 3, 66 | browsers: browsers, 67 | testname: "qunit tests", 68 | tags: tags 69 | } 70 | } 71 | }, 72 | jshint: { 73 | options: { 74 | jshintrc: "./.jshintrc" 75 | }, 76 | all: ['./lib/*.js'] 77 | }, 78 | browserify: { 79 | all: { 80 | files: { 81 | 'dist/jszip.js': ['lib/index.js'] 82 | }, 83 | options: { 84 | bundleOptions: { 85 | standalone: 'JSZip', 86 | insertGlobalVars : { 87 | Buffer: function () { 88 | // instead of the full polyfill, we just use the raw value 89 | // (or undefined). 90 | return '(typeof Buffer !== "undefined" ? Buffer : undefined)'; 91 | } 92 | } 93 | }, 94 | postBundleCB: function(err, src, done) { 95 | // add the license 96 | var license = require('fs').readFileSync('lib/license_header.js'); 97 | // remove the source mapping of zlib.js, see #75 98 | var srcWithoutSourceMapping = src.replace(/\/\/@ sourceMappingURL=raw..flate.min.js.map/g, ''); 99 | done(err, license + srcWithoutSourceMapping); 100 | } 101 | } 102 | } 103 | }, 104 | uglify: { 105 | options: { 106 | report: 'gzip', 107 | mangle: true, 108 | preserveComments: 'some' 109 | }, 110 | all: { 111 | src: 'dist/jszip.js', 112 | dest: 'dist/jszip.min.js' 113 | } 114 | } 115 | }); 116 | 117 | grunt.loadNpmTasks("grunt-saucelabs"); 118 | grunt.loadNpmTasks("grunt-contrib-connect"); 119 | grunt.loadNpmTasks('grunt-browserify'); 120 | grunt.loadNpmTasks('grunt-contrib-jshint'); 121 | grunt.loadNpmTasks('grunt-contrib-uglify'); 122 | 123 | if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY) { 124 | grunt.registerTask("test", ["connect", "saucelabs-qunit"]); 125 | } else { 126 | grunt.registerTask("test", []); 127 | } 128 | grunt.registerTask("build", ["browserify", "uglify"]); 129 | grunt.registerTask("default", ["jshint", "build"]); 130 | }; 131 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/crc32.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var utils = require('./utils'); 4 | 5 | var table = [ 6 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 7 | 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 8 | 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 9 | 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 10 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 11 | 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 12 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 13 | 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 14 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 15 | 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 16 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 17 | 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 18 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 19 | 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 20 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 21 | 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 22 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 23 | 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 24 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 25 | 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 26 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 27 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 28 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 29 | 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 30 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 31 | 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 32 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 33 | 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 34 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 35 | 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 36 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 37 | 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 38 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 39 | 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 40 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 41 | 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 42 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 43 | 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 44 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 45 | 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 46 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 47 | 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 48 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 49 | 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 50 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 51 | 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 52 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 53 | 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 54 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 55 | 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 56 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 57 | 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 58 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 59 | 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 60 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 61 | 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 62 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 63 | 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 64 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 65 | 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 66 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 67 | 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 68 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 69 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 70 | ]; 71 | 72 | /** 73 | * 74 | * Javascript crc32 75 | * http://www.webtoolkit.info/ 76 | * 77 | */ 78 | module.exports = function crc32(input, crc) { 79 | if (typeof input === "undefined" || !input.length) { 80 | return 0; 81 | } 82 | 83 | var isArray = utils.getTypeOf(input) !== "string"; 84 | 85 | if (typeof(crc) == "undefined") { 86 | crc = 0; 87 | } 88 | var x = 0; 89 | var y = 0; 90 | var b = 0; 91 | 92 | crc = crc ^ (-1); 93 | for (var i = 0, iTop = input.length; i < iTop; i++) { 94 | b = isArray ? input[i] : input.charCodeAt(i); 95 | y = (crc ^ b) & 0xFF; 96 | x = table[y]; 97 | crc = (crc >>> 8) ^ x; 98 | } 99 | 100 | return crc ^ (-1); 101 | }; 102 | // vim: set shiftwidth=4 softtabstop=4: 103 | -------------------------------------------------------------------------------- /js/thirdparty/domReady.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. 3 | * Available via the MIT or new BSD license. 4 | * see: http://github.com/requirejs/domReady for details 5 | */ 6 | /*jslint */ 7 | /*global require: false, define: false, requirejs: false, 8 | window: false, clearInterval: false, document: false, 9 | self: false, setInterval: false */ 10 | 11 | 12 | define(function () { 13 | 'use strict'; 14 | 15 | var isTop, testDiv, scrollIntervalId, 16 | isBrowser = typeof window !== "undefined" && window.document, 17 | isPageLoaded = !isBrowser, 18 | doc = isBrowser ? document : null, 19 | readyCalls = []; 20 | 21 | function runCallbacks(callbacks) { 22 | var i; 23 | for (i = 0; i < callbacks.length; i += 1) { 24 | callbacks[i](doc); 25 | } 26 | } 27 | 28 | function callReady() { 29 | var callbacks = readyCalls; 30 | 31 | if (isPageLoaded) { 32 | //Call the DOM ready callbacks 33 | if (callbacks.length) { 34 | readyCalls = []; 35 | runCallbacks(callbacks); 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * Sets the page as loaded. 42 | */ 43 | function pageLoaded() { 44 | if (!isPageLoaded) { 45 | isPageLoaded = true; 46 | if (scrollIntervalId) { 47 | clearInterval(scrollIntervalId); 48 | } 49 | 50 | callReady(); 51 | } 52 | } 53 | 54 | if (isBrowser) { 55 | if (document.addEventListener) { 56 | //Standards. Hooray! Assumption here that if standards based, 57 | //it knows about DOMContentLoaded. 58 | document.addEventListener("DOMContentLoaded", pageLoaded, false); 59 | window.addEventListener("load", pageLoaded, false); 60 | } else if (window.attachEvent) { 61 | window.attachEvent("onload", pageLoaded); 62 | 63 | testDiv = document.createElement('div'); 64 | try { 65 | isTop = window.frameElement === null; 66 | } catch (e) {} 67 | 68 | //DOMContentLoaded approximation that uses a doScroll, as found by 69 | //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, 70 | //but modified by other contributors, including jdalton 71 | if (testDiv.doScroll && isTop && window.external) { 72 | scrollIntervalId = setInterval(function () { 73 | try { 74 | testDiv.doScroll(); 75 | pageLoaded(); 76 | } catch (e) {} 77 | }, 30); 78 | } 79 | } 80 | 81 | //Check if document already complete, and if so, just trigger page load 82 | //listeners. Latest webkit browsers also use "interactive", and 83 | //will fire the onDOMContentLoaded before "interactive" but not after 84 | //entering "interactive" or "complete". More details: 85 | //http://dev.w3.org/html5/spec/the-end.html#the-end 86 | //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded 87 | //Hmm, this is more complicated on further use, see "firing too early" 88 | //bug: https://github.com/requirejs/domReady/issues/1 89 | //so removing the || document.readyState === "interactive" test. 90 | //There is still a window.onload binding that should get fired if 91 | //DOMContentLoaded is missed. 92 | if (document.readyState === "complete") { 93 | pageLoaded(); 94 | } 95 | } 96 | 97 | /** START OF PUBLIC API **/ 98 | 99 | /** 100 | * Registers a callback for DOM ready. If DOM is already ready, the 101 | * callback is called immediately. 102 | * @param {Function} callback 103 | */ 104 | function domReady(callback) { 105 | if (isPageLoaded) { 106 | callback(doc); 107 | } else { 108 | readyCalls.push(callback); 109 | } 110 | return domReady; 111 | } 112 | 113 | domReady.version = '2.0.1'; 114 | 115 | /** 116 | * Loader Plugin API method 117 | */ 118 | domReady.load = function (name, req, onLoad, config) { 119 | if (config.isBuild) { 120 | onLoad(null); 121 | } else { 122 | domReady(onLoad); 123 | } 124 | }; 125 | 126 | /** END OF PUBLIC API **/ 127 | 128 | return domReady; 129 | }); 130 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/howto/read_zip.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to read a file" 3 | layout: default 4 | section: example 5 | --- 6 | 7 | This page explains how to read an existing zip file or add a existing file into 8 | the zip file. 9 | 10 | 11 | ### In the browser 12 | 13 | #### AJAX request 14 | 15 | Getting binary data with an ajax request is hard (mainly because of IE <= 9). 16 | The easy way is to use [JSZipUtils.getBinaryContent](https://github.com/stuk/jszip-utils). 17 | With JSZipUtils.getBinaryContent, you can do the following (see the 18 | documentation for more examples) : 19 | 20 | ```js 21 | JSZipUtils.getBinaryContent('path/to/content.zip', function(err, data) { 22 | if(err) { 23 | throw err; // or handle err 24 | } 25 | 26 | var zip = new JSZip(data); 27 | }); 28 | ``` 29 | 30 |
31 | 32 | If you need to adapt an existing solution to what getBinaryContent does, here 33 | are the details. When doing a XHR request (level 1, without setting the 34 | `responseType`) the browser will try to interpret the response as a string and 35 | decode it from its charset. To avoid this on Firefox/Chrome/Opera, you need to 36 | set mime type : `xhr.overrideMimeType("text/plain; charset=x-user-defined");`. 37 | On IE <= 9, this is harder. The overrideMimeType trick doesn't work so we need 38 | to use [vbscript](http://stackoverflow.com/questions/1095102/how-do-i-load-binary-image-data-using-javascript-and-xmlhttprequest) 39 | and non standard attributes. 40 | On IE > 9, overrideMimeType doesn't work but xhr2 does. 41 | 42 | With [xhr 2](http://caniuse.com/xhr2), you can just set the responseType 43 | attribute : `xhr.responseType = "arraybuffer";`. With this, the browser will 44 | return an ArrayBuffer. 45 | 46 | #### Local files 47 | 48 | If the browser supports the [FileReader API](http://caniuse.com/filereader), 49 | you can use it to read a zip file. JSZip can read ArrayBuffer, so you can use 50 | `FileReader.readAsArrayBuffer(Blob)`, see this [example]({{site.baseurl}}/documentation/examples/read-local-file-api.html). 51 | 52 | ### In nodejs 53 | 54 | JSZip can read Buffers so you can do the following : 55 | 56 | #### Local file 57 | 58 | ```js 59 | "use strict"; 60 | 61 | var fs = require("fs"); 62 | var JSZip = require("jszip"); 63 | 64 | // read a zip file 65 | fs.readFile("test.zip", function(err, data) { 66 | if (err) throw err; 67 | var zip = new JSZip(data); 68 | }); 69 | 70 | // read a file and add it to a zip 71 | fs.readFile("picture.png", function(err, data) { 72 | if (err) throw err; 73 | var zip = new JSZip(); 74 | zip.file("picture.png", data); 75 | }); 76 | ``` 77 | 78 | #### Remote file 79 | 80 | There are a lot of nodejs libraries doing http requests, from the built-in 81 | [http](http://nodejs.org/docs/latest/api/http.html) to the 82 | [npm packages](https://www.npmjs.org/browse/keyword/http). Here are two 83 | examples, one with the default http API, the other with 84 | [request](https://github.com/mikeal/request) (but you're free to use your 85 | favorite library !). If possible, download the file as a Buffer (you will get 86 | better performances). If it's not possible, you can fallback to a binary string 87 | (the option is likely to be `encoding : "binary"`). 88 | 89 | ##### With http : 90 | 91 | ```js 92 | "use strict"; 93 | 94 | var http = require("http"); 95 | var url = require("url"); 96 | var JSZip = require("jszip"); 97 | 98 | var req = http.get(url.parse("http://localhost/.../file.zip"), function (res) { 99 | if (res.statusCode !== 200) { 100 | console.log(res.statusCode); 101 | // handle error 102 | return; 103 | } 104 | var data = [], dataLen = 0; 105 | 106 | // don't set the encoding, it will break everything ! 107 | // or, if you must, set it to null. In that case the chunk will be a string. 108 | 109 | res.on("data", function (chunk) { 110 | data.push(chunk); 111 | dataLen += chunk.length; 112 | }); 113 | 114 | res.on("end", function () { 115 | var buf = new Buffer(dataLen); 116 | for (var i=0,len=data.length,pos=0; i 8 |
9 | 10 | JSZip is a javascript library for creating, reading and editing .zip files, with a 11 | lovely and simple API. 12 | 13 |
14 |
15 |

16 | Current version : v2.4.0 17 |

18 |

19 | License : JSZip is dual-licensed. You may use it under the 20 | MIT license or the GPLv3 license. See 21 | LICENSE.markdown. 22 |

23 |
24 | 25 |
26 |
27 | 28 |

Example

29 | 30 | 57 | 65 | 66 | 67 | 71 |
72 |
73 | 74 |

Installation

75 | 76 |

77 | With npm : npm install jszip 78 |

79 |

80 | With bower : bower install Stuk/jszip 81 |

82 |

83 | With component : component install Stuk/jszip 84 |

85 |

86 | Manually : download JSZip 87 | and include the file dist/jszip.js or dist/jszip.min.js 88 |

89 |
90 |

91 | Installed ? Great ! You can now check our 92 | guides and examples ! 93 |

94 |
95 |
96 | 97 |

Support

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
OperaFirefoxSafariChromeInternet ExplorerNode.js
YesYesYesYesYesYes
Tested with the latest versionTested with 3.0 / 3.6 / latest versionTested with the latest versionTested with the latest versionTested with IE 6 / 7 / 8 / 9 / 10Tested with node.js 0.8 and 0.10
125 | 126 |

Getting help

127 | 128 |

129 | Having trouble ? We'd like to help ! 130 |

131 |
    132 |
  • 133 | Try the FAQ, it has 134 | answers to common questions. 135 |
  • 136 |
  • 137 | If you're looking for informations about a specific method, try the 138 | documentation. 139 |
  • 140 |
  • 141 | Check the 142 | examples. 143 |
  • 144 |
  • 145 | Report bugs in our 146 | Bug tracker. 147 |
  • 148 |
149 | 150 |

Test status

151 | 152 |
153 |
Travis build :
154 |
155 | 156 | 157 | 158 |
159 |
Saucelabs build :
160 |
161 | 162 | 163 | 164 |
165 |
Live tests :
166 |
167 | See for yourself ! 168 |
169 |
170 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/test/qunit-1.11.0.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QUnit v1.11.0 - A JavaScript Unit Testing Framework 3 | * 4 | * http://qunitjs.com 5 | * 6 | * Copyright 2012 jQuery Foundation and other contributors 7 | * Released under the MIT license. 8 | * http://jquery.org/license 9 | */ 10 | 11 | /** Font Family and Sizes */ 12 | 13 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 14 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 15 | } 16 | 17 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 18 | #qunit-tests { font-size: smaller; } 19 | 20 | 21 | /** Resets */ 22 | 23 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | 28 | 29 | /** Header */ 30 | 31 | #qunit-header { 32 | padding: 0.5em 0 0.5em 1em; 33 | 34 | color: #8699a4; 35 | background-color: #0d3349; 36 | 37 | font-size: 1.5em; 38 | line-height: 1em; 39 | font-weight: normal; 40 | 41 | border-radius: 5px 5px 0 0; 42 | -moz-border-radius: 5px 5px 0 0; 43 | -webkit-border-top-right-radius: 5px; 44 | -webkit-border-top-left-radius: 5px; 45 | } 46 | 47 | #qunit-header a { 48 | text-decoration: none; 49 | color: #c2ccd1; 50 | } 51 | 52 | #qunit-header a:hover, 53 | #qunit-header a:focus { 54 | color: #fff; 55 | } 56 | 57 | #qunit-testrunner-toolbar label { 58 | display: inline-block; 59 | padding: 0 .5em 0 .1em; 60 | } 61 | 62 | #qunit-banner { 63 | height: 5px; 64 | } 65 | 66 | #qunit-testrunner-toolbar { 67 | padding: 0.5em 0 0.5em 2em; 68 | color: #5E740B; 69 | background-color: #eee; 70 | overflow: hidden; 71 | } 72 | 73 | #qunit-userAgent { 74 | padding: 0.5em 0 0.5em 2.5em; 75 | background-color: #2b81af; 76 | color: #fff; 77 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 78 | } 79 | 80 | #qunit-modulefilter-container { 81 | float: right; 82 | } 83 | 84 | /** Tests: Pass/Fail */ 85 | 86 | #qunit-tests { 87 | list-style-position: inside; 88 | } 89 | 90 | #qunit-tests li { 91 | padding: 0.4em 0.5em 0.4em 2.5em; 92 | border-bottom: 1px solid #fff; 93 | list-style-position: inside; 94 | } 95 | 96 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 97 | display: none; 98 | } 99 | 100 | #qunit-tests li strong { 101 | cursor: pointer; 102 | } 103 | 104 | #qunit-tests li a { 105 | padding: 0.5em; 106 | color: #c2ccd1; 107 | text-decoration: none; 108 | } 109 | #qunit-tests li a:hover, 110 | #qunit-tests li a:focus { 111 | color: #000; 112 | } 113 | 114 | #qunit-tests li .runtime { 115 | float: right; 116 | font-size: smaller; 117 | } 118 | 119 | .qunit-assert-list { 120 | margin-top: 0.5em; 121 | padding: 0.5em; 122 | 123 | background-color: #fff; 124 | 125 | border-radius: 5px; 126 | -moz-border-radius: 5px; 127 | -webkit-border-radius: 5px; 128 | } 129 | 130 | .qunit-collapsed { 131 | display: none; 132 | } 133 | 134 | #qunit-tests table { 135 | border-collapse: collapse; 136 | margin-top: .2em; 137 | } 138 | 139 | #qunit-tests th { 140 | text-align: right; 141 | vertical-align: top; 142 | padding: 0 .5em 0 0; 143 | } 144 | 145 | #qunit-tests td { 146 | vertical-align: top; 147 | } 148 | 149 | #qunit-tests pre { 150 | margin: 0; 151 | white-space: pre-wrap; 152 | word-wrap: break-word; 153 | } 154 | 155 | #qunit-tests del { 156 | background-color: #e0f2be; 157 | color: #374e0c; 158 | text-decoration: none; 159 | } 160 | 161 | #qunit-tests ins { 162 | background-color: #ffcaca; 163 | color: #500; 164 | text-decoration: none; 165 | } 166 | 167 | /*** Test Counts */ 168 | 169 | #qunit-tests b.counts { color: black; } 170 | #qunit-tests b.passed { color: #5E740B; } 171 | #qunit-tests b.failed { color: #710909; } 172 | 173 | #qunit-tests li li { 174 | padding: 5px; 175 | background-color: #fff; 176 | border-bottom: none; 177 | list-style-position: inside; 178 | } 179 | 180 | /*** Passing Styles */ 181 | 182 | #qunit-tests li li.pass { 183 | color: #3c510c; 184 | background-color: #fff; 185 | border-left: 10px solid #C6E746; 186 | } 187 | 188 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 189 | #qunit-tests .pass .test-name { color: #366097; } 190 | 191 | #qunit-tests .pass .test-actual, 192 | #qunit-tests .pass .test-expected { color: #999999; } 193 | 194 | #qunit-banner.qunit-pass { background-color: #C6E746; } 195 | 196 | /*** Failing Styles */ 197 | 198 | #qunit-tests li li.fail { 199 | color: #710909; 200 | background-color: #fff; 201 | border-left: 10px solid #EE5757; 202 | white-space: pre; 203 | } 204 | 205 | #qunit-tests > li:last-child { 206 | border-radius: 0 0 5px 5px; 207 | -moz-border-radius: 0 0 5px 5px; 208 | -webkit-border-bottom-right-radius: 5px; 209 | -webkit-border-bottom-left-radius: 5px; 210 | } 211 | 212 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 213 | #qunit-tests .fail .test-name, 214 | #qunit-tests .fail .module-name { color: #000000; } 215 | 216 | #qunit-tests .fail .test-actual { color: #EE5757; } 217 | #qunit-tests .fail .test-expected { color: green; } 218 | 219 | #qunit-banner.qunit-fail { background-color: #EE5757; } 220 | 221 | 222 | /** Result */ 223 | 224 | #qunit-testresult { 225 | padding: 0.5em 0.5em 0.5em 2.5em; 226 | 227 | color: #2b81af; 228 | background-color: #D2E0E6; 229 | 230 | border-bottom: 1px solid white; 231 | } 232 | #qunit-testresult .module-name { 233 | font-weight: bold; 234 | } 235 | 236 | /** Fixture */ 237 | 238 | #qunit-fixture { 239 | position: absolute; 240 | top: -10000px; 241 | left: -10000px; 242 | width: 1000px; 243 | height: 1000px; 244 | } 245 | -------------------------------------------------------------------------------- /js/c64/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'c64/vic', 3 | 'c64/mmu', 4 | 'c64/cpu', 5 | 'c64/iec', 6 | 'c64/cia', 7 | 'c64/disk', 8 | 'thirdparty/jquery-ajax-blob-arraybuffer', 9 | 'thirdparty/jszip/dist/jszip.min' 10 | ], function(VIC, MMU, CPU, IEC, CIA, DISK, blob, JSZip) { 11 | var C64 = { 12 | MMU: MMU, 13 | CPU: CPU, 14 | IEC: IEC, 15 | CIA: CIA, 16 | DISK: DISK, 17 | VIC: VIC 18 | }; 19 | for (var i in C64) { 20 | if (C64.hasOwnProperty(i)) { 21 | C64[i].owner = C64; 22 | C64[i].init.call(C64[i]); 23 | } 24 | } 25 | C64.reset = function() { 26 | C64.MMU.reset(); 27 | C64.CPU.reset(); 28 | C64.IEC.reset(); 29 | C64.CIA.reset(); 30 | C64.DISK.reset(); 31 | C64.VIC.reset(); 32 | C64.saveFrame(0, 1); 33 | }; 34 | 35 | C64.savedFrames = {}; 36 | C64.saveFrame = function(frame, numFrames) { 37 | if (C64.savedFrames[frame]) { 38 | return; 39 | } 40 | if (numFrames > 2) { 41 | numFrames = 2; 42 | } 43 | C64.savedFrames[frame] = { 44 | MMU: C64.MMU.getState(), 45 | CPU: C64.CPU.getState(), 46 | IEC: C64.IEC.getState(), 47 | CIA: C64.CIA.getState(), 48 | DISK: C64.DISK.getState(), 49 | VIC: C64.VIC.getState() 50 | }; 51 | for (i in C64.savedFrames) { 52 | if (i > 0 && i < (frame - numFrames)) { 53 | delete C64.savedFrames[i]; 54 | } 55 | } 56 | }; 57 | C64.restoreFrame = function(frame) { 58 | if (!C64.savedFrames[frame]) { 59 | frame = 0; 60 | } 61 | for (i in C64.savedFrames[frame]) { 62 | C64[i].setState(C64.savedFrames[frame][i]); 63 | } 64 | }; 65 | C64.dropFrame = function(frame) { 66 | if (C64.savedFrames[frame]) { 67 | delete C64.savedFrames[frame]; 68 | } 69 | }; 70 | 71 | C64.loadPrg = function(prg) { 72 | var promise = $.Deferred(); 73 | 74 | $.ajax({ 75 | url: prg, 76 | dataType: 'arraybuffer', 77 | beforeSend: function(xhr) { 78 | xhr.overrideMimeType("text/plain; charset=x-user-defined"); 79 | } 80 | }).done(function(data) { 81 | var content = new Uint8Array(data); 82 | var pc = content[0] + (content[1] * 256); 83 | for (var i = 2; i < content.length; i++) { 84 | this.MMU.ram[pc+i] = content[i]; 85 | } 86 | this.CPU.reg.PC = pc; 87 | promise.resolve(); 88 | }.bind(this)); 89 | 90 | return promise; 91 | }; 92 | 93 | C64.loadDisk = function(d64) { 94 | var promise = $.Deferred(); 95 | 96 | $.ajax({ 97 | url: d64, 98 | dataType: 'arraybuffer', 99 | beforeSend: function(xhr) { 100 | xhr.overrideMimeType("text/plain; charset=x-user-defined"); 101 | } 102 | }).done(function(data) { 103 | this.dropFrame(0); 104 | this.CPU.reset(); 105 | this.MMU.reset(); 106 | this.IEC.reset(); 107 | this.CIA.reset(); 108 | this.DISK.reset(); 109 | this.VIC.reset(); 110 | 111 | this.VIC.renderPixels(this.VIC.sizes.FRAME_SIZE * 10); 112 | 113 | for (var i = 0; i < 65536; i++) { 114 | this.MMU.ram[i] = DISK.loadDump[i]; 115 | } 116 | this.CPU.reg.A = 0x00; 117 | this.CPU.reg.X = 0x0C; 118 | this.CPU.reg.Y = 0x26; 119 | this.CPU.reg.PC = 0xE168; 120 | this.CPU.reg.S = 0xE9; 121 | 122 | this.DISK.load(data); 123 | this.saveFrame(0, 1); 124 | promise.resolve(); 125 | }.bind(this)); 126 | 127 | return promise; 128 | }; 129 | 130 | C64.loadGame = function() { 131 | var promise = $.Deferred(); 132 | 133 | $.ajax({ 134 | url: '/rom/game.zip', 135 | dataType: 'arraybuffer', 136 | beforeSend: function(xhr) { 137 | xhr.overrideMimeType("text/plain; charset=x-user-defined"); 138 | } 139 | }).done(function(data) { 140 | this.dropFrame(0); 141 | this.CPU.reset(); 142 | this.MMU.reset(); 143 | 144 | var i, zip = new JSZip(); 145 | zip.load(data); 146 | 147 | var kernal = zip.file('kernal.rom').asUint8Array(), 148 | basic = zip.file('basic.rom').asUint8Array(), 149 | game = zip.file('game.bin').asUint8Array(), 150 | loadDump = zip.file('loadram.bin').asUint8Array(); 151 | 152 | for (var i = 0; i < kernal.length; i++) { 153 | this.MMU.romKernal[i] = kernal[i]; 154 | } 155 | for (var i = 0; i < basic.length; i++) { 156 | this.MMU.romBasic[i] = basic[i]; 157 | } 158 | for (var i = 0; i < game.length; i++) { 159 | this.MMU.ram[0xC000 + i] = game[i]; 160 | } 161 | 162 | DISK.loadDump = new Uint8Array(loadDump); 163 | 164 | this.IEC.reset(); 165 | this.CIA.reset(); 166 | this.DISK.reset(); 167 | this.VIC.reset(); 168 | 169 | this.VIC.renderPixels(this.VIC.sizes.FRAME_SIZE * 10); 170 | this.CPU.reg.PC = 0xC000; 171 | 172 | this.VIC.backContext.fillStyle = 'black'; 173 | this.VIC.backContext.fillRect(0, 0, this.VIC.sizes.RASTER_LENGTH, this.VIC.sizes.RASTER_COUNT); 174 | this.saveFrame(0, 1); 175 | promise.resolve(); 176 | }.bind(this)); 177 | 178 | return promise; 179 | }; 180 | 181 | return C64; 182 | }); 183 | -------------------------------------------------------------------------------- /css/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | -webkit-user-select: none; 5 | -moz-user-select: none; 6 | -ms-user-select: none; 7 | -o-user-select: none; 8 | user-select: none; 9 | } 10 | 11 | body { 12 | background: black; 13 | color: white; 14 | font-family: Arial, sans-serif; 15 | } 16 | 17 | .head { 18 | margin: 15px 0; 19 | } 20 | 21 | .head h1 { 22 | margin: 0 auto; 23 | width: 776px; 24 | height: 90px; 25 | background: url(/img/cclicker.png) no-repeat top left; 26 | text-indent: -9999px; 27 | font-size: 1px; 28 | } 29 | 30 | .head h1 a { 31 | text-decoration: none; 32 | text-indent: -9999px; 33 | display: block; 34 | width: 776px; 35 | height: 90px; 36 | } 37 | 38 | #about { 39 | display: none; 40 | } 41 | 42 | .content { 43 | clear: both; 44 | margin: 0 auto; 45 | width: 840px; 46 | } 47 | 48 | .screen { 49 | width: 504px; 50 | padding-top: 36px; 51 | position: relative; 52 | } 53 | 54 | #screen { 55 | width: 504px; 56 | height: 312px; 57 | padding: 1px; 58 | border: 5px solid #c8ad7f; 59 | border-radius: 5px 5px 5px 5px; 60 | } 61 | 62 | .status { 63 | list-style: none inside; 64 | margin: 10px 0; 65 | color: #bbb; 66 | } 67 | 68 | .status span { 69 | font-weight: bold; 70 | } 71 | 72 | .cursor_x { 73 | height: 8px; 74 | width: 1px; 75 | position: absolute; 76 | top: 28px; 77 | left: 6px; 78 | background: #c8ad7f; 79 | } 80 | 81 | .cursor_y { 82 | width: 8px; 83 | height: 1px; 84 | position: absolute; 85 | top: 42px; 86 | left: -8px; 87 | background: #c8ad7f; 88 | } 89 | 90 | .sidebar { 91 | float: right; 92 | width: 320px; 93 | } 94 | 95 | .topbar { 96 | width: 840px; 97 | margin: 0 auto; 98 | } 99 | 100 | .joystick { 101 | float: right; 102 | width: 100px; 103 | height: 100px; 104 | position: relative; 105 | margin-top: 10px; 106 | } 107 | .joystick.hidden { 108 | display: none; 109 | } 110 | 111 | .joystick .active { 112 | background: #c8ad7f; 113 | color: black; 114 | font-weight: bold; 115 | } 116 | 117 | #joy_left, #joy_right { 118 | position: absolute; 119 | top: 35px; 120 | height: 20px; 121 | padding: 5px; 122 | line-height: 20px; 123 | border: 2px solid #c8ad7f; 124 | border-radius: 5px 5px 5px 5px; 125 | } 126 | 127 | #joy_left { 128 | left: 0; 129 | width: 55px; 130 | border-right: 0; 131 | } 132 | #joy_right { 133 | right: 0; 134 | width: 53px; 135 | text-align: right; 136 | border-left: 0; 137 | } 138 | 139 | #joy_up, #joy_down { 140 | position: absolute; 141 | left: 35px; 142 | width: 20px; 143 | padding: 5px; 144 | text-align: center; 145 | border: 2px solid #c8ad7f; 146 | border-radius: 5px 5px 5px 5px; 147 | } 148 | 149 | #joy_up { 150 | top: 0; 151 | border-bottom: 0; 152 | height: 55px; 153 | } 154 | #joy_down { 155 | bottom: 0; 156 | height: 53px; 157 | line-height: 90px; 158 | border-top: 0; 159 | } 160 | 161 | #joy_fire { 162 | display: none; 163 | } 164 | 165 | #bank { 166 | text-align: center; 167 | font-size: 30px; 168 | } 169 | 170 | #cps { 171 | text-align: center; 172 | font-size: 22px; 173 | margin: 8px 0; 174 | } 175 | 176 | #click { 177 | text-align: center; 178 | font-size: 26px; 179 | width: 250px; 180 | background: #5d594f; 181 | border-radius: 13px 13px 13px 13px; 182 | margin: 10px 360px 10px 230px; 183 | padding: 12px; 184 | cursor: pointer; 185 | } 186 | .joystick.hidden ~ #click { 187 | margin: 10px auto; 188 | } 189 | 190 | #reset { 191 | cursor: pointer; 192 | text-decoration: underline; 193 | } 194 | 195 | .tabs { 196 | list-style: none inside; 197 | padding-top: 10px; 198 | } 199 | 200 | .tabs li { 201 | background: #5d594f; 202 | color: white; 203 | padding: 8px; 204 | border-radius: 8px 8px 0 0; 205 | display: inline; 206 | cursor: pointer; 207 | } 208 | 209 | .tabs li.active { 210 | background: #c8ad7f; 211 | color: black; 212 | } 213 | 214 | .itemlists { 215 | border: 5px solid #c8ad7f; 216 | border-radius: 0 0 5px 5px; 217 | padding: 5px; 218 | margin-top: 7px; 219 | height: 305px; 220 | overflow: auto; 221 | } 222 | 223 | .itemlists ul { 224 | list-style: none inside; 225 | } 226 | 227 | .itemlists li { 228 | background: #444; 229 | border: 5px solid #5d594f; 230 | border-radius: 8px 8px 8px 8px; 231 | color: #999; 232 | padding: 8px; 233 | margin: 8px; 234 | cursor: pointer; 235 | display: none; 236 | } 237 | 238 | .itemlists li.active { 239 | display: block; 240 | } 241 | 242 | .itemlists li.available { 243 | background: #bbb; 244 | border-color: #c8ad7f; 245 | color: #000; 246 | } 247 | 248 | .itemlists li span { 249 | display: block; 250 | } 251 | 252 | .foot { 253 | clear: both; 254 | text-align: center; 255 | padding-top: 2em; 256 | color: #bbb; 257 | } 258 | 259 | a { 260 | color: #ddd; 261 | } 262 | 263 | p { 264 | margin-bottom: 1em; 265 | } 266 | 267 | body.quarterscreen .content { 268 | width: 966px; 269 | } 270 | body.quarterscreen .screen { 271 | width: 630px; 272 | } 273 | body.quarterscreen #screen { 274 | width: 630px; 275 | height: 390px; 276 | } 277 | body.quarterscreen .itemlists { 278 | height: 383px; 279 | } 280 | body.quarterscreen .disk { 281 | width: 622px; 282 | } 283 | 284 | .disk { 285 | width: 496px; 286 | border: 5px solid #c8ad7f; 287 | border-radius: 5px 5px 5px 5px; 288 | padding: 5px; 289 | line-height: 25px; 290 | } 291 | .disk.hidden { 292 | display: none; 293 | } 294 | .disk .disk_drive { 295 | font-weight: bold; 296 | float: left; 297 | padding-bottom: 4px; 298 | } 299 | .disk #disk_files { 300 | margin-left: 10px; 301 | } 302 | .disk #disk_power { 303 | width: 20px; 304 | height: 25px; 305 | background: #300; 306 | float: right; 307 | } 308 | .disk #disk_power.disk_on { 309 | background: #c33; 310 | } 311 | .disk .disk_bar { 312 | clear: both; 313 | height: 25px; 314 | width: 100%; 315 | border: 1px solid #c8ad7f; 316 | } 317 | .disk #disk_progress { 318 | background: #c8ad7f; 319 | display: block; 320 | height: 25px; 321 | } 322 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/utf8.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var utils = require('./utils'); 4 | var support = require('./support'); 5 | var nodeBuffer = require('./nodeBuffer'); 6 | 7 | /** 8 | * The following functions come from pako, from pako/lib/utils/strings 9 | * released under the MIT license, see pako https://github.com/nodeca/pako/ 10 | */ 11 | 12 | // Table with utf8 lengths (calculated by first byte of sequence) 13 | // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, 14 | // because max possible codepoint is 0x10ffff 15 | var _utf8len = new Array(256); 16 | for (var i=0; i<256; i++) { 17 | _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); 18 | } 19 | _utf8len[254]=_utf8len[254]=1; // Invalid sequence start 20 | 21 | // convert string to array (typed, when possible) 22 | var string2buf = function (str) { 23 | var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; 24 | 25 | // count binary size 26 | for (m_pos = 0; m_pos < str_len; m_pos++) { 27 | c = str.charCodeAt(m_pos); 28 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { 29 | c2 = str.charCodeAt(m_pos+1); 30 | if ((c2 & 0xfc00) === 0xdc00) { 31 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); 32 | m_pos++; 33 | } 34 | } 35 | buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; 36 | } 37 | 38 | // allocate buffer 39 | if (support.uint8array) { 40 | buf = new Uint8Array(buf_len); 41 | } else { 42 | buf = new Array(buf_len); 43 | } 44 | 45 | // convert 46 | for (i=0, m_pos = 0; i < buf_len; m_pos++) { 47 | c = str.charCodeAt(m_pos); 48 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { 49 | c2 = str.charCodeAt(m_pos+1); 50 | if ((c2 & 0xfc00) === 0xdc00) { 51 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); 52 | m_pos++; 53 | } 54 | } 55 | if (c < 0x80) { 56 | /* one byte */ 57 | buf[i++] = c; 58 | } else if (c < 0x800) { 59 | /* two bytes */ 60 | buf[i++] = 0xC0 | (c >>> 6); 61 | buf[i++] = 0x80 | (c & 0x3f); 62 | } else if (c < 0x10000) { 63 | /* three bytes */ 64 | buf[i++] = 0xE0 | (c >>> 12); 65 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); 66 | buf[i++] = 0x80 | (c & 0x3f); 67 | } else { 68 | /* four bytes */ 69 | buf[i++] = 0xf0 | (c >>> 18); 70 | buf[i++] = 0x80 | (c >>> 12 & 0x3f); 71 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); 72 | buf[i++] = 0x80 | (c & 0x3f); 73 | } 74 | } 75 | 76 | return buf; 77 | }; 78 | 79 | // Calculate max possible position in utf8 buffer, 80 | // that will not break sequence. If that's not possible 81 | // - (very small limits) return max size as is. 82 | // 83 | // buf[] - utf8 bytes array 84 | // max - length limit (mandatory); 85 | var utf8border = function(buf, max) { 86 | var pos; 87 | 88 | max = max || buf.length; 89 | if (max > buf.length) { max = buf.length; } 90 | 91 | // go back from last position, until start of sequence found 92 | pos = max-1; 93 | while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } 94 | 95 | // Fuckup - very small and broken sequence, 96 | // return max, because we should return something anyway. 97 | if (pos < 0) { return max; } 98 | 99 | // If we came to start of buffer - that means vuffer is too small, 100 | // return max too. 101 | if (pos === 0) { return max; } 102 | 103 | return (pos + _utf8len[buf[pos]] > max) ? pos : max; 104 | }; 105 | 106 | // convert array to string 107 | var buf2string = function (buf) { 108 | var str, i, out, c, c_len; 109 | var len = buf.length; 110 | 111 | // Reserve max possible length (2 words per char) 112 | // NB: by unknown reasons, Array is significantly faster for 113 | // String.fromCharCode.apply than Uint16Array. 114 | var utf16buf = new Array(len*2); 115 | 116 | for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } 124 | 125 | // apply mask on first byte 126 | c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; 127 | // join the rest 128 | while (c_len > 1 && i < len) { 129 | c = (c << 6) | (buf[i++] & 0x3f); 130 | c_len--; 131 | } 132 | 133 | // terminated by end of string? 134 | if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } 135 | 136 | if (c < 0x10000) { 137 | utf16buf[out++] = c; 138 | } else { 139 | c -= 0x10000; 140 | utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); 141 | utf16buf[out++] = 0xdc00 | (c & 0x3ff); 142 | } 143 | } 144 | 145 | // shrinkBuf(utf16buf, out) 146 | if (utf16buf.length !== out) { 147 | if(utf16buf.subarray) { 148 | utf16buf = utf16buf.subarray(0, out); 149 | } else { 150 | utf16buf.length = out; 151 | } 152 | } 153 | 154 | // return String.fromCharCode.apply(null, utf16buf); 155 | return utils.applyFromCharCode(utf16buf); 156 | }; 157 | 158 | 159 | // That's all for the pako functions. 160 | 161 | 162 | /** 163 | * Transform a javascript string into an array (typed if possible) of bytes, 164 | * UTF-8 encoded. 165 | * @param {String} str the string to encode 166 | * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. 167 | */ 168 | exports.utf8encode = function utf8encode(str) { 169 | if (support.nodebuffer) { 170 | return nodeBuffer(str, "utf-8"); 171 | } 172 | 173 | return string2buf(str); 174 | }; 175 | 176 | 177 | /** 178 | * Transform a bytes array (or a representation) representing an UTF-8 encoded 179 | * string into a javascript string. 180 | * @param {Array|Uint8Array|Buffer} buf the data de decode 181 | * @return {String} the decoded string. 182 | */ 183 | exports.utf8decode = function utf8decode(buf) { 184 | if (support.nodebuffer) { 185 | return utils.transformTo("nodebuffer", buf).toString("utf-8"); 186 | } 187 | 188 | buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); 189 | 190 | // return buf2string(buf); 191 | // Chrome prefers to work with "small" chunks of data 192 | // for the method buf2string. 193 | // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. 194 | var result = [], k = 0, len = buf.length, chunk = 65536; 195 | while (k < len) { 196 | var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); 197 | if (support.uint8array) { 198 | result.push(buf2string(buf.subarray(k, nextBoundary))); 199 | } else { 200 | result.push(buf2string(buf.slice(k, nextBoundary))); 201 | } 202 | k = nextBoundary; 203 | } 204 | return result.join(""); 205 | 206 | }; 207 | // vim: set shiftwidth=4 softtabstop=4: 208 | -------------------------------------------------------------------------------- /rom/game.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | GAMEFLAGS = $DE00 4 | SPR_X_LO = $10 5 | SPR_X_HI = $11 6 | SPR_Y = $12 7 | SCR_RAM = $13 8 | COL_RAM = $15 9 | SCR_RAM2 = $15 10 | RASTER_LO = $17 11 | RASTER_HI = $18 12 | RASTERBAR = $19 13 | SCROLLPOS = $1A 14 | BGCOL = $1B 15 | 16 | TMP0 = $30 17 | TMP1 = $31 18 | 19 | reset: 20 | ;--- VIC setup -------------------------------------------------------- 21 | sei 22 | lda #$1b ; Standard text mode 23 | sta TMP1 24 | lda #$0f ; Enable all interrupts 25 | sta $d01a 26 | lda #44 ; Interrupt at line 300 27 | sta $d012 ; (within vblank) 28 | sta RASTER_LO 29 | lda #1 30 | sta RASTER_HI ; And store 304 for the IRQ 31 | lda #0 32 | sta RASTERBAR ; Start off with no rasterbars 33 | 34 | lda #handler_raster 37 | sta $0315 38 | 39 | ;--- CIA interrupt setup ---------------------------------------------- 40 | lda #$7f 41 | sta $dc0d 42 | sta $dd0d ; Disable interrupts on both CIAs 43 | lda $dc0d 44 | lda $dd0d ; Acknowledge interrupts on both CIAs 45 | 46 | cli ; Turn interrupts back on 47 | 48 | ;--- Sprite loading --------------------------------------------------- 49 | ldx #62 50 | sprlp: 51 | lda sprdata, x 52 | sta $3fc0, x 53 | dex 54 | bne sprlp 55 | 56 | lda #$ff ; Set pointer for sprite 0 57 | sta $07f8 58 | lda #$80 ; Set sprite 0 X and Y 59 | sta $d000 60 | sta $d001 61 | sta SPR_X_LO 62 | sta SPR_Y 63 | lda #0 64 | sta SPR_X_HI 65 | lda #$07 ; Sprite 0 is yellow 66 | sta $d027 67 | 68 | ;--- We're done, spin forever ----------------------------------------- 69 | jmp * 70 | 71 | ;-------------------------------------------------------------------------- 72 | ; Raster interrupt handler! 73 | handler_raster: 74 | pla 75 | pla ; Pop Y and X off the stack 76 | dec $d019 ; Acknowledge 77 | 78 | ;--- Check if this was the CIA interrupting --------------------------- 79 | lda $dc0d 80 | bne handler_cia 81 | 82 | ;--- Change the border color ------------------------------------------ 83 | raster_bars: 84 | lda $d020 85 | adc RASTERBAR 86 | sta $d020 87 | 88 | ;--- Increment raster trap point by 12 -------------------------------- 89 | raster_inc: 90 | lda $d012 91 | adc #12 ; (Carry is cleared above) 92 | sta RASTER_LO 93 | sta $d012 ; And write to VIC 94 | lda RASTER_HI ; 16-bit addition 95 | adc #0 96 | sta RASTER_HI 97 | ror ; Again, carry is clear, so 98 | ror ; this rotates bit 0 to bit 7 99 | ora TMP1 ; Set the original VIC flags 100 | sta $d011 101 | 102 | rol 103 | bcc raster_notop ; If the high bit is 1, 104 | lda RASTER_LO 105 | cmp #50 ; and the low byte is 106 | bcc raster_notop ; >= 44 or so, then 107 | lda #1 108 | sta $d012 109 | sta RASTER_LO 110 | lda #0 111 | sta RASTER_HI ; Go back to the top (line 1) 112 | lda TMP1 113 | sta $d011 114 | bne vbl_frame ; Skip over to do the per-frame work 115 | 116 | raster_notop: 117 | pla 118 | rti ; Leaving the handler early! 119 | 120 | ;--- CIA handler (within relative-jump range of the top of handler) --- 121 | handler_cia: 122 | lda GAMEFLAGS 123 | and #16 ; Bit 4 of GAMEFLAGS 124 | beq cia_end ; is "background change on" 125 | lda BGCOL 126 | adc #3 127 | sta BGCOL 128 | sta $d021 ; Change the background color 129 | cia_end: 130 | pla 131 | rti ; Leaving the handler 132 | 133 | ;--- Per-frame events: scrollshake ------------------------------------ 134 | vbl_frame: 135 | txa 136 | pha 137 | 138 | lda GAMEFLAGS 139 | and #1 ; Bit 0 of GAMEFLAGS 140 | beq vbl_shake ; is "rasterbars on" 141 | lda #3 ; If it's on, we'll add 3 to 142 | sta RASTERBAR ; the color every 12 lines 143 | 144 | vbl_shake: 145 | lda GAMEFLAGS 146 | and #2 ; Bit 1 of GAMEFLAGS 147 | beq vbl_kb ; is "scrollshake on" 148 | lda SCROLLPOS 149 | clc 150 | adc #$1b ; Add 3 to Y, and 5 to X 151 | sta SCROLLPOS ; to simulate "random" 152 | tax 153 | 154 | lda $d016 155 | and #$f8 ; Mask off and save the 156 | sta TMP0 ; top 5 bits of D016 157 | txa 158 | and #7 ; Mask in the X component 159 | ora TMP0 ; And tack them together 160 | sta $d016 161 | 162 | lda $d011 163 | and #$f8 ; Do the same for D011 164 | sta TMP0 165 | txa 166 | lsr ; This time, push the 167 | lsr ; Y component into place 168 | lsr ; before we do the masking 169 | and #7 ; of the bottom 3 bits 170 | ora TMP0 ; Tack them together too 171 | sta $d011 172 | and #$7f 173 | sta TMP1 174 | 175 | ;--- Per-frame events: Move sprite by joystick direction -------------- 176 | vbl_kb: 177 | ldx $dc00 ; Get Joy2's status 178 | 179 | vbl_kb_up: 180 | txa 181 | and #1 ; Check bit 0 (UP) 182 | bne vbl_kb_down 183 | dec SPR_Y ; If it's set, move up 184 | 185 | vbl_kb_down: 186 | txa 187 | and #2 ; Check bit 1 (DOWN) 188 | bne vbl_kb_right 189 | inc SPR_Y ; If it's set, move down 190 | 191 | vbl_kb_right: 192 | txa 193 | and #8 ; Check bit 3 (RIGHT) 194 | bne vbl_kb_left 195 | lda SPR_X_LO ; If it's set, perform a 196 | clc ; 16-bit addition of 1 197 | adc #1 ; and mask it down to 0-511 198 | sta SPR_X_LO 199 | lda SPR_X_HI 200 | adc #0 201 | and #1 202 | sta SPR_X_HI 203 | 204 | vbl_kb_left: 205 | txa 206 | and #4 ; Check bit 2 (LEFT) 207 | bne vbl_kb_end 208 | lda SPR_X_LO ; If it's set, perform a 209 | clc ; 16-bit subtraction of 1 210 | sbc #1 ; and mask it down to 0-511 211 | sta SPR_X_LO 212 | lda SPR_X_HI 213 | sbc #0 214 | and #1 215 | sta SPR_X_HI 216 | 217 | vbl_kb_end: 218 | lda SPR_X_LO ; Positions have been determined, 219 | sta $d000 ; set them 220 | lda SPR_X_HI ; We don't worry about the X-pos 221 | sta $d010 ; of any other sprites 222 | ldx SPR_Y 223 | stx $d001 224 | 225 | ;--- Per-frame events: Check if sprite is enabled --------------------- 226 | vbl_spr: 227 | lda GAMEFLAGS 228 | tax 229 | and #4 ; Bit 2 of GAMEFLAGS 230 | beq vbl_sprdbl ; is "sprite on" 231 | lda #1 232 | sta $d015 233 | vbl_sprdbl: 234 | txa 235 | and #8 ; Bit 3 of GAMEFLAGS 236 | beq raster_end ; is "sprite doubled" 237 | lda #1 238 | sta $d017 239 | sta $d01d 240 | 241 | ;--- End of handler: we skipped to here for mid-frame rasters --------- 242 | raster_end: 243 | pla 244 | tax 245 | raster_endx: 246 | pla 247 | rti 248 | 249 | ;-------------------------------------------------------------------------- 250 | sprdata: 251 | .byt 0, 126, 0, 3, 255, 192, 7, 255, 224 252 | .byt 31, 255, 248, 31, 255, 248, 63, 255, 252 253 | .byt 127, 255, 254, 127, 254, 254, 255, 253, 255 254 | .byt 255, 251, 255, 255, 247, 255, 255, 239, 255 255 | .byt 255, 223, 255, 127, 191, 254, 127, 127, 254 256 | .byt 63, 255, 252, 31, 255, 248, 31, 255, 248 257 | .byt 7, 255, 224, 3, 255, 192, 0, 126, 0 258 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/documentation/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{page.title}} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 32 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 65 | {% if page.section and page.fullpage != true %} 66 |
67 | 123 | {% endif %} 124 |
125 |

{{page.title}}

126 | 127 | 128 | 129 | 130 | {{content}} 131 | 132 | 133 | 134 | 135 |
136 |
137 |
138 | 147 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/vendor/FileSaver.js: -------------------------------------------------------------------------------- 1 | /*! FileSaver.js 2 | * A saveAs() FileSaver implementation. 3 | * 2014-01-24 4 | * 5 | * By Eli Grey, http://eligrey.com 6 | * License: X11/MIT 7 | * See LICENSE.md 8 | */ 9 | 10 | /*global self */ 11 | /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ 12 | 13 | /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 14 | 15 | var saveAs = saveAs 16 | // IE 10+ (native saveAs) 17 | || (typeof navigator !== "undefined" && 18 | navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) 19 | // Everyone else 20 | || (function(view) { 21 | "use strict"; 22 | // IE <10 is explicitly unsupported 23 | if (typeof navigator !== "undefined" && 24 | /MSIE [1-9]\./.test(navigator.userAgent)) { 25 | return; 26 | } 27 | var 28 | doc = view.document 29 | // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet 30 | , get_URL = function() { 31 | return view.URL || view.webkitURL || view; 32 | } 33 | , URL = view.URL || view.webkitURL || view 34 | , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") 35 | , can_use_save_link = !view.externalHost && "download" in save_link 36 | , click = function(node) { 37 | var event = doc.createEvent("MouseEvents"); 38 | event.initMouseEvent( 39 | "click", true, false, view, 0, 0, 0, 0, 0 40 | , false, false, false, false, 0, null 41 | ); 42 | node.dispatchEvent(event); 43 | } 44 | , webkit_req_fs = view.webkitRequestFileSystem 45 | , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem 46 | , throw_outside = function(ex) { 47 | (view.setImmediate || view.setTimeout)(function() { 48 | throw ex; 49 | }, 0); 50 | } 51 | , force_saveable_type = "application/octet-stream" 52 | , fs_min_size = 0 53 | , deletion_queue = [] 54 | , process_deletion_queue = function() { 55 | var i = deletion_queue.length; 56 | while (i--) { 57 | var file = deletion_queue[i]; 58 | if (typeof file === "string") { // file is an object URL 59 | URL.revokeObjectURL(file); 60 | } else { // file is a File 61 | file.remove(); 62 | } 63 | } 64 | deletion_queue.length = 0; // clear queue 65 | } 66 | , dispatch = function(filesaver, event_types, event) { 67 | event_types = [].concat(event_types); 68 | var i = event_types.length; 69 | while (i--) { 70 | var listener = filesaver["on" + event_types[i]]; 71 | if (typeof listener === "function") { 72 | try { 73 | listener.call(filesaver, event || filesaver); 74 | } catch (ex) { 75 | throw_outside(ex); 76 | } 77 | } 78 | } 79 | } 80 | , FileSaver = function(blob, name) { 81 | // First try a.download, then web filesystem, then object URLs 82 | var 83 | filesaver = this 84 | , type = blob.type 85 | , blob_changed = false 86 | , object_url 87 | , target_view 88 | , get_object_url = function() { 89 | var object_url = get_URL().createObjectURL(blob); 90 | deletion_queue.push(object_url); 91 | return object_url; 92 | } 93 | , dispatch_all = function() { 94 | dispatch(filesaver, "writestart progress write writeend".split(" ")); 95 | } 96 | // on any filesys errors revert to saving with object URLs 97 | , fs_error = function() { 98 | // don't create more object URLs than needed 99 | if (blob_changed || !object_url) { 100 | object_url = get_object_url(blob); 101 | } 102 | if (target_view) { 103 | target_view.location.href = object_url; 104 | } else { 105 | window.open(object_url, "_blank"); 106 | } 107 | filesaver.readyState = filesaver.DONE; 108 | dispatch_all(); 109 | } 110 | , abortable = function(func) { 111 | return function() { 112 | if (filesaver.readyState !== filesaver.DONE) { 113 | return func.apply(this, arguments); 114 | } 115 | }; 116 | } 117 | , create_if_not_found = {create: true, exclusive: false} 118 | , slice 119 | ; 120 | filesaver.readyState = filesaver.INIT; 121 | if (!name) { 122 | name = "download"; 123 | } 124 | if (can_use_save_link) { 125 | object_url = get_object_url(blob); 126 | // FF for Android has a nasty garbage collection mechanism 127 | // that turns all objects that are not pure javascript into 'deadObject' 128 | // this means `doc` and `save_link` are unusable and need to be recreated 129 | // `view` is usable though: 130 | doc = view.document; 131 | save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"); 132 | save_link.href = object_url; 133 | save_link.download = name; 134 | var event = doc.createEvent("MouseEvents"); 135 | event.initMouseEvent( 136 | "click", true, false, view, 0, 0, 0, 0, 0 137 | , false, false, false, false, 0, null 138 | ); 139 | save_link.dispatchEvent(event); 140 | filesaver.readyState = filesaver.DONE; 141 | dispatch_all(); 142 | return; 143 | } 144 | // Object and web filesystem URLs have a problem saving in Google Chrome when 145 | // viewed in a tab, so I force save with application/octet-stream 146 | // http://code.google.com/p/chromium/issues/detail?id=91158 147 | if (view.chrome && type && type !== force_saveable_type) { 148 | slice = blob.slice || blob.webkitSlice; 149 | blob = slice.call(blob, 0, blob.size, force_saveable_type); 150 | blob_changed = true; 151 | } 152 | // Since I can't be sure that the guessed media type will trigger a download 153 | // in WebKit, I append .download to the filename. 154 | // https://bugs.webkit.org/show_bug.cgi?id=65440 155 | if (webkit_req_fs && name !== "download") { 156 | name += ".download"; 157 | } 158 | if (type === force_saveable_type || webkit_req_fs) { 159 | target_view = view; 160 | } 161 | if (!req_fs) { 162 | fs_error(); 163 | return; 164 | } 165 | fs_min_size += blob.size; 166 | req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { 167 | fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { 168 | var save = function() { 169 | dir.getFile(name, create_if_not_found, abortable(function(file) { 170 | file.createWriter(abortable(function(writer) { 171 | writer.onwriteend = function(event) { 172 | target_view.location.href = file.toURL(); 173 | deletion_queue.push(file); 174 | filesaver.readyState = filesaver.DONE; 175 | dispatch(filesaver, "writeend", event); 176 | }; 177 | writer.onerror = function() { 178 | var error = writer.error; 179 | if (error.code !== error.ABORT_ERR) { 180 | fs_error(); 181 | } 182 | }; 183 | "writestart progress write abort".split(" ").forEach(function(event) { 184 | writer["on" + event] = filesaver["on" + event]; 185 | }); 186 | writer.write(blob); 187 | filesaver.abort = function() { 188 | writer.abort(); 189 | filesaver.readyState = filesaver.DONE; 190 | }; 191 | filesaver.readyState = filesaver.WRITING; 192 | }), fs_error); 193 | }), fs_error); 194 | }; 195 | dir.getFile(name, {create: false}, abortable(function(file) { 196 | // delete file if it already exists 197 | file.remove(); 198 | save(); 199 | }), abortable(function(ex) { 200 | if (ex.code === ex.NOT_FOUND_ERR) { 201 | save(); 202 | } else { 203 | fs_error(); 204 | } 205 | })); 206 | }), fs_error); 207 | }), fs_error); 208 | } 209 | , FS_proto = FileSaver.prototype 210 | , saveAs = function(blob, name) { 211 | return new FileSaver(blob, name); 212 | } 213 | ; 214 | FS_proto.abort = function() { 215 | var filesaver = this; 216 | filesaver.readyState = filesaver.DONE; 217 | dispatch(filesaver, "abort"); 218 | }; 219 | FS_proto.readyState = FS_proto.INIT = 0; 220 | FS_proto.WRITING = 1; 221 | FS_proto.DONE = 2; 222 | 223 | FS_proto.error = 224 | FS_proto.onwritestart = 225 | FS_proto.onprogress = 226 | FS_proto.onwrite = 227 | FS_proto.onabort = 228 | FS_proto.onerror = 229 | FS_proto.onwriteend = 230 | null; 231 | 232 | view.addEventListener("unload", process_deletion_queue, false); 233 | saveAs.unload = function() { 234 | process_deletion_queue(); 235 | view.removeEventListener("unload", process_deletion_queue, false); 236 | }; 237 | return saveAs; 238 | }( 239 | typeof self !== "undefined" && self 240 | || typeof window !== "undefined" && window 241 | || this.content 242 | )); 243 | // `self` is undefined in Firefox for Android content script context 244 | // while `this` is nsIContentFrameMessageManager 245 | // with an attribute `content` that corresponds to the window 246 | 247 | if (typeof module !== "undefined") module.exports = saveAs; 248 | -------------------------------------------------------------------------------- /js/thirdparty/jquery.powertip.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | PowerTip - v1.2.0 - 2013-04-03 3 | http://stevenbenner.github.com/jquery-powertip/ 4 | Copyright (c) 2013 Steven Benner (http://stevenbenner.com/). 5 | Released under MIT license. 6 | https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt 7 | */ 8 | (function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(){var t=this;t.top="auto",t.left="auto",t.right="auto",t.bottom="auto",t.set=function(o,n){e.isNumeric(n)&&(t[o]=Math.round(n))}}function o(e,t,o){function n(n,i){r(),e.data(v)||(n?(i&&e.data(m,!0),o.showTip(e)):(P.tipOpenImminent=!0,l=setTimeout(function(){l=null,s()},t.intentPollInterval)))}function i(n){r(),P.tipOpenImminent=!1,e.data(v)&&(e.data(m,!1),n?o.hideTip(e):(P.delayInProgress=!0,l=setTimeout(function(){l=null,o.hideTip(e),P.delayInProgress=!1},t.closeDelay)))}function s(){var i=Math.abs(P.previousX-P.currentX),s=Math.abs(P.previousY-P.currentY),r=i+s;t.intentSensitivity>r?o.showTip(e):(P.previousX=P.currentX,P.previousY=P.currentY,n())}function r(){l=clearTimeout(l),P.delayInProgress=!1}function a(){o.resetPosition(e)}var l=null;this.show=n,this.hide=i,this.cancel=r,this.resetPosition=a}function n(){function e(e,i,r,a,l){var p,c=i.split("-")[0],u=new t;switch(p=s(e)?n(e,c):o(e,c),i){case"n":u.set("left",p.left-r/2),u.set("bottom",P.windowHeight-p.top+l);break;case"e":u.set("left",p.left+l),u.set("top",p.top-a/2);break;case"s":u.set("left",p.left-r/2),u.set("top",p.top+l);break;case"w":u.set("top",p.top-a/2),u.set("right",P.windowWidth-p.left+l);break;case"nw":u.set("bottom",P.windowHeight-p.top+l),u.set("right",P.windowWidth-p.left-20);break;case"nw-alt":u.set("left",p.left),u.set("bottom",P.windowHeight-p.top+l);break;case"ne":u.set("left",p.left-20),u.set("bottom",P.windowHeight-p.top+l);break;case"ne-alt":u.set("bottom",P.windowHeight-p.top+l),u.set("right",P.windowWidth-p.left);break;case"sw":u.set("top",p.top+l),u.set("right",P.windowWidth-p.left-20);break;case"sw-alt":u.set("left",p.left),u.set("top",p.top+l);break;case"se":u.set("left",p.left-20),u.set("top",p.top+l);break;case"se-alt":u.set("top",p.top+l),u.set("right",P.windowWidth-p.left)}return u}function o(e,t){var o,n,i=e.offset(),s=e.outerWidth(),r=e.outerHeight();switch(t){case"n":o=i.left+s/2,n=i.top;break;case"e":o=i.left+s,n=i.top+r/2;break;case"s":o=i.left+s/2,n=i.top+r;break;case"w":o=i.left,n=i.top+r/2;break;case"nw":o=i.left,n=i.top;break;case"ne":o=i.left+s,n=i.top;break;case"sw":o=i.left,n=i.top+r;break;case"se":o=i.left+s,n=i.top+r}return{top:n,left:o}}function n(e,t){function o(){d.push(p.matrixTransform(u))}var n,i,s,r,a=e.closest("svg")[0],l=e[0],p=a.createSVGPoint(),c=l.getBBox(),u=l.getScreenCTM(),f=c.width/2,w=c.height/2,d=[],h=["nw","n","ne","e","se","s","sw","w"];if(p.x=c.x,p.y=c.y,o(),p.x+=f,o(),p.x+=f,o(),p.y+=w,o(),p.y+=w,o(),p.x-=f,o(),p.x-=f,o(),p.y-=w,o(),d[0].y!==d[1].y||d[0].x!==d[7].x)for(i=Math.atan2(u.b,u.a)*O,s=Math.ceil((i%360-22.5)/45),1>s&&(s+=8);s--;)h.push(h.shift());for(r=0;d.length>r;r++)if(h[r]===t){n=d[r];break}return{top:n.y+P.scrollTop,left:n.x+P.scrollLeft}}this.compute=e}function i(o){function i(e){e.data(v,!0),O.queue(function(t){s(e),t()})}function s(e){var t;if(e.data(v)){if(P.isTipOpen)return P.isClosing||r(P.activeHover),O.delay(100).queue(function(t){s(e),t()}),void 0;e.trigger("powerTipPreRender"),t=p(e),t&&(O.empty().append(t),e.trigger("powerTipRender"),P.activeHover=e,P.isTipOpen=!0,O.data(g,o.mouseOnToPopup),o.followMouse?a():(b(e),P.isFixedTipOpen=!0),O.fadeIn(o.fadeInTime,function(){P.desyncTimeout||(P.desyncTimeout=setInterval(H,500)),e.trigger("powerTipOpen")}))}}function r(e){P.isClosing=!0,P.activeHover=null,P.isTipOpen=!1,P.desyncTimeout=clearInterval(P.desyncTimeout),e.data(v,!1),e.data(m,!1),O.fadeOut(o.fadeOutTime,function(){var n=new t;P.isClosing=!1,P.isFixedTipOpen=!1,O.removeClass(),n.set("top",P.currentY+o.offset),n.set("left",P.currentX+o.offset),O.css(n),e.trigger("powerTipClose")})}function a(){if(!P.isFixedTipOpen&&(P.isTipOpen||P.tipOpenImminent&&O.data(T))){var e,n,i=O.outerWidth(),s=O.outerHeight(),r=new t;r.set("top",P.currentY+o.offset),r.set("left",P.currentX+o.offset),e=c(r,i,s),e!==I.none&&(n=u(e),1===n?e===I.right?r.set("left",P.windowWidth-i):e===I.bottom&&r.set("top",P.scrollTop+P.windowHeight-s):(r.set("left",P.currentX-i-o.offset),r.set("top",P.currentY-s-o.offset))),O.css(r)}}function b(t){var n,i;o.smartPlacement?(n=e.fn.powerTip.smartPlacementLists[o.placement],e.each(n,function(e,o){var n=c(y(t,o),O.outerWidth(),O.outerHeight());return i=o,n===I.none?!1:void 0})):(y(t,o.placement),i=o.placement),O.addClass(i)}function y(e,n){var i,s,r=0,a=new t;a.set("top",0),a.set("left",0),O.css(a);do i=O.outerWidth(),s=O.outerHeight(),a=k.compute(e,n,i,s,o.offset),O.css(a);while(5>=++r&&(i!==O.outerWidth()||s!==O.outerHeight()));return a}function H(){var e=!1;!P.isTipOpen||P.isClosing||P.delayInProgress||(P.activeHover.data(v)===!1||P.activeHover.is(":disabled")?e=!0:l(P.activeHover)||P.activeHover.is(":focus")||P.activeHover.data(m)||(O.data(g)?l(O)||(e=!0):e=!0),e&&r(P.activeHover))}var k=new n,O=e("#"+o.popupId);0===O.length&&(O=e("
",{id:o.popupId}),0===d.length&&(d=e("body")),d.append(O)),o.followMouse&&(O.data(T)||(f.on("mousemove",a),w.on("scroll",a),O.data(T,!0))),o.mouseOnToPopup&&O.on({mouseenter:function(){O.data(g)&&P.activeHover&&P.activeHover.data(h).cancel()},mouseleave:function(){P.activeHover&&P.activeHover.data(h).hide()}}),this.showTip=i,this.hideTip=r,this.resetPosition=b}function s(e){return window.SVGElement&&e[0]instanceof SVGElement}function r(){P.mouseTrackingActive||(P.mouseTrackingActive=!0,e(function(){P.scrollLeft=w.scrollLeft(),P.scrollTop=w.scrollTop(),P.windowWidth=w.width(),P.windowHeight=w.height()}),f.on("mousemove",a),w.on({resize:function(){P.windowWidth=w.width(),P.windowHeight=w.height()},scroll:function(){var e=w.scrollLeft(),t=w.scrollTop();e!==P.scrollLeft&&(P.currentX+=e-P.scrollLeft,P.scrollLeft=e),t!==P.scrollTop&&(P.currentY+=t-P.scrollTop,P.scrollTop=t)}}))}function a(e){P.currentX=e.pageX,P.currentY=e.pageY}function l(e){var t=e.offset(),o=e[0].getBoundingClientRect(),n=o.right-o.left,i=o.bottom-o.top;return P.currentX>=t.left&&P.currentX<=t.left+n&&P.currentY>=t.top&&P.currentY<=t.top+i}function p(t){var o,n,i=t.data(y),s=t.data(H),r=t.data(k);return i?(e.isFunction(i)&&(i=i.call(t[0])),n=i):s?(e.isFunction(s)&&(s=s.call(t[0])),s.length>0&&(n=s.clone(!0,!0))):r&&(o=e("#"+r),o.length>0&&(n=o.html())),n}function c(e,t,o){var n=P.scrollTop,i=P.scrollLeft,s=n+P.windowHeight,r=i+P.windowWidth,a=I.none;return(n>e.top||n>Math.abs(e.bottom-P.windowHeight)-o)&&(a|=I.top),(e.top+o>s||Math.abs(e.bottom-P.windowHeight)>s)&&(a|=I.bottom),(i>e.left||e.right+t>r)&&(a|=I.left),(e.left+t>r||i>e.right)&&(a|=I.right),a}function u(e){for(var t=0;e;)e&=e-1,t++;return t}var f=e(document),w=e(window),d=e("body"),h="displayController",v="hasActiveHover",m="forcedOpen",T="hasMouseMove",g="mouseOnToPopup",b="originalTitle",y="powertip",H="powertipjq",k="powertiptarget",O=180/Math.PI,P={isTipOpen:!1,isFixedTipOpen:!1,isClosing:!1,tipOpenImminent:!1,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:!1,delayInProgress:!1,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0},I={none:0,top:1,bottom:2,left:4,right:8};e.fn.powerTip=function(t,n){if(!this.length)return this;if("string"===e.type(t)&&e.powerTip[t])return e.powerTip[t].call(this,this,n);var s=e.extend({},e.fn.powerTip.defaults,t),a=new i(s);return r(),this.each(function(){var t,n=e(this),i=n.data(y),r=n.data(H),l=n.data(k);n.data(h)&&e.powerTip.destroy(n),t=n.attr("title"),i||l||r||!t||(n.data(y,t),n.data(b,t),n.removeAttr("title")),n.data(h,new o(n,s,a))}),s.manual||this.on({"mouseenter.powertip":function(t){e.powerTip.show(this,t)},"mouseleave.powertip":function(){e.powerTip.hide(this)},"focus.powertip":function(){e.powerTip.show(this)},"blur.powertip":function(){e.powerTip.hide(this,!0)},"keydown.powertip":function(t){27===t.keyCode&&e.powerTip.hide(this,!0)}}),this},e.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:!1,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:!1,offset:10,mouseOnToPopup:!1,manual:!1},e.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]},e.powerTip={show:function(t,o){return o?(a(o),P.previousX=o.pageX,P.previousY=o.pageY,e(t).data(h).show()):e(t).first().data(h).show(!0,!0),t},reposition:function(t){return e(t).first().data(h).resetPosition(),t},hide:function(t,o){return t?e(t).first().data(h).hide(o):P.activeHover&&P.activeHover.data(h).hide(!0),t},destroy:function(t){return e(t).off(".powertip").each(function(){var t=e(this),o=[b,h,v,m];t.data(b)&&(t.attr("title",t.data(b)),o.push(y)),t.removeData(o)}),t}},e.powerTip.showTip=e.powerTip.show,e.powerTip.closeTip=e.powerTip.hide}); -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/zipEntries.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var StringReader = require('./stringReader'); 3 | var NodeBufferReader = require('./nodeBufferReader'); 4 | var Uint8ArrayReader = require('./uint8ArrayReader'); 5 | var utils = require('./utils'); 6 | var sig = require('./signature'); 7 | var ZipEntry = require('./zipEntry'); 8 | var support = require('./support'); 9 | var jszipProto = require('./object'); 10 | // class ZipEntries {{{ 11 | /** 12 | * All the entries in the zip file. 13 | * @constructor 14 | * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. 15 | * @param {Object} loadOptions Options for loading the stream. 16 | */ 17 | function ZipEntries(data, loadOptions) { 18 | this.files = []; 19 | this.loadOptions = loadOptions; 20 | if (data) { 21 | this.load(data); 22 | } 23 | } 24 | ZipEntries.prototype = { 25 | /** 26 | * Check that the reader is on the speficied signature. 27 | * @param {string} expectedSignature the expected signature. 28 | * @throws {Error} if it is an other signature. 29 | */ 30 | checkSignature: function(expectedSignature) { 31 | var signature = this.reader.readString(4); 32 | if (signature !== expectedSignature) { 33 | throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); 34 | } 35 | }, 36 | /** 37 | * Read the end of the central directory. 38 | */ 39 | readBlockEndOfCentral: function() { 40 | this.diskNumber = this.reader.readInt(2); 41 | this.diskWithCentralDirStart = this.reader.readInt(2); 42 | this.centralDirRecordsOnThisDisk = this.reader.readInt(2); 43 | this.centralDirRecords = this.reader.readInt(2); 44 | this.centralDirSize = this.reader.readInt(4); 45 | this.centralDirOffset = this.reader.readInt(4); 46 | 47 | this.zipCommentLength = this.reader.readInt(2); 48 | // warning : the encoding depends of the system locale 49 | // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. 50 | // On a windows machine, this field is encoded with the localized windows code page. 51 | this.zipComment = this.reader.readString(this.zipCommentLength); 52 | // To get consistent behavior with the generation part, we will assume that 53 | // this is utf8 encoded. 54 | this.zipComment = jszipProto.utf8decode(this.zipComment); 55 | }, 56 | /** 57 | * Read the end of the Zip 64 central directory. 58 | * Not merged with the method readEndOfCentral : 59 | * The end of central can coexist with its Zip64 brother, 60 | * I don't want to read the wrong number of bytes ! 61 | */ 62 | readBlockZip64EndOfCentral: function() { 63 | this.zip64EndOfCentralSize = this.reader.readInt(8); 64 | this.versionMadeBy = this.reader.readString(2); 65 | this.versionNeeded = this.reader.readInt(2); 66 | this.diskNumber = this.reader.readInt(4); 67 | this.diskWithCentralDirStart = this.reader.readInt(4); 68 | this.centralDirRecordsOnThisDisk = this.reader.readInt(8); 69 | this.centralDirRecords = this.reader.readInt(8); 70 | this.centralDirSize = this.reader.readInt(8); 71 | this.centralDirOffset = this.reader.readInt(8); 72 | 73 | this.zip64ExtensibleData = {}; 74 | var extraDataSize = this.zip64EndOfCentralSize - 44, 75 | index = 0, 76 | extraFieldId, 77 | extraFieldLength, 78 | extraFieldValue; 79 | while (index < extraDataSize) { 80 | extraFieldId = this.reader.readInt(2); 81 | extraFieldLength = this.reader.readInt(4); 82 | extraFieldValue = this.reader.readString(extraFieldLength); 83 | this.zip64ExtensibleData[extraFieldId] = { 84 | id: extraFieldId, 85 | length: extraFieldLength, 86 | value: extraFieldValue 87 | }; 88 | } 89 | }, 90 | /** 91 | * Read the end of the Zip 64 central directory locator. 92 | */ 93 | readBlockZip64EndOfCentralLocator: function() { 94 | this.diskWithZip64CentralDirStart = this.reader.readInt(4); 95 | this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); 96 | this.disksCount = this.reader.readInt(4); 97 | if (this.disksCount > 1) { 98 | throw new Error("Multi-volumes zip are not supported"); 99 | } 100 | }, 101 | /** 102 | * Read the local files, based on the offset read in the central part. 103 | */ 104 | readLocalFiles: function() { 105 | var i, file; 106 | for (i = 0; i < this.files.length; i++) { 107 | file = this.files[i]; 108 | this.reader.setIndex(file.localHeaderOffset); 109 | this.checkSignature(sig.LOCAL_FILE_HEADER); 110 | file.readLocalPart(this.reader); 111 | file.handleUTF8(); 112 | } 113 | }, 114 | /** 115 | * Read the central directory. 116 | */ 117 | readCentralDir: function() { 118 | var file; 119 | 120 | this.reader.setIndex(this.centralDirOffset); 121 | while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { 122 | file = new ZipEntry({ 123 | zip64: this.zip64 124 | }, this.loadOptions); 125 | file.readCentralPart(this.reader); 126 | this.files.push(file); 127 | } 128 | }, 129 | /** 130 | * Read the end of central directory. 131 | */ 132 | readEndOfCentral: function() { 133 | var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); 134 | if (offset === -1) { 135 | throw new Error("Corrupted zip : can't find end of central directory"); 136 | } 137 | this.reader.setIndex(offset); 138 | this.checkSignature(sig.CENTRAL_DIRECTORY_END); 139 | this.readBlockEndOfCentral(); 140 | 141 | 142 | /* extract from the zip spec : 143 | 4) If one of the fields in the end of central directory 144 | record is too small to hold required data, the field 145 | should be set to -1 (0xFFFF or 0xFFFFFFFF) and the 146 | ZIP64 format record should be created. 147 | 5) The end of central directory record and the 148 | Zip64 end of central directory locator record must 149 | reside on the same disk when splitting or spanning 150 | an archive. 151 | */ 152 | if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { 153 | this.zip64 = true; 154 | 155 | /* 156 | Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from 157 | the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents 158 | all numbers as 64-bit double precision IEEE 754 floating point numbers. 159 | So, we have 53bits for integers and bitwise operations treat everything as 32bits. 160 | see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators 161 | and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 162 | */ 163 | 164 | // should look for a zip64 EOCD locator 165 | offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); 166 | if (offset === -1) { 167 | throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); 168 | } 169 | this.reader.setIndex(offset); 170 | this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); 171 | this.readBlockZip64EndOfCentralLocator(); 172 | 173 | // now the zip64 EOCD record 174 | this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); 175 | this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); 176 | this.readBlockZip64EndOfCentral(); 177 | } 178 | }, 179 | prepareReader: function(data) { 180 | var type = utils.getTypeOf(data); 181 | if (type === "string" && !support.uint8array) { 182 | this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); 183 | } 184 | else if (type === "nodebuffer") { 185 | this.reader = new NodeBufferReader(data); 186 | } 187 | else { 188 | this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); 189 | } 190 | }, 191 | /** 192 | * Read a zip file and create ZipEntries. 193 | * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. 194 | */ 195 | load: function(data) { 196 | this.prepareReader(data); 197 | this.readEndOfCentral(); 198 | this.readCentralDir(); 199 | this.readLocalFiles(); 200 | } 201 | }; 202 | // }}} end of ZipEntries 203 | module.exports = ZipEntries; 204 | -------------------------------------------------------------------------------- /js/thirdparty/jszip/lib/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var support = require('./support'); 3 | var compressions = require('./compressions'); 4 | var nodeBuffer = require('./nodeBuffer'); 5 | /** 6 | * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. 7 | * @param {string} str the string to transform. 8 | * @return {String} the binary string. 9 | */ 10 | exports.string2binary = function(str) { 11 | var result = ""; 12 | for (var i = 0; i < str.length; i++) { 13 | result += String.fromCharCode(str.charCodeAt(i) & 0xff); 14 | } 15 | return result; 16 | }; 17 | exports.arrayBuffer2Blob = function(buffer) { 18 | exports.checkSupport("blob"); 19 | 20 | try { 21 | // Blob constructor 22 | return new Blob([buffer], { 23 | type: "application/zip" 24 | }); 25 | } 26 | catch (e) { 27 | 28 | try { 29 | // deprecated, browser only, old way 30 | var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; 31 | var builder = new Builder(); 32 | builder.append(buffer); 33 | return builder.getBlob('application/zip'); 34 | } 35 | catch (e) { 36 | 37 | // well, fuck ?! 38 | throw new Error("Bug : can't construct the Blob."); 39 | } 40 | } 41 | 42 | 43 | }; 44 | /** 45 | * The identity function. 46 | * @param {Object} input the input. 47 | * @return {Object} the same input. 48 | */ 49 | function identity(input) { 50 | return input; 51 | } 52 | 53 | /** 54 | * Fill in an array with a string. 55 | * @param {String} str the string to use. 56 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). 57 | * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. 58 | */ 59 | function stringToArrayLike(str, array) { 60 | for (var i = 0; i < str.length; ++i) { 61 | array[i] = str.charCodeAt(i) & 0xFF; 62 | } 63 | return array; 64 | } 65 | 66 | /** 67 | * Transform an array-like object to a string. 68 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. 69 | * @return {String} the result. 70 | */ 71 | function arrayLikeToString(array) { 72 | // Performances notes : 73 | // -------------------- 74 | // String.fromCharCode.apply(null, array) is the fastest, see 75 | // see http://jsperf.com/converting-a-uint8array-to-a-string/2 76 | // but the stack is limited (and we can get huge arrays !). 77 | // 78 | // result += String.fromCharCode(array[i]); generate too many strings ! 79 | // 80 | // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 81 | var chunk = 65536; 82 | var result = [], 83 | len = array.length, 84 | type = exports.getTypeOf(array), 85 | k = 0, 86 | canUseApply = true; 87 | try { 88 | switch(type) { 89 | case "uint8array": 90 | String.fromCharCode.apply(null, new Uint8Array(0)); 91 | break; 92 | case "nodebuffer": 93 | String.fromCharCode.apply(null, nodeBuffer(0)); 94 | break; 95 | } 96 | } catch(e) { 97 | canUseApply = false; 98 | } 99 | 100 | // no apply : slow and painful algorithm 101 | // default browser on android 4.* 102 | if (!canUseApply) { 103 | var resultStr = ""; 104 | for(var i = 0; i < array.length;i++) { 105 | resultStr += String.fromCharCode(array[i]); 106 | } 107 | return resultStr; 108 | } 109 | while (k < len && chunk > 1) { 110 | try { 111 | if (type === "array" || type === "nodebuffer") { 112 | result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); 113 | } 114 | else { 115 | result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); 116 | } 117 | k += chunk; 118 | } 119 | catch (e) { 120 | chunk = Math.floor(chunk / 2); 121 | } 122 | } 123 | return result.join(""); 124 | } 125 | 126 | exports.applyFromCharCode = arrayLikeToString; 127 | 128 | 129 | /** 130 | * Copy the data from an array-like to an other array-like. 131 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. 132 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. 133 | * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. 134 | */ 135 | function arrayLikeToArrayLike(arrayFrom, arrayTo) { 136 | for (var i = 0; i < arrayFrom.length; i++) { 137 | arrayTo[i] = arrayFrom[i]; 138 | } 139 | return arrayTo; 140 | } 141 | 142 | // a matrix containing functions to transform everything into everything. 143 | var transform = {}; 144 | 145 | // string to ? 146 | transform["string"] = { 147 | "string": identity, 148 | "array": function(input) { 149 | return stringToArrayLike(input, new Array(input.length)); 150 | }, 151 | "arraybuffer": function(input) { 152 | return transform["string"]["uint8array"](input).buffer; 153 | }, 154 | "uint8array": function(input) { 155 | return stringToArrayLike(input, new Uint8Array(input.length)); 156 | }, 157 | "nodebuffer": function(input) { 158 | return stringToArrayLike(input, nodeBuffer(input.length)); 159 | } 160 | }; 161 | 162 | // array to ? 163 | transform["array"] = { 164 | "string": arrayLikeToString, 165 | "array": identity, 166 | "arraybuffer": function(input) { 167 | return (new Uint8Array(input)).buffer; 168 | }, 169 | "uint8array": function(input) { 170 | return new Uint8Array(input); 171 | }, 172 | "nodebuffer": function(input) { 173 | return nodeBuffer(input); 174 | } 175 | }; 176 | 177 | // arraybuffer to ? 178 | transform["arraybuffer"] = { 179 | "string": function(input) { 180 | return arrayLikeToString(new Uint8Array(input)); 181 | }, 182 | "array": function(input) { 183 | return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); 184 | }, 185 | "arraybuffer": identity, 186 | "uint8array": function(input) { 187 | return new Uint8Array(input); 188 | }, 189 | "nodebuffer": function(input) { 190 | return nodeBuffer(new Uint8Array(input)); 191 | } 192 | }; 193 | 194 | // uint8array to ? 195 | transform["uint8array"] = { 196 | "string": arrayLikeToString, 197 | "array": function(input) { 198 | return arrayLikeToArrayLike(input, new Array(input.length)); 199 | }, 200 | "arraybuffer": function(input) { 201 | return input.buffer; 202 | }, 203 | "uint8array": identity, 204 | "nodebuffer": function(input) { 205 | return nodeBuffer(input); 206 | } 207 | }; 208 | 209 | // nodebuffer to ? 210 | transform["nodebuffer"] = { 211 | "string": arrayLikeToString, 212 | "array": function(input) { 213 | return arrayLikeToArrayLike(input, new Array(input.length)); 214 | }, 215 | "arraybuffer": function(input) { 216 | return transform["nodebuffer"]["uint8array"](input).buffer; 217 | }, 218 | "uint8array": function(input) { 219 | return arrayLikeToArrayLike(input, new Uint8Array(input.length)); 220 | }, 221 | "nodebuffer": identity 222 | }; 223 | 224 | /** 225 | * Transform an input into any type. 226 | * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. 227 | * If no output type is specified, the unmodified input will be returned. 228 | * @param {String} outputType the output type. 229 | * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. 230 | * @throws {Error} an Error if the browser doesn't support the requested output type. 231 | */ 232 | exports.transformTo = function(outputType, input) { 233 | if (!input) { 234 | // undefined, null, etc 235 | // an empty string won't harm. 236 | input = ""; 237 | } 238 | if (!outputType) { 239 | return input; 240 | } 241 | exports.checkSupport(outputType); 242 | var inputType = exports.getTypeOf(input); 243 | var result = transform[inputType][outputType](input); 244 | return result; 245 | }; 246 | 247 | /** 248 | * Return the type of the input. 249 | * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. 250 | * @param {Object} input the input to identify. 251 | * @return {String} the (lowercase) type of the input. 252 | */ 253 | exports.getTypeOf = function(input) { 254 | if (typeof input === "string") { 255 | return "string"; 256 | } 257 | if (Object.prototype.toString.call(input) === "[object Array]") { 258 | return "array"; 259 | } 260 | if (support.nodebuffer && nodeBuffer.test(input)) { 261 | return "nodebuffer"; 262 | } 263 | if (support.uint8array && input instanceof Uint8Array) { 264 | return "uint8array"; 265 | } 266 | if (support.arraybuffer && input instanceof ArrayBuffer) { 267 | return "arraybuffer"; 268 | } 269 | }; 270 | 271 | /** 272 | * Throw an exception if the type is not supported. 273 | * @param {String} type the type to check. 274 | * @throws {Error} an Error if the browser doesn't support the requested type. 275 | */ 276 | exports.checkSupport = function(type) { 277 | var supported = support[type.toLowerCase()]; 278 | if (!supported) { 279 | throw new Error(type + " is not supported by this browser"); 280 | } 281 | }; 282 | exports.MAX_VALUE_16BITS = 65535; 283 | exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 284 | 285 | /** 286 | * Prettify a string read as binary. 287 | * @param {string} str the string to prettify. 288 | * @return {string} a pretty string. 289 | */ 290 | exports.pretty = function(str) { 291 | var res = '', 292 | code, i; 293 | for (i = 0; i < (str || "").length; i++) { 294 | code = str.charCodeAt(i); 295 | res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); 296 | } 297 | return res; 298 | }; 299 | 300 | /** 301 | * Find a compression registered in JSZip. 302 | * @param {string} compressionMethod the method magic to find. 303 | * @return {Object|null} the JSZip compression object, null if none found. 304 | */ 305 | exports.findCompression = function(compressionMethod) { 306 | for (var method in compressions) { 307 | if (!compressions.hasOwnProperty(method)) { 308 | continue; 309 | } 310 | if (compressions[method].magic === compressionMethod) { 311 | return compressions[method]; 312 | } 313 | } 314 | return null; 315 | }; 316 | /** 317 | * Cross-window, cross-Node-context regular expression detection 318 | * @param {Object} object Anything 319 | * @return {Boolean} true if the object is a regular expression, 320 | * false otherwise 321 | */ 322 | exports.isRegExp = function (object) { 323 | return Object.prototype.toString.call(object) === "[object RegExp]"; 324 | }; 325 | 326 | --------------------------------------------------------------------------------