diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj
index aaa47303..2a8fb39a 100644
--- a/MeshCentralServer.njsproj
+++ b/MeshCentralServer.njsproj
@@ -44,7 +44,6 @@
-
@@ -58,7 +57,6 @@
-
@@ -119,8 +117,6 @@
-
-
diff --git a/agents/MeshService.exe b/agents/MeshService.exe
index 257fa188..89a96c5c 100644
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
diff --git a/agents/MeshService64.exe b/agents/MeshService64.exe
index bfe22f32..5a7340f5 100644
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
diff --git a/agents/meshcore.js b/agents/meshcore.js
index 14bac0d1..f438f7bf 100644
--- a/agents/meshcore.js
+++ b/agents/meshcore.js
@@ -36,6 +36,7 @@ function createMeshCore(agent) {
var wifiScanner = null;
var networkMonitor = null;
var amtscanner = null;
+ var nextTunnelIndex = 1;
/*
var AMTScanner = require("AMTScanner");
@@ -337,7 +338,7 @@ function createMeshCore(agent) {
if (xurl != null) {
var woptions = http.parseUri(xurl);
woptions.rejectUnauthorized = 0;
- sendConsoleText(JSON.stringify(woptions));
+ //sendConsoleText(JSON.stringify(woptions));
var tunnel = http.request(woptions);
tunnel.upgrade = onTunnelUpgrade;
tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }
@@ -349,10 +350,8 @@ function createMeshCore(agent) {
tunnel.tcpaddr = data.tcpaddr;
tunnel.tcpport = data.tcpport;
tunnel.end();
- sendConsoleText('tunnel.end() called');
// Put the tunnel in the tunnels list
- var index = 1;
- while (tunnels[index]) { index++; }
+ var index = nextTunnelIndex++;;
tunnel.index = index;
tunnels[index] = tunnel;
@@ -443,6 +442,7 @@ function createMeshCore(agent) {
this.s = s;
s.httprequest = this;
s.end = onTunnelClosed;
+ s.tunnel = this;
if (this.tcpport != null) {
// This is a TCP relay connection, pause now and try to connect to the target.
@@ -472,6 +472,7 @@ function createMeshCore(agent) {
}
function onTunnelClosed() {
+ if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
delete tunnels[this.httprequest.index];
@@ -487,6 +488,21 @@ function createMeshCore(agent) {
// If there is a upload or download active on this connection, close the file
if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
+
+ // Clean up WebRTC
+ if (this.webrtc != null) {
+ if (this.webrtc.rtcchannel) { try { this.webrtc.rtcchannel.close(); } catch (e) { } this.webrtc.rtcchannel.removeAllListeners('data'); this.webrtc.rtcchannel.removeAllListeners('end'); delete this.webrtc.rtcchannel; }
+ if (this.webrtc.websocket) { delete this.webrtc.websocket; }
+ try { this.webrtc.close(); } catch (e) { }
+ this.webrtc.removeAllListeners('connected');
+ this.webrtc.removeAllListeners('disconnected');
+ this.webrtc.removeAllListeners('dataChannel');
+ delete this.webrtc;
+ }
+
+ // Clean up WebSocket
+ this.removeAllListeners('data');
+ delete this;
}
function onTunnelSendOk() { sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid); }
function onTunnelData(data) {
@@ -661,34 +677,71 @@ function createMeshCore(agent) {
}
}
- // Attempt to setup and switch the tunnel over to WebRTC
+ // Called when receiving control data on WebRTC
+ function onTunnelWebRTCControlData(data) {
+ if (typeof data != 'string') return;
+ var obj;
+ try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC'); return; }
+ if (obj.type == 'close') {
+ sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
+ try { this.close(); } catch (e) { }
+ try { this.xrtc.close(); } catch (e) { }
+ }
+ }
+
+ // Called when receiving control data on websocket
function onTunnelControlData(data) {
- sendConsoleText('onTunnelControlData: ' + data);
- var obj = JSON.parse(data);
- if (obj.type == 'offer') {
+ if (typeof data != 'string') return;
+ //sendConsoleText('onTunnelControlData: ' + data);
+ //console.log('onTunnelControlData: ' + data);
+
+ var obj;
+ try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; }
+
+ if (obj.type == 'close') {
+ // We received the close on the websocket
+ sendConsoleText('Tunnel #' + this.tunnel.index + ' WebSocket control close');
+ try { this.close(); } catch (e) { }
+ } else if (obj.type == 'webrtc1') {
+ this.write("{\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
+ if (this.httprequest.protocol == 1) { // Terminal
+ // Switch the user input from websocket to webrtc at this point.
+ this.unpipe(this.httprequest.process.stdin);
+ this.rtcchannel.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
+ this.resume(); // Resume the websocket to keep receiving control data
+ } else if (this.httprequest.protocol == 2) { // Desktop
+ // Switch the user input from websocket to webrtc at this point.
+ this.unpipe(this.httprequest.desktop.kvm);
+ this.webrtc.rtcchannel.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
+ this.resume(); // Resume the websocket to keep receiving control data
+ }
+ } else if (obj.type == 'webrtc2') {
+ // Other side received websocket end of data marker, start sending data on WebRTC channel
+ if (this.httprequest.protocol == 1) { // Terminal
+ this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
+ } else if (this.httprequest.protocol == 2) { // Desktop
+ this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
+ }
+ } else if (obj.type == 'offer') {
// This is a WebRTC offer.
this.webrtc = rtc.createConnection();
this.webrtc.websocket = this;
- this.webrtc.on('connected', function () { sendConsoleText('WebRTC connected'); });
+ this.webrtc.on('connected', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected'); });
+ this.webrtc.on('disconnected', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected'); });
this.webrtc.on('dataChannel', function (rtcchannel) {
- sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
+ //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
+ rtcchannel.xrtc = this;
this.rtcchannel = rtcchannel;
+ this.rtcchannel.on('data', onTunnelWebRTCControlData);
+ this.rtcchannel.on('end', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); });
if (this.websocket.httprequest.protocol == 1) { // Terminal
- // This is a terminal data stream, re-setup the pipes
- // Un-pipe
- this.websocket.unpipe(this.websocket.httprequest.process.stdin);
- //this.websocket.httprequest.process.stdout.unpipe(this.websocket);
- // Re-pipe
- rtcchannel.pipe(this.websocket.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
- //this.websocket.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
+ // This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket
+ this.websocket.httprequest.process.stdout.unpipe(this.websocket);
+ this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
} else if (this.websocket.httprequest.protocol == 2) { // Desktop
- // This is a KVM data stream, re-setup the pipes
- // Un-pipe
- this.websocket.unpipe(this.websocket.httprequest.desktop.kvm);
- //this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
- // Re-pipe
- rtcchannel.pipe(this.websocket.httprequest.desktop.kvm, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
- //this.websocket.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
+ // This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket
+ this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
+ this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
}
/*
else {
diff --git a/package.json b/package.json
index a5ebf957..12663b94 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "meshcentral",
- "version": "0.1.2-t",
+ "version": "0.1.2-u",
"keywords": [
"Remote Management",
"Intel AMT",
diff --git a/public/commander.htm b/public/commander.htm
index 98fee1e8..13d84bf9 100644
--- a/public/commander.htm
+++ b/public/commander.htm
@@ -1133,6 +1133,7 @@ var CreateAmtRedirect = function (module) {
obj.user = null;
obj.pass = null;
obj.authuri = "/RedirectionService";
+ obj.tlsv1only = 0;
obj.connectstate = 0;
obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER
@@ -1152,7 +1153,7 @@ var CreateAmtRedirect = function (module) {
obj.user = user;
obj.pass = pass;
obj.connectstate = 0;
- obj.socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=2&host=" + host + "&port=" + port + "&tls=" + tls + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : "")); // The "p=2" indicates to the relay that this is a REDIRECTION session
+ obj.socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=2&host=" + host + "&port=" + port + "&tls=" + tls + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : "") + "&tls1only=" + obj.tlsv1only); // The "p=2" indicates to the relay that this is a REDIRECTION session
obj.socket.onopen = obj.xxOnSocketConnected;
obj.socket.onmessage = obj.xxOnMessage;
obj.socket.onclose = obj.xxOnSocketClosed;
@@ -33060,7 +33061,7 @@ if (typeof module !== "undefined" && module.exports) {
});
}
- var version = '0.5.7';
+ var version = '0.5.8';
var urlvars = null;
var amtstack;
var wsstack = null;
diff --git a/public/samples/relay.htm b/public/samples/relay.htm
new file mode 100644
index 00000000..e30765b3
--- /dev/null
+++ b/public/samples/relay.htm
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/samples/relay.js b/public/samples/relay.js
new file mode 100644
index 00000000..6b1f4f65
--- /dev/null
+++ b/public/samples/relay.js
@@ -0,0 +1,48 @@
+/**
+* @fileoverview Dynamic interface to MeshCentral2
+* @author Ylian Saint-Hilaire
+* @version v0.0.1
+*/
+
+var createMeshConnection = function (connectionId) {
+ var obj = {};
+ obj.connectionId = connectionId;
+ obj.state = 0;
+ obj.websocket = null;
+ obj.onStateChanged = null;
+ obj.onData = null;
+
+ obj.connect = function () {
+ if (obj.state == 0) {
+ obj.websocket = new WebSocket(window.location.protocol.replace('http', 'ws') + '//' + window.location.host + '/meshrelay.ashx?id=' + obj.connectionId);
+ obj.websocket.binaryType = "arraybuffer";
+ obj.websocket.onopen = function (e) { console.log('WebSocket Connected', e); };
+ obj.websocket.onmessage = function (e) {
+ console.log('WebSocket Message', e);
+ if ((obj.state = 1) && (e.data == 'c')) {
+ obj.state = 2;
+ if (obj.onStateChanged) { onStateChanged(obj, 2); }
+ console.log('WebSocket Peer Connection', e);
+ obj.send('bob');
+ } else {
+ if (obj.onData != null) { obj.onData(obj, e.data); }
+ }
+ };
+ obj.websocket.onclose = function (e) {
+ console.log('WebSocket Closed', e);
+ obj.state = 0;
+ if (obj.onStateChanged) { onStateChanged(obj, 0); }
+ };
+ obj.websocket.onerror = function (e) { console.log('WebSocket Error', e); };
+ obj.state = 1;
+ if (obj.onStateChanged) { onStateChanged(obj, 1); }
+ }
+ return obj;
+ };
+
+ obj.send = function (data) {
+ if ((obj.state == 2) && (obj.websocket != null)) { obj.websocket.send(data); }
+ };
+
+ return obj;
+}
\ No newline at end of file
diff --git a/public/scripts/agent-desktop-0.0.2.js b/public/scripts/agent-desktop-0.0.2.js
index 8ad4f92c..a15a1600 100644
--- a/public/scripts/agent-desktop-0.0.2.js
+++ b/public/scripts/agent-desktop-0.0.2.js
@@ -93,15 +93,18 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
obj.ProcessPictureMsg = function (str, X, Y) {
//if (obj.targetnode != null) obj.Debug("ProcessPictureMsg " + X + "," + Y + " - " + obj.targetnode.substring(0, 8));
var tile = new Image();
- obj.tilesReceived++;
+ tile.xcount = obj.tilesReceived++;
+ //console.log('Tile #' + tile.xcount);
var r = obj.tilesReceived;
tile.src = "data:image/jpeg;base64," + btoa(str.substring(4, str.length));
tile.onload = function () {
+ //console.log('DecodeTile #' + this.xcount);
if (obj.Canvas != null && obj.KillDraw < r && obj.State != 0) {
obj.PendingOperations.push([r, 2, tile, X, Y]);
while (obj.DoPendingOperations()) { }
}
}
+ tile.error = function () { console.log('DecodeTileError'); }
}
obj.DoPendingOperations = function () {
diff --git a/public/scripts/agent-redir-ws-0.1.0.js b/public/scripts/agent-redir-ws-0.1.0.js
index a815287d..87c8ca48 100644
--- a/public/scripts/agent-redir-ws-0.1.0.js
+++ b/public/scripts/agent-redir-ws-0.1.0.js
@@ -50,17 +50,25 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
// Called to pass websocket control messages
obj.xxOnControlCommand = function (msg) {
- var controlMsg = JSON.parse(msg);
- if ((controlMsg.type == 'answer') && (obj.webrtc != null)) {
- //console.log('gotAnswer', JSON.stringify(controlMsg));
- obj.webrtc.setRemoteDescription(new RTCSessionDescription(controlMsg), function () { /*console.log('WebRTC remote ok');*/ }, obj.xxCloseWebRTC);
+ var controlMsg;
+ try { controlMsg = JSON.parse(msg); } catch (e) { return; }
+ if (obj.webrtc != null) {
+ if (controlMsg.type == 'answer') {
+ obj.webrtc.setRemoteDescription(new RTCSessionDescription(controlMsg), function () { /*console.log('WebRTC remote ok');*/ }, obj.xxCloseWebRTC);
+ } else if (controlMsg.type == 'webrtc1') {
+ obj.socket.send("{\"type\":\"webrtc2\"}"); // Confirm we got end of data marker, indicates data will no longer be received on websocket.
+ } else if (controlMsg.type == 'webrtc2') {
+ // TODO: Resume/Start sending data over WebRTC
+ }
}
}
// Close the WebRTC connection, should be called if a problem occurs during WebRTC setup.
obj.xxCloseWebRTC = function () {
- if (obj.webchannel != null) { obj.webchannel.close(); obj.webchannel = null; }
- if (obj.webrtc != null) { obj.webrtc.close(); obj.webrtc = null; }
+ try { obj.webchannel.send("{\"type\":\"close\"}"); } catch (e) { }
+ if (obj.webchannel != null) { try { obj.webchannel.close(); } catch (e) { } obj.webchannel = null; }
+ if (obj.webrtc != null) { try { obj.webrtc.close(); } catch (e) { } obj.webrtc = null; }
+ obj.webRtcActive = false;
}
obj.xxOnMessage = function (e) {
@@ -78,23 +86,22 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
if (obj.webrtc != null) {
obj.webchannel = obj.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
- obj.webchannel.onmessage = function (event) { console.log("DataChannel - onmessage", event.data); obj.xxOnMessage(event.data); };
- obj.webchannel.onopen = function () { obj.webRtcActive = true; if (obj.onStateChanged != null) { obj.onStateChanged(obj, obj.State); } /*obj.webchannel.send("Browser WebRTC Hello!!!");*/ };
- obj.webchannel.onclose = function (event) { obj.Stop(); }
+ obj.webchannel.onmessage = function (event) { obj.xxOnMessage({ data: event.data }); };
+ obj.webchannel.onopen = function () {
+ obj.webRtcActive = true;
+ obj.socket.send("{\"type\":\"webrtc1\"}"); // Indicate to the other side that data traffic will no longer be sent over websocket.
+ // TODO: Hold/Stop sending data over websocket
+ if (obj.onStateChanged != null) { obj.onStateChanged(obj, obj.State); }
+ };
+ obj.webchannel.onclose = function (event) { console.log('WebRTC close'); obj.Stop(); }
obj.webrtc.onicecandidate = function (e) {
if (e.candidate == null) {
- //console.log('createOffer', JSON.stringify(obj.webrtcoffer));
obj.socket.send(JSON.stringify(obj.webrtcoffer)); // End of candidates, send the offer
} else {
obj.webrtcoffer.sdp += ("a=" + e.candidate.candidate + "\r\n"); // New candidate, add it to the SDP
}
}
- obj.webrtc.oniceconnectionstatechange = function () {
- if (obj.webrtc != null) {
- //console.log('WebRTC ICE', obj.webrtc.iceConnectionState);
- if ((obj.webrtc.iceConnectionState == 'disconnected') || (obj.webrtc.iceConnectionState == 'failed')) { obj.xxCloseWebRTC(); }
- }
- }
+ obj.webrtc.oniceconnectionstatechange = function () { if (obj.webrtc != null) { if ((obj.webrtc.iceConnectionState == 'disconnected') || (obj.webrtc.iceConnectionState == 'failed')) { obj.xxCloseWebRTC(); } } }
obj.webrtc.createOffer(function (offer) {
// Got the offer
obj.webrtcoffer = offer;
@@ -189,13 +196,14 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
obj.Stop = function (x) {
if (obj.debugmode == 1) { console.log('stop', x); }
//obj.debug("Agent Redir Socket Stopped");
- obj.webRtcActive = false;
- obj.webrtc = null;
- obj.webchannel = null;
- obj.xxStateChange(0);
obj.connectstate = -1;
obj.xxCloseWebRTC();
- if (obj.socket != null) { obj.socket.close(); obj.socket = null; }
+ if (obj.socket != null) {
+ try { obj.socket.send("{\"type\":\"close\"}"); } catch (e) { }
+ try { obj.socket.close(); } catch (e) { }
+ obj.socket = null;
+ }
+ obj.xxStateChange(0);
}
return obj;
diff --git a/public/scripts/amt-desktop-0.0.2.js b/public/scripts/amt-desktop-0.0.2.js
index cd2fbc27..72eacd8f 100644
--- a/public/scripts/amt-desktop-0.0.2.js
+++ b/public/scripts/amt-desktop-0.0.2.js
@@ -23,6 +23,8 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.useZRLE = true;
obj.showmouse = true;
obj.buttonmask = 0;
+ //obj.inbytes = 0;
+ //obj.outbytes = 0;
obj.spare = null;
obj.sparew = 0;
obj.spareh = 0;
@@ -33,9 +35,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.onScreenSizeChange = null;
obj.frameRateDelay = 0;
// ###BEGIN###{DesktopRotation}
+ obj.noMouseRotate = false;
obj.rotation = 0;
// ###END###{DesktopRotation}
-
+
// ###BEGIN###{DesktopFocus}
obj.mx = 0; // Last mouse x position
obj.my = 0; // Last mouse y position
@@ -43,10 +46,13 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.oy = -1; // Old mouse y position
obj.focusmode = 0;
// ###END###{DesktopFocus}
-
+ // ###BEGIN###{Inflate}
+ obj.inflate = ZLIB.inflateInit(-15);
+ // ###END###{Inflate}
+
// Private method
obj.Debug = function (msg) { console.log(msg); }
-
+
obj.xxStateChange = function (newstate) {
if (newstate == 0) {
obj.canvas.fillStyle = '#000000';
@@ -58,10 +64,12 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (!obj.showmouse) { QS(obj.canvasid).cursor = 'none'; }
}
}
-
+
obj.ProcessData = function (data) {
if (!data) return;
// obj.Debug("KRecv(" + data.length + "): " + rstr2hex(data));
+ //obj.inbytes += data.length;
+ //obj.Debug("KRecv(" + obj.inbytes + ")");
obj.acc += data;
while (obj.acc.length > 0) {
//obj.Debug("KAcc(" + obj.acc.length + "): " + rstr2hex(obj.acc));
@@ -90,12 +98,15 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
else if (obj.state == 3 && obj.acc.length >= 24) {
// Getting server init
+ // ###BEGIN###{DesktopRotation}
+ obj.rotation = 0; // We don't currently support screen init while rotated.
+ // ###END###{DesktopRotation}
var namelen = ReadInt(obj.acc, 20);
if (obj.acc.length < 24 + namelen) return;
cmdsize = 24 + namelen;
obj.canvas.canvas.width = obj.rwidth = obj.width = obj.ScreenWidth = ReadShort(obj.acc, 0);
obj.canvas.canvas.height = obj.rheight = obj.height = obj.ScreenHeight = ReadShort(obj.acc, 2);
-
+
// These are all values we don't really need, we are going to only run in RGB565 or RGB332 and not use the flexibility provided by these settings.
// Makes the javascript code smaller and maybe a bit faster.
/*
@@ -126,22 +137,22 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
var supportedEncodings = '';
if (obj.useZRLE) supportedEncodings += IntToStr(16);
supportedEncodings += IntToStr(0);
-
+
obj.Send(String.fromCharCode(2, 0) + ShortToStr((supportedEncodings.length / 4) + 1) + supportedEncodings + IntToStr(-223)); // Supported Encodings + Desktop Size
-
+
// Set the pixel encoding to something much smaller
// obj.Send(String.fromCharCode(0, 0, 0, 0, 16, 16, 0, 1) + ShortToStr(31) + ShortToStr(63) + ShortToStr(31) + String.fromCharCode(11, 5, 0, 0, 0, 0)); // Setup 16 bit color RGB565 (This is the default, so we don't need to set it)
if (obj.bpp == 1) obj.Send(String.fromCharCode(0, 0, 0, 0, 8, 8, 0, 1) + ShortToStr(7) + ShortToStr(7) + ShortToStr(3) + String.fromCharCode(5, 2, 0, 0, 0, 0)); // Setup 8 bit color RGB332
-
+
obj.state = 4;
obj.parent.xxStateChange(3);
_SendRefresh();
//obj.timer = setInterval(obj.xxOnTimer, 50);
-
+
// ###BEGIN###{DesktopFocus}
obj.ox = -1; // Old mouse x position
// ###END###{DesktopFocus}
-
+
if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); }
}
else if (obj.state == 4) {
@@ -161,10 +172,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
height = ReadShort(obj.acc, 6),
s = width * height,
encoding = ReadInt(obj.acc, 8);
-
+
if (encoding < 17) {
if (width < 1 || width > 64 || height < 1 || height > 64) { console.log("Invalid tile size (" + width + "," + height + "), disconnecting."); return obj.Stop(); }
-
+
// Set the spare bitmap to the rigth size if it's not already. This allows us to recycle the spare most if not all the time.
if (obj.sparew != width || obj.spareh != height) {
obj.sparew = obj.sparew2 = width;
@@ -178,7 +189,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
}
-
+
if (encoding == 0xFFFFFF21) {
// Desktop Size (0xFFFFFF21, -223)
obj.canvas.canvas.width = obj.rwidth = obj.width = width;
@@ -193,7 +204,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
var ptr = 12, cs = 12 + (s * obj.bpp);
if (obj.acc.length < cs) return; // Check we have all the data needed and we can only draw 64x64 tiles.
cmdsize = cs;
-
+
// CRITICAL LOOP, optimize this as much as possible
for (var i = 0; i < s; i++) { _setPixel(obj.acc.charCodeAt(ptr++) + ((obj.bpp == 2) ? (obj.acc.charCodeAt(ptr++) << 8) : 0), i); }
_putImage(obj.spare, x, y);
@@ -205,23 +216,22 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.acc.length < (16 + datalen)) return;
//obj.Debug("RECT ZRLE (" + x + "," + y + "," + width + "," + height + ") LEN = " + datalen);
//obj.Debug("RECT ZRLE LEN: " + ReadShortX(obj.acc, 17) + ", DATA: " + rstr2hex(obj.acc.substring(16)));
-
+
// Process the ZLib header if this is the first block
var ptr = 16, delta = 5, dx = 0;
- if (obj.ZRLEfirst == 1) { obj.ZRLEfirst = 0; ptr += 2; delta = 7; dx = 2; } // Skip the ZLib header
-
+
if (datalen > 5 && obj.acc.charCodeAt(ptr) == 0 && ReadShortX(obj.acc, ptr + 1) == (datalen - delta)) {
// This is an uncompressed ZLib data block
_decodeLRE(obj.acc, ptr + 5, x, y, width, height, s, datalen);
}
- // ###BEGIN###{Inflate}
+ // ###BEGIN###{Inflate}
else {
// This is compressed ZLib data, decompress and process it.
- var arr = inflate(obj.acc.substring(ptr, ptr + datalen - dx));
- if (arr.length > 0) { _decodeLRE(String.fromCharCode.apply(null, new Uint8Array(arr)), 0, x, y, width, height, s, arr.length); } else { obj.Debug("Invalid deflate data"); }
+ var arr = obj.inflate.inflate(obj.acc.substring(ptr, ptr + datalen - dx));
+ if (arr.length > 0) { _decodeLRE(arr, 0, x, y, width, height, s, arr.length); } else { obj.Debug("Invalid deflate data"); }
}
// ###END###{Inflate}
-
+
cmdsize = 16 + datalen;
}
else {
@@ -237,12 +247,12 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
}
}
-
+
if (cmdsize == 0) return;
obj.acc = obj.acc.substring(cmdsize);
}
}
-
+
function _decodeLRE(data, ptr, x, y, width, height, s, datalen) {
var subencoding = data.charCodeAt(ptr++), index, v, runlengthdecode, palette = {}, rlecount = 0, runlength = 0, i;
// obj.Debug("RECT RLE (" + (datalen - 5) + ", " + subencoding + "):" + rstr2hex(data.substring(21, 21 + (datalen - 5))));
@@ -255,23 +265,23 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
// Solid color tile
v = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0);
obj.canvas.fillStyle = 'rgb(' + ((obj.bpp == 1) ? ((v & 224) + ',' + ((v & 28) << 3) + ',' + _fixColor((v & 3) << 6)) : (((v >> 8) & 248) + ',' + ((v >> 3) & 252) + ',' + ((v & 31) << 3))) + ')';
-
+
// ###BEGIN###{DesktopRotation}
var xx = _rotX(x, y);
y = _rotY(x, y);
x = xx;
// ###END###{DesktopRotation}
-
+
obj.canvas.fillRect(x, y, width, height);
}
else if (subencoding > 1 && subencoding < 17) { // Packed palette encoded tile
// Read the palette
var br = 4, bm = 15; // br is BitRead and bm is BitMask. By adjusting these two we can support all the variations in this encoding.
for (i = 0; i < subencoding; i++) { palette[i] = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0); }
-
+
// Compute bits to read & bit mark
if (subencoding == 2) { br = 1; bm = 1; } else if (subencoding <= 4) { br = 2; bm = 3; }
-
+
// Display all the bits
while (rlecount < s && ptr < data.length) { v = data.charCodeAt(ptr++); for (i = (8 - br) ; i >= 0; i -= br) { _setPixel(palette[(v >> i) & bm], rlecount++); } }
_putImage(obj.spare, x, y);
@@ -280,10 +290,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
while (rlecount < s && ptr < data.length) {
// Get the run color
v = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0);
-
+
// Decode the run length. This is the fastest and most compact way I found to do this.
runlength = 1; do { runlength += (runlengthdecode = data.charCodeAt(ptr++)); } while (runlengthdecode == 255);
-
+
// Draw a run
while (--runlength >= 0) { _setPixel(v, rlecount++); }
}
@@ -292,22 +302,22 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
else if (subencoding > 129) { // Palette RLE encoded tile
// Read the palette
for (i = 0; i < (subencoding - 128) ; i++) { palette[i] = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0); }
-
+
// Decode RLE on palette
while (rlecount < s && ptr < data.length) {
// Setup the run, get the color index and get the color from the palette.
runlength = 1; index = data.charCodeAt(ptr++); v = palette[index % 128];
-
+
// If the index starts with high order bit 1, this is a run and decode the run length.
if (index > 127) { do { runlength += (runlengthdecode = data.charCodeAt(ptr++)); } while (runlengthdecode == 255); }
-
+
// Draw a run
while (--runlength >= 0) { _setPixel(v, rlecount++); }
}
_putImage(obj.spare, x, y);
}
}
-
+
function _putImage(i, x, y) {
// ###BEGIN###{DesktopRotation}
var xx = _arotX(x, y);
@@ -316,10 +326,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
// ###END###{DesktopRotation}
obj.canvas.putImageData(i, x, y);
}
-
+
function _setPixel(v, p) {
var pp = p * 4;
-
+
// ###BEGIN###{DesktopRotation}
if (obj.rotation > 0) {
if (obj.rotation == 1) {
@@ -337,7 +347,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
}
// ###END###{DesktopRotation}
-
+
if (obj.bpp == 1) {
// Set 8bit color RGB332
obj.spare.data[pp++] = v & 224;
@@ -351,7 +361,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
obj.spare.data[pp] = 0xFF; // Set alpha channel to opaque.
}
-
+
// ###BEGIN###{DesktopRotation}
function _arotX(x, y) {
if (obj.rotation == 0) return x;
@@ -360,7 +370,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return y;
return 0;
}
-
+
function _arotY(x, y) {
if (obj.rotation == 0) return y;
if (obj.rotation == 1) return x;
@@ -368,7 +378,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return obj.canvas.canvas.height - obj.spareh - x;
return 0;
}
-
+
function _crotX(x, y) {
if (obj.rotation == 0) return x;
if (obj.rotation == 1) return y;
@@ -376,7 +386,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return obj.canvas.canvas.height - y;
return 0;
}
-
+
function _crotY(x, y) {
if (obj.rotation == 0) return y;
if (obj.rotation == 1) return obj.canvas.canvas.width - x;
@@ -384,7 +394,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return x;
return 0;
}
-
+
function _rotX(x, y) {
if (obj.rotation == 0) return x;
if (obj.rotation == 1) return x;
@@ -392,7 +402,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return x - obj.canvas.canvas.height;
return 0;
}
-
+
function _rotY(x, y) {
if (obj.rotation == 0) return y;
if (obj.rotation == 1) return y - obj.canvas.canvas.width;
@@ -400,7 +410,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 3) return y;
return 0;
}
-
+
obj.tcanvas = null;
obj.setRotation = function (x) {
while (x < 0) { x += 4; }
@@ -409,7 +419,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
var rw = obj.canvas.canvas.width;
var rh = obj.canvas.canvas.height;
if (obj.rotation == 1 || obj.rotation == 3) { rw = obj.canvas.canvas.height; rh = obj.canvas.canvas.width; }
-
+
// Copy the canvas, put it back in the correct direction
if (obj.tcanvas == null) obj.tcanvas = document.createElement('canvas');
var tcanvasctx = obj.tcanvas.getContext('2d');
@@ -421,7 +431,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.rotation == 1) tcanvasctx.drawImage(obj.canvas.canvas, -obj.canvas.canvas.width, 0);
if (obj.rotation == 2) tcanvasctx.drawImage(obj.canvas.canvas, -obj.canvas.canvas.width, -obj.canvas.canvas.height);
if (obj.rotation == 3) tcanvasctx.drawImage(obj.canvas.canvas, 0, -obj.canvas.canvas.height);
-
+
// Change the size and orientation and copy the canvas back into the rotation
if (obj.rotation == 0 || obj.rotation == 2) { obj.canvas.canvas.height = rw; obj.canvas.canvas.width = rh; }
if (obj.rotation == 1 || obj.rotation == 3) { obj.canvas.canvas.height = rh; obj.canvas.canvas.width = rw; }
@@ -429,16 +439,16 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.canvas.rotate((newrotation * 90) * Math.PI / 180);
obj.rotation = newrotation;
obj.canvas.drawImage(obj.tcanvas, _rotX(0, 0), _rotY(0, 0));
-
+
obj.width = obj.canvas.canvas.width;
obj.height = obj.canvas.canvas.height;
if (obj.onScreenResize != null) obj.onScreenResize(obj, obj.width, obj.height, obj.CanvasId);
return true;
}
// ###END###{DesktopRotation}
-
+
function _fixColor(c) { return (c > 127) ? (c + 32) : c; }
-
+
function _SendRefresh() {
// ###BEGIN###{DesktopFocus}
if (obj.focusmode > 0) {
@@ -447,34 +457,40 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.Send(String.fromCharCode(3, 1) + ShortToStr(Math.max(Math.min(obj.ox, obj.mx) - obj.focusmode, 0)) + ShortToStr(Math.max(Math.min(obj.oy, obj.my) - obj.focusmode, 0)) + ShortToStr(df + Math.abs(obj.ox - obj.mx)) + ShortToStr(df + Math.abs(obj.oy - obj.my))); // FramebufferUpdateRequest
obj.ox = obj.mx;
obj.oy = obj.my;
- } else
- // ###END###{DesktopFocus} {
+ } else {
+ // ###END###{DesktopFocus}
// Request the entire screen
obj.Send(String.fromCharCode(3, 1, 0, 0, 0, 0) + ShortToStr(obj.rwidth) + ShortToStr(obj.rheight)); // FramebufferUpdateRequest
+ // ###BEGIN###{DesktopFocus}
+ }
+ // ###END###{DesktopFocus}
}
-
+
obj.Start = function () {
//obj.Debug("KVM-Start");
obj.state = 0;
obj.acc = "";
obj.ZRLEfirst = 1;
+ //obj.inbytes = 0;
+ //obj.outbytes = 0;
// ###BEGIN###{Inflate}
- inflate_start();
+ obj.inflate.inflateReset();
// ###END###{Inflate}
for (var i in obj.sparecache) { delete obj.sparecache[i]; }
}
-
+
obj.Stop = function () {
obj.UnGrabMouseInput();
obj.UnGrabKeyInput();
obj.parent.Stop();
}
-
+
obj.Send = function (x) {
//obj.Debug("KSend(" + x.length + "): " + rstr2hex(x));
+ //obj.outbytes += x.length;
obj.parent.Send(x);
}
-
+
/*
Intel AMT only recognizes a small subset of keysym characters defined in the keysymdef.h so you don’t need to
implement all the languages (this is taken care by the USB Scancode Extension in RFB4.0 protocol).
@@ -535,9 +551,9 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.sendkey(kk, d);
return obj.haltEvent(e);
}
-
+
obj.sendkey = function (k, d) { obj.Send(String.fromCharCode(4, d, 0, 0) + IntToStr(k)); }
-
+
obj.SendCtrlAltDelMsg = function () { obj.sendcad(); }
obj.sendcad = function () {
obj.sendkey(0xFFE3, 1); // Control
@@ -547,10 +563,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.sendkey(0xFFE9, 0); // Alt
obj.sendkey(0xFFE3, 0); // Control
}
-
+
var _MouseInputGrab = false;
var _KeyInputGrab = false;
-
+
obj.GrabMouseInput = function () {
if (_MouseInputGrab == true) return;
var c = obj.canvas.canvas;
@@ -560,7 +576,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
//if (navigator.userAgent.match(/mozilla/i)) c.DOMMouseScroll = obj.xxDOMMouseScroll; else c.onmousewheel = obj.xxMouseWheel;
_MouseInputGrab = true;
}
-
+
obj.UnGrabMouseInput = function () {
if (_MouseInputGrab == false) return;
var c = obj.canvas.canvas;
@@ -570,7 +586,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
//if (navigator.userAgent.match(/mozilla/i)) c.DOMMouseScroll = null; else c.onmousewheel = null;
_MouseInputGrab = false;
}
-
+
obj.GrabKeyInput = function () {
if (_KeyInputGrab == true) return;
document.onkeyup = obj.handleKeyUp;
@@ -578,7 +594,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
document.onkeypress = obj.handleKeys;
_KeyInputGrab = true;
}
-
+
obj.UnGrabKeyInput = function () {
if (_KeyInputGrab == false) return;
document.onkeyup = null;
@@ -586,12 +602,12 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
document.onkeypress = null;
_KeyInputGrab = false;
}
-
+
obj.handleKeys = function (e) { return obj.haltEvent(e); }
obj.handleKeyUp = function (e) { return _keyevent(0, e); }
obj.handleKeyDown = function (e) { return _keyevent(1, e); }
obj.haltEvent = function (e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
-
+
// RFB "PointerEvent" and mouse handlers
obj.mousedown = function (e) { obj.buttonmask |= (1 << e.button); return obj.mousemove(e); }
obj.mouseup = function (e) { obj.buttonmask &= (0xFFFF - (1 << e.button)); return obj.mousemove(e); }
@@ -600,15 +616,17 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
var pos = obj.getPositionOfControl(Q(obj.canvasid));
obj.mx = (e.pageX - pos[0]) * (obj.canvas.canvas.height / Q(obj.canvasid).offsetHeight);
obj.my = ((e.pageY - pos[1] + (scrolldiv ? scrolldiv.scrollTop : 0)) * (obj.canvas.canvas.width / Q(obj.canvasid).offsetWidth));
-
+
// ###BEGIN###{DesktopRotation}
- obj.mx2 = _crotX(obj.mx, obj.my);
- obj.my = _crotY(obj.mx, obj.my);
- obj.mx = obj.mx2;
+ if (obj.noMouseRotate != true) {
+ obj.mx2 = _crotX(obj.mx, obj.my);
+ obj.my = _crotY(obj.mx, obj.my);
+ obj.mx = obj.mx2;
+ }
// ###END###{DesktopRotation}
-
+
obj.Send(String.fromCharCode(5, obj.buttonmask) + ShortToStr(obj.mx) + ShortToStr(obj.my));
-
+
// ###BEGIN###{DesktopFocus}
// Update focus area if we are in focus mode
QV('DeskFocus', obj.focusmode);
@@ -627,11 +645,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
q.height = ((df * qx) - 6) + 'px';
}
// ###END###{DesktopFocus}
-
+
return obj.haltEvent(e);
}
- obj.mousewheel = function (e) { }
-
+
obj.getPositionOfControl = function (Control) {
var Position = Array(2);
Position[0] = Position[1] = 0;
@@ -642,6 +659,6 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
return Position;
}
-
+
return obj;
}
diff --git a/public/scripts/zlib-adler32.js b/public/scripts/zlib-adler32.js
new file mode 100644
index 00000000..d1165fab
--- /dev/null
+++ b/public/scripts/zlib-adler32.js
@@ -0,0 +1,279 @@
+/* zlib-adler32.js -- JavaScript implementation for the zlib adler32.
+ Version: 0.2.0
+ LastModified: Apr 12 2012
+ Copyright (C) 2012 Masanao Izumo
+
+ API documentation
+==============================================================================
+Usage: adler = ZLIB.adler32(adler, buf, offset, len);
+
+ Update a running Adler-32 checksum with the bytes buf[offset..offset+len-1] and
+ return the updated checksum. If buf is null, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ var adler = ZLIB.adler32(0, null, 0, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = ZLIB.adler32(adler, buffer, 0, length);
+ }
+ if (adler != original_adler) error();
+
+==============================================================================
+Usage: adler = ZLIB.adler32_combine(adler1, adler2, len2);
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+if( typeof ZLIB === 'undefined' ) {
+ alert('ZLIB is not defined. SRC zlib.js before zlib-adler32.js')
+}
+
+(function() {
+
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+var BASE = 65521; /* largest prime smaller than 65536 */
+var NMAX = 5552;
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+/* ========================================================================= */
+function adler32_string(adler, buf, offset, len)
+{
+ var sum2;
+ var n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >>> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf.charCodeAt(offset) & 0xff;
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf === null)
+ return 1;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += buf.charCodeAt(offset++) & 0xff;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 %= BASE; /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX >> 4; /* NMAX is divisible by 16 */
+ do {
+ /* 16 sums unrolled */
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ } while (--n);
+ adler %= BASE;
+ sum2 %= BASE;
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ }
+ while (len--) {
+ adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
+ }
+ adler %= BASE;
+ sum2 %= BASE;
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+function adler32_array(adler, buf, offset, len)
+{
+ var sum2;
+ var n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >>> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[offset];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf === null)
+ return 1;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += buf[offset++];
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 %= BASE; /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX >> 4; /* NMAX is divisible by 16 */
+ do {
+ /* 16 sums unrolled */
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ } while (--n);
+ adler %= BASE;
+ sum2 %= BASE;
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ adler += buf[offset++]; sum2 += adler;
+ }
+ while (len--) {
+ adler += buf[offset++]; sum2 += adler;
+ }
+ adler %= BASE;
+ sum2 %= BASE;
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+ZLIB.adler32 = function(adler, buf, offset, len)
+{
+ if(typeof buf === 'string') {
+ return adler32_string(adler, buf, offset, len);
+ } else {
+ return adler32_array(adler, buf, offset, len);
+ }
+};
+
+ZLIB.adler32_combine = function(adler1, adler2, len2)
+{
+ var sum1;
+ var sum2;
+ var rem;
+
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffff;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ len2 %= BASE; /* assumes len2 >= 0 */
+ rem = len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ sum2 %= BASE;
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
+
+}());
diff --git a/public/scripts/zlib-crc32.js b/public/scripts/zlib-crc32.js
new file mode 100644
index 00000000..734bab63
--- /dev/null
+++ b/public/scripts/zlib-crc32.js
@@ -0,0 +1,246 @@
+/* zlib-adler32.js -- JavaScript implementation for the zlib crc32.
+ Version: 0.2.0
+ LastModified: Apr 12 2012
+ Copyright (C) 2012 Masanao Izumo
+
+ API documentation
+==============================================================================
+Usage: crc = ZLIB.crc32(crc, buf, offset, len);
+
+ Update a running CRC-32 with the bytes buf[offset..offset+len-1] and return the
+ updated CRC-32. If buf is null, this function returns the required
+ initial value for the for the crc. Pre- and post-conditioning (one's
+ complement) is performed within this function so it shouldn't be done by the
+ application.
+
+ Usage example:
+
+ var crc = ZLIB.crc32(0, null, 0, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = ZLIB.crc32(crc, buffer, 0, length);
+ }
+ if (crc != original_crc) error();
+
+==============================================================================
+Usage: crc = crc32_combine(crc1, crc2, len2);
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+if( typeof ZLIB === 'undefined' ) {
+ alert('ZLIB is not defined. SRC zlib.js before zlib-crc32.js')
+}
+
+(function() {
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+var crc_table = [
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d ];
+
+/* ========================================================================= */
+function crc32_string(crc, buf, offset, len)
+{
+ if (buf == null) return 0;
+
+ crc = crc ^ 0xffffffff;
+ while (len >= 8) {
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ len -= 8;
+ }
+ if (len) do {
+ crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
+ } while (--len);
+ return crc ^ 0xffffffff;
+}
+
+/* ========================================================================= */
+function crc32_array(crc, buf, offset, len)
+{
+ if (buf == null) return 0;
+
+ crc = crc ^ 0xffffffff;
+ while (len >= 8) {
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ len -= 8;
+ }
+ if (len) do {
+ crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
+ } while (--len);
+ return crc ^ 0xffffffff;
+}
+
+/* ========================================================================= */
+ZLIB.crc32 = function(crc, buf, offset, len)
+{
+ if(typeof buf === 'string') {
+ return crc32_string(crc, buf, offset, len);
+ } else {
+ return crc32_array(crc, buf, offset, len);
+ }
+};
+
+/* ========================================================================= */
+var GF2_DIM = 32; /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+function gf2_matrix_times(mat, vec)
+{
+ var sum;
+ var mat_i = 0;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= mat[mat_i];
+ vec >>= 1;
+ mat_i++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+function gf2_matrix_square(square, mat)
+{
+ var n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+ZLIB.crc32_combine = function(crc1, crc2, len2)
+{
+ var n;
+ var row;
+ var even; /* even-power-of-two zeros operator */
+ var odd; /* odd-power-of-two zeros operator */
+
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
+ return crc1;
+
+ even = new Array(GF2_DIM);
+ odd = new Array(GF2_DIM);
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+};
+
+}());
diff --git a/public/scripts/zlib-inflate.js b/public/scripts/zlib-inflate.js
new file mode 100644
index 00000000..c536b5e6
--- /dev/null
+++ b/public/scripts/zlib-inflate.js
@@ -0,0 +1,1950 @@
+/* zlib-inflate.js -- JavaScript implementation for the zlib inflate.
+ Version: 0.2.0
+ LastModified: Apr 12 2012
+ Copyright (C) 2012 Masanao Izumo
+
+ This library is one of the JavaScript zlib implementation.
+ Some API's are modified from the original.
+ Only inflate API is implemented.
+
+ The original copyright notice (zlib 1.2.6):
+
+ Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+/*
+ API documentation
+==============================================================================
+Usage: z_stream = ZLIB.inflateInit([windowBits]);
+
+ Create the stream object for decompression.
+ See zlib.h for windowBits information.
+
+==============================================================================
+Usage: decoded_string = z_stream.inflate(encoded_string [, {OPTIONS...}]);
+
+OPTIONS:
+ next_in: decode start offset for encoded_string.
+
+ avail_in: // TODO document. See zlib.h for the information.
+
+ avail_out: // TODO document. See zlib.h for the information.
+
+ flush: // TODO document. See zlib.h for the information.
+
+Ex: decoded_string = z_stream.inflate(encoded_string);
+ decoded_string = z_stream.inflate(encoded_string,
+ {next_in: 0,
+ avail_in: encoded_string.length,
+ avail_out: 1024,
+ flush: ZLIB.Z_NO_FLUSH});
+
+ See zlib.h for more information.
+
+==============================================================================
+Usage: z_stream.inflateReset();
+ TODO document
+
+*/
+
+if( typeof ZLIB === 'undefined' ) {
+ alert('ZLIB is not defined. SRC zlib.js before zlib-inflate.js')
+}
+
+(function() {
+
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+var DEF_WBITS = 15;
+
+// inflate_mode
+var HEAD = 0; /* i: waiting for magic header */
+var FLAGS = 1; /* i: waiting for method and flags (gzip) */
+var TIME = 2; /* i: waiting for modification time (gzip) */
+var OS = 3; /* i: waiting for extra flags and operating system (gzip) */
+var EXLEN = 4; /* i: waiting for extra length (gzip) */
+var EXTRA = 5; /* i: waiting for extra bytes (gzip) */
+var NAME = 6; /* i: waiting for end of file name (gzip) */
+var COMMENT = 7; /* i: waiting for end of comment (gzip) */
+var HCRC = 8; /* i: waiting for header crc (gzip) */
+var DICTID = 9; /* i: waiting for dictionary check value */
+var DICT = 10; /* waiting for inflateSetDictionary() call */
+var TYPE = 11; /* i: waiting for type bits, including last-flag bit */
+var TYPEDO = 12; /* i: same, but skip check to exit inflate on new block */
+var STORED = 13; /* i: waiting for stored size (length and complement) */
+var COPY_ = 14; /* i/o: same as COPY below, but only first time in */
+var COPY = 15; /* i/o: waiting for input or output to copy stored block */
+var TABLE = 16; /* i: waiting for dynamic block table lengths */
+var LENLENS = 17; /* i: waiting for code length code lengths */
+var CODELENS = 18; /* i: waiting for length/lit and distance code lengths */
+var LEN_ = 19; /* i: same as LEN below, but only first time in */
+var LEN = 20; /* i: waiting for length/lit/eob code */
+var LENEXT = 21; /* i: waiting for length extra bits */
+var DIST = 22; /* i: waiting for distance code */
+var DISTEXT = 23; /* i: waiting for distance extra bits */
+var MATCH = 24; /* o: waiting for output space to copy string */
+var LIT = 25; /* o: waiting for output space to write literal */
+var CHECK = 26; /* i: waiting for 32-bit check value */
+var LENGTH = 27; /* i: waiting for 32-bit length (gzip) */
+var DONE = 28; /* finished check, done -- remain here until reset */
+var BAD = 29; /* got a data error -- remain here until reset */
+var MEM = 30; /* got an inflate() memory error -- remain here until reset */
+var SYNC = 31; /* looking for synchronization bytes to restart inflate() */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+var ENOUGH_LENS = 852;
+var ENOUGH_DISTS = 592;
+var ENOUGH = (ENOUGH_LENS + ENOUGH_DISTS);
+
+/* Type of code to build for inflate_table() */
+var CODES = 0;
+var LENS = 1;
+var DISTS = 2;
+
+
+
+var inflate_table_lbase = [ /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];
+var inflate_table_lext = [ /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 69];
+var inflate_table_dbase = [ /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0];
+var inflate_table_dext = [ /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64];
+
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+ZLIB.inflate_copyright =
+ ' inflate 1.2.6 Copyright 1995-2012 Mark Adler ';
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+*/
+function inflate_table(state, type)
+{
+ var MAXBITS = 15;
+ var table = state.next;
+ var bits = (type == DISTS ? state.distbits : state.lenbits);
+ var work = state.work;
+ var lens = state.lens;
+ var lens_offset = (type == DISTS ? state.nlen : 0);
+ var state_codes = state.codes;
+ var codes;
+ if(type == LENS)
+ codes = state.nlen;
+ else if(type == DISTS)
+ codes = state.ndist;
+ else // CODES
+ codes = 19;
+
+ var len; /* a code's length in bits */
+ var sym; /* index of code symbols */
+ var min, max; /* minimum and maximum code lengths */
+ var root; /* number of index bits for root table */
+ var curr; /* number of index bits for current table */
+ var drop; /* code bits to drop for sub-table */
+ var left; /* number of prefix codes available */
+ var used; /* code entries in table used */
+ var huff; /* Huffman code */
+ var incr; /* for incrementing code, index */
+ var fill; /* index for replicating entries */
+ var low; /* low bits for current root entry */
+ var mask; /* mask for low root bits */
+ var here; /* table entry for duplication */
+ var next; /* next available space in table */
+ var base; /* base value table to use */
+ var base_offset;
+ var extra; /* extra bits table to use */
+ var extra_offset;
+ var end; /* use base and extra for symbol > end */
+ var count = new Array(MAXBITS+1); /* number of codes of each length */
+ var offs = new Array(MAXBITS+1); /* offsets in table for each length */
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[lens_offset + sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = bits;
+
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) {
+ /* no symbols to code at all */
+ /* invalid code marker */
+ here = {op:64, bits:1, val:0};
+ state_codes[table++] = here; /* make a table to force an error */
+ state_codes[table++] = here;
+ if(type == DISTS) state.distbits = 1; else state.lenbits = 1; // *bits = 1;
+ state.next = table;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min < max; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1)) {
+ state.next = table;
+ return -1; /* incomplete set */
+ }
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[lens_offset + sym] != 0) work[offs[lens[lens_offset + sym]]++] = sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ base_offset = 0;
+ extra_offset = 0;
+ end = 19;
+ break;
+ case LENS:
+ base = inflate_table_lbase;
+ base_offset = -257; // base -= 257;
+ extra = inflate_table_lext;
+ extra_offset = -257; // extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = inflate_table_dbase;
+ extra = inflate_table_dext;
+ base_offset = 0;
+ extra_offset = 0;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = -1; /* trigger new sub-table when len > root */
+ used = 1 << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS)) {
+ state.next = table;
+ return 1;
+ }
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ here = {op:0, bits:len - drop, val:0};
+ if (work[sym] < end) {
+ here.val = work[sym];
+ }
+ else if (work[sym] > end) {
+ here.op = extra[extra_offset + work[sym]];
+ here.val = base[base_offset + work[sym]];
+ }
+ else {
+ here.op = 32 + 64; /* end of block */
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1 << (len - drop);
+ fill = 1 << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ state_codes[next + (huff >>> drop) + fill] = here;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1 << (len - 1);
+ while (huff & incr)
+ incr >>>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[lens_offset + work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1 << curr;
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS)) {
+ state.next = table;
+ return 1;
+ }
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ state_codes[table + low] = {op:curr, bits:root, val:next - table};
+ }
+ }
+
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ state_codes[next + huff] = {op:64, bits:len - drop, val:0};
+ }
+
+ /* set return parameters */
+ state.next = table + used;
+ if(type == DISTS) state.distbits = root; else state.lenbits = root; //*bits = root;
+ return 0;
+}
+
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+function inflate_fast(strm,
+ start) /* inflate()'s starting value for strm->avail_out */
+{
+ var state;
+ var input_data; /* local strm->input_data */
+ var next_in; /* zlib.js: index of input_data */
+ var last; /* while next_in < last, enough input available */
+ var out; /* local strm.next_out */
+ var beg; /* inflate()'s initial strm.next_out */
+ var end; /* while out < end, enough space available */
+//NOSPRT #ifdef INFLATE_STRICT
+// unsigned dmax; /* maximum distance from zlib header */
+//#endif
+ var wsize; /* window size or zero if not using window */
+ var whave; /* valid bytes in the window */
+ var wnext; /* window write index */
+ var window; /* allocated sliding window, if wsize != 0 */
+ var hold; /* local strm->hold */
+ var bits; /* local strm->bits */
+ var codes; /* zlib.js: local state.codes */
+ var lcode; /* local strm->lencode */
+ var dcode; /* local strm->distcode */
+ var lmask; /* mask for first level of length codes */
+ var dmask; /* mask for first level of distance codes */
+ var here; /* retrieved table entry */
+ var op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ var len; /* match length, unused bytes */
+ var dist; /* match distance */
+ // var from; /* where to copy match from */
+ var from_window_offset = -1; /* index of window[] */
+ var from_out_offset = -1; /* index of next_out[] */
+
+ /* copy state to local variables */
+ state = strm.state;
+ input_data = strm.input_data;
+ next_in = strm.next_in;
+ last = next_in + strm.avail_in - 5;
+ out = strm.next_out;
+ beg = out - (start - strm.avail_out);
+ end = out + (strm.avail_out - 257);
+//NOSPRT #ifdef INFLATE_STRICT
+// dmax = state->dmax;
+//#endif
+ wsize = state.wsize;
+ whave = state.whave;
+ wnext = state.wnext;
+ window = state.window;
+ hold = state.hold;
+ bits = state.bits;
+ codes = state.codes;
+ lcode = state.lencode;
+ dcode = state.distcode;
+ lmask = (1 << state.lenbits) - 1;
+ dmask = (1 << state.distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+loop: do {
+ if (bits < 15) {
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ }
+ here = codes[lcode + (hold & lmask)];
+ dolen: while(true) {
+ op = here.bits;
+ hold >>>= op;
+ bits -= op;
+ op = here.op;
+ if (op == 0) { /* literal */
+// Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+// "inflate: literal '%c'\n" :
+// "inflate: literal 0x%02x\n", here.val));
+ strm.output_data += String.fromCharCode(here.val);
+ out++;
+ }
+ else if (op & 16) { /* length base */
+ len = here.val;
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ }
+ len += hold & ((1 << op) - 1);
+ hold >>>= op;
+ bits -= op;
+ }
+// Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ }
+ here = codes[dcode + (hold & dmask)];
+ dodist: while(true) {
+ op = here.bits;
+ hold >>>= op;
+ bits -= op;
+ op = here.op;
+ if (op & 16) { /* distance base */
+ dist = here.val;
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
+ bits += 8;
+ }
+ }
+ dist += hold & ((1 << op) - 1);
+//NOSPRT #ifdef INFLATE_STRICT
+// if (dist > dmax) {
+// strm->msg = (char *)"invalid distance too far back";
+// state->mode = BAD;
+// break loop;
+// }
+//#endif
+ hold >>>= op;
+ bits -= op;
+// Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = out - beg; /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ if (state.sane) {
+ strm.msg = 'invalid distance too far back';
+ state.mode = BAD;
+ break loop;
+ }
+//NOSPRT #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+// if (len <= op - whave) {
+// do {
+// PUP(out) = 0;
+// } while (--len);
+// continue;
+// }
+// len -= op - whave;
+// do {
+// PUP(out) = 0;
+// } while (--op > whave);
+// if (op == 0) {
+// from = out - dist;
+// do {
+// PUP(out) = PUP(from);
+// } while (--len);
+// continue;
+// }
+//#endif
+ } // if (op > whave)
+
+ from_window_offset = 0;
+ from_out_offset = -1;
+ if (wnext == 0) { /* very common case */
+ from_window_offset += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ strm.output_data += window.substring(from_window_offset, from_window_offset + op);
+ out += op;
+ op = 0;
+ from_window_offset = -1;
+ from_out_offset = out - dist; /* rest from output */
+ }
+ }
+//NOTREACHED else if (wnext < op) { /* wrap around window */
+//NOTREACHED from += wsize + wnext - op;
+//NOTREACHED op -= wnext;
+//NOTREACHED if (op < len) { /* some from end of window */
+//NOTREACHED len -= op;
+//NOTREACHED do {
+//NOTREACHED PUP(out) = PUP(from);
+//NOTREACHED } while (--op);
+//NOTREACHED from = window - OFF;
+//NOTREACHED if (wnext < len) { /* some from start of window */
+//NOTREACHED op = wnext;
+//NOTREACHED len -= op;
+//NOTREACHED do {
+//NOTREACHED PUP(out) = PUP(from);
+//NOTREACHED } while (--op);
+//NOTREACHED from = out - dist; /* rest from output */
+//NOTREACHED }
+//NOTREACHED }
+//NOTREACHED }
+ else { /* contiguous in window */
+ from_window_offset += wnext - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ strm.output_data += window.substring(from_window_offset, from_window_offset + op);
+ out += op;
+ from_window_offset = -1;
+ from_out_offset = out - dist; /* rest from output */
+ }
+ }
+ }
+ else {
+ from_window_offset = -1;
+ from_out_offset = out - dist; /* copy direct from output */
+ }
+
+ if (from_window_offset >= 0) {
+ strm.output_data += window.substring(from_window_offset, from_window_offset + len);
+ out += len;
+ from_window_offset += len;
+ } else {
+ var len_inner = len;
+ if(len_inner > out - from_out_offset)
+ len_inner = out - from_out_offset;
+ strm.output_data += strm.output_data.substring(
+ from_out_offset, from_out_offset + len_inner);
+ out += len_inner;
+ len -= len_inner;
+ from_out_offset += len_inner;
+ out += len;
+ while (len > 2) {
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ len -= 3;
+ }
+ if (len) {
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ if (len > 1)
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ here = codes[dcode + (here.val + (hold & ((1 << op) - 1)))];
+ continue dodist; // goto dodist
+ }
+ else {
+ strm.msg = 'invalid distance code';
+ state.mode = BAD;
+ break loop;
+ }
+ break dodist; }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ here = codes[lcode + (here.val + (hold & ((1 << op) - 1)))];
+ continue dolen; // goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ // Tracevv((stderr, "inflate: end of block\n"));
+ state.mode = TYPE;
+ break loop;
+ }
+ else {
+ strm.msg = 'invalid literal/length code';
+ state.mode = BAD;
+ break loop;
+ }
+ break dolen; }
+ } while (next_in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >>> 3;
+ next_in -= len;
+ bits -= len << 3;
+ hold &= (1 << bits) - 1;
+
+ /* update state and return */
+ strm.next_in = next_in;
+ strm.next_out = out;
+ strm.avail_in = (next_in < last ? 5 + (last - next_in) : 5 - (next_in - last));
+ strm.avail_out = (out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state.hold = hold;
+ state.bits = bits;
+}
+
+function new_array(size)
+{
+ var i;
+ var ary = new Array(size);
+ for(i = 0; i < size; i++)
+ ary[i] = 0;
+ return ary;
+}
+
+function getarg(opts, name, def_value)
+{
+ return (opts && (name in opts)) ? opts[name] : def_value;
+}
+
+function checksum_none()
+{
+ return 0;
+}
+
+/**
+ * z_stream constructor
+ * @constructor
+ */
+function inflate_state()
+{
+ var i;
+
+ this.mode = 0; /* current inflate mode */
+ this.last = 0; /* true if processing last block */
+ this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
+ this.havedict = 0; /* true if dictionary provided */
+ this.flags = 0; /* gzip header method and flags (0 if zlib) */
+ this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
+ this.check = 0; /* protected copy of check value */
+ this.total = 0; /* protected copy of output count */
+ this.head = null; /* where to save gzip header information */
+ /* sliding window */
+ this.wbits = 0; /* log base 2 of requested window size */
+ this.wsize = 0; /* window size or zero if not using window */
+ this.whave = 0; /* valid bytes in the window */
+ this.wnext = 0; /* window write index (TODO remove) */
+ this.window = null; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ this.hold = 0; /* input bit accumulator */
+ this.bits = 0; /* number of bits in "in" */
+ /* for string and stored block copying */
+ this.length = 0; /* literal or length of data to copy */
+ this.offset = 0; /* distance back to copy string from */
+ /* for table and code decoding */
+ this.extra = 0; /* extra bits needed */
+ /* fixed and dynamic code tables */
+
+ /* zlib.js: modified implementation: lencode, distcode, next are offset of codes[] */
+ this.lencode = 0; /* starting table for length/literal codes */
+ this.distcode = 0; /* starting table for distance codes */
+ this.lenbits = 0; /* index bits for lencode */
+ this.distbits = 0; /* index bits for distcode */
+ /* dynamic table building */
+ this.ncode = 0; /* number of code length code lengths */
+ this.nlen = 0; /* number of length code lengths */
+ this.ndist = 0; /* number of distance code lengths */
+ this.have = 0; /* number of code lengths in lens[] */
+ this.next = 0; /* next available space in codes[] */
+ this.lens = new_array(320); /* temporary storage for code lengths */
+ this.work = new_array(288); /* work area for code table building */
+ this.codes = new Array(ENOUGH); /* space for code tables */
+ var c = {op:0, bits:0, val:0};
+ for(i = 0; i < ENOUGH; i++)
+ this.codes[i] = c;
+ this.sane = 0; /* if false, allow invalid distance too far */
+ this.back = 0; /* bits back of last unprocessed length/lit */
+ this.was = 0; /* initial length of match */
+}
+
+ZLIB.inflateResetKeep = function(strm)
+{
+ var state;
+
+ if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
+ state = strm.state;
+ strm.total_in = strm.total_out = state.total = 0;
+ strm.msg = null;
+ if (state.wrap) { /* to support ill-conceived Java test suite */
+ strm.adler = state.wrap & 1;
+ }
+
+ state.mode = HEAD;
+ state.last = 0;
+ state.havedict = 0;
+ state.dmax = 32768;
+ state.head = null;
+ state.hold = 0;
+ state.bits = 0;
+ state.lencode = 0;
+ state.distcode = 0;
+ state.next = 0;
+ state.sane = 1;
+ state.back = -1;
+ return ZLIB.Z_OK;
+};
+
+// Usage: strm = ZLIB.inflateReset(z_stream [, windowBits]);
+ZLIB.inflateReset = function(strm, windowBits)
+{
+ var wrap;
+ var state;
+
+ /* get the state */
+ if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
+ state = strm.state;
+
+ if(typeof windowBits === "undefined")
+ windowBits = DEF_WBITS;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >>> 4) + 1;
+ if (windowBits < 48)
+ windowBits &= 15;
+ }
+
+ if(wrap == 1 && (typeof ZLIB.adler32 === 'function')) {
+ strm.checksum_function = ZLIB.adler32;
+ } else if(wrap == 2 && (typeof ZLIB.crc32 === 'function')) {
+ strm.checksum_function = ZLIB.crc32;
+ } else {
+ strm.checksum_function = checksum_none;
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return ZLIB.Z_STREAM_ERROR;
+ if (state.window && state.wbits != windowBits) {
+ state.window = null;
+ }
+
+ /* update state and reset the rest of it */
+ state.wrap = wrap;
+ state.wbits = windowBits;
+ state.wsize = 0;
+ state.whave = 0;
+ state.wnext = 0;
+ return ZLIB.inflateResetKeep(strm);
+};
+
+// Usage: strm = ZLIB.inflateInit([windowBits]);
+ZLIB.inflateInit = function(windowBits)
+{
+ var strm = new ZLIB.z_stream();
+ strm.state = new inflate_state();
+ ZLIB.inflateReset(strm, windowBits);
+ return strm;
+};
+
+ZLIB.inflatePrime = function(strm, bits, value)
+{
+ var state;
+
+ if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
+ state = strm.state;
+ if (bits < 0) {
+ state.hold = 0;
+ state.bits = 0;
+ return ZLIB.Z_OK;
+ }
+ if (bits > 16 || state.bits + bits > 32) return ZLIB.Z_STREAM_ERROR;
+ value &= (1 << bits) - 1;
+ state.hold += value << state.bits;
+ state.bits += bits;
+ return ZLIB.Z_OK;
+};
+
+var lenfix_ary = null;
+var distfix_ary = null;
+function fixedtables(state)
+{
+ var i;
+ if (!lenfix_ary) lenfix_ary = [ { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 80 }, { op: 0, bits: 8, val: 16 }, { op: 20, bits: 8, val: 115 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 112 }, { op: 0, bits: 8, val: 48 }, { op: 0, bits: 9, val: 192 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 96 }, { op: 0, bits: 8, val: 32 }, { op: 0, bits: 9, val: 160 }, { op: 0, bits: 8, val: 0 }, { op: 0, bits: 8, val: 128 }, { op: 0, bits: 8, val: 64 }, { op: 0, bits: 9, val: 224 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 88 }, { op: 0, bits: 8, val: 24 }, { op: 0, bits: 9, val: 144 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 120 }, { op: 0, bits: 8, val: 56 }, { op: 0, bits: 9, val: 208 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 104 }, { op: 0, bits: 8, val: 40 }, { op: 0, bits: 9, val: 176 }, { op: 0, bits: 8, val: 8 }, { op: 0, bits: 8, val: 136 }, { op: 0, bits: 8, val: 72 }, { op: 0, bits: 9, val: 240 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 84 }, { op: 0, bits: 8, val: 20 }, { op: 21, bits: 8, val: 227 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 116 }, { op: 0, bits: 8, val: 52 }, { op: 0, bits: 9, val: 200 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 100 }, { op: 0, bits: 8, val: 36 }, { op: 0, bits: 9, val: 168 }, { op: 0, bits: 8, val: 4 }, { op: 0, bits: 8, val: 132 }, { op: 0, bits: 8, val: 68 }, { op: 0, bits: 9, val: 232 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 92 }, { op: 0, bits: 8, val: 28 }, { op: 0, bits: 9, val: 152 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 124 }, { op: 0, bits: 8, val: 60 }, { op: 0, bits: 9, val: 216 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 108 }, { op: 0, bits: 8, val: 44 }, { op: 0, bits: 9, val: 184 }, { op: 0, bits: 8, val: 12 }, { op: 0, bits: 8, val: 140 }, { op: 0, bits: 8, val: 76 }, { op: 0, bits: 9, val: 248 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 82 }, { op: 0, bits: 8, val: 18 }, { op: 21, bits: 8, val: 163 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 114 }, { op: 0, bits: 8, val: 50 }, { op: 0, bits: 9, val: 196 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 98 }, { op: 0, bits: 8, val: 34 }, { op: 0, bits: 9, val: 164 }, { op: 0, bits: 8, val: 2 }, { op: 0, bits: 8, val: 130 }, { op: 0, bits: 8, val: 66 }, { op: 0, bits: 9, val: 228 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 90 }, { op: 0, bits: 8, val: 26 }, { op: 0, bits: 9, val: 148 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 122 }, { op: 0, bits: 8, val: 58 }, { op: 0, bits: 9, val: 212 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 106 }, { op: 0, bits: 8, val: 42 }, { op: 0, bits: 9, val: 180 }, { op: 0, bits: 8, val: 10 }, { op: 0, bits: 8, val: 138 }, { op: 0, bits: 8, val: 74 }, { op: 0, bits: 9, val: 244 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 86 }, { op: 0, bits: 8, val: 22 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 118 }, { op: 0, bits: 8, val: 54 }, { op: 0, bits: 9, val: 204 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 102 }, { op: 0, bits: 8, val: 38 }, { op: 0, bits: 9, val: 172 }, { op: 0, bits: 8, val: 6 }, { op: 0, bits: 8, val: 134 }, { op: 0, bits: 8, val: 70 }, { op: 0, bits: 9, val: 236 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 94 }, { op: 0, bits: 8, val: 30 }, { op: 0, bits: 9, val: 156 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 126 }, { op: 0, bits: 8, val: 62 }, { op: 0, bits: 9, val: 220 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 110 }, { op: 0, bits: 8, val: 46 }, { op: 0, bits: 9, val: 188 }, { op: 0, bits: 8, val: 14 }, { op: 0, bits: 8, val: 142 }, { op: 0, bits: 8, val: 78 }, { op: 0, bits: 9, val: 252 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 81 }, { op: 0, bits: 8, val: 17 }, { op: 21, bits: 8, val: 131 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 113 }, { op: 0, bits: 8, val: 49 }, { op: 0, bits: 9, val: 194 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 97 }, { op: 0, bits: 8, val: 33 }, { op: 0, bits: 9, val: 162 }, { op: 0, bits: 8, val: 1 }, { op: 0, bits: 8, val: 129 }, { op: 0, bits: 8, val: 65 }, { op: 0, bits: 9, val: 226 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 89 }, { op: 0, bits: 8, val: 25 }, { op: 0, bits: 9, val: 146 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 121 }, { op: 0, bits: 8, val: 57 }, { op: 0, bits: 9, val: 210 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 105 }, { op: 0, bits: 8, val: 41 }, { op: 0, bits: 9, val: 178 }, { op: 0, bits: 8, val: 9 }, { op: 0, bits: 8, val: 137 }, { op: 0, bits: 8, val: 73 }, { op: 0, bits: 9, val: 242 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 85 }, { op: 0, bits: 8, val: 21 }, { op: 16, bits: 8, val: 258 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 117 }, { op: 0, bits: 8, val: 53 }, { op: 0, bits: 9, val: 202 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 101 }, { op: 0, bits: 8, val: 37 }, { op: 0, bits: 9, val: 170 }, { op: 0, bits: 8, val: 5 }, { op: 0, bits: 8, val: 133 }, { op: 0, bits: 8, val: 69 }, { op: 0, bits: 9, val: 234 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 93 }, { op: 0, bits: 8, val: 29 }, { op: 0, bits: 9, val: 154 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 125 }, { op: 0, bits: 8, val: 61 }, { op: 0, bits: 9, val: 218 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 109 }, { op: 0, bits: 8, val: 45 }, { op: 0, bits: 9, val: 186 }, { op: 0, bits: 8, val: 13 }, { op: 0, bits: 8, val: 141 }, { op: 0, bits: 8, val: 77 }, { op: 0, bits: 9, val: 250 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 83 }, { op: 0, bits: 8, val: 19 }, { op: 21, bits: 8, val: 195 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 115 }, { op: 0, bits: 8, val: 51 }, { op: 0, bits: 9, val: 198 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 99 }, { op: 0, bits: 8, val: 35 }, { op: 0, bits: 9, val: 166 }, { op: 0, bits: 8, val: 3 }, { op: 0, bits: 8, val: 131 }, { op: 0, bits: 8, val: 67 }, { op: 0, bits: 9, val: 230 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 91 }, { op: 0, bits: 8, val: 27 }, { op: 0, bits: 9, val: 150 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 123 }, { op: 0, bits: 8, val: 59 }, { op: 0, bits: 9, val: 214 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 107 }, { op: 0, bits: 8, val: 43 }, { op: 0, bits: 9, val: 182 }, { op: 0, bits: 8, val: 11 }, { op: 0, bits: 8, val: 139 }, { op: 0, bits: 8, val: 75 }, { op: 0, bits: 9, val: 246 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 87 }, { op: 0, bits: 8, val: 23 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 119 }, { op: 0, bits: 8, val: 55 }, { op: 0, bits: 9, val: 206 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 103 }, { op: 0, bits: 8, val: 39 }, { op: 0, bits: 9, val: 174 }, { op: 0, bits: 8, val: 7 }, { op: 0, bits: 8, val: 135 }, { op: 0, bits: 8, val: 71 }, { op: 0, bits: 9, val: 238 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 95 }, { op: 0, bits: 8, val: 31 }, { op: 0, bits: 9, val: 158 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 127 }, { op: 0, bits: 8, val: 63 }, { op: 0, bits: 9, val: 222 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 111 }, { op: 0, bits: 8, val: 47 }, { op: 0, bits: 9, val: 190 }, { op: 0, bits: 8, val: 15 }, { op: 0, bits: 8, val: 143 }, { op: 0, bits: 8, val: 79 }, { op: 0, bits: 9, val: 254 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 80 }, { op: 0, bits: 8, val: 16 }, { op: 20, bits: 8, val: 115 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 112 }, { op: 0, bits: 8, val: 48 }, { op: 0, bits: 9, val: 193 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 96 }, { op: 0, bits: 8, val: 32 }, { op: 0, bits: 9, val: 161 }, { op: 0, bits: 8, val: 0 }, { op: 0, bits: 8, val: 128 }, { op: 0, bits: 8, val: 64 }, { op: 0, bits: 9, val: 225 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 88 }, { op: 0, bits: 8, val: 24 }, { op: 0, bits: 9, val: 145 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 120 }, { op: 0, bits: 8, val: 56 }, { op: 0, bits: 9, val: 209 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 104 }, { op: 0, bits: 8, val: 40 }, { op: 0, bits: 9, val: 177 }, { op: 0, bits: 8, val: 8 }, { op: 0, bits: 8, val: 136 }, { op: 0, bits: 8, val: 72 }, { op: 0, bits: 9, val: 241 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 84 }, { op: 0, bits: 8, val: 20 }, { op: 21, bits: 8, val: 227 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 116 }, { op: 0, bits: 8, val: 52 }, { op: 0, bits: 9, val: 201 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 100 }, { op: 0, bits: 8, val: 36 }, { op: 0, bits: 9, val: 169 }, { op: 0, bits: 8, val: 4 }, { op: 0, bits: 8, val: 132 }, { op: 0, bits: 8, val: 68 }, { op: 0, bits: 9, val: 233 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 92 }, { op: 0, bits: 8, val: 28 }, { op: 0, bits: 9, val: 153 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 124 }, { op: 0, bits: 8, val: 60 }, { op: 0, bits: 9, val: 217 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 108 }, { op: 0, bits: 8, val: 44 }, { op: 0, bits: 9, val: 185 }, { op: 0, bits: 8, val: 12 }, { op: 0, bits: 8, val: 140 }, { op: 0, bits: 8, val: 76 }, { op: 0, bits: 9, val: 249 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 82 }, { op: 0, bits: 8, val: 18 }, { op: 21, bits: 8, val: 163 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 114 }, { op: 0, bits: 8, val: 50 }, { op: 0, bits: 9, val: 197 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 98 }, { op: 0, bits: 8, val: 34 }, { op: 0, bits: 9, val: 165 }, { op: 0, bits: 8, val: 2 }, { op: 0, bits: 8, val: 130 }, { op: 0, bits: 8, val: 66 }, { op: 0, bits: 9, val: 229 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 90 }, { op: 0, bits: 8, val: 26 }, { op: 0, bits: 9, val: 149 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 122 }, { op: 0, bits: 8, val: 58 },{ op: 0, bits: 9, val: 213 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 106 }, { op: 0, bits: 8, val: 42 }, { op: 0, bits: 9, val: 181 }, { op: 0, bits: 8, val: 10 }, { op: 0, bits: 8, val: 138 },{ op: 0, bits: 8, val: 74 }, { op: 0, bits: 9, val: 245 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 86 }, { op: 0, bits: 8, val: 22 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 },{ op: 0, bits: 8, val: 118 }, { op: 0, bits: 8, val: 54 }, { op: 0, bits: 9, val: 205 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 102 }, { op: 0, bits: 8, val: 38 }, { op: 0, bits: 9, val: 173 },{ op: 0, bits: 8, val: 6 }, { op: 0, bits: 8, val: 134 }, { op: 0, bits: 8, val: 70 }, { op: 0, bits: 9, val: 237 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 94 }, { op: 0, bits: 8, val: 30 },{ op: 0, bits: 9, val: 157 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 126 }, { op: 0, bits: 8, val: 62 }, { op: 0, bits: 9, val: 221 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 110 }, { op: 0, bits: 8, val: 46 }, { op: 0, bits: 9, val: 189 }, { op: 0, bits: 8, val: 14 }, { op: 0, bits: 8, val: 142 }, { op: 0, bits: 8, val: 78 }, { op: 0, bits: 9, val: 253 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 81 }, { op: 0, bits: 8, val: 17 }, { op: 21, bits: 8, val: 131 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 113 }, { op: 0, bits: 8, val: 49 }, { op: 0, bits: 9, val: 195 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 97 }, { op: 0, bits: 8, val: 33 }, { op: 0, bits: 9, val: 163 }, { op: 0, bits: 8, val: 1 }, { op: 0, bits: 8, val: 129 }, { op: 0, bits: 8, val: 65 }, { op: 0, bits: 9, val: 227 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 89 }, { op: 0, bits: 8, val: 25 }, { op: 0, bits: 9, val: 147 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 121 }, { op: 0, bits: 8, val: 57 }, { op: 0, bits: 9, val: 211 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 105 }, { op: 0, bits: 8, val: 41 }, { op: 0, bits: 9, val: 179 }, { op: 0, bits: 8, val: 9 },{ op: 0, bits: 8, val: 137 }, { op: 0, bits: 8, val: 73 }, { op: 0, bits: 9, val: 243 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 85 }, { op: 0, bits: 8, val: 21 }, { op: 16, bits: 8, val: 258 },{ op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 117 }, { op: 0, bits: 8, val: 53 }, { op: 0, bits: 9, val: 203 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 101 }, { op: 0, bits: 8, val: 37 },{ op: 0, bits: 9, val: 171 }, { op: 0, bits: 8, val: 5 }, { op: 0, bits: 8, val: 133 }, { op: 0, bits: 8, val: 69 }, { op: 0, bits: 9, val: 235 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 93 },{ op: 0, bits: 8, val: 29 }, { op: 0, bits: 9, val: 155 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 125 }, { op: 0, bits: 8, val: 61 }, { op: 0, bits: 9, val: 219 }, { op: 18, bits: 7, val: 23 },{ op: 0, bits: 8, val: 109 }, { op: 0, bits: 8, val: 45 }, { op: 0, bits: 9, val: 187 }, { op: 0, bits: 8, val: 13 }, { op: 0, bits: 8, val: 141 }, { op: 0, bits: 8, val: 77 }, { op: 0, bits: 9, val: 251 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 83 }, { op: 0, bits: 8, val: 19 }, { op: 21, bits: 8, val: 195 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 115 }, { op: 0, bits: 8, val: 51 }, { op: 0, bits: 9, val: 199 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 99 }, { op: 0, bits: 8, val: 35 }, { op: 0, bits: 9, val: 167 }, { op: 0, bits: 8, val: 3 }, { op: 0, bits: 8, val: 131 }, { op: 0, bits: 8, val: 67 }, { op: 0, bits: 9, val: 231 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 91 }, { op: 0, bits: 8, val: 27 }, { op: 0, bits: 9, val: 151 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 123 }, { op: 0, bits: 8, val: 59 }, { op: 0, bits: 9, val: 215 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 107 }, { op: 0, bits: 8, val: 43 }, { op: 0, bits: 9, val: 183 }, { op: 0, bits: 8, val: 11 }, { op: 0, bits: 8, val: 139 }, { op: 0, bits: 8, val: 75 }, { op: 0, bits: 9, val: 247 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 87 }, { op: 0, bits: 8, val: 23 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 119 }, { op: 0, bits: 8, val: 55 }, { op: 0, bits: 9, val: 207 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 103 }, { op: 0, bits: 8, val: 39 }, { op: 0, bits: 9, val: 175 }, { op: 0, bits: 8, val: 7 }, { op: 0, bits: 8, val: 135 }, { op: 0, bits: 8, val: 71 }, { op: 0, bits: 9, val: 239 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 95 }, { op: 0, bits: 8, val: 31 }, { op: 0, bits: 9, val: 159 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 127 }, { op: 0, bits: 8, val: 63 }, { op: 0, bits: 9, val: 223 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 111 }, { op: 0, bits: 8, val: 47 }, { op: 0, bits: 9, val: 191 }, { op: 0, bits: 8, val: 15 }, { op: 0, bits: 8, val: 143 }, { op: 0, bits: 8, val: 79 }, { op: 0, bits: 9, val: 255 } ];
+ if (!distfix_ary) distfix_ary = [ { op: 16, bits: 5, val: 1 }, { op: 23, bits: 5, val: 257 }, { op: 19, bits: 5, val: 17 }, { op: 27, bits: 5, val: 4097 }, { op: 17, bits: 5, val: 5 }, { op: 25, bits: 5, val: 1025 }, { op: 21, bits: 5, val: 65 }, { op: 29, bits: 5, val: 16385 }, { op: 16, bits: 5, val: 3 }, { op: 24, bits: 5, val: 513 }, { op: 20, bits: 5, val: 33 }, { op: 28, bits: 5, val: 8193 }, { op: 18, bits: 5, val: 9 }, { op: 26, bits: 5, val: 2049 }, { op: 22, bits: 5, val: 129 }, { op: 64, bits: 5, val: 0 }, { op: 16, bits: 5, val: 2 }, { op: 23, bits: 5, val: 385 }, { op: 19, bits: 5, val: 25 }, { op: 27, bits: 5, val: 6145 }, { op: 17, bits: 5, val: 7 }, { op: 25, bits: 5, val: 1537 }, { op: 21, bits: 5, val: 97 }, { op: 29, bits: 5, val: 24577 }, { op: 16, bits: 5, val: 4 }, { op: 24, bits: 5, val: 769 }, { op: 20, bits: 5, val: 49 }, { op: 28, bits: 5, val: 12289 }, { op: 18, bits: 5, val: 13 }, { op: 26, bits: 5, val: 3073 }, { op: 22, bits: 5, val: 193 }, { op: 64, bits: 5, val: 0 } ];
+ state.lencode = 0;
+ state.distcode = 512;
+ for (i = 0; i < 512; i++) { state.codes[i] = lenfix_ary[i]; }
+ for (i = 0; i < 32; i++) { state.codes[i + 512] = distfix_ary[i]; }
+ state.lenbits = 9;
+ state.distbits = 5;
+}
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+*/
+function updatewindow(strm)
+{
+ var state = strm.state;
+ var out = strm.output_data.length;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state.window === null) {
+ state.window = '';
+ }
+
+ /* if window not in use yet, initialize */
+ if (state.wsize == 0) {
+ state.wsize = 1 << state.wbits;
+ }
+
+ // zlib.js: Sliding window
+ if (out >= state.wsize) {
+ state.window = strm.output_data.substring(out - state.wsize);
+ } else {
+ if(state.whave + out < state.wsize) {
+ state.window += strm.output_data;
+ } else {
+ state.window = state.window.substring(state.whave - (state.wsize - out)) + strm.output_data;
+ }
+ }
+ state.whave = state.window.length;
+ if(state.whave < state.wsize) {
+ state.wnext = state.whave;
+ } else {
+ state.wnext = 0;
+ }
+ return 0;
+}
+
+
+// #ifdef GUNZIP
+function CRC2(strm, word)
+{
+ var hbuf = [word & 0xff, (word >>> 8) & 0xff];
+ strm.state.check = strm.checksum_function(strm.state.check, hbuf, 0, 2);
+}
+
+function CRC4(strm, word)
+{
+ var hbuf = [word & 0xff,
+ (word >>> 8) & 0xff,
+ (word >>> 16) & 0xff,
+ (word >>> 24) & 0xff];
+ strm.state.check = strm.checksum_function(strm.state.check, hbuf, 0, 4);
+}
+
+/* Load registers with state in inflate() for speed */
+function LOAD(strm, s)
+{
+ s.strm = strm; /* z_stream */
+ s.left = strm.avail_out; /* available output */
+ s.next = strm.next_in; /* next input */
+ s.have = strm.avail_in; /* available input */
+ s.hold = strm.state.hold; /* bit buffer */
+ s.bits = strm.state.bits; /* bits in bit buffer */
+ return s;
+}
+
+/* Restore state from registers in inflate() */
+function RESTORE(s)
+{
+ var strm = s.strm;
+ strm.next_in = s.next;
+ strm.avail_out = s.left;
+ strm.avail_in = s.have;
+ strm.state.hold = s.hold;
+ strm.state.bits = s.bits;
+}
+
+/* Clear the input bit accumulator */
+function INITBITS(s)
+{
+ s.hold = 0;
+ s.bits = 0;
+}
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+function PULLBYTE(s)
+{
+ if (s.have == 0) return false;
+ s.have--;
+ s.hold += (s.strm.input_data.charCodeAt(s.next++) & 0xff) << s.bits;
+ s.bits += 8;
+ return true;
+}
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+function NEEDBITS(s, n)
+{
+ // if(typeof n != 'number') throw 'ERROR';
+ while (s.bits < n) {
+ if(!PULLBYTE(s))
+ return false;
+ }
+ return true;
+}
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+function BITS(s, n)
+{
+ return s.hold & ((1 << n) - 1);
+}
+
+/* Remove n bits from the bit accumulator */
+function DROPBITS(s, n)
+{
+ // if(typeof n != 'number') throw 'ERROR';
+ s.hold >>>= n;
+ s.bits -= n;
+}
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+function BYTEBITS(s)
+{
+ s.hold >>>= s.bits & 7;
+ s.bits -= s.bits & 7;
+}
+
+/* Reverse the bytes in a 32-bit value */
+function REVERSE(q)
+{
+ return ((q >>> 24) & 0xff) +
+ ((q >>> 8) & 0xff00) +
+ ((q & 0xff00) << 8) +
+ ((q & 0xff) << 24);
+}
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+/* permutation of code lengths */
+var inflate_order = [
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
+ZLIB.inflate = function(strm, flush)
+{
+ var state;
+ var s;
+ var _in, out; /* save starting available input and output */
+ var copy; /* number of stored or match bytes to copy */
+ var from_window_offset = -1; /* index of window[] */
+ var from_out_offset = -1; /* index of next_out[] */
+ var here; /* current decoding table entry */
+ var last; /* parent table entry */
+ var len; /* length to copy for repeats, bits to drop */
+ var ret; /* return code */
+
+ if (!strm || !strm.state ||
+ (!strm.input_data && strm.avail_in != 0))
+ return ZLIB.Z_STREAM_ERROR;
+
+ state = strm.state;
+ if (state.mode == TYPE) state.mode = TYPEDO; /* skip check */
+
+ // LOAD
+ s = {};
+ LOAD(strm, s);
+
+ _in = s.have;
+ out = s.left;
+ ret = ZLIB.Z_OK;
+inf_leave: for (;;) {
+ switch (state.mode) {
+ case HEAD:
+ if (state.wrap == 0) {
+ state.mode = TYPEDO;
+ break;
+ }
+ if(!NEEDBITS(s, 16)) break inf_leave;
+// #ifdef GUNZIP
+ if ((state.wrap & 2) && s.hold == 0x8b1f) { /* gzip header */
+ state.check = strm.checksum_function(0, null, 0, 0);
+ CRC2(strm, s.hold);
+ INITBITS(s);
+ state.mode = FLAGS;
+ break;
+ }
+ state.flags = 0; /* expect zlib header */
+ if (state.head !== null)
+ state.head.done = -1;
+ if (!(state.wrap & 1) || /* check if zlib header allowed */
+//#else
+// if (
+//#endif
+ ((BITS(s, 8) << 8) + (s.hold >>> 8)) % 31) {
+ strm.msg = 'incorrect header check';
+ state.mode = BAD;
+ break;
+ }
+ if (BITS(s, 4) != ZLIB.Z_DEFLATED) {
+ strm.msg = 'unknown compression method';
+ state.mode = BAD;
+ break;
+ }
+
+ DROPBITS(s, 4);
+ len = BITS(s, 4) + 8;
+ if (state.wbits == 0)
+ state.wbits = len;
+ else if (len > state.wbits) {
+ strm.msg = 'invalid window size';
+ state.mode = BAD;
+ break;
+ }
+ state.dmax = 1 << len;
+// Tracev((stderr, "inflate: zlib header ok\n"));
+ strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
+ state.mode = s.hold & 0x200 ? DICTID : TYPE;
+ INITBITS(s);
+ break;
+// #ifdef GUNZIP
+ case FLAGS:
+ if(!NEEDBITS(s, 16)) break inf_leave;
+ state.flags = s.hold;
+ if ((state.flags & 0xff) != ZLIB.Z_DEFLATED) {
+ strm.msg = "unknown compression method";
+ state.mode = BAD;
+ break;
+ }
+ if (state.flags & 0xe000) {
+ strm.msg = "unknown header flags set";
+ state.mode = BAD;
+ break;
+ }
+ if (state.head !== null)
+ state.head.text = (s.hold >>> 8) & 1;
+ if (state.flags & 0x0200) {
+ CRC2(strm, s.hold);
+ }
+ INITBITS(s);
+ state.mode = TIME;
+ case TIME:
+ if(!NEEDBITS(s, 32)) break inf_leave;
+ if (state.head !== null)
+ state.head.time = s.hold;
+ if (state.flags & 0x0200) {
+ CRC4(strm, s.hold);
+ }
+ INITBITS(s);
+ state.mode = OS;
+ case OS:
+ if(!NEEDBITS(s, 16)) break inf_leave;
+ if (state.head !== null) {
+ state.head.xflags = s.hold & 0xff;
+ state.head.os = s.hold >>> 8;
+ }
+ if (state.flags & 0x0200) {
+ CRC2(strm, s.hold);
+ }
+ INITBITS(s);
+ state.mode = EXLEN;
+ case EXLEN:
+ if (state.flags & 0x0400) {
+ if(!NEEDBITS(s, 16)) break inf_leave;
+ state.length = s.hold;
+ if (state.head !== null) {
+ state.head.extra_len = s.hold;
+ }
+ if (state.flags & 0x0200) {
+ CRC2(strm, s.hold);
+ }
+ INITBITS(s);
+ state.head.extra = "";
+ }
+ else if (state.head !== null) {
+ state.head.extra = null;
+ }
+ state.mode = EXTRA;
+ case EXTRA:
+ if (state.flags & 0x0400) {
+ copy = state.length;
+ if (copy > s.have) copy = s.have;
+ if (copy) {
+ if (state.head !== null &&
+ state.head.extra !== null) {
+ len = state.head.extra_len - state.length;
+/*
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+*/
+ state.head.extra += strm.input_data.substring(
+ s.next, s.next + (len + copy > state.head.extra_max ?
+ state.head.extra_max - len : copy));
+
+ }
+ if (state.flags & 0x0200)
+ state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
+ s.have -= copy;
+ s.next += copy;
+ state.length -= copy;
+ }
+ if (state.length) break inf_leave;
+ }
+ state.length = 0;
+ state.mode = NAME;
+ case NAME:
+ if (state.flags & 0x0800) {
+ if (s.have == 0) break inf_leave;
+ if (state.head !== null && state.head.name === null) {
+ state.head.name = "";
+ }
+ copy = 0;
+ // TODO end = strm.input_data.indexOf("\0", s.next);
+ // TODO state.length => state.head.name.length
+ do {
+ len = strm.input_data.charAt(s.next + copy); copy++;
+ if(len === "\0")
+ break;
+ if (state.head !== null &&
+ state.length < state.head.name_max) {
+ state.head.name += len;
+ state.length++;
+ }
+ } while (copy < s.have);
+ if (state.flags & 0x0200) {
+ state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
+ }
+ s.have -= copy;
+ s.next += copy;
+ if (len !== "\0") break inf_leave;
+ }
+ else if (state.head !== null)
+ state.head.name = null;
+ state.length = 0;
+ state.mode = COMMENT;
+ case COMMENT:
+ if (state.flags & 0x1000) {
+ if (s.have == 0) break inf_leave;
+ copy = 0;
+ if (state.head !== null && state.head.comment === null) {
+ state.head.comment = "";
+ }
+ // TODO end = strm.input_data.indexOf("\0", s.next);
+ // TODO state.length => state.head.comment.length
+ do {
+ len = strm.input_data.charAt(s.next + copy); copy++;
+ if(len === "\0")
+ break;
+ if (state.head !== null &&
+ state.length < state.head.comm_max) {
+ state.head.comment += len;
+ state.length++;
+ }
+ } while (copy < s.have);
+ if (state.flags & 0x0200)
+ state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
+ s.have -= copy;
+ s.next += copy;
+ if (len !== "\0") break inf_leave;
+ }
+ else if (state.head !== null)
+ state.head.comment = null;
+ state.mode = HCRC;
+ case HCRC:
+ if (state.flags & 0x0200) {
+ if(!NEEDBITS(s, 16)) break inf_leave;
+ if (s.hold != (state.check & 0xffff)) {
+ strm.msg = "header crc mismatch";
+ state.mode = BAD;
+ break;
+ }
+ INITBITS(s);
+ }
+ if (state.head !== null) {
+ state.head.hcrc = (state.flags >>> 9) & 1;
+ state.head.done = 1;
+ }
+ strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
+ state.mode = TYPE;
+ break;
+//#endif
+ case DICTID:
+ if(!NEEDBITS(s, 32)) break inf_leave;
+ strm.adler = state.check = REVERSE(s.hold);
+ INITBITS(s);
+ state.mode = DICT;
+ case DICT:
+ if (state.havedict == 0) {
+ RESTORE(s);
+ return ZLIB.Z_NEED_DICT;
+ }
+ strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
+ state.mode = TYPE;
+ case TYPE:
+ if (flush == ZLIB.Z_BLOCK || flush == ZLIB.Z_TREES) break inf_leave;
+ case TYPEDO:
+ if (state.last) {
+ BYTEBITS(s);
+ state.mode = CHECK;
+ break;
+ }
+ if(!NEEDBITS(s, 3)) break inf_leave;
+ state.last = BITS(s, 1);
+ DROPBITS(s, 1);
+ switch (BITS(s, 2)) {
+ case 0: /* stored block */
+// Tracev((stderr, "inflate: stored block%s\n",
+// state->last ? " (last)" : ""));
+ state.mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+// Tracev((stderr, "inflate: fixed codes block%s\n",
+// state->last ? " (last)" : ""));
+ state.mode = LEN_; /* decode codes */
+ if (flush == ZLIB.Z_TREES) {
+ DROPBITS(s, 2);
+ break inf_leave;
+ }
+ break;
+ case 2: /* dynamic block */
+// Tracev((stderr, "inflate: dynamic codes block%s\n",
+// state->last ? " (last)" : ""));
+ state.mode = TABLE;
+ break;
+ case 3:
+ strm.msg = 'invalid block type';
+ state.mode = BAD;
+ }
+ DROPBITS(s, 2);
+ break;
+ case STORED:
+ BYTEBITS(s); /* go to byte boundary */
+ if(!NEEDBITS(s, 32)) break inf_leave;
+ if ((s.hold & 0xffff) != (((s.hold >>> 16) & 0xffff) ^ 0xffff)) {
+ strm.msg = 'invalid stored block lengths';
+ state.mode = BAD;
+ break;
+ }
+ state.length = s.hold & 0xffff;
+// Tracev((stderr, "inflate: stored length %u\n",
+// state->length));
+ INITBITS(s);
+ state.mode = COPY_;
+ if (flush == ZLIB.Z_TREES) break inf_leave;
+ case COPY_:
+ state.mode = COPY;
+ case COPY:
+ copy = state.length;
+ if (copy) {
+ if (copy > s.have) copy = s.have;
+ if (copy > s.left) copy = s.left;
+ if (copy == 0) break inf_leave;
+ strm.output_data += strm.input_data.substring(s.next, s.next + copy);
+ strm.next_out += copy;
+ s.have -= copy;
+ s.next += copy;
+ s.left -= copy;
+ state.length -= copy;
+ break;
+ }
+// Tracev((stderr, "inflate: stored end\n"));
+ state.mode = TYPE;
+ break;
+ case TABLE:
+ if(!NEEDBITS(s, 14)) break inf_leave;
+ state.nlen = BITS(s, 5) + 257;
+ DROPBITS(s, 5);
+ state.ndist = BITS(s, 5) + 1;
+ DROPBITS(s, 5);
+ state.ncode = BITS(s, 4) + 4;
+ DROPBITS(s, 4);
+//#ifndef PKZIP_BUG_WORKAROUND
+ if (state.nlen > 286 || state.ndist > 30) {
+ strm.msg = 'too many length or distance symbols';
+ state.mode = BAD;
+ break;
+ }
+//#endif
+// Tracev((stderr, "inflate: table sizes ok\n"));
+ state.have = 0;
+ state.mode = LENLENS;
+ case LENLENS:
+ while (state.have < state.ncode) {
+ if(!NEEDBITS(s, 3)) break inf_leave;
+ var tmp = BITS(s, 3);
+ state.lens[inflate_order[state.have++]] = tmp;
+ DROPBITS(s, 3);
+ }
+ while (state.have < 19)
+ state.lens[inflate_order[state.have++]] = 0;
+ state.next = 0;
+ state.lencode = 0;
+ state.lenbits = 7;
+
+// ret = inflate_table(CODES, state->lens, 19, &(state->next),
+// &(state->lenbits), state->work);
+ ret = inflate_table(state, CODES);
+
+ if (ret) {
+ strm.msg = 'invalid code lengths set';
+ state.mode = BAD;
+ break;
+ }
+// Tracev((stderr, "inflate: code lengths ok\n"));
+ state.have = 0;
+ state.mode = CODELENS;
+ case CODELENS:
+ while (state.have < state.nlen + state.ndist) {
+ for (;;) {
+ here = state.codes[state.lencode + BITS(s, state.lenbits)];
+ if (here.bits <= s.bits) break;
+ if(!PULLBYTE(s)) break inf_leave;
+ }
+ if (here.val < 16) {
+ DROPBITS(s, here.bits);
+ state.lens[state.have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ if(!NEEDBITS(s, here.bits + 2)) break inf_leave;
+ DROPBITS(s, here.bits);
+ if (state.have == 0) {
+ strm.msg = 'invalid bit length repeat';
+ state.mode = BAD;
+ break;
+ }
+ len = state.lens[state.have - 1];
+ copy = 3 + BITS(s, 2);
+ DROPBITS(s, 2);
+ }
+ else if (here.val == 17) {
+ if(!NEEDBITS(s, here.bits + 3)) break inf_leave;
+ DROPBITS(s, here.bits);
+ len = 0;
+ copy = 3 + BITS(s, 3);
+ DROPBITS(s, 3);
+ }
+ else {
+ if(!NEEDBITS(s, here.bits + 7)) break inf_leave;
+ DROPBITS(s, here.bits);
+ len = 0;
+ copy = 11 + BITS(s, 7);
+ DROPBITS(s, 7);
+ }
+ if (state.have + copy > state.nlen + state.ndist) {
+ strm.msg = 'invalid bit length repeat';
+ state.mode = BAD;
+ break;
+ }
+ while (copy--)
+ state.lens[state.have++] = len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state.mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state.lens[256] == 0) {
+ strm.msg = 'invalid code -- missing end-of-block';
+ state.mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state.next = 0;
+ state.lencode = state.next;
+ state.lenbits = 9;
+// ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+// &(state->lenbits), state->work);
+ ret = inflate_table(state, LENS);
+ if (ret) {
+ strm.msg = 'invalid literal/lengths set';
+ state.mode = BAD;
+ break;
+ }
+ state.distcode = state.next;
+ state.distbits = 6;
+// ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next),
+// &(state->distbits), state->work);
+ ret = inflate_table(state, DISTS);
+ if (ret) {
+ strm.msg = 'invalid distances set';
+ state.mode = BAD;
+ break;
+ }
+// Tracev((stderr, "inflate: codes ok\n"));
+ state.mode = LEN_;
+ if (flush == ZLIB.Z_TREES) break inf_leave;
+ case LEN_:
+ state.mode = LEN;
+ case LEN:
+ if (s.have >= 6 && s.left >= 258) {
+ RESTORE(s);
+ inflate_fast(strm, out);
+ LOAD(strm, s);
+ if (state.mode == TYPE)
+ state.back = -1;
+ break;
+ }
+ state.back = 0;
+ for (;;) {
+ here = state.codes[state.lencode + BITS(s, state.lenbits)];
+ if (here.bits <= s.bits) break;
+ if(!PULLBYTE(s)) break inf_leave;
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state.codes[state.lencode + last.val +
+ (BITS(s, last.bits + last.op) >>> last.bits)];
+ if (last.bits + here.bits <= s.bits) break;
+ if(!PULLBYTE(s)) break inf_leave;
+ }
+ DROPBITS(s, last.bits);
+ state.back += last.bits;
+ }
+ DROPBITS(s, here.bits);
+ state.back += here.bits;
+ state.length = here.val;
+ if (here.op == 0) {
+// Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+// "inflate: literal '%c'\n" :
+// "inflate: literal 0x%02x\n", here.val));
+ state.mode = LIT;
+ break;
+ }
+ if (here.op & 32) {
+// Tracevv((stderr, "inflate: end of block\n"));
+ state.back = -1;
+ state.mode = TYPE;
+ break;
+ }
+ if (here.op & 64) {
+ strm.msg = 'invalid literal/length code';
+ state.mode = BAD;
+ break;
+ }
+ state.extra = here.op & 15;
+ state.mode = LENEXT;
+ case LENEXT:
+ if (state.extra) {
+ if(!NEEDBITS(s, state.extra)) break inf_leave;
+ state.length += BITS(s, state.extra);
+ DROPBITS(s, state.extra);
+ state.back += state.extra;
+ }
+ //Tracevv((stderr, "inflate: length %u\n", state->length));
+ state.was = state.length;
+ state.mode = DIST;
+ case DIST:
+ for (;;) {
+ here = state.codes[state.distcode + BITS(s, state.distbits)];
+ if (here.bits <= s.bits) break;
+ if(!PULLBYTE(s)) break inf_leave;
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state.codes[state.distcode + last.val +
+ (BITS(s, last.bits + last.op) >>> last.bits)];
+ if ((last.bits + here.bits) <= s.bits) break;
+ if(!PULLBYTE(s)) break inf_leave;
+ }
+ DROPBITS(s, last.bits);
+ state.back += last.bits;
+ }
+ DROPBITS(s, here.bits);
+ state.back += here.bits;
+ if (here.op & 64) {
+ strm.msg = 'invalid distance code';
+ state.mode = BAD;
+ break;
+ }
+ state.offset = here.val;
+ state.extra = here.op & 15;
+ state.mode = DISTEXT;
+ case DISTEXT:
+ if (state.extra) {
+ if(!NEEDBITS(s, state.extra)) break inf_leave;
+ state.offset += BITS(s, state.extra);
+ DROPBITS(s, state.extra);
+ state.back += state.extra;
+ }
+//NOSPRT #ifdef INFLATE_STRICT
+// if (state->offset > state->dmax) {
+// strm->msg = (char *)"invalid distance too far back";
+// state->mode = BAD;
+// break;
+// }
+//#endif
+// Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state.mode = MATCH;
+ case MATCH:
+ if (s.left == 0) break inf_leave;
+ copy = out - s.left;
+ if (state.offset > copy) { /* copy from window */
+ copy = state.offset - copy;
+ if (copy > state.whave) {
+ if (state.sane) {
+ strm.msg = 'invalid distance too far back';
+ state.mode = BAD;
+ break;
+ }
+//NOSPRT #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+// Trace((stderr, "inflate.c too far\n"));
+// copy -= state->whave;
+// if (copy > state->length) copy = state->length;
+// if (copy > left) copy = left;
+// left -= copy;
+// state->length -= copy;
+// do {
+// *put++ = 0;
+// } while (--copy);
+// if (state->length == 0) state->mode = LEN;
+// break;
+//#endif
+ }
+ if (copy > state.wnext) {
+ copy -= state.wnext;
+ // from = state->window + (state->wsize - copy);
+ from_window_offset = state.wsize - copy;
+ from_out_offset = -1;
+ }
+ else {
+ // from = state->window + (state->wnext - copy);
+ from_window_offset = state.wnext - copy;
+ from_out_offset = -1;
+ }
+ if (copy > state.length) copy = state.length;
+ }
+ else { /* copy from output */
+ // from = put - state->offset;
+ from_window_offset = -1;
+ from_out_offset = strm.next_out - state.offset;
+ copy = state.length;
+ }
+ if (copy > s.left) copy = s.left;
+ s.left -= copy;
+ state.length -= copy;
+ if( from_window_offset >= 0 ) {
+ strm.output_data += state.window.substring(from_window_offset, from_window_offset + copy);
+ strm.next_out += copy;
+ copy = 0;
+ } else {
+ strm.next_out += copy;
+ do {
+ strm.output_data += strm.output_data.charAt(from_out_offset++);
+ } while (--copy);
+ }
+ if (state.length == 0) state.mode = LEN;
+ break;
+ case LIT:
+ if (s.left == 0) break inf_leave;
+
+ strm.output_data += String.fromCharCode(state.length);
+ strm.next_out++;
+ //*put++ = (unsigned char)(state->length);
+
+ s.left--;
+ state.mode = LEN;
+ break;
+ case CHECK:
+ if (state.wrap) {
+ if(!NEEDBITS(s, 32)) break inf_leave;
+ out -= s.left;
+ strm.total_out += out;
+ state.total += out;
+ if (out)
+ strm.adler = state.check =
+ strm.checksum_function(state.check, strm.output_data, strm.output_data.length - out, out);
+ out = s.left;
+ if ((
+// #ifdef GUNZIP
+ state.flags ? s.hold :
+//#endif
+ REVERSE(s.hold)) != state.check) {
+ strm.msg = "incorrect data check";
+ state.mode = BAD;
+ break;
+ }
+ INITBITS(s);
+//debug("## inflate: check matches trailer\n");
+// Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+//#ifdef GUNZIP
+ state.mode = LENGTH;
+ case LENGTH:
+ if (state.wrap && state.flags) {
+ if(!NEEDBITS(s, 32)) break inf_leave;
+ if (s.hold != (state.total & 0xffffffff)) {
+ strm.msg = 'incorrect length check';
+ state.mode = BAD;
+ break;
+ }
+ INITBITS(s);
+ //Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+//#endif
+ state.mode = DONE;
+ case DONE:
+ ret = ZLIB.Z_STREAM_END;
+ break inf_leave;
+ case BAD:
+ ret = ZLIB.Z_DATA_ERROR;
+ break inf_leave;
+ case MEM:
+ return ZLIB.Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return ZLIB.Z_STREAM_ERROR;
+ } }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+inf_leave:
+ RESTORE(s);
+ if (state.wsize || (out != strm.avail_out && state.mode < BAD &&
+ (state.mode < CHECK || flush != ZLIB.Z_FINISH)))
+ if (updatewindow(strm)) {
+ state.mode = MEM;
+ return ZLIB.Z_MEM_ERROR;
+ }
+ _in -= strm.avail_in;
+ out -= strm.avail_out;
+ strm.total_in += _in;
+ strm.total_out += out;
+ state.total += out;
+ if (state.wrap && out)
+ strm.adler = state.check = strm.checksum_function(state.check, strm.output_data, 0, strm.output_data.length);
+ strm.data_type = state.bits + (state.last ? 64 : 0) +
+ (state.mode == TYPE ? 128 : 0) +
+ (state.mode == LEN_ || state.mode == COPY_ ? 256 : 0);
+ if (((_in == 0 && out == 0) || flush == ZLIB.Z_FINISH) && ret == ZLIB.Z_OK)
+ ret = ZLIB.Z_BUF_ERROR;
+ return ret;
+};
+
+ZLIB.inflateEnd = function(strm)
+{
+ var state;
+ if (!strm || !strm.state )
+ return ZLIB.Z_STREAM_ERROR;
+ state = strm.state;
+ state.window = null;
+ strm.state = null;
+ // Tracev((stderr, "inflate: end\n"));
+ return ZLIB.Z_OK;
+};
+
+ZLIB.z_stream.prototype.inflate = function(input_string, opts)
+{
+ var flush;
+ var avail_out;
+ var DEFAULT_BUFFER_SIZE = 16384;
+
+ this.input_data = input_string;
+ this.next_in = getarg(opts, 'next_in', 0);
+ this.avail_in = getarg(opts, 'avail_in', input_string.length - this.next_in);
+
+ flush = getarg(opts, 'flush', ZLIB.Z_SYNC_FLUSH);
+ avail_out = getarg(opts, 'avail_out', -1);
+
+ var result = '';
+ do {
+ this.avail_out = (avail_out >= 0 ? avail_out : DEFAULT_BUFFER_SIZE);
+ this.output_data = '';
+ this.next_out = 0;
+ this.error = ZLIB.inflate(this, flush);
+ if(avail_out >= 0) {
+ return this.output_data;
+ }
+ result += this.output_data;
+ if(this.avail_out > 0) {
+ break;
+ }
+ } while(this.error == ZLIB.Z_OK);
+
+ return result;
+};
+
+ZLIB.z_stream.prototype.inflateReset = function(windowBits)
+{
+ return ZLIB.inflateReset(this, windowBits);
+};
+
+}());
diff --git a/public/scripts/zlib.js b/public/scripts/zlib.js
new file mode 100644
index 00000000..1b6fbba5
--- /dev/null
+++ b/public/scripts/zlib.js
@@ -0,0 +1,111 @@
+/* zlib.js -- JavaScript implementation for the zlib.
+ Version: 0.2.0
+ LastModified: Apr 12 2012
+ Copyright (C) 2012 Masanao Izumo
+
+ The original copyright notice (zlib 1.2.6):
+
+ Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+var ZLIB = ( ZLIB || {} ); // ZLIB namespace initialization
+
+// common definitions
+if(typeof ZLIB.common_initialized === 'undefined') {
+ ZLIB.Z_NO_FLUSH = 0;
+ ZLIB.Z_PARTIAL_FLUSH = 1;
+ ZLIB.Z_SYNC_FLUSH = 2;
+ ZLIB.Z_FULL_FLUSH = 3;
+ ZLIB.Z_FINISH = 4;
+ ZLIB.Z_BLOCK = 5;
+ ZLIB.Z_TREES = 6;
+ /* Allowed flush values; see deflate() and inflate() below for details */
+
+ ZLIB.Z_OK = 0;
+ ZLIB.Z_STREAM_END = 1;
+ ZLIB.Z_NEED_DICT = 2;
+ ZLIB.Z_ERRNO = (-1);
+ ZLIB.Z_STREAM_ERROR = (-2);
+ ZLIB.Z_DATA_ERROR = (-3);
+ ZLIB.Z_MEM_ERROR = (-4);
+ ZLIB.Z_BUF_ERROR = (-5);
+ ZLIB.Z_VERSION_ERROR = (-6);
+ /* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+ ZLIB.Z_DEFLATED = 8; /* The deflate compression method (the only one supported in this version) */
+
+ /**
+ * z_stream constructor
+ * @constructor
+ */
+ ZLIB.z_stream = function() {
+ this.next_in = 0; /* next input byte */
+ this.avail_in = 0; /* number of bytes available in input_data */
+ this.total_in = 0; /* total number of input bytes read so far */
+
+ this.next_out = 0; /* next output byte */
+ this.avail_out = 0; /* remaining free space at next_out */
+ this.total_out = 0; /* total number of bytes output so far */
+
+ this.msg = null; /* last error message, null if no error */
+ this.state = null; /* not visible by applications */
+
+ this.data_type = 0; /* best guess about the data type: binary or text */
+ this.adler = 0; /* TODO: adler32 value of the uncompressed data */
+
+ // zlib.js
+ this.input_data = ''; /* input data */
+ this.output_data = ''; /* output data */
+ this.error = 0; /* error code */
+ this.checksum_function = null; /* crc32(for gzip) or adler32(for zlib) */
+ };
+
+ /**
+ * TODO
+ * @constructor
+ */
+ ZLIB.gz_header = function() {
+ this.text = 0; /* true if compressed data believed to be text */
+ this.time = 0; /* modification time */
+ this.xflags = 0; /* extra flags (not used when writing a gzip file) */
+ this.os = 0xff; /* operating system */
+ this.extra = null; /* extra field string or null if none */
+ this.extra_len = 0; /* this.extra.length (only when reading header) */
+ this.extra_max = 0; /* space at extra (only when reading header) */
+ this.name = null; /* file name string or null if none */
+ this.name_max = 0; /* space at name (only when reading header) */
+ this.comment = null; /* comment string or null if none */
+ this.comm_max = 0; /* space at comment (only when reading header) */
+ this.hcrc = 0; /* true if there was or will be a header crc */
+ this.done = 0; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+ };
+
+ ZLIB.common_initialized = true;
+} // common definitions
diff --git a/views/default.handlebars b/views/default.handlebars
index c2b1cd66..563ce697 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -15,7 +15,10 @@
-
+
+
+
+
@@ -660,6 +663,7 @@
// Check if we are in debug mode
args = parseUriArgs();
debugmode = (args.debug == 1);
+ attemptWebRTC = (args.webrtc == 1);
QV('p13AutoConnect', debugmode); // Files
QV('autoconnectbutton2', debugmode); // Terminal
QV('autoconnectbutton1', debugmode); // Desktop