mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-30 14:53:01 +00:00 
			
		
		
		
	Update comic reader js
This commit is contained in:
		| @@ -8,7 +8,7 @@ | |||||||
|  * Copyright(c) 2011 Google Inc. |  * Copyright(c) 2011 Google Inc. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /* global bitjs */ | /* global bitjs, Uint8Array */ | ||||||
|  |  | ||||||
| var bitjs = bitjs || {}; | var bitjs = bitjs || {}; | ||||||
| bitjs.archive = bitjs.archive || {}; | bitjs.archive = bitjs.archive || {}; | ||||||
| @@ -17,7 +17,7 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|  |  | ||||||
|     // =========================================================================== |     // =========================================================================== | ||||||
|     // Stolen from Closure because it's the best way to do Java-like inheritance. |     // Stolen from Closure because it's the best way to do Java-like inheritance. | ||||||
|     bitjs.base = function(me, opt_methodName, var_args) { |     bitjs.base = function(me, optMethodName, varArgs) { | ||||||
|         var caller = arguments.callee.caller; |         var caller = arguments.callee.caller; | ||||||
|         if (caller.superClass_) { |         if (caller.superClass_) { | ||||||
|             // This is a constructor. Call the superclass constructor. |             // This is a constructor. Call the superclass constructor. | ||||||
| @@ -28,10 +28,10 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|         var args = Array.prototype.slice.call(arguments, 2); |         var args = Array.prototype.slice.call(arguments, 2); | ||||||
|         var foundCaller = false; |         var foundCaller = false; | ||||||
|         for (var ctor = me.constructor; ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { |         for (var ctor = me.constructor; ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { | ||||||
|             if (ctor.prototype[opt_methodName] === caller) { |             if (ctor.prototype[optMethodName] === caller) { | ||||||
|                 foundCaller = true; |                 foundCaller = true; | ||||||
|             } else if (foundCaller) { |             } else if (foundCaller) { | ||||||
|                 return ctor.prototype[opt_methodName].apply(me, args); |                 return ctor.prototype[optMethodName].apply(me, args); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -39,8 +39,8 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|         // then one of two things happened: |         // then one of two things happened: | ||||||
|         // 1) The caller is an instance method. |         // 1) The caller is an instance method. | ||||||
|         // 2) This method was not called by the right caller. |         // 2) This method was not called by the right caller. | ||||||
|         if (me[opt_methodName] === caller) { |         if (me[optMethodName] === caller) { | ||||||
|             return me.constructor.prototype[opt_methodName].apply(me, args); |             return me.constructor.prototype[optMethodName].apply(me, args); | ||||||
|         } else { |         } else { | ||||||
|             throw Error( |             throw Error( | ||||||
|                 "goog.base called from a method of one name " + |                 "goog.base called from a method of one name " + | ||||||
| @@ -49,10 +49,10 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|     }; |     }; | ||||||
|     bitjs.inherits = function(childCtor, parentCtor) { |     bitjs.inherits = function(childCtor, parentCtor) { | ||||||
|         /** @constructor */ |         /** @constructor */ | ||||||
|         function tempCtor() {}; |         function TempCtor() {} | ||||||
|         tempCtor.prototype = parentCtor.prototype; |         TempCtor.prototype = parentCtor.prototype; | ||||||
|         childCtor.superClass_ = parentCtor.prototype; |         childCtor.superClass_ = parentCtor.prototype; | ||||||
|         childCtor.prototype = new tempCtor(); |         childCtor.prototype = new TempCtor(); | ||||||
|         childCtor.prototype.constructor = childCtor; |         childCtor.prototype.constructor = childCtor; | ||||||
|     }; |     }; | ||||||
|     // =========================================================================== |     // =========================================================================== | ||||||
| @@ -188,10 +188,10 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|      * Base class for all Unarchivers. |      * Base class for all Unarchivers. | ||||||
|      * |      * | ||||||
|      * @param {ArrayBuffer} arrayBuffer The Array Buffer. |      * @param {ArrayBuffer} arrayBuffer The Array Buffer. | ||||||
|      * @param {string} opt_pathToBitJS Optional string for where the BitJS files are located. |      * @param {string} optPathToBitJS Optional string for where the BitJS files are located. | ||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.archive.Unarchiver = function(arrayBuffer, opt_pathToBitJS) { |     bitjs.archive.Unarchiver = function(arrayBuffer, optPathToBitJS) { | ||||||
|         /** |         /** | ||||||
|          * The ArrayBuffer object. |          * The ArrayBuffer object. | ||||||
|          * @type {ArrayBuffer} |          * @type {ArrayBuffer} | ||||||
| @@ -204,7 +204,7 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|          * @type {string} |          * @type {string} | ||||||
|          * @private |          * @private | ||||||
|          */ |          */ | ||||||
|         this.pathToBitJS_ = opt_pathToBitJS || "/"; |         this.pathToBitJS_ = optPathToBitJS || "/"; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * A map from event type to an array of listeners. |          * A map from event type to an array of listeners. | ||||||
| @@ -319,8 +319,8 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|      * @extends {bitjs.archive.Unarchiver} |      * @extends {bitjs.archive.Unarchiver} | ||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.archive.Unzipper = function(arrayBuffer, opt_pathToBitJS) { |     bitjs.archive.Unzipper = function(arrayBuffer, optPathToBitJS) { | ||||||
|         bitjs.base(this, arrayBuffer, opt_pathToBitJS); |         bitjs.base(this, arrayBuffer, optPathToBitJS); | ||||||
|     }; |     }; | ||||||
|     bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); |     bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); | ||||||
|     bitjs.archive.Unzipper.prototype.getScriptFileName = function() { |     bitjs.archive.Unzipper.prototype.getScriptFileName = function() { | ||||||
| @@ -332,8 +332,8 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|      * @extends {bitjs.archive.Unarchiver} |      * @extends {bitjs.archive.Unarchiver} | ||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.archive.Unrarrer = function(arrayBuffer, opt_pathToBitJS) { |     bitjs.archive.Unrarrer = function(arrayBuffer, optPathToBitJS) { | ||||||
|         bitjs.base(this, arrayBuffer, opt_pathToBitJS); |         bitjs.base(this, arrayBuffer, optPathToBitJS); | ||||||
|     }; |     }; | ||||||
|     bitjs.inherits(bitjs.archive.Unrarrer, bitjs.archive.Unarchiver); |     bitjs.inherits(bitjs.archive.Unrarrer, bitjs.archive.Unarchiver); | ||||||
|     bitjs.archive.Unrarrer.prototype.getScriptFileName = function() { |     bitjs.archive.Unrarrer.prototype.getScriptFileName = function() { | ||||||
| @@ -345,8 +345,8 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|      * @extends {bitjs.archive.Unarchiver} |      * @extends {bitjs.archive.Unarchiver} | ||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.archive.Untarrer = function(arrayBuffer, opt_pathToBitJS) { |     bitjs.archive.Untarrer = function(arrayBuffer, optPathToBitJS) { | ||||||
|         bitjs.base(this, arrayBuffer, opt_pathToBitJS); |         bitjs.base(this, arrayBuffer, optPathToBitJS); | ||||||
|     }; |     }; | ||||||
|     bitjs.inherits(bitjs.archive.Untarrer, bitjs.archive.Unarchiver); |     bitjs.inherits(bitjs.archive.Untarrer, bitjs.archive.Unarchiver); | ||||||
|     bitjs.archive.Untarrer.prototype.getScriptFileName = function() { |     bitjs.archive.Untarrer.prototype.getScriptFileName = function() { | ||||||
| @@ -357,20 +357,19 @@ bitjs.archive = bitjs.archive || {}; | |||||||
|      * Factory method that creates an unarchiver based on the byte signature found |      * Factory method that creates an unarchiver based on the byte signature found | ||||||
|      * in the arrayBuffer. |      * in the arrayBuffer. | ||||||
|      * @param {ArrayBuffer} ab |      * @param {ArrayBuffer} ab | ||||||
|      * @param {string=} opt_pathToBitJS Path to the unarchiver script files. |      * @param {string=} optPathToBitJS Path to the unarchiver script files. | ||||||
|      * @return {bitjs.archive.Unarchiver} |      * @return {bitjs.archive.Unarchiver} | ||||||
|      */ |      */ | ||||||
|     bitjs.archive.GetUnarchiver = function(ab, opt_pathToBitJS) { |     bitjs.archive.GetUnarchiver = function(ab, optPathToBitJS) { | ||||||
|         var unarchiver = null; |         var unarchiver = null; | ||||||
|         var pathToBitJS = opt_pathToBitJS || ''; |         var pathToBitJS = optPathToBitJS || ""; | ||||||
|         var h = new Uint8Array(ab, 0, 10); |         var h = new Uint8Array(ab, 0, 10); | ||||||
|  |  | ||||||
|         if (h[0] == 0x52 && h[1] == 0x61 && h[2] == 0x72 && h[3] == 0x21) { // Rar! |         if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { // Rar! | ||||||
|             unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); |             unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); | ||||||
|         } else if (h[0] == 80 && h[1] == 75) { // PK (Zip) |         } else if (h[0] === 80 && h[1] === 75) { // PK (Zip) | ||||||
|             unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); |             unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); | ||||||
|         } else { // Try with tar |         } else { // Try with tar | ||||||
|             console.log('geter'); |  | ||||||
|             unarchiver = new bitjs.archive.Untarrer(ab, pathToBitJS); |             unarchiver = new bitjs.archive.Untarrer(ab, pathToBitJS); | ||||||
|         } |         } | ||||||
|         return unarchiver; |         return unarchiver; | ||||||
|   | |||||||
| @@ -9,9 +9,12 @@ | |||||||
| /** | /** | ||||||
|  * CRC Implementation. |  * CRC Implementation. | ||||||
|  */ |  */ | ||||||
|  | /* global Uint8Array, Uint32Array, bitjs, DataView */ | ||||||
|  | /* exported MAXWINMASK, UnpackFilter */ | ||||||
|  |  | ||||||
| var CRCTab = new Array(256).fill(0); | var CRCTab = new Array(256).fill(0); | ||||||
|  |  | ||||||
| function InitCRC() { | function initCRC() { | ||||||
|     for (var i = 0; i < 256; ++i) { |     for (var i = 0; i < 256; ++i) { | ||||||
|         var c = i; |         var c = i; | ||||||
|         for (var j = 0; j < 8; ++j) { |         for (var j = 0; j < 8; ++j) { | ||||||
| @@ -30,8 +33,8 @@ function InitCRC() { | |||||||
|  * @return {number} |  * @return {number} | ||||||
|  */ |  */ | ||||||
| function CRC(startCRC, arr) { | function CRC(startCRC, arr) { | ||||||
|     if (CRCTab[1] == 0) { |     if (CRCTab[1] === 0) { | ||||||
|         InitCRC(); |         initCRC(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
| @@ -84,7 +87,7 @@ var MAXWINMASK = (MAXWINSIZE - 1); | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  */ |  */ | ||||||
| var VM_Commands = { | var VmCommands = { | ||||||
|     VM_MOV: 0, |     VM_MOV: 0, | ||||||
|     VM_CMP: 1, |     VM_CMP: 1, | ||||||
|     VM_ADD: 2, |     VM_ADD: 2, | ||||||
| @@ -141,7 +144,7 @@ var VM_Commands = { | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  */ |  */ | ||||||
| var VM_StandardFilters = { | var VmStandardFilters = { | ||||||
|     VMSF_NONE: 0, |     VMSF_NONE: 0, | ||||||
|     VMSF_E8: 1, |     VMSF_E8: 1, | ||||||
|     VMSF_E8E9: 2, |     VMSF_E8E9: 2, | ||||||
| @@ -154,7 +157,7 @@ var VM_StandardFilters = { | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  */ |  */ | ||||||
| var VM_Flags = { | var VmFlags = { | ||||||
|     VM_FC: 1, |     VM_FC: 1, | ||||||
|     VM_FZ: 2, |     VM_FZ: 2, | ||||||
|     VM_FS: 0x80000000, |     VM_FS: 0x80000000, | ||||||
| @@ -162,7 +165,7 @@ var VM_Flags = { | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  */ |  */ | ||||||
| var VM_OpType = { | var VmOpType = { | ||||||
|     VM_OPREG: 0, |     VM_OPREG: 0, | ||||||
|     VM_OPINT: 1, |     VM_OPINT: 1, | ||||||
|     VM_OPREGMEM: 2, |     VM_OPREGMEM: 2, | ||||||
| @@ -186,15 +189,15 @@ function findKeyForValue(obj, val) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getDebugString(obj, val) { | function getDebugString(obj, val) { | ||||||
|     var s = 'Unknown.'; |     var s = "Unknown."; | ||||||
|     if (obj === VM_Commands) { |     if (obj === VmCommands) { | ||||||
|         s = 'VM_Commands.'; |         s = "VmCommands."; | ||||||
|     } else if (obj === VM_StandardFilters) { |     } else if (obj === VmStandardFilters) { | ||||||
|         s = 'VM_StandardFilters.'; |         s = "VmStandardFilters."; | ||||||
|     } else if (obj === VM_Flags) { |     } else if (obj === VmFlags) { | ||||||
|         s = 'VM_OpType.'; |         s = "VmOpType."; | ||||||
|     } else if (obj === VM_OpType) { |     } else if (obj === VmOpType) { | ||||||
|         s = 'VM_OpType.'; |         s = "VmOpType."; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return s + findKeyForValue(obj, val); |     return s + findKeyForValue(obj, val); | ||||||
| @@ -204,8 +207,8 @@ function getDebugString(obj, val) { | |||||||
|  * @struct |  * @struct | ||||||
|  * @constructor |  * @constructor | ||||||
|  */ |  */ | ||||||
| var VM_PreparedOperand = function() { | var VmPreparedOperand = function() { | ||||||
|     /** @type {VM_OpType} */ |     /** @type {VmOpType} */ | ||||||
|     this.Type; |     this.Type; | ||||||
|  |  | ||||||
|     /** @type {number} */ |     /** @type {number} */ | ||||||
| @@ -220,58 +223,58 @@ var VM_PreparedOperand = function() { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /** @return {string} */ | /** @return {string} */ | ||||||
| VM_PreparedOperand.prototype.toString = function() { | VmPreparedOperand.prototype.toString = function() { | ||||||
|     if (this.Type === null) { |     if (this.Type === null) { | ||||||
|         return 'Error: Type was null in VM_PreparedOperand'; |         return "Error: Type was null in VmPreparedOperand"; | ||||||
|     } |     } | ||||||
|     return '{ ' + |     return "{ " + | ||||||
|         'Type: ' + getDebugString(VM_OpType, this.Type) + |         "Type: " + getDebugString(VmOpType, this.Type) + | ||||||
|         ', Data: ' + this.Data + |         ", Data: " + this.Data + | ||||||
|         ', Base: ' + this.Base + |         ", Base: " + this.Base + | ||||||
|         ' }'; |         " }"; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @struct |  * @struct | ||||||
|  * @constructor |  * @constructor | ||||||
|  */ |  */ | ||||||
| var VM_PreparedCommand = function() { | var VmPreparedCommand = function() { | ||||||
|     /** @type {VM_Commands} */ |     /** @type {VmCommands} */ | ||||||
|     this.OpCode; |     this.OpCode; | ||||||
|  |  | ||||||
|     /** @type {boolean} */ |     /** @type {boolean} */ | ||||||
|     this.ByteMode = false; |     this.ByteMode = false; | ||||||
|  |  | ||||||
|     /** @type {VM_PreparedOperand} */ |     /** @type {VmPreparedOperand} */ | ||||||
|     this.Op1 = new VM_PreparedOperand(); |     this.Op1 = new VmPreparedOperand(); | ||||||
|  |  | ||||||
|     /** @type {VM_PreparedOperand} */ |     /** @type {VmPreparedOperand} */ | ||||||
|     this.Op2 = new VM_PreparedOperand(); |     this.Op2 = new VmPreparedOperand(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** @return {string} */ | /** @return {string} */ | ||||||
| VM_PreparedCommand.prototype.toString = function(indent) { | VmPreparedCommand.prototype.toString = function(indent) { | ||||||
|     if (this.OpCode === null) { |     if (this.OpCode === null) { | ||||||
|         return 'Error: OpCode was null in VM_PreparedCommand'; |         return "Error: OpCode was null in VmPreparedCommand"; | ||||||
|     } |     } | ||||||
|     indent = indent || ''; |     indent = indent || ""; | ||||||
|     return indent + '{\n' + |     return indent + "{\n" + | ||||||
|         indent + '  OpCode: ' + getDebugString(VM_Commands, this.OpCode) + ',\n' + |         indent + "  OpCode: " + getDebugString(VmCommands, this.OpCode) + ",\n" + | ||||||
|         indent + '  ByteMode: ' + this.ByteMode + ',\n' + |         indent + "  ByteMode: " + this.ByteMode + ",\n" + | ||||||
|         indent + '  Op1: ' + this.Op1.toString() + ',\n' + |         indent + "  Op1: " + this.Op1.toString() + ",\n" + | ||||||
|         indent + '  Op2: ' + this.Op2.toString() + ',\n' + |         indent + "  Op2: " + this.Op2.toString() + ",\n" + | ||||||
|         indent + '}'; |         indent + "}"; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @struct |  * @struct | ||||||
|  * @constructor |  * @constructor | ||||||
|  */ |  */ | ||||||
| var VM_PreparedProgram = function() { | var VmPreparedProgram = function() { | ||||||
|     /** @type {Array<VM_PreparedCommand>} */ |     /** @type {Array<VmPreparedCommand>} */ | ||||||
|     this.Cmd = []; |     this.Cmd = []; | ||||||
|  |  | ||||||
|     /** @type {Array<VM_PreparedCommand>} */ |     /** @type {Array<VmPreparedCommand>} */ | ||||||
|     this.AltCmd = null; |     this.AltCmd = null; | ||||||
|  |  | ||||||
|     /** @type {Uint8Array} */ |     /** @type {Uint8Array} */ | ||||||
| @@ -291,14 +294,14 @@ var VM_PreparedProgram = function() { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /** @return {string} */ | /** @return {string} */ | ||||||
| VM_PreparedProgram.prototype.toString = function() { | VmPreparedProgram.prototype.toString = function() { | ||||||
|     var s = '{\n  Cmd: [\n'; |     var s = "{\n  Cmd: [\n"; | ||||||
|     for (var i = 0; i < this.Cmd.length; ++i) { |     for (var i = 0; i < this.Cmd.length; ++i) { | ||||||
|         s += this.Cmd[i].toString('  ') + ',\n'; |         s += this.Cmd[i].toString("  ") + ",\n"; | ||||||
|     } |     } | ||||||
|     s += '],\n'; |     s += "],\n"; | ||||||
|     // TODO: Dump GlobalData, StaticData, InitR? |     // TODO: Dump GlobalData, StaticData, InitR? | ||||||
|     s += ' }\n'; |     s += " }\n"; | ||||||
|     return s; |     return s; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -324,8 +327,8 @@ var UnpackFilter = function() { | |||||||
|     /** @type {number} */ |     /** @type {number} */ | ||||||
|     this.ParentFilter = null; |     this.ParentFilter = null; | ||||||
|  |  | ||||||
|     /** @type {VM_PreparedProgram} */ |     /** @type {VmPreparedProgram} */ | ||||||
|     this.Prg = new VM_PreparedProgram(); |     this.Prg = new VmPreparedProgram(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| var VMCF_OP0 = 0; | var VMCF_OP0 = 0; | ||||||
| @@ -338,7 +341,7 @@ var VMCF_PROC = 16; | |||||||
| var VMCF_USEFLAGS = 32; | var VMCF_USEFLAGS = 32; | ||||||
| var VMCF_CHFLAGS = 64; | var VMCF_CHFLAGS = 64; | ||||||
|  |  | ||||||
| var VM_CmdFlags = [ | var VmCmdFlags = [ | ||||||
|     /* VM_MOV   */ |     /* VM_MOV   */ | ||||||
|     VMCF_OP2 | VMCF_BYTEMODE, |     VMCF_OP2 | VMCF_BYTEMODE, | ||||||
|     /* VM_CMP   */ |     /* VM_CMP   */ | ||||||
| @@ -425,7 +428,7 @@ var VM_CmdFlags = [ | |||||||
| /** | /** | ||||||
|  * @param {number} length |  * @param {number} length | ||||||
|  * @param {number} crc |  * @param {number} crc | ||||||
|  * @param {VM_StandardFilters} type |  * @param {VmStandardFilters} type | ||||||
|  * @struct |  * @struct | ||||||
|  * @constructor |  * @constructor | ||||||
|  */ |  */ | ||||||
| @@ -436,7 +439,7 @@ var StandardFilterSignature = function(length, crc, type) { | |||||||
|     /** @type {number} */ |     /** @type {number} */ | ||||||
|     this.CRC = crc; |     this.CRC = crc; | ||||||
|  |  | ||||||
|     /** @type {VM_StandardFilters} */ |     /** @type {VmStandardFilters} */ | ||||||
|     this.Type = type; |     this.Type = type; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -444,13 +447,13 @@ var StandardFilterSignature = function(length, crc, type) { | |||||||
|  * @type {Array<StandardFilterSignature>} |  * @type {Array<StandardFilterSignature>} | ||||||
|  */ |  */ | ||||||
| var StdList = [ | var StdList = [ | ||||||
|     new StandardFilterSignature(53, 0xad576887, VM_StandardFilters.VMSF_E8), |     new StandardFilterSignature(53, 0xad576887, VmStandardFilters.VMSF_E8), | ||||||
|     new StandardFilterSignature(57, 0x3cd7e57e, VM_StandardFilters.VMSF_E8E9), |     new StandardFilterSignature(57, 0x3cd7e57e, VmStandardFilters.VMSF_E8E9), | ||||||
|     new StandardFilterSignature(120, 0x3769893f, VM_StandardFilters.VMSF_ITANIUM), |     new StandardFilterSignature(120, 0x3769893f, VmStandardFilters.VMSF_ITANIUM), | ||||||
|     new StandardFilterSignature(29, 0x0e06077d, VM_StandardFilters.VMSF_DELTA), |     new StandardFilterSignature(29, 0x0e06077d, VmStandardFilters.VMSF_DELTA), | ||||||
|     new StandardFilterSignature(149, 0x1c2c5dc8, VM_StandardFilters.VMSF_RGB), |     new StandardFilterSignature(149, 0x1c2c5dc8, VmStandardFilters.VMSF_RGB), | ||||||
|     new StandardFilterSignature(216, 0xbc85e701, VM_StandardFilters.VMSF_AUDIO), |     new StandardFilterSignature(216, 0xbc85e701, VmStandardFilters.VMSF_AUDIO), | ||||||
|     new StandardFilterSignature(40, 0x46b9c560, VM_StandardFilters.VMSF_UPCASE), |     new StandardFilterSignature(40, 0x46b9c560, VmStandardFilters.VMSF_UPCASE), | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -478,33 +481,34 @@ RarVM.prototype.init = function() { | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param {Uint8Array} code |  * @param {Uint8Array} code | ||||||
|  * @return {VM_StandardFilters} |  * @return {VmStandardFilters} | ||||||
|  */ |  */ | ||||||
| RarVM.prototype.isStandardFilter = function(code) { | RarVM.prototype.isStandardFilter = function(code) { | ||||||
|     var codeCRC = (CRC(0xffffffff, code, code.length) ^ 0xffffffff) >>> 0; |     var codeCRC = (CRC(0xffffffff, code, code.length) ^ 0xffffffff) >>> 0; | ||||||
|     for (var i = 0; i < StdList.length; ++i) { |     for (var i = 0; i < StdList.length; ++i) { | ||||||
|         if (StdList[i].CRC == codeCRC && StdList[i].Length == code.length) |         if (StdList[i].CRC === codeCRC && StdList[i].Length === code.length) { | ||||||
|             return StdList[i].Type; |             return StdList[i].Type; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return VM_StandardFilters.VMSF_NONE; |     return VmStandardFilters.VMSF_NONE; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param {VM_PreparedOperand} op |  * @param {VmPreparedOperand} op | ||||||
|  * @param {boolean} byteMode |  * @param {boolean} byteMode | ||||||
|  * @param {bitjs.io.BitStream} bstream A rtl bit stream. |  * @param {bitjs.io.BitStream} bstream A rtl bit stream. | ||||||
|  */ |  */ | ||||||
| RarVM.prototype.decodeArg = function(op, byteMode, bstream) { | RarVM.prototype.decodeArg = function(op, byteMode, bstream) { | ||||||
|     var data = bstream.peekBits(16); |     var data = bstream.peekBits(16); | ||||||
|     if (data & 0x8000) { |     if (data & 0x8000) { | ||||||
|         op.Type = VM_OpType.VM_OPREG; // Operand is register (R[0]..R[7]) |         op.Type = VmOpType.VM_OPREG; // Operand is register (R[0]..R[7]) | ||||||
|         bstream.readBits(1); // 1 flag bit and... |         bstream.readBits(1); // 1 flag bit and... | ||||||
|         op.Data = bstream.readBits(3); // ... 3 register number bits |         op.Data = bstream.readBits(3); // ... 3 register number bits | ||||||
|         op.Addr = [this.R_[op.Data]] // TODO &R[Op.Data] // Register address |         op.Addr = [this.R_[op.Data]]; // TODO &R[Op.Data] // Register address | ||||||
|     } else { |     } else { | ||||||
|         if ((data & 0xc000) == 0) { |         if ((data & 0xc000) === 0) { | ||||||
|             op.Type = VM_OpType.VM_OPINT; // Operand is integer |             op.Type = VmOpType.VM_OPINT; // Operand is integer | ||||||
|             bstream.readBits(2); // 2 flag bits |             bstream.readBits(2); // 2 flag bits | ||||||
|             if (byteMode) { |             if (byteMode) { | ||||||
|                 op.Data = bstream.readBits(8); // Byte integer. |                 op.Data = bstream.readBits(8); // Byte integer. | ||||||
| @@ -513,8 +517,8 @@ RarVM.prototype.decodeArg = function(op, byteMode, bstream) { | |||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // Operand is data addressed by register data, base address or both. |             // Operand is data addressed by register data, base address or both. | ||||||
|             op.Type = VM_OpType.VM_OPREGMEM; |             op.Type = VmOpType.VM_OPREGMEM; | ||||||
|             if ((data & 0x2000) == 0) { |             if ((data & 0x2000) === 0) { | ||||||
|                 bstream.readBits(3); // 3 flag bits |                 bstream.readBits(3); // 3 flag bits | ||||||
|                 // Base address is zero, just use the address from register. |                 // Base address is zero, just use the address from register. | ||||||
|                 op.Data = bstream.readBits(3); // (Data>>10)&7 |                 op.Data = bstream.readBits(3); // (Data>>10)&7 | ||||||
| @@ -522,7 +526,7 @@ RarVM.prototype.decodeArg = function(op, byteMode, bstream) { | |||||||
|                 op.Base = 0; |                 op.Base = 0; | ||||||
|             } else { |             } else { | ||||||
|                 bstream.readBits(4); // 4 flag bits |                 bstream.readBits(4); // 4 flag bits | ||||||
|                 if ((data & 0x1000) == 0) { |                 if ((data & 0x1000) === 0) { | ||||||
|                     // Use both register and base address. |                     // Use both register and base address. | ||||||
|                     op.Data = bstream.readBits(3); |                     op.Data = bstream.readBits(3); | ||||||
|                     op.Addr = [this.R_[op.Data]]; // TODO &R[op.Data] |                     op.Addr = [this.R_[op.Data]]; // TODO &R[op.Data] | ||||||
| @@ -537,7 +541,7 @@ RarVM.prototype.decodeArg = function(op, byteMode, bstream) { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param {VM_PreparedProgram} prg |  * @param {VmPreparedProgram} prg | ||||||
|  */ |  */ | ||||||
| RarVM.prototype.execute = function(prg) { | RarVM.prototype.execute = function(prg) { | ||||||
|     this.R_.set(prg.InitR); |     this.R_.set(prg.InitR); | ||||||
| @@ -558,7 +562,7 @@ RarVM.prototype.execute = function(prg) { | |||||||
|     var preparedCodes = prg.AltCmd ? prg.AltCmd : prg.Cmd; |     var preparedCodes = prg.AltCmd ? prg.AltCmd : prg.Cmd; | ||||||
|     if (prg.Cmd.length > 0 && !this.executeCode(preparedCodes)) { |     if (prg.Cmd.length > 0 && !this.executeCode(preparedCodes)) { | ||||||
|         // Invalid VM program. Let's replace it with 'return' command. |         // Invalid VM program. Let's replace it with 'return' command. | ||||||
|         preparedCode.OpCode = VM_Commands.VM_RET; |         preparedCodes.OpCode = VmCommands.VM_RET; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     var dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR); |     var dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR); | ||||||
| @@ -573,7 +577,7 @@ RarVM.prototype.execute = function(prg) { | |||||||
|  |  | ||||||
|     var dataSize = Math.min(dataView.getUint32(0x30), |     var dataSize = Math.min(dataView.getUint32(0x30), | ||||||
|         (VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE)); |         (VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE)); | ||||||
|     if (dataSize != 0) { |     if (dataSize !== 0) { | ||||||
|         var len = dataSize + VM_FIXEDGLOBALSIZE; |         var len = dataSize + VM_FIXEDGLOBALSIZE; | ||||||
|         prg.GlobalData = new Uint8Array(len); |         prg.GlobalData = new Uint8Array(len); | ||||||
|         prg.GlobalData.set(mem.subarray(VM_GLOBALMEMADDR, VM_GLOBALMEMADDR + len)); |         prg.GlobalData.set(mem.subarray(VM_GLOBALMEMADDR, VM_GLOBALMEMADDR + len)); | ||||||
| @@ -581,7 +585,7 @@ RarVM.prototype.execute = function(prg) { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param {Array<VM_PreparedCommand>} preparedCodes |  * @param {Array<VmPreparedCommand>} preparedCodes | ||||||
|  * @return {boolean} |  * @return {boolean} | ||||||
|  */ |  */ | ||||||
| RarVM.prototype.executeCode = function(preparedCodes) { | RarVM.prototype.executeCode = function(preparedCodes) { | ||||||
| @@ -591,7 +595,7 @@ RarVM.prototype.executeCode = function(preparedCodes) { | |||||||
|     // when a VM_RET is hit? |     // when a VM_RET is hit? | ||||||
|     while (1) { |     while (1) { | ||||||
|         switch (cmd.OpCode) { |         switch (cmd.OpCode) { | ||||||
|             case VM_Commands.VM_RET: |             case VmCommands.VM_RET: | ||||||
|                 if (this.R_[7] >= VM_MEMSIZE) { |                 if (this.R_[7] >= VM_MEMSIZE) { | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
| @@ -599,12 +603,12 @@ RarVM.prototype.executeCode = function(preparedCodes) { | |||||||
|                 this.R_[7] += 4; |                 this.R_[7] += 4; | ||||||
|                 continue; |                 continue; | ||||||
|  |  | ||||||
|             case VM_Commands.VM_STANDARD: |             case VmCommands.VM_STANDARD: | ||||||
|                 this.executeStandardFilter(cmd.Op1.Data); |                 this.executeStandardFilter(cmd.Op1.Data); | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             default: |             default: | ||||||
|                 console.error('RarVM OpCode not supported: ' + getDebugString(VM_Commands, cmd.OpCode)); |                 console.error("RarVM OpCode not supported: " + getDebugString(VmCommands, cmd.OpCode)); | ||||||
|                 break; |                 break; | ||||||
|         } // switch (cmd.OpCode) |         } // switch (cmd.OpCode) | ||||||
|         codeIndex++; |         codeIndex++; | ||||||
| @@ -617,7 +621,7 @@ RarVM.prototype.executeCode = function(preparedCodes) { | |||||||
|  */ |  */ | ||||||
| RarVM.prototype.executeStandardFilter = function(filterType) { | RarVM.prototype.executeStandardFilter = function(filterType) { | ||||||
|     switch (filterType) { |     switch (filterType) { | ||||||
|         case VM_StandardFilters.VMSF_DELTA: |         case VmStandardFilters.VMSF_DELTA: | ||||||
|             var dataSize = this.R_[4]; |             var dataSize = this.R_[4]; | ||||||
|             var channels = this.R_[0]; |             var channels = this.R_[0]; | ||||||
|             var srcPos = 0; |             var srcPos = 0; | ||||||
| @@ -644,17 +648,19 @@ RarVM.prototype.executeStandardFilter = function(filterType) { | |||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         default: |         default: | ||||||
|             console.error('RarVM Standard Filter not supported: ' + getDebugString(VM_StandardFilters, filterType)); |             console.error("RarVM Standard Filter not supported: " + getDebugString(VmStandardFilters, filterType)); | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param {Uint8Array} code |  * @param {Uint8Array} code | ||||||
|  * @param {VM_PreparedProgram} prg |  * @param {VmPreparedProgram} prg | ||||||
|  */ |  */ | ||||||
| RarVM.prototype.prepare = function(code, prg) { | RarVM.prototype.prepare = function(code, prg) { | ||||||
|     var codeSize = code.length; |     var codeSize = code.length; | ||||||
|  |     var i; | ||||||
|  |     var curCmd; | ||||||
|  |  | ||||||
|     //InitBitInput(); |     //InitBitInput(); | ||||||
|     //memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE)); |     //memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE)); | ||||||
| @@ -662,7 +668,7 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|  |  | ||||||
|     // Calculate the single byte XOR checksum to check validity of VM code. |     // Calculate the single byte XOR checksum to check validity of VM code. | ||||||
|     var xorSum = 0; |     var xorSum = 0; | ||||||
|     for (var i = 1; i < codeSize; ++i) { |     for (i = 1; i < codeSize; ++i) { | ||||||
|         xorSum ^= code[i]; |         xorSum ^= code[i]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -671,20 +677,20 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|     prg.Cmd = []; // TODO: Is this right?  I don't see it being done in rarvm.cpp. |     prg.Cmd = []; // TODO: Is this right?  I don't see it being done in rarvm.cpp. | ||||||
|  |  | ||||||
|     // VM code is valid if equal. |     // VM code is valid if equal. | ||||||
|     if (xorSum == code[0]) { |     if (xorSum === code[0]) { | ||||||
|         var filterType = this.isStandardFilter(code); |         var filterType = this.isStandardFilter(code); | ||||||
|         if (filterType != VM_StandardFilters.VMSF_NONE) { |         if (filterType !== VmStandardFilters.VMSF_NONE) { | ||||||
|             // VM code is found among standard filters. |             // VM code is found among standard filters. | ||||||
|             var curCmd = new VM_PreparedCommand(); |             curCmd = new VmPreparedCommand(); | ||||||
|             prg.Cmd.push(curCmd); |             prg.Cmd.push(curCmd); | ||||||
|  |  | ||||||
|             curCmd.OpCode = VM_Commands.VM_STANDARD; |             curCmd.OpCode = VmCommands.VM_STANDARD; | ||||||
|             curCmd.Op1.Data = filterType; |             curCmd.Op1.Data = filterType; | ||||||
|             // TODO: Addr=&CurCmd->Op1.Data |             // TODO: Addr=&CurCmd->Op1.Data | ||||||
|             curCmd.Op1.Addr = [curCmd.Op1.Data]; |             curCmd.Op1.Addr = [curCmd.Op1.Data]; | ||||||
|             curCmd.Op2.Addr = [null]; // &CurCmd->Op2.Data; |             curCmd.Op2.Addr = [null]; // &CurCmd->Op2.Data; | ||||||
|             curCmd.Op1.Type = VM_OpType.VM_OPNONE; |             curCmd.Op1.Type = VmOpType.VM_OPNONE; | ||||||
|             curCmd.Op2.Type = VM_OpType.VM_OPNONE; |             curCmd.Op2.Type = VmOpType.VM_OPNONE; | ||||||
|             codeSize = 0; |             codeSize = 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -696,7 +702,7 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|         if (dataFlag & 0x8000) { |         if (dataFlag & 0x8000) { | ||||||
|             var dataSize = RarVM.readData(bstream) + 1; |             var dataSize = RarVM.readData(bstream) + 1; | ||||||
|             // TODO: This accesses the byte pointer of the bstream directly.  Is that ok? |             // TODO: This accesses the byte pointer of the bstream directly.  Is that ok? | ||||||
|             for (var i = 0; i < bstream.bytePtr < codeSize && i < dataSize; ++i) { |             for (i = 0; i < bstream.bytePtr < codeSize && i < dataSize; ++i) { | ||||||
|                 // Append a byte to the program's static data. |                 // Append a byte to the program's static data. | ||||||
|                 var newStaticData = new Uint8Array(prg.StaticData.length + 1); |                 var newStaticData = new Uint8Array(prg.StaticData.length + 1); | ||||||
|                 newStaticData.set(prg.StaticData); |                 newStaticData.set(prg.StaticData); | ||||||
| @@ -706,7 +712,7 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         while (bstream.bytePtr < codeSize) { |         while (bstream.bytePtr < codeSize) { | ||||||
|             var curCmd = new VM_PreparedCommand(); |             curCmd = new VmPreparedCommand(); | ||||||
|             prg.Cmd.push(curCmd); // Prg->Cmd.Add(1) |             prg.Cmd.push(curCmd); // Prg->Cmd.Add(1) | ||||||
|             var flag = bstream.peekBits(1); |             var flag = bstream.peekBits(1); | ||||||
|             if (!flag) { // (Data&0x8000)==0 |             if (!flag) { // (Data&0x8000)==0 | ||||||
| @@ -715,22 +721,22 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|                 curCmd.OpCode = (bstream.readBits(6) - 24); |                 curCmd.OpCode = (bstream.readBits(6) - 24); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (VM_CmdFlags[curCmd.OpCode] & VMCF_BYTEMODE) { |             if (VmCmdFlags[curCmd.OpCode] & VMCF_BYTEMODE) { | ||||||
|                 curCmd.ByteMode = (bstream.readBits(1) != 0); |                 curCmd.ByteMode = (bstream.readBits(1) !== 0); | ||||||
|             } else { |             } else { | ||||||
|                 curCmd.ByteMode = 0; |                 curCmd.ByteMode = 0; | ||||||
|             } |             } | ||||||
|             curCmd.Op1.Type = VM_OpType.VM_OPNONE; |             curCmd.Op1.Type = VmOpType.VM_OPNONE; | ||||||
|             curCmd.Op2.Type = VM_OpType.VM_OPNONE; |             curCmd.Op2.Type = VmOpType.VM_OPNONE; | ||||||
|             var opNum = (VM_CmdFlags[curCmd.OpCode] & VMCF_OPMASK); |             var opNum = (VmCmdFlags[curCmd.OpCode] & VMCF_OPMASK); | ||||||
|             curCmd.Op1.Addr = null; |             curCmd.Op1.Addr = null; | ||||||
|             curCmd.Op2.Addr = null; |             curCmd.Op2.Addr = null; | ||||||
|             if (opNum > 0) { |             if (opNum > 0) { | ||||||
|                 this.decodeArg(curCmd.Op1, curCmd.ByteMode, bstream); // reading the first operand |                 this.decodeArg(curCmd.Op1, curCmd.ByteMode, bstream); // reading the first operand | ||||||
|                 if (opNum == 2) { |                 if (opNum === 2) { | ||||||
|                     this.decodeArg(curCmd.Op2, curCmd.ByteMode, bstream); // reading the second operand |                     this.decodeArg(curCmd.Op2, curCmd.ByteMode, bstream); // reading the second operand | ||||||
|                 } else { |                 } else { | ||||||
|                     if (curCmd.Op1.Type == VM_OpType.VM_OPINT && (VM_CmdFlags[curCmd.OpCode] & (VMCF_JUMP | VMCF_PROC))) { |                     if (curCmd.Op1.Type === VmOpType.VM_OPINT && (VmCmdFlags[curCmd.OpCode] & (VMCF_JUMP | VMCF_PROC))) { | ||||||
|                         // Calculating jump distance. |                         // Calculating jump distance. | ||||||
|                         var distance = curCmd.Op1.Data; |                         var distance = curCmd.Op1.Data; | ||||||
|                         if (distance >= 256) { |                         if (distance >= 256) { | ||||||
| @@ -756,26 +762,26 @@ RarVM.prototype.prepare = function(code, prg) { | |||||||
|         } // while ((uint)InAddr<CodeSize) |         } // while ((uint)InAddr<CodeSize) | ||||||
|     } // if (XorSum==Code[0]) |     } // if (XorSum==Code[0]) | ||||||
|  |  | ||||||
|     var curCmd = new VM_PreparedCommand(); |     curCmd = new VmPreparedCommand(); | ||||||
|     prg.Cmd.push(curCmd); |     prg.Cmd.push(curCmd); | ||||||
|     curCmd.OpCode = VM_Commands.VM_RET; |     curCmd.OpCode = VmCommands.VM_RET; | ||||||
|     // TODO: Addr=&CurCmd->Op1.Data |     // TODO: Addr=&CurCmd->Op1.Data | ||||||
|     curCmd.Op1.Addr = [curCmd.Op1.Data]; |     curCmd.Op1.Addr = [curCmd.Op1.Data]; | ||||||
|     curCmd.Op2.Addr = [curCmd.Op2.Data]; |     curCmd.Op2.Addr = [curCmd.Op2.Data]; | ||||||
|     curCmd.Op1.Type = VM_OpType.VM_OPNONE; |     curCmd.Op1.Type = VmOpType.VM_OPNONE; | ||||||
|     curCmd.Op2.Type = VM_OpType.VM_OPNONE; |     curCmd.Op2.Type = VmOpType.VM_OPNONE; | ||||||
|  |  | ||||||
|     // If operand 'Addr' field has not been set by DecodeArg calls above, |     // If operand 'Addr' field has not been set by DecodeArg calls above, | ||||||
|     // let's set it to point to operand 'Data' field. It is necessary for |     // let's set it to point to operand 'Data' field. It is necessary for | ||||||
|     // VM_OPINT type operands (usual integers) or maybe if something was |     // VM_OPINT type operands (usual integers) or maybe if something was | ||||||
|     // not set properly for other operands. 'Addr' field is required |     // not set properly for other operands. 'Addr' field is required | ||||||
|     // for quicker addressing of operand data. |     // for quicker addressing of operand data. | ||||||
|     for (var i = 0; i < prg.Cmd.length; ++i) { |     for (i = 0; i < prg.Cmd.length; ++i) { | ||||||
|         var cmd = prg.Cmd[i]; |         var cmd = prg.Cmd[i]; | ||||||
|         if (cmd.Op1.Addr == null) { |         if (cmd.Op1.Addr === null) { | ||||||
|             cmd.Op1.Addr = [cmd.Op1.Data]; |             cmd.Op1.Addr = [cmd.Op1.Data]; | ||||||
|         } |         } | ||||||
|         if (cmd.Op2.Addr == null) { |         if (cmd.Op2.Addr === null) { | ||||||
|             cmd.Op2.Addr = [cmd.Op2.Data]; |             cmd.Op2.Addr = [cmd.Op2.Data]; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -833,7 +839,7 @@ RarVM.readData = function(bstream) { | |||||||
|  |  | ||||||
|         case 1: // 0x4000 |         case 1: // 0x4000 | ||||||
|             // 0x3c00 => 0011 1100 0000 0000 |             // 0x3c00 => 0011 1100 0000 0000 | ||||||
|             if (bstream.peekBits(4) == 0) { // (Data&0x3c00)==0 |             if (bstream.peekBits(4) === 0) { // (Data&0x3c00)==0 | ||||||
|                 // Skip the 4 zero bits. |                 // Skip the 4 zero bits. | ||||||
|                 bstream.readBits(4); |                 bstream.readBits(4); | ||||||
|                 // Read in the next 8 and pad with 1s to 32 bits. |                 // Read in the next 8 and pad with 1s to 32 bits. | ||||||
| @@ -855,4 +861,4 @@ RarVM.readData = function(bstream) { | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // ============================================================================================== // | // ============================================================================================== // | ||||||
|   | |||||||
| @@ -10,13 +10,14 @@ | |||||||
|  * |  * | ||||||
|  * http://kthoom.googlecode.com/hg/docs/unrar.html |  * http://kthoom.googlecode.com/hg/docs/unrar.html | ||||||
|  */ |  */ | ||||||
| /* global bitjs, importScripts */ | /* global bitjs, importScripts, RarVM, Uint8Array, UnpackFilter */ | ||||||
|  | /* global VM_FIXEDGLOBALSIZE, VM_GLOBALMEMSIZE, MAXWINMASK, VM_GLOBALMEMADDR, MAXWINSIZE */ | ||||||
|  |  | ||||||
| // This file expects to be invoked as a Worker (see onmessage below). | // This file expects to be invoked as a Worker (see onmessage below). | ||||||
| importScripts('../io/bitstream.js'); | importScripts("../io/bitstream.js"); | ||||||
| importScripts('../io/bytebuffer.js'); | importScripts("../io/bytebuffer.js"); | ||||||
| importScripts('archive.js'); | importScripts("archive.js"); | ||||||
| importScripts('rarvm.js'); | importScripts("rarvm.js"); | ||||||
|  |  | ||||||
| // Progress variables. | // Progress variables. | ||||||
| var currentFilename = ""; | var currentFilename = ""; | ||||||
| @@ -296,6 +297,12 @@ var rBuffer; | |||||||
|  */ |  */ | ||||||
| var wBuffer; | var wBuffer; | ||||||
|  |  | ||||||
|  | var lowDistRepCount = 0; | ||||||
|  | var prevLowDist = 0; | ||||||
|  |  | ||||||
|  | var rOldDist = [0, 0, 0, 0]; | ||||||
|  | var lastDist; | ||||||
|  | var lastLength; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * In unpack.cpp, UnpPtr keeps track of what bytes have been unpacked |  * In unpack.cpp, UnpPtr keeps track of what bytes have been unpacked | ||||||
| @@ -401,15 +408,15 @@ function rarDecodeNumber(bstream, dec) { | |||||||
|                 ((bitField < DecodeLen[1]) ? 1 : 2) : |                 ((bitField < DecodeLen[1]) ? 1 : 2) : | ||||||
|                 ((bitField < DecodeLen[3]) ? 3 : 4)) : |                 ((bitField < DecodeLen[3]) ? 3 : 4)) : | ||||||
|             (bitField < DecodeLen[6]) ? |             (bitField < DecodeLen[6]) ? | ||||||
|             ((bitField < DecodeLen[5]) ? 5 : 6) : |                 ((bitField < DecodeLen[5]) ? 5 : 6) : | ||||||
|             ((bitField < DecodeLen[7]) ? 7 : 8)) : |                 ((bitField < DecodeLen[7]) ? 7 : 8)) : | ||||||
|         ((bitField < DecodeLen[12]) ? |         ((bitField < DecodeLen[12]) ? | ||||||
|             ((bitField < DecodeLen[10]) ? |             ((bitField < DecodeLen[10]) ? | ||||||
|                 ((bitField < DecodeLen[9]) ? 9 : 10) : |                 ((bitField < DecodeLen[9]) ? 9 : 10) : | ||||||
|                 ((bitField < DecodeLen[11]) ? 11 : 12)) : |                 ((bitField < DecodeLen[11]) ? 11 : 12)) : | ||||||
|             (bitField < DecodeLen[14]) ? |             (bitField < DecodeLen[14]) ? | ||||||
|             ((bitField < DecodeLen[13]) ? 13 : 14) : |                 ((bitField < DecodeLen[13]) ? 13 : 14) : | ||||||
|             15)); |                 15)); | ||||||
|     bstream.readBits(bits); |     bstream.readBits(bits); | ||||||
|     var N = DecodePos[bits] + ((bitField - DecodeLen[bits - 1]) >>> (16 - bits)); |     var N = DecodePos[bits] + ((bitField - DecodeLen[bits - 1]) >>> (16 - bits)); | ||||||
|  |  | ||||||
| @@ -449,7 +456,7 @@ function rarMakeDecodeTables(BitLength, offset, dec, size) { | |||||||
|         TmpPos[I] = DecodePos[I]; |         TmpPos[I] = DecodePos[I]; | ||||||
|     } |     } | ||||||
|     for (I = 0; I < size; ++I) { |     for (I = 0; I < size; ++I) { | ||||||
|         if (BitLength[I + offset] != 0) { |         if (BitLength[I + offset] !== 0) { | ||||||
|             DecodeNum[TmpPos[BitLength[offset + I] & 0xF]++] = I; |             DecodeNum[TmpPos[BitLength[offset + I] & 0xF]++] = I; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -524,7 +531,7 @@ function unpack20(bstream) { //, Solid) { | |||||||
|             if (Distance >= 0x101) { |             if (Distance >= 0x101) { | ||||||
|                 Length++; |                 Length++; | ||||||
|                 if (Distance >= 0x2000) { |                 if (Distance >= 0x2000) { | ||||||
|                     Length++ |                     Length++; | ||||||
|                     if (Distance >= 0x40000) { |                     if (Distance >= 0x40000) { | ||||||
|                         Length++; |                         Length++; | ||||||
|                     } |                     } | ||||||
| @@ -611,13 +618,6 @@ function rarReadTables20(bstream) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| var lowDistRepCount = 0; |  | ||||||
| var prevLowDist = 0; |  | ||||||
|  |  | ||||||
| var rOldDist = [0, 0, 0, 0]; |  | ||||||
| var lastDist; |  | ||||||
| var lastLength; |  | ||||||
|  |  | ||||||
| // ============================================================================================== // | // ============================================================================================== // | ||||||
|  |  | ||||||
| // Unpack code specific to RarVM | // Unpack code specific to RarVM | ||||||
| @@ -644,7 +644,7 @@ var OldFilterLengths = []; | |||||||
|  |  | ||||||
| var LastFilter = 0; | var LastFilter = 0; | ||||||
|  |  | ||||||
| function InitFilters() { | function initFilters() { | ||||||
|     OldFilterLengths = []; |     OldFilterLengths = []; | ||||||
|     LastFilter = 0; |     LastFilter = 0; | ||||||
|     Filters = []; |     Filters = []; | ||||||
| @@ -658,13 +658,14 @@ function InitFilters() { | |||||||
|  */ |  */ | ||||||
| function rarAddVMCode(firstByte, vmCode) { | function rarAddVMCode(firstByte, vmCode) { | ||||||
|     VM.init(); |     VM.init(); | ||||||
|  |     var i; | ||||||
|     var bstream = new bitjs.io.BitStream(vmCode.buffer, true /* rtl */ ); |     var bstream = new bitjs.io.BitStream(vmCode.buffer, true /* rtl */ ); | ||||||
|  |  | ||||||
|     var filtPos; |     var filtPos; | ||||||
|     if (firstByte & 0x80) { |     if (firstByte & 0x80) { | ||||||
|         filtPos = RarVM.readData(bstream); |         filtPos = RarVM.readData(bstream); | ||||||
|         if (filtPos == 0) { |         if (filtPos === 0) { | ||||||
|             InitFilters(); |             initFilters(); | ||||||
|         } else { |         } else { | ||||||
|             filtPos--; |             filtPos--; | ||||||
|         } |         } | ||||||
| @@ -677,7 +678,7 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     LastFilter = filtPos; |     LastFilter = filtPos; | ||||||
|     var newFilter = (filtPos == Filters.length); |     var newFilter = (filtPos === Filters.length); | ||||||
|  |  | ||||||
|     // new filter for PrgStack |     // new filter for PrgStack | ||||||
|     var stackFilter = new UnpackFilter(); |     var stackFilter = new UnpackFilter(); | ||||||
| @@ -701,10 +702,10 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     var emptyCount = 0; |     var emptyCount = 0; | ||||||
|     for (var i = 0; i < PrgStack.length; ++i) { |     for (i = 0; i < PrgStack.length; ++i) { | ||||||
|         PrgStack[i - emptyCount] = PrgStack[i]; |         PrgStack[i - emptyCount] = PrgStack[i]; | ||||||
|  |  | ||||||
|         if (PrgStack[i] == null) { |         if (PrgStack[i] === null) { | ||||||
|             emptyCount++; |             emptyCount++; | ||||||
|         } |         } | ||||||
|         if (emptyCount > 0) { |         if (emptyCount > 0) { | ||||||
| @@ -712,7 +713,7 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (emptyCount == 0) { |     if (emptyCount === 0) { | ||||||
|         PrgStack.push(null); //PrgStack.Add(1); |         PrgStack.push(null); //PrgStack.Add(1); | ||||||
|         emptyCount = 1; |         emptyCount = 1; | ||||||
|     } |     } | ||||||
| @@ -734,12 +735,12 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|             OldFilterLengths[filtPos] : |             OldFilterLengths[filtPos] : | ||||||
|             0; |             0; | ||||||
|     } |     } | ||||||
|     stackFilter.NextWindow = (wBuffer.ptr != rBuffer.ptr) && |     stackFilter.NextWindow = (wBuffer.ptr !== rBuffer.ptr) && | ||||||
|         (((wBuffer.ptr - rBuffer.ptr) & MAXWINMASK) <= blockStart); |         (((wBuffer.ptr - rBuffer.ptr) & MAXWINMASK) <= blockStart); | ||||||
|  |  | ||||||
|     OldFilterLengths[filtPos] = stackFilter.BlockLength; |     OldFilterLengths[filtPos] = stackFilter.BlockLength; | ||||||
|  |  | ||||||
|     for (var i = 0; i < 7; ++i) { |     for (i = 0; i < 7; ++i) { | ||||||
|         stackFilter.Prg.InitR[i] = 0; |         stackFilter.Prg.InitR[i] = 0; | ||||||
|     } |     } | ||||||
|     stackFilter.Prg.InitR[3] = VM_GLOBALMEMADDR; |     stackFilter.Prg.InitR[3] = VM_GLOBALMEMADDR; | ||||||
| @@ -749,7 +750,7 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|     // set registers to optional parameters if any |     // set registers to optional parameters if any | ||||||
|     if (firstByte & 0x10) { |     if (firstByte & 0x10) { | ||||||
|         var initMask = bstream.readBits(7); |         var initMask = bstream.readBits(7); | ||||||
|         for (var i = 0; i < 7; ++i) { |         for (i = 0; i < 7; ++i) { | ||||||
|             if (initMask & (1 << i)) { |             if (initMask & (1 << i)) { | ||||||
|                 stackFilter.Prg.InitR[i] = RarVM.readData(bstream); |                 stackFilter.Prg.InitR[i] = RarVM.readData(bstream); | ||||||
|             } |             } | ||||||
| @@ -758,11 +759,11 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|  |  | ||||||
|     if (newFilter) { |     if (newFilter) { | ||||||
|         var vmCodeSize = RarVM.readData(bstream); |         var vmCodeSize = RarVM.readData(bstream); | ||||||
|         if (vmCodeSize >= 0x10000 || vmCodeSize == 0) { |         if (vmCodeSize >= 0x10000 || vmCodeSize === 0) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         var vmCode = new Uint8Array(vmCodeSize); |         vmCode = new Uint8Array(vmCodeSize); | ||||||
|         for (var i = 0; i < vmCodeSize; ++i) { |         for (i = 0; i < vmCodeSize; ++i) { | ||||||
|             //if (Inp.Overflow(3)) |             //if (Inp.Overflow(3)) | ||||||
|             //  return(false); |             //  return(false); | ||||||
|             vmCode[i] = bstream.readBits(8); |             vmCode[i] = bstream.readBits(8); | ||||||
| @@ -775,7 +776,7 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|     var staticDataSize = filter.Prg.StaticData.length; |     var staticDataSize = filter.Prg.StaticData.length; | ||||||
|     if (staticDataSize > 0 && staticDataSize < VM_GLOBALMEMSIZE) { |     if (staticDataSize > 0 && staticDataSize < VM_GLOBALMEMSIZE) { | ||||||
|         // read statically defined data contained in DB commands |         // read statically defined data contained in DB commands | ||||||
|         for (var i = 0; i < staticDataSize; ++i) { |         for (i = 0; i < staticDataSize; ++i) { | ||||||
|             stackFilter.Prg.StaticData[i] = filter.Prg.StaticData[i]; |             stackFilter.Prg.StaticData[i] = filter.Prg.StaticData[i]; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -785,14 +786,14 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     var globalData = stackFilter.Prg.GlobalData; |     var globalData = stackFilter.Prg.GlobalData; | ||||||
|     for (var i = 0; i < 7; ++i) { |     for (i = 0; i < 7; ++i) { | ||||||
|         VM.setLowEndianValue(globalData, stackFilter.Prg.InitR[i], i * 4); |         VM.setLowEndianValue(globalData, stackFilter.Prg.InitR[i], i * 4); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     VM.setLowEndianValue(globalData, stackFilter.BlockLength, 0x1c); |     VM.setLowEndianValue(globalData, stackFilter.BlockLength, 0x1c); | ||||||
|     VM.setLowEndianValue(globalData, 0, 0x20); |     VM.setLowEndianValue(globalData, 0, 0x20); | ||||||
|     VM.setLowEndianValue(globalData, stackFilter.ExecCount, 0x2c); |     VM.setLowEndianValue(globalData, stackFilter.ExecCount, 0x2c); | ||||||
|     for (var i = 0; i < 16; ++i) { |     for (i = 0; i < 16; ++i) { | ||||||
|         globalData[0x30 + i] = 0; |         globalData[0x30 + i] = 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -816,7 +817,7 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
|             globalData = newGlobalData; |             globalData = newGlobalData; | ||||||
|         } |         } | ||||||
|         //byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE]; |         //byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE]; | ||||||
|         for (var i = 0; i < dataSize; ++i) { |         for (i = 0; i < dataSize; ++i) { | ||||||
|             //if (Inp.Overflow(3)) |             //if (Inp.Overflow(3)) | ||||||
|             //  return(false); |             //  return(false); | ||||||
|             globalData[VM_FIXEDGLOBALSIZE + i] = bstream.readBits(8); |             globalData[VM_FIXEDGLOBALSIZE + i] = bstream.readBits(8); | ||||||
| @@ -833,9 +834,9 @@ function rarAddVMCode(firstByte, vmCode) { | |||||||
| function rarReadVMCode(bstream) { | function rarReadVMCode(bstream) { | ||||||
|     var firstByte = bstream.readBits(8); |     var firstByte = bstream.readBits(8); | ||||||
|     var length = (firstByte & 7) + 1; |     var length = (firstByte & 7) + 1; | ||||||
|     if (length == 7) { |     if (length === 7) { | ||||||
|         length = bstream.readBits(8) + 7; |         length = bstream.readBits(8) + 7; | ||||||
|     } else if (length == 8) { |     } else if (length === 8) { | ||||||
|         length = bstream.readBits(16); |         length = bstream.readBits(16); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -845,7 +846,7 @@ function rarReadVMCode(bstream) { | |||||||
|         // Do something here with checking readbuf. |         // Do something here with checking readbuf. | ||||||
|         vmCode[i] = bstream.readBits(8); |         vmCode[i] = bstream.readBits(8); | ||||||
|     } |     } | ||||||
|     return RarAddVMCode(firstByte, vmCode); |     return rarAddVMCode(firstByte, vmCode); | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -946,7 +947,7 @@ function unpack29(bstream) { | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         if (num === 258) { |         if (num === 258) { | ||||||
|             if (lastLength != 0) { |             if (lastLength !== 0) { | ||||||
|                 rarCopyString(lastLength, lastDist); |                 rarCopyString(lastLength, lastDist); | ||||||
|             } |             } | ||||||
|             continue; |             continue; | ||||||
| @@ -955,8 +956,8 @@ function unpack29(bstream) { | |||||||
|             var DistNum = num - 259; |             var DistNum = num - 259; | ||||||
|             Distance = rOldDist[DistNum]; |             Distance = rOldDist[DistNum]; | ||||||
|  |  | ||||||
|             for (var I = DistNum; I > 0; I--) { |             for (var I2 = DistNum; I2 > 0; I2--) { | ||||||
|                 rOldDist[I] = rOldDist[I - 1]; |                 rOldDist[I2] = rOldDist[I2 - 1]; | ||||||
|             } |             } | ||||||
|             rOldDist[0] = Distance; |             rOldDist[0] = Distance; | ||||||
|  |  | ||||||
| @@ -990,10 +991,11 @@ function unpack29(bstream) { | |||||||
|  */ |  */ | ||||||
| function rarWriteBuf() { | function rarWriteBuf() { | ||||||
|     var writeSize = (rBuffer.ptr & MAXWINMASK); |     var writeSize = (rBuffer.ptr & MAXWINMASK); | ||||||
|  |     var j; | ||||||
|  |     var flt; | ||||||
|     for (var i = 0; i < PrgStack.length; ++i) { |     for (var i = 0; i < PrgStack.length; ++i) { | ||||||
|         var flt = PrgStack[i]; |         flt = PrgStack[i]; | ||||||
|         if (flt == null) { |         if (flt === null) { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -1004,17 +1006,18 @@ function rarWriteBuf() { | |||||||
|  |  | ||||||
|         var blockStart = flt.BlockStart; |         var blockStart = flt.BlockStart; | ||||||
|         var blockLength = flt.BlockLength; |         var blockLength = flt.BlockLength; | ||||||
|  |         var parentPrg; | ||||||
|  |  | ||||||
|         // WrittenBorder = wBuffer.ptr |         // WrittenBorder = wBuffer.ptr | ||||||
|         if (((blockStart - wBuffer.ptr) & MAXWINMASK) < writeSize) { |         if (((blockStart - wBuffer.ptr) & MAXWINMASK) < writeSize) { | ||||||
|             if (wBuffer.ptr != blockStart) { |             if (wBuffer.ptr !== blockStart) { | ||||||
|                 // Copy blockStart bytes from rBuffer into wBuffer. |                 // Copy blockStart bytes from rBuffer into wBuffer. | ||||||
|                 rarWriteArea(wBuffer.ptr, blockStart); |                 rarWriteArea(wBuffer.ptr, blockStart); | ||||||
|                 writeSize = (rBuffer.ptr - wBuffer.ptr) & MAXWINMASK; |                 writeSize = (rBuffer.ptr - wBuffer.ptr) & MAXWINMASK; | ||||||
|             } |             } | ||||||
|             if (blockLength <= writeSize) { |             if (blockLength <= writeSize) { | ||||||
|                 var blockEnd = (blockStart + blockLength) & MAXWINMASK; |                 var blockEnd = (blockStart + blockLength) & MAXWINMASK; | ||||||
|                 if (blockStart < blockEnd || blockEnd == 0) { |                 if (blockStart < blockEnd || blockEnd === 0) { | ||||||
|                     VM.setMemory(0, rBuffer.data.subarray(blockStart, blockStart + blockLength), blockLength); |                     VM.setMemory(0, rBuffer.data.subarray(blockStart, blockStart + blockLength), blockLength); | ||||||
|                 } else { |                 } else { | ||||||
|                     var firstPartLength = MAXWINSIZE - blockStart; |                     var firstPartLength = MAXWINSIZE - blockStart; | ||||||
| @@ -1022,7 +1025,7 @@ function rarWriteBuf() { | |||||||
|                     VM.setMemory(firstPartLength, rBuffer.data, blockEnd); |                     VM.setMemory(firstPartLength, rBuffer.data, blockEnd); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 var parentPrg = Filters[flt.ParentFilter].Prg; |                 parentPrg = Filters[flt.ParentFilter].Prg; | ||||||
|                 var prg = flt.Prg; |                 var prg = flt.Prg; | ||||||
|  |  | ||||||
|                 if (parentPrg.GlobalData.length > VM_FIXEDGLOBALSIZE) { |                 if (parentPrg.GlobalData.length > VM_FIXEDGLOBALSIZE) { | ||||||
| @@ -1031,10 +1034,11 @@ function rarWriteBuf() { | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 rarExecuteCode(prg); |                 rarExecuteCode(prg); | ||||||
|  |                 var globalDataLen; | ||||||
|  |  | ||||||
|                 if (prg.GlobalData.length > VM_FIXEDGLOBALSIZE) { |                 if (prg.GlobalData.length > VM_FIXEDGLOBALSIZE) { | ||||||
|                     // Save global data for next script execution. |                     // Save global data for next script execution. | ||||||
|                     var globalDataLen = prg.GlobalData.length; |                     globalDataLen = prg.GlobalData.length; | ||||||
|                     if (parentPrg.GlobalData.length < globalDataLen) { |                     if (parentPrg.GlobalData.length < globalDataLen) { | ||||||
|                         parentPrg.GlobalData = new Uint8Array(globalDataLen); |                         parentPrg.GlobalData = new Uint8Array(globalDataLen); | ||||||
|                     } |                     } | ||||||
| @@ -1050,8 +1054,8 @@ function rarWriteBuf() { | |||||||
|                 PrgStack[i] = null; |                 PrgStack[i] = null; | ||||||
|                 while (i + 1 < PrgStack.length) { |                 while (i + 1 < PrgStack.length) { | ||||||
|                     var nextFilter = PrgStack[i + 1]; |                     var nextFilter = PrgStack[i + 1]; | ||||||
|                     if (nextFilter == null || nextFilter.BlockStart != blockStart || |                     if (nextFilter === null || nextFilter.BlockStart !== blockStart || | ||||||
|                         nextFilter.BlockLength != filteredData.length || nextFilter.NextWindow) { |                         nextFilter.BlockLength !== filteredData.length || nextFilter.NextWindow) { | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
| @@ -1059,10 +1063,10 @@ function rarWriteBuf() { | |||||||
|  |  | ||||||
|                     VM.setMemory(0, filteredData, filteredData.length); |                     VM.setMemory(0, filteredData, filteredData.length); | ||||||
|  |  | ||||||
|                     var parentPrg = Filters[nextFilter.ParentFilter].Prg; |                     parentPrg = Filters[nextFilter.ParentFilter].Prg; | ||||||
|                     var nextPrg = nextFilter.Prg; |                     var nextPrg = nextFilter.Prg; | ||||||
|  |  | ||||||
|                     var globalDataLen = parentPrg.GlobalData.length; |                     globalDataLen = parentPrg.GlobalData.length; | ||||||
|                     if (globalDataLen > VM_FIXEDGLOBALSIZE) { |                     if (globalDataLen > VM_FIXEDGLOBALSIZE) { | ||||||
|                         // Copy global data from previous script execution if any. |                         // Copy global data from previous script execution if any. | ||||||
|                         nextPrg.GlobalData = new Uint8Array(globalDataLen); |                         nextPrg.GlobalData = new Uint8Array(globalDataLen); | ||||||
| @@ -1073,7 +1077,7 @@ function rarWriteBuf() { | |||||||
|  |  | ||||||
|                     if (nextPrg.GlobalData.length > VM_GLOBALMEMSIZE) { |                     if (nextPrg.GlobalData.length > VM_GLOBALMEMSIZE) { | ||||||
|                         // Save global data for next script execution. |                         // Save global data for next script execution. | ||||||
|                         var globalDataLen = nextPrg.GlobalData.length; |                         globalDataLen = nextPrg.GlobalData.length; | ||||||
|                         if (parentPrg.GlobalData.length < globalDataLen) { |                         if (parentPrg.GlobalData.length < globalDataLen) { | ||||||
|                             parentPrg.GlobalData = new Uint8Array(globalDataLen); |                             parentPrg.GlobalData = new Uint8Array(globalDataLen); | ||||||
|                         } |                         } | ||||||
| @@ -1089,15 +1093,14 @@ function rarWriteBuf() { | |||||||
|                     PrgStack[i] = null; |                     PrgStack[i] = null; | ||||||
|                 } // while (i + 1 < PrgStack.length) |                 } // while (i + 1 < PrgStack.length) | ||||||
|  |  | ||||||
|                 for (var j = 0; j < filteredData.length; ++j) { |                 for (j = 0; j < filteredData.length; ++j) { | ||||||
|                     wBuffer.insertByte(filteredData[j]); |                     wBuffer.insertByte(filteredData[j]); | ||||||
|                 } |                 } | ||||||
|                 writeSize = (rBuffer.ptr - wBuffer.ptr) & MAXWINMASK; |                 writeSize = (rBuffer.ptr - wBuffer.ptr) & MAXWINMASK; | ||||||
|             } // if (blockLength <= writeSize) |             } else { // if (blockLength <= writeSize) | ||||||
|             else { |                 for (j = i; j < PrgStack.length; ++j) { | ||||||
|                 for (var j = i; j < PrgStack.length; ++j) { |                     flt = PrgStack[j]; | ||||||
|                     var flt = PrgStack[j]; |                     if (flt !== null && flt.NextWindow) { | ||||||
|                     if (flt != null && flt.NextWindow) { |  | ||||||
|                         flt.NextWindow = false; |                         flt.NextWindow = false; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -1121,7 +1124,7 @@ function rarWriteBuf() { | |||||||
|  */ |  */ | ||||||
| function rarWriteArea(startPtr, endPtr) { | function rarWriteArea(startPtr, endPtr) { | ||||||
|     if (endPtr < startPtr) { |     if (endPtr < startPtr) { | ||||||
|         console.error('endPtr < startPtr, endPtr=' + endPtr + ', startPtr=' + startPtr); |         console.error("endPtr < startPtr, endPtr=" + endPtr + ", startPtr=" + startPtr); | ||||||
|         //    rarWriteData(startPtr, -(int)StartPtr & MAXWINMASK); |         //    rarWriteData(startPtr, -(int)StartPtr & MAXWINMASK); | ||||||
|         //    RarWriteData(0, endPtr); |         //    RarWriteData(0, endPtr); | ||||||
|         return; |         return; | ||||||
| @@ -1173,7 +1176,7 @@ function rarReadEndOfBlock(bstream) { | |||||||
|         NewTable = !!bstream.readBits(1); |         NewTable = !!bstream.readBits(1); | ||||||
|     } |     } | ||||||
|     //tablesRead = !NewTable; |     //tablesRead = !NewTable; | ||||||
|     return !(NewFile || NewTable && !rarReadTables(bstream)); |     return !(NewFile || (NewTable && !rarReadTables(bstream))); | ||||||
| } | } | ||||||
|  |  | ||||||
| function rarInsertLastMatch(length, distance) { | function rarInsertLastMatch(length, distance) { | ||||||
| @@ -1220,8 +1223,8 @@ function rarCopyString(length, distance) { | |||||||
| function unpack(v) { | function unpack(v) { | ||||||
|     // TODO: implement what happens when unpVer is < 15 |     // TODO: implement what happens when unpVer is < 15 | ||||||
|     var Ver = v.header.unpVer <= 15 ? 15 : v.header.unpVer; |     var Ver = v.header.unpVer <= 15 ? 15 : v.header.unpVer; | ||||||
|     var Solid = v.header.LHD_SOLID; |     // var Solid = v.header.LHD_SOLID; | ||||||
|     var bstream = new bitjs.io.BitStream(v.fileData.buffer, true /* rtl */ , v.fileData.byteOffset, v.fileData.byteLength); |     var bstream = new bitjs.io.BitStream(v.fileData.buffer, true /* rtl */, v.fileData.byteOffset, v.fileData.byteLength); | ||||||
|  |  | ||||||
|     rBuffer = new bitjs.io.ByteBuffer(v.header.unpackedSize); |     rBuffer = new bitjs.io.ByteBuffer(v.header.unpackedSize); | ||||||
|  |  | ||||||
| @@ -1252,7 +1255,7 @@ var RarLocalFile = function(bstream) { | |||||||
|     this.header = new RarVolumeHeader(bstream); |     this.header = new RarVolumeHeader(bstream); | ||||||
|     this.filename = this.header.filename; |     this.filename = this.header.filename; | ||||||
|  |  | ||||||
|     if (this.header.headType != FILE_HEAD && this.header.headType != ENDARC_HEAD) { |     if (this.header.headType !== FILE_HEAD && this.header.headType !== ENDARC_HEAD) { | ||||||
|         this.isValid = false; |         this.isValid = false; | ||||||
|         info("Error! RAR Volume did not include a FILE_HEAD header "); |         info("Error! RAR Volume did not include a FILE_HEAD header "); | ||||||
|     } else { |     } else { | ||||||
| @@ -1306,7 +1309,7 @@ var unrar = function(arrayBuffer) { | |||||||
|         info("Found RAR signature"); |         info("Found RAR signature"); | ||||||
|  |  | ||||||
|         var mhead = new RarVolumeHeader(bstream); |         var mhead = new RarVolumeHeader(bstream); | ||||||
|         if (mhead.headType != MAIN_HEAD) { |         if (mhead.headType !== MAIN_HEAD) { | ||||||
|             info("Error! RAR did not include a MAIN_HEAD header"); |             info("Error! RAR did not include a MAIN_HEAD header"); | ||||||
|         } else { |         } else { | ||||||
|             var localFiles = []; |             var localFiles = []; | ||||||
|   | |||||||
| @@ -10,9 +10,11 @@ | |||||||
|  * TAR format: http://www.gnu.org/software/automake/manual/tar/Standard.html |  * TAR format: http://www.gnu.org/software/automake/manual/tar/Standard.html | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /* global bitjs, importScripts, Uint8Array */ | ||||||
|  |  | ||||||
| // This file expects to be invoked as a Worker (see onmessage below). | // This file expects to be invoked as a Worker (see onmessage below). | ||||||
| importScripts('../io/bytestream.js'); | importScripts("../io/bytestream.js"); | ||||||
| importScripts('archive.js'); | importScripts("archive.js"); | ||||||
|  |  | ||||||
| // Progress variables. | // Progress variables. | ||||||
| var currentFilename = ""; | var currentFilename = ""; | ||||||
| @@ -21,6 +23,7 @@ var currentBytesUnarchivedInFile = 0; | |||||||
| var currentBytesUnarchived = 0; | var currentBytesUnarchived = 0; | ||||||
| var totalUncompressedBytesInArchive = 0; | var totalUncompressedBytesInArchive = 0; | ||||||
| var totalFilesInArchive = 0; | var totalFilesInArchive = 0; | ||||||
|  | var allLocalFiles = []; | ||||||
|  |  | ||||||
| // Helper functions. | // Helper functions. | ||||||
| var info = function(str) { | var info = function(str) { | ||||||
| @@ -44,8 +47,8 @@ var postProgress = function() { | |||||||
|         currentBytesUnarchivedInFile, |         currentBytesUnarchivedInFile, | ||||||
|         currentBytesUnarchived, |         currentBytesUnarchived, | ||||||
|         totalUncompressedBytesInArchive, |         totalUncompressedBytesInArchive, | ||||||
|         totalFilesInArchive, |         totalFilesInArchive | ||||||
| 	)); |     )); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // takes a ByteStream and parses out the local file information | // takes a ByteStream and parses out the local file information | ||||||
| @@ -66,7 +69,7 @@ var TarLocalFile = function(bstream) { | |||||||
|     this.linkname = readCleanString(bstream, 100); |     this.linkname = readCleanString(bstream, 100); | ||||||
|     this.maybeMagic = readCleanString(bstream, 6); |     this.maybeMagic = readCleanString(bstream, 6); | ||||||
|  |  | ||||||
|     if (this.maybeMagic == "ustar") { |     if (this.maybeMagic === "ustar") { | ||||||
|         this.version = readCleanString(bstream, 2); |         this.version = readCleanString(bstream, 2); | ||||||
|         this.uname = readCleanString(bstream, 32); |         this.uname = readCleanString(bstream, 32); | ||||||
|         this.gname = readCleanString(bstream, 32); |         this.gname = readCleanString(bstream, 32); | ||||||
| @@ -103,14 +106,14 @@ var TarLocalFile = function(bstream) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Round up to 512-byte blocks. |         // Round up to 512-byte blocks. | ||||||
|         var remaining = 512 - bytesRead % 512; |         var remaining = 512 - (bytesRead % 512); | ||||||
|         if (remaining > 0 && remaining < 512) { |         if (remaining > 0 && remaining < 512) { | ||||||
|             bstream.readBytes(remaining); |             bstream.readBytes(remaining); | ||||||
|         } |         } | ||||||
|     } else if (this.typeflag == 5) { |     } else if (this.typeflag == 5) { | ||||||
|         info("  This is a directory."); |         info("  This is a directory."); | ||||||
|     } |     } | ||||||
| } | }; | ||||||
|  |  | ||||||
| var untar = function(arrayBuffer) { | var untar = function(arrayBuffer) { | ||||||
|     postMessage(new bitjs.archive.UnarchiveStartEvent()); |     postMessage(new bitjs.archive.UnarchiveStartEvent()); | ||||||
| @@ -125,7 +128,7 @@ var untar = function(arrayBuffer) { | |||||||
|     var bstream = new bitjs.io.ByteStream(arrayBuffer); |     var bstream = new bitjs.io.ByteStream(arrayBuffer); | ||||||
|     postProgress(); |     postProgress(); | ||||||
|     // While we don't encounter an empty block, keep making TarLocalFiles. |     // While we don't encounter an empty block, keep making TarLocalFiles. | ||||||
|     while (bstream.peekNumber(4) != 0) { |     while (bstream.peekNumber(4) !== 0) { | ||||||
|         var oneLocalFile = new TarLocalFile(bstream); |         var oneLocalFile = new TarLocalFile(bstream); | ||||||
|         if (oneLocalFile && oneLocalFile.isValid) { |         if (oneLocalFile && oneLocalFile.isValid) { | ||||||
|             // If we make it to this point and haven't thrown an error, we have successfully |             // If we make it to this point and haven't thrown an error, we have successfully | ||||||
| @@ -159,8 +162,8 @@ onmessage = function(event) { | |||||||
|             // Overrun the buffer. |             // Overrun the buffer. | ||||||
|             // unarchiveState = UnarchiveState.WAITING; |             // unarchiveState = UnarchiveState.WAITING; | ||||||
|         } else { |         } else { | ||||||
|             console.error("Found an error while untarring"); |             err("Found an error while untarring"); | ||||||
|             console.log(e); |             err(e); | ||||||
|             throw e; |             throw e; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -14,10 +14,10 @@ | |||||||
| /* global bitjs, importScripts, Uint8Array*/ | /* global bitjs, importScripts, Uint8Array*/ | ||||||
|  |  | ||||||
| // This file expects to be invoked as a Worker (see onmessage below). | // This file expects to be invoked as a Worker (see onmessage below). | ||||||
| importScripts('../io/bitstream.js'); | importScripts("../io/bitstream.js"); | ||||||
| importScripts('../io/bytebuffer.js'); | importScripts("../io/bytebuffer.js"); | ||||||
| importScripts('../io/bytestream.js'); | importScripts("../io/bytestream.js"); | ||||||
| importScripts('archive.js'); | importScripts("archive.js"); | ||||||
|  |  | ||||||
| // Progress variables. | // Progress variables. | ||||||
| var currentFilename = ""; | var currentFilename = ""; | ||||||
| @@ -118,13 +118,11 @@ ZipLocalFile.prototype.unzip = function() { | |||||||
|         currentBytesUnarchivedInFile = this.compressedSize; |         currentBytesUnarchivedInFile = this.compressedSize; | ||||||
|         currentBytesUnarchived += this.compressedSize; |         currentBytesUnarchived += this.compressedSize; | ||||||
|         this.fileData = zeroCompression(this.fileData, this.uncompressedSize); |         this.fileData = zeroCompression(this.fileData, this.uncompressedSize); | ||||||
|     } |     } else if (this.compressionMethod === 8) { | ||||||
|     // version == 20, compression method == 8 (DEFLATE) |         // version == 20, compression method == 8 (DEFLATE) | ||||||
|     else if (this.compressionMethod === 8) { |  | ||||||
|         info("ZIP v2.0, DEFLATE: " + this.filename + " (" + this.compressedSize + " bytes)"); |         info("ZIP v2.0, DEFLATE: " + this.filename + " (" + this.compressedSize + " bytes)"); | ||||||
|         this.fileData = inflate(this.fileData, this.uncompressedSize); |         this.fileData = inflate(this.fileData, this.uncompressedSize); | ||||||
|     } |     } else { | ||||||
|     else { |  | ||||||
|         err("UNSUPPORTED VERSION/FORMAT: ZIP v" + this.version + ", compression method=" + this.compressionMethod + ": " + this.filename + " (" + this.compressedSize + " bytes)"); |         err("UNSUPPORTED VERSION/FORMAT: ZIP v" + this.version + ", compression method=" + this.compressionMethod + ": " + this.filename + " (" + this.compressedSize + " bytes)"); | ||||||
|         this.fileData = null; |         this.fileData = null; | ||||||
|     } |     } | ||||||
| @@ -497,13 +495,11 @@ function inflateBlockData(bstream, hcLiteralTable, hcDistanceTable, buffer) { | |||||||
|             // copy literal byte to output |             // copy literal byte to output | ||||||
|             buffer.insertByte(symbol); |             buffer.insertByte(symbol); | ||||||
|             blockSize++; |             blockSize++; | ||||||
|         } |         } else { | ||||||
|         else { |  | ||||||
|             // end of block reached |             // end of block reached | ||||||
|             if (symbol === 256) { |             if (symbol === 256) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } else { | ||||||
|             else { |  | ||||||
|                 var lengthLookup = LengthLookupTable[symbol - 257], |                 var lengthLookup = LengthLookupTable[symbol - 257], | ||||||
|                     length = lengthLookup[1] + bstream.readBits(lengthLookup[0]), |                     length = lengthLookup[1] + bstream.readBits(lengthLookup[0]), | ||||||
|                     distLookup = DistLookupTable[decodeSymbol(bstream, hcDistanceTable)], |                     distLookup = DistLookupTable[decodeSymbol(bstream, hcDistanceTable)], | ||||||
| @@ -566,7 +562,7 @@ function inflate(compressedData, numDecompressedBytes) { | |||||||
|         blockSize = 0; |         blockSize = 0; | ||||||
|         // ++numBlocks; |         // ++numBlocks; | ||||||
|         // no compression |         // no compression | ||||||
|         if (bType == 0) { |         if (bType === 0) { | ||||||
|             // skip remaining bits in this byte |             // skip remaining bits in this byte | ||||||
|             while (bstream.bitPtr !== 0) bstream.readBits(1); |             while (bstream.bitPtr !== 0) bstream.readBits(1); | ||||||
|             var len = bstream.readBits(16); |             var len = bstream.readBits(16); | ||||||
| @@ -575,13 +571,11 @@ function inflate(compressedData, numDecompressedBytes) { | |||||||
|  |  | ||||||
|             if (len > 0) buffer.insertBytes(bstream.readBytes(len)); |             if (len > 0) buffer.insertBytes(bstream.readBytes(len)); | ||||||
|             blockSize = len; |             blockSize = len; | ||||||
|         } |         } else if (bType === 1) { | ||||||
|         // fixed Huffman codes |             // fixed Huffman codes | ||||||
|         else if (bType === 1) { |  | ||||||
|             blockSize = inflateBlockData(bstream, getFixedLiteralTable(), getFixedDistanceTable(), buffer); |             blockSize = inflateBlockData(bstream, getFixedLiteralTable(), getFixedDistanceTable(), buffer); | ||||||
|         } |         } else if (bType === 2) { | ||||||
|         // dynamic Huffman codes |             // dynamic Huffman codes | ||||||
|         else if (bType === 2) { |  | ||||||
|             var numLiteralLengthCodes = bstream.readBits(5) + 257; |             var numLiteralLengthCodes = bstream.readBits(5) + 257; | ||||||
|             var numDistanceCodes = bstream.readBits(5) + 1, |             var numDistanceCodes = bstream.readBits(5) + 1, | ||||||
|                 numCodeLengthCodes = bstream.readBits(4) + 4; |                 numCodeLengthCodes = bstream.readBits(4) + 4; | ||||||
| @@ -664,4 +658,4 @@ function inflate(compressedData, numDecompressedBytes) { | |||||||
| // event.data.file has the ArrayBuffer. | // event.data.file has the ArrayBuffer. | ||||||
| onmessage = function(event) { | onmessage = function(event) { | ||||||
|     unzip(event.data.file, true); |     unzip(event.data.file, true); | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								cps/static/js/io/bitstream.js
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										42
									
								
								cps/static/js/io/bitstream.js
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -8,6 +8,9 @@ | |||||||
|  * Copyright(c) 2011 Google Inc. |  * Copyright(c) 2011 Google Inc. | ||||||
|  * Copyright(c) 2011 antimatter15 |  * Copyright(c) 2011 antimatter15 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /* global bitjs, Uint8Array */ | ||||||
|  |  | ||||||
| var bitjs = bitjs || {}; | var bitjs = bitjs || {}; | ||||||
| bitjs.io = bitjs.io || {}; | bitjs.io = bitjs.io || {}; | ||||||
|  |  | ||||||
| @@ -30,20 +33,20 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. |      * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. | ||||||
|      * @param {boolean} rtl Whether the stream reads bits from the byte starting |      * @param {boolean} rtl Whether the stream reads bits from the byte starting | ||||||
|      *     from bit 7 to 0 (true) or bit 0 to 7 (false). |      *     from bit 7 to 0 (true) or bit 0 to 7 (false). | ||||||
|      * @param {Number} opt_offset The offset into the ArrayBuffer |      * @param {Number} optOffset The offset into the ArrayBuffer | ||||||
|      * @param {Number} opt_length The length of this BitStream |      * @param {Number} optLength The length of this BitStream | ||||||
|      */ |      */ | ||||||
|     bitjs.io.BitStream = function(ab, rtl, opt_offset, opt_length) { |     bitjs.io.BitStream = function(ab, rtl, optOffset, optLength) { | ||||||
|         if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { |         if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { | ||||||
|             throw "Error! BitArray constructed with an invalid ArrayBuffer object"; |             throw "Error! BitArray constructed with an invalid ArrayBuffer object"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         var offset = opt_offset || 0; |         var offset = optOffset || 0; | ||||||
|         var length = opt_length || ab.byteLength; |         var length = optLength || ab.byteLength; | ||||||
|         this.bytes = new Uint8Array(ab, offset, length); |         this.bytes = new Uint8Array(ab, offset, length); | ||||||
|         this.bytePtr = 0; // tracks which byte we are on |         this.bytePtr = 0; // tracks which byte we are on | ||||||
|         this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) |         this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) | ||||||
|         this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr; |         this.peekBits = rtl ? this.peekBitsRtl : this.peekBitsLtr; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -57,8 +60,8 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @param {boolean=} movePointers Whether to move the pointer, defaults false. |      * @param {boolean=} movePointers Whether to move the pointer, defaults false. | ||||||
|      * @return {number} The peeked bits, as an unsigned number. |      * @return {number} The peeked bits, as an unsigned number. | ||||||
|      */ |      */ | ||||||
|     bitjs.io.BitStream.prototype.peekBits_ltr = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBitsLtr = function(n, movePointers) { | ||||||
|         if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return 0; |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -77,12 +80,13 @@ bitjs.io = bitjs.io || {}; | |||||||
|             if (bytePtr >= bytes.length) { |             if (bytePtr >= bytes.length) { | ||||||
|                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + |                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + | ||||||
|                     bytes.length + ", bitPtr=" + bitPtr; |                     bytes.length + ", bitPtr=" + bitPtr; | ||||||
|                 return -1; |                 // return -1; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             var numBitsLeftInThisByte = (8 - bitPtr); |             var numBitsLeftInThisByte = (8 - bitPtr); | ||||||
|  |             var mask; | ||||||
|             if (n >= numBitsLeftInThisByte) { |             if (n >= numBitsLeftInThisByte) { | ||||||
|                 var mask = (BITMASK[numBitsLeftInThisByte] << bitPtr); |                 mask = (BITMASK[numBitsLeftInThisByte] << bitPtr); | ||||||
|                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); |                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); | ||||||
|  |  | ||||||
|                 bytePtr++; |                 bytePtr++; | ||||||
| @@ -90,7 +94,7 @@ bitjs.io = bitjs.io || {}; | |||||||
|                 bitsIn += numBitsLeftInThisByte; |                 bitsIn += numBitsLeftInThisByte; | ||||||
|                 n -= numBitsLeftInThisByte; |                 n -= numBitsLeftInThisByte; | ||||||
|             } else { |             } else { | ||||||
|                 var mask = (BITMASK[n] << bitPtr); |                 mask = (BITMASK[n] << bitPtr); | ||||||
|                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); |                 result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); | ||||||
|  |  | ||||||
|                 bitPtr += n; |                 bitPtr += n; | ||||||
| @@ -118,8 +122,8 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @param {boolean=} movePointers Whether to move the pointer, defaults false. |      * @param {boolean=} movePointers Whether to move the pointer, defaults false. | ||||||
|      * @return {number} The peeked bits, as an unsigned number. |      * @return {number} The peeked bits, as an unsigned number. | ||||||
|      */ |      */ | ||||||
|     bitjs.io.BitStream.prototype.peekBits_rtl = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBitsRtl = function(n, movePointers) { | ||||||
|         if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return 0; |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -138,7 +142,7 @@ bitjs.io = bitjs.io || {}; | |||||||
|             if (bytePtr >= bytes.length) { |             if (bytePtr >= bytes.length) { | ||||||
|                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + |                 throw "Error!  Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + | ||||||
|                     bytes.length + ", bitPtr=" + bitPtr; |                     bytes.length + ", bitPtr=" + bitPtr; | ||||||
|                 return -1; |                 // return -1; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             var numBitsLeftInThisByte = (8 - bitPtr); |             var numBitsLeftInThisByte = (8 - bitPtr); | ||||||
| @@ -198,19 +202,19 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|      */ |      */ | ||||||
|     bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) { |     bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) { | ||||||
|         if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return 0; |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // from http://tools.ietf.org/html/rfc1951#page-11 |         // from http://tools.ietf.org/html/rfc1951#page-11 | ||||||
|         // "Any bits of input up to the next byte boundary are ignored." |         // "Any bits of input up to the next byte boundary are ignored." | ||||||
|         while (this.bitPtr != 0) { |         while (this.bitPtr !== 0) { | ||||||
|             this.readBits(1); |             this.readBits(1); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         var movePointers = movePointers || false; |         var movePointers = movePointers || false; | ||||||
|         var bytePtr = this.bytePtr, |         var bytePtr = this.bytePtr; | ||||||
|             bitPtr = this.bitPtr; |         // bitPtr = this.bitPtr; | ||||||
|  |  | ||||||
|         var result = this.bytes.subarray(bytePtr, bytePtr + n); |         var result = this.bytes.subarray(bytePtr, bytePtr + n); | ||||||
|  |  | ||||||
| @@ -230,4 +234,4 @@ bitjs.io = bitjs.io || {}; | |||||||
|         return this.peekBytes(n, true); |         return this.peekBytes(n, true); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
| @@ -8,6 +8,9 @@ | |||||||
|  * Copyright(c) 2011 Google Inc. |  * Copyright(c) 2011 Google Inc. | ||||||
|  * Copyright(c) 2011 antimatter15 |  * Copyright(c) 2011 antimatter15 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /* global bitjs, Uint8Array */ | ||||||
|  |  | ||||||
| var bitjs = bitjs || {}; | var bitjs = bitjs || {}; | ||||||
| bitjs.io = bitjs.io || {}; | bitjs.io = bitjs.io || {}; | ||||||
|  |  | ||||||
| @@ -20,7 +23,7 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteBuffer = function(numBytes) { |     bitjs.io.ByteBuffer = function(numBytes) { | ||||||
|         if (typeof numBytes != typeof 1 || numBytes <= 0) { |         if (typeof numBytes !== typeof 1 || numBytes <= 0) { | ||||||
|             throw "Error! ByteBuffer initialized with '" + numBytes + "'"; |             throw "Error! ByteBuffer initialized with '" + numBytes + "'"; | ||||||
|         } |         } | ||||||
|         this.data = new Uint8Array(numBytes); |         this.data = new Uint8Array(numBytes); | ||||||
| @@ -55,14 +58,14 @@ bitjs.io = bitjs.io || {}; | |||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) { |     bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) { | ||||||
|         if (numBytes < 1) { |         if (numBytes < 1) { | ||||||
|             throw 'Trying to write into too few bytes: ' + numBytes; |             throw "Trying to write into too few bytes: " + numBytes; | ||||||
|         } |         } | ||||||
|         if (num < 0) { |         if (num < 0) { | ||||||
|             throw 'Trying to write a negative number (' + num + |             throw "Trying to write a negative number (" + num + | ||||||
|                 ') as an unsigned number to an ArrayBuffer'; |                 ") as an unsigned number to an ArrayBuffer"; | ||||||
|         } |         } | ||||||
|         if (num > (Math.pow(2, numBytes * 8) - 1)) { |         if (num > (Math.pow(2, numBytes * 8) - 1)) { | ||||||
|             throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; |             throw "Trying to write " + num + " into only " + numBytes + " bytes"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Roll 8-bits at a time into an array of bytes. |         // Roll 8-bits at a time into an array of bytes. | ||||||
| @@ -85,12 +88,12 @@ bitjs.io = bitjs.io || {}; | |||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) { |     bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) { | ||||||
|         if (numBytes < 1) { |         if (numBytes < 1) { | ||||||
|             throw 'Trying to write into too few bytes: ' + numBytes; |             throw "Trying to write into too few bytes: " + numBytes; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         var HALF = Math.pow(2, (numBytes * 8) - 1); |         var HALF = Math.pow(2, (numBytes * 8) - 1); | ||||||
|         if (num >= HALF || num < -HALF) { |         if (num >= HALF || num < -HALF) { | ||||||
|             throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; |             throw "Trying to write " + num + " into only " + numBytes + " bytes"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Roll 8-bits at a time into an array of bytes. |         // Roll 8-bits at a time into an array of bytes. | ||||||
| @@ -112,10 +115,10 @@ bitjs.io = bitjs.io || {}; | |||||||
|         for (var i = 0; i < str.length; ++i) { |         for (var i = 0; i < str.length; ++i) { | ||||||
|             var curByte = str.charCodeAt(i); |             var curByte = str.charCodeAt(i); | ||||||
|             if (curByte < 0 || curByte > 255) { |             if (curByte < 0 || curByte > 255) { | ||||||
|                 throw 'Trying to write a non-ASCII string!'; |                 throw "Trying to write a non-ASCII string!"; | ||||||
|             } |             } | ||||||
|             this.insertByte(curByte); |             this.insertByte(curByte); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
| @@ -8,6 +8,9 @@ | |||||||
|  * Copyright(c) 2011 Google Inc. |  * Copyright(c) 2011 Google Inc. | ||||||
|  * Copyright(c) 2011 antimatter15 |  * Copyright(c) 2011 antimatter15 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /* global bitjs, Uint8Array */ | ||||||
|  |  | ||||||
| var bitjs = bitjs || {}; | var bitjs = bitjs || {}; | ||||||
| bitjs.io = bitjs.io || {}; | bitjs.io = bitjs.io || {}; | ||||||
|  |  | ||||||
| @@ -19,13 +22,13 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * out of an ArrayBuffer.  In this buffer, everything must be byte-aligned. |      * out of an ArrayBuffer.  In this buffer, everything must be byte-aligned. | ||||||
|      * |      * | ||||||
|      * @param {ArrayBuffer} ab The ArrayBuffer object. |      * @param {ArrayBuffer} ab The ArrayBuffer object. | ||||||
|      * @param {number=} opt_offset The offset into the ArrayBuffer |      * @param {number=} optOffset The offset into the ArrayBuffer | ||||||
|      * @param {number=} opt_length The length of this BitStream |      * @param {number=} optLength The length of this BitStream | ||||||
|      * @constructor |      * @constructor | ||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteStream = function(ab, opt_offset, opt_length) { |     bitjs.io.ByteStream = function(ab, optOffset, optLength) { | ||||||
|         var offset = opt_offset || 0; |         var offset = optOffset || 0; | ||||||
|         var length = opt_length || ab.byteLength; |         var length = optLength || ab.byteLength; | ||||||
|         this.bytes = new Uint8Array(ab, offset, length); |         this.bytes = new Uint8Array(ab, offset, length); | ||||||
|         this.ptr = 0; |         this.ptr = 0; | ||||||
|     }; |     }; | ||||||
| @@ -40,8 +43,9 @@ bitjs.io = bitjs.io || {}; | |||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteStream.prototype.peekNumber = function(n) { |     bitjs.io.ByteStream.prototype.peekNumber = function(n) { | ||||||
|         // TODO: return error if n would go past the end of the stream? |         // TODO: return error if n would go past the end of the stream? | ||||||
|         if (n <= 0 || typeof n != typeof 1) |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return -1; |             return -1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         var result = 0; |         var result = 0; | ||||||
|         // read from last byte to first byte and roll them in |         // read from last byte to first byte and roll them in | ||||||
| @@ -105,7 +109,7 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @return {Uint8Array} The subarray. |      * @return {Uint8Array} The subarray. | ||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) { |     bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) { | ||||||
|         if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -135,7 +139,7 @@ bitjs.io = bitjs.io || {}; | |||||||
|      * @return {string} The next n bytes as a string. |      * @return {string} The next n bytes as a string. | ||||||
|      */ |      */ | ||||||
|     bitjs.io.ByteStream.prototype.peekString = function(n) { |     bitjs.io.ByteStream.prototype.peekString = function(n) { | ||||||
|         if (n <= 0 || typeof n != typeof 1) { |         if (n <= 0 || typeof n !== typeof 1) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,10 @@ | |||||||
|   * Typed Arrays: http://www.khronos.org/registry/typedarray/specs/latest/#6 |   * Typed Arrays: http://www.khronos.org/registry/typedarray/specs/latest/#6 | ||||||
|  |  | ||||||
| */ | */ | ||||||
| /* global screenfull, bitjs */ | /* global screenfull, bitjs, Uint8Array, opera */ | ||||||
|  | /* exported init, event */ | ||||||
|  |  | ||||||
|  |  | ||||||
| if (window.opera) { | if (window.opera) { | ||||||
|     window.console.log = function(str) { |     window.console.log = function(str) { | ||||||
|         opera.postError(str); |         opera.postError(str); | ||||||
| @@ -101,12 +104,12 @@ kthoom.setSettings = function() { | |||||||
| var createURLFromArray = function(array, mimeType) { | var createURLFromArray = function(array, mimeType) { | ||||||
|     var offset = array.byteOffset; |     var offset = array.byteOffset; | ||||||
|     var len = array.byteLength; |     var len = array.byteLength; | ||||||
|     var url; |     // var url; | ||||||
|     var blob; |     var blob; | ||||||
|  |  | ||||||
|     if (mimeType === 'image/xml+svg') { |     if (mimeType === "image/xml+svg") { | ||||||
|         const xmlStr = new TextDecoder('utf-8').decode(array); |         var xmlStr = new TextDecoder("utf-8").decode(array); | ||||||
|         return 'data:image/svg+xml;UTF-8,' + encodeURIComponent(xmlStr); |         return "data:image/svg+xml;UTF-8," + encodeURIComponent(xmlStr); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO: Move all this browser support testing to a common place |     // TODO: Move all this browser support testing to a common place | ||||||
| @@ -140,7 +143,7 @@ kthoom.ImageFile = function(file) { | |||||||
|     var fileExtension = file.filename.split(".").pop().toLowerCase(); |     var fileExtension = file.filename.split(".").pop().toLowerCase(); | ||||||
|     this.mimeType = fileExtension === "png" ? "image/png" : |     this.mimeType = fileExtension === "png" ? "image/png" : | ||||||
|         (fileExtension === "jpg" || fileExtension === "jpeg") ? "image/jpeg" : |         (fileExtension === "jpg" || fileExtension === "jpeg") ? "image/jpeg" : | ||||||
|             fileExtension === "gif" ? "image/gif" : fileExtension == 'svg' ? 'image/xml+svg' : undefined; |             fileExtension === "gif" ? "image/gif" : fileExtension === "svg" ? "image/xml+svg" : undefined; | ||||||
|     if ( this.mimeType !== undefined) { |     if ( this.mimeType !== undefined) { | ||||||
|         this.dataURI = createURLFromArray(file.fileData, this.mimeType); |         this.dataURI = createURLFromArray(file.fileData, this.mimeType); | ||||||
|         this.data = file; |         this.data = file; | ||||||
| @@ -154,17 +157,18 @@ function initProgressClick() { | |||||||
|         currentImage = page; |         currentImage = page; | ||||||
|         updatePage(); |         updatePage(); | ||||||
|     }); |     }); | ||||||
| }; | } | ||||||
|  |  | ||||||
| function loadFromArrayBuffer(ab) { | function loadFromArrayBuffer(ab) { | ||||||
|     var start = (new Date).getTime(); |     var start = (new Date).getTime(); | ||||||
|     var h = new Uint8Array(ab, 0, 10); |     var h = new Uint8Array(ab, 0, 10); | ||||||
|     var pathToBitJS = "../../static/js/archive/"; |     var pathToBitJS = "../../static/js/archive/"; | ||||||
|  |     var lastCompletion = 0; | ||||||
|     if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { //Rar! |     if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { //Rar! | ||||||
|         unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); |         unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); | ||||||
|     } else if (h[0] === 80 && h[1] === 75) { //PK (Zip) |     } else if (h[0] === 80 && h[1] === 75) { //PK (Zip) | ||||||
|         unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); |         unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); | ||||||
|     } else if (h[0] == 255 && h[1] == 216) { // JPEG |     } else if (h[0] === 255 && h[1] === 216) { // JPEG | ||||||
|         // ToDo: check |         // ToDo: check | ||||||
|         updateProgress(100); |         updateProgress(100); | ||||||
|         lastCompletion = 100; |         lastCompletion = 100; | ||||||
| @@ -180,12 +184,12 @@ function loadFromArrayBuffer(ab) { | |||||||
|                 if (totalImages === 0) { |                 if (totalImages === 0) { | ||||||
|                     totalImages = e.totalFilesInArchive; |                     totalImages = e.totalFilesInArchive; | ||||||
|                 } |                 } | ||||||
|                 updateProgress(percentage *100); |                 updateProgress(percentage * 100); | ||||||
|                 lastCompletion = percentage * 100; |                 lastCompletion = percentage * 100; | ||||||
|             }); |             }); | ||||||
|         unarchiver.addEventListener(bitjs.archive.UnarchiveEvent.Type.INFO, |         unarchiver.addEventListener(bitjs.archive.UnarchiveEvent.Type.INFO, | ||||||
|             function(e) { |             function(e) { | ||||||
|                 // console.log(e.msg);  77 Enable debug output here |                 // console.log(e.msg);  // Enable debug output here | ||||||
|             }); |             }); | ||||||
|         unarchiver.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, |         unarchiver.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, | ||||||
|             function(e) { |             function(e) { | ||||||
| @@ -211,8 +215,7 @@ function loadFromArrayBuffer(ab) { | |||||||
|                             if (imageFiles.length === currentImage + 1) { |                             if (imageFiles.length === currentImage + 1) { | ||||||
|                                 updatePage(lastCompletion); |                                 updatePage(lastCompletion); | ||||||
|                             } |                             } | ||||||
|                         } |                         } else { | ||||||
|                         else { |  | ||||||
|                             totalImages--; |                             totalImages--; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| @@ -231,22 +234,22 @@ function loadFromArrayBuffer(ab) { | |||||||
|  |  | ||||||
| function scrollTocToActive() { | function scrollTocToActive() { | ||||||
|     // Scroll to the thumbnail in the TOC on page change |     // Scroll to the thumbnail in the TOC on page change | ||||||
|     $('#tocView').stop().animate({ |     $("#tocView").stop().animate({ | ||||||
|         scrollTop: $('#tocView a.active').position().top |         scrollTop: $("#tocView a.active").position().top | ||||||
|     }, 200); |     }, 200); | ||||||
| } | } | ||||||
|  |  | ||||||
| function updatePage() { | function updatePage() { | ||||||
|     $('.page').text((currentImage + 1 ) + "/" + totalImages); |     $(".page").text((currentImage + 1 ) + "/" + totalImages); | ||||||
|  |  | ||||||
|     // Mark the current page in the TOC |     // Mark the current page in the TOC | ||||||
|     $('#tocView a[data-page]') |     $("#tocView a[data-page]") | ||||||
|     // Remove the currently active thumbnail |     // Remove the currently active thumbnail | ||||||
|         .removeClass('active') |         .removeClass("active") | ||||||
|         // Find the new one |         // Find the new one | ||||||
|         .filter('[data-page='+ (currentImage + 1) +']') |         .filter("[data-page=" + (currentImage + 1) + "]") | ||||||
|         // Set it to active |         // Set it to active | ||||||
|         .addClass('active'); |         .addClass("active"); | ||||||
|  |  | ||||||
|     scrollTocToActive(); |     scrollTocToActive(); | ||||||
|     updateProgress(); |     updateProgress(); | ||||||
| @@ -270,8 +273,8 @@ function updateProgress(loadPercentage) { | |||||||
|  |  | ||||||
|         if (loadPercentage === 100) { |         if (loadPercentage === 100) { | ||||||
|             $("#progress") |             $("#progress") | ||||||
|                 .removeClass('loading') |                 .removeClass("loading") | ||||||
|                 .find(".load").text(''); |                 .find(".load").text(""); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -326,7 +329,7 @@ function setImage(url) { | |||||||
|                     xhr.onload = function() { |                     xhr.onload = function() { | ||||||
|                         $("#mainText").css("display", ""); |                         $("#mainText").css("display", ""); | ||||||
|                         $("#mainText").innerHTML("<iframe style=\"width:100%;height:700px;border:0\" src=\"data:text/html," + escape(xhr.responseText) + "\"></iframe>"); |                         $("#mainText").innerHTML("<iframe style=\"width:100%;height:700px;border:0\" src=\"data:text/html," + escape(xhr.responseText) + "\"></iframe>"); | ||||||
|                     } |                     }; | ||||||
|                     xhr.send(null); |                     xhr.send(null); | ||||||
|                 } else if (!/(jpg|jpeg|png|gif)$/.test(imageFiles[currentImage].filename) && imageFiles[currentImage].data.uncompressedSize < 10 * 1024) { |                 } else if (!/(jpg|jpeg|png|gif)$/.test(imageFiles[currentImage].filename) && imageFiles[currentImage].data.uncompressedSize < 10 * 1024) { | ||||||
|                     xhr.open("GET", url, true); |                     xhr.open("GET", url, true); | ||||||
| @@ -378,17 +381,17 @@ function setImage(url) { | |||||||
|  |  | ||||||
| function showLeftPage() { | function showLeftPage() { | ||||||
|     if (settings.direction === 0) { |     if (settings.direction === 0) { | ||||||
|         showPrevPage() |         showPrevPage(); | ||||||
|     } else { |     } else { | ||||||
|         showNextPage() |         showNextPage(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function showRightPage() { | function showRightPage() { | ||||||
|     if (settings.direction === 0) { |     if (settings.direction === 0) { | ||||||
|         showNextPage() |         showNextPage(); | ||||||
|     } else { |     } else { | ||||||
|         showPrevPage() |         showPrevPage(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -504,7 +507,7 @@ function keyHandler(evt) { | |||||||
|             updateScale(false); |             updateScale(false); | ||||||
|             break; |             break; | ||||||
|         case kthoom.Key.SPACE: |         case kthoom.Key.SPACE: | ||||||
|             var container = $('#mainContent'); |             var container = $("#mainContent"); | ||||||
|             var atTop = container.scrollTop() === 0; |             var atTop = container.scrollTop() === 0; | ||||||
|             var atBottom = container.scrollTop() >= container[0].scrollHeight - container.height(); |             var atBottom = container.scrollTop() >= container[0].scrollHeight - container.height(); | ||||||
|  |  | ||||||
| @@ -577,9 +580,9 @@ function init(filename) { | |||||||
|         $(this).toggleClass("icon-menu icon-right"); |         $(this).toggleClass("icon-menu icon-right"); | ||||||
|  |  | ||||||
|         // We need this in a timeout because if we call it during the CSS transition, IE11 shakes the page ¯\_(ツ)_/¯ |         // We need this in a timeout because if we call it during the CSS transition, IE11 shakes the page ¯\_(ツ)_/¯ | ||||||
|         setTimeout(function(){ |         setTimeout(function() { | ||||||
|             // Focus on the TOC or the main content area, depending on which is open |             // Focus on the TOC or the main content area, depending on which is open | ||||||
|             $('#main:not(.closed) #mainContent, #sidebar.open #tocView').focus(); |             $("#main:not(.closed) #mainContent, #sidebar.open #tocView").focus(); | ||||||
|             scrollTocToActive(); |             scrollTocToActive(); | ||||||
|         }, 500); |         }, 500); | ||||||
|     }); |     }); | ||||||
| @@ -630,7 +633,7 @@ function init(filename) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Focus the scrollable area so that keyboard scrolling work as expected |     // Focus the scrollable area so that keyboard scrolling work as expected | ||||||
|     $('#mainContent').focus(); |     $("#mainContent").focus(); | ||||||
|  |  | ||||||
|     $("#mainImage").click(function(evt) { |     $("#mainImage").click(function(evt) { | ||||||
|         // Firefox does not support offsetX/Y so we have to manually calculate |         // Firefox does not support offsetX/Y so we have to manually calculate | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzieisaacs
					Ozzieisaacs