mirror of
https://github.com/arfct/itty-bitty.git
synced 2026-03-11 08:54:33 +00:00
Add Codepen support
This commit is contained in:
parent
0aa1fee631
commit
2761e6d689
18 changed files with 6105 additions and 97 deletions
77
data.js
Normal file
77
data.js
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
var BASE64_MARKER = ';base64,';
|
||||
var LZMA64_MARKER = ';baze64,';
|
||||
|
||||
function compressDataURI(dataURI, callback) {
|
||||
var base64Index = dataURI.indexOf(BASE64_MARKER);
|
||||
var base64 = dataURI.substring(base64Index + BASE64_MARKER.length);
|
||||
stringToZip(base64ToByteArray(base64), function(result) {
|
||||
callback(dataURI.substring(0, base64Index) + LZMA64_MARKER + result)
|
||||
})
|
||||
}
|
||||
|
||||
function base64ToByteArray(base64) {
|
||||
var raw = window.atob(base64);
|
||||
var rawLength = raw.length;
|
||||
var array = new Uint8Array(new ArrayBuffer(rawLength));
|
||||
for(i = 0; i < rawLength; i++) {
|
||||
array[i] = raw.charCodeAt(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function stringToZip(string, callback) {
|
||||
LZMA.compress(string, 9, function(result, error) {
|
||||
if (error) console.error(error);
|
||||
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(result)));
|
||||
return callback(base64String);
|
||||
});
|
||||
}
|
||||
|
||||
function decompressDataURI(dataURI, preamble, callback) {
|
||||
var base64Index = dataURI.indexOf(LZMA64_MARKER);
|
||||
if (base64Index > 0) {
|
||||
var base64 = dataURI.substring(base64Index + LZMA64_MARKER.length);
|
||||
zipToString(base64, function(result) {
|
||||
stringToData(result, function(data) {
|
||||
callback(dataURI.substring(0, base64Index) + BASE64_MARKER + (preamble || '') + data.split(',')[1])
|
||||
})
|
||||
})
|
||||
} else {
|
||||
callback(dataURI)
|
||||
}
|
||||
}
|
||||
|
||||
function zipToString(data, callback) {
|
||||
var array = base64ToByteArray(data); //new Uint8Array([...atob(data)].map(char => char.charCodeAt(0)));
|
||||
LZMA.decompress(array, function(result, error) {
|
||||
if (error) console.error(error);
|
||||
callback(result);
|
||||
});
|
||||
}
|
||||
|
||||
function stringToData(string, callback) {
|
||||
if (!string.length) return callback("");
|
||||
var a = new FileReader();
|
||||
a.onload = function(e) { callback(e.target.result.replace()) }
|
||||
a.readAsDataURL(new Blob([string], {encoding:"UTF-8",type:"text/html;charset=UTF-8"}));
|
||||
}
|
||||
|
||||
function dataToString(data, callback) {
|
||||
var blob = dataURItoBlob(data)
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) { callback(reader.result) }
|
||||
reader.readAsText(blob);
|
||||
}
|
||||
|
||||
function dataURItoBlob(dataURI) {
|
||||
var byteString = atob(dataURI.split(',')[1]);
|
||||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||
var arrayBuffer = new ArrayBuffer(byteString.length);
|
||||
var _ia = new Uint8Array(arrayBuffer);
|
||||
for (var i = 0; i < byteString.length; i++) {
|
||||
_ia[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
var dataView = new DataView(arrayBuffer);
|
||||
var blob = new Blob([dataView], { type: mimeString });
|
||||
return blob;
|
||||
}
|
||||
29
edit.css
29
edit.css
|
|
@ -1,8 +1,9 @@
|
|||
body {
|
||||
margin: 0 auto;padding:12vmin 10vmin;
|
||||
margin: 0 auto;padding:12vh 10vmin;
|
||||
max-width:35em;
|
||||
line-height:1.5em;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
line-height:1.5em;
|
||||
color:rgba(0,0,0,0.87);
|
||||
}
|
||||
|
||||
h1 { font-weight:400; }
|
||||
|
|
@ -30,7 +31,7 @@ body.drag #content {
|
|||
#content, #placeholder{
|
||||
width:100%;
|
||||
margin:-1em; padding: 1em;
|
||||
min-height:50vh
|
||||
min-height:2em
|
||||
}
|
||||
|
||||
#content {
|
||||
|
|
@ -77,29 +78,31 @@ body.has-content #toolbar {
|
|||
position:fixed;
|
||||
top:0;
|
||||
right:0;
|
||||
padding:1em;
|
||||
padding:3px 10px 5px 30px;
|
||||
transition: opacity 218ms ease-in;
|
||||
text-align:center;
|
||||
background-color:white;
|
||||
border-bottom-left-radius:1em;
|
||||
text-align:right;
|
||||
background-color:#f1f1f1;
|
||||
border-bottom-left-radius:10em;
|
||||
font-family:monospace;
|
||||
font-weight:bold;
|
||||
border
|
||||
}
|
||||
|
||||
#toolbar button {
|
||||
vertical-align: baseline;
|
||||
margin-bottom:11px;
|
||||
|
||||
font-family:monospace;
|
||||
}
|
||||
|
||||
#toolbar a.invalid {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
#length {
|
||||
border:1px solid transparent
|
||||
}
|
||||
|
||||
|
||||
|
||||
#toolbar a {font-size:11px; margin-right:0.5em; cursor: pointer; text-decoration:none; color:gray;}
|
||||
#toolbar a:hover { text-decoration: underline; color:blue;}
|
||||
|
||||
#toolbar a {font-size:11px; margin-right:0.5em; cursor: pointer; text-decoration:none; color:#333;}
|
||||
#toolbar a:hover { text-decoration: underline; color:#111;}
|
||||
|
||||
*[contenteditable="true"]{display: inline-block;}
|
||||
18
edit.html
18
edit.html
|
|
@ -1,8 +1,11 @@
|
|||
<html>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
|
||||
<title>itty bitty</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src https://codepen.io">
|
||||
<title>itty.bitty</title>
|
||||
<script src="src/lzma_worker-min.js"></script>
|
||||
<script src="jquery-3.3.1.min.js"></script>
|
||||
<script src="data.js"></script>
|
||||
<script src="edit.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="edit.css">
|
||||
<body>
|
||||
|
|
@ -13,10 +16,11 @@
|
|||
<a target="_blank" id="twitter" href="https://twitter.com/">Twitter</a>
|
||||
<button id="copy">Copy Link</button><br>
|
||||
</span>
|
||||
<div id="placeholder"><br>
|
||||
Share itty bitty things<br>with just a link.<br>
|
||||
To get started, type here<br>or drop an HTML file.<br>
|
||||
<p><a id="ib-info" href="http://about.bitty.site">Learn more</a></div>
|
||||
<div id="content"></div>
|
||||
<div id="placeholder">
|
||||
Share itty bitty things<br>with just a link.<br>
|
||||
To get started, type here<br>or drop an HTML file.<br>
|
||||
<p><a id="ib-info" contenteditable=false href="http://about.bitty.site">Learn more</a><br>
|
||||
</div>
|
||||
<div id="content"> </div>
|
||||
</body>
|
||||
</html>
|
||||
108
edit.js
108
edit.js
|
|
@ -1,30 +1,34 @@
|
|||
var $ = document.querySelector.bind(document)
|
||||
var $$ = document.querySelectorAll.bind(document)
|
||||
// var $ = document.querySelector.bind(document)
|
||||
// var $$ = document.querySelectorAll.bind(document)
|
||||
|
||||
var DATA_PREFIX = 'data:text/html;base64,'
|
||||
var DATA_PREFIX_8 = 'data:text/html;charset=utf-8;base64,'
|
||||
var DATA_PREFIX_BAZE = 'data:text/html;charset=utf-8;baze64,'
|
||||
|
||||
var content = undefined
|
||||
window.onload = function() {
|
||||
window.onpopstate = function(e) { setContent(e.state) }
|
||||
|
||||
content = document.getElementById("content");
|
||||
content.ondrop = dropEvent;
|
||||
document.body.ondragenter = function(e) { document.body.classList.add("drag"); };
|
||||
document.body.ondragleave = function(e) { document.body.classList.remove("drag"); };
|
||||
document.body.onclick = function() { content.focus()};
|
||||
content.oninput = handleInput;
|
||||
content.onkeydown = handleKey;
|
||||
document.body.onclick = function(e) { if (e.target == document.body) content.focus() };
|
||||
content = document.getElementById("content");
|
||||
content.addEventListener('keydown', handleKey);
|
||||
content.addEventListener('keyup', handleInput);
|
||||
content.addEventListener('drop', handleDrop);
|
||||
content.addEventListener('paste', handlePaste)
|
||||
content.contentEditable = 'true';
|
||||
content.focus();
|
||||
$('#qrcode').onclick = makeQRCode
|
||||
$('#copy').onclick = copyLink
|
||||
document.execCommand('selectAll',false,null);
|
||||
$('#qrcode')[0].onclick = makeQRCode
|
||||
$('#copy')[0].onclick = copyLink
|
||||
var hash = window.location.hash.substring(1)
|
||||
if (hash.length) {
|
||||
updateLink(hash)
|
||||
if (hash.startsWith('!')) { hash = hash.substring(1) }
|
||||
if (!hash.startsWith("data:")) { hash = 'data:text/html;charset=utf-8;base64,' + hash; }
|
||||
dataToString(hash, setContent);
|
||||
if (hash.startsWith('!')) {
|
||||
hash = hash.substring(1)
|
||||
zipToString(hash, setContent);
|
||||
}
|
||||
} else {
|
||||
updateBodyClass()
|
||||
}
|
||||
|
|
@ -41,7 +45,7 @@ function updateBodyClass() {
|
|||
document.body.classList.toggle("placeholder", !length)
|
||||
}
|
||||
|
||||
function dropEvent(e) {
|
||||
function handleDrop(e) {
|
||||
e.preventDefault();
|
||||
if (e.dataTransfer.files) {
|
||||
var file = e.dataTransfer.files[0]
|
||||
|
|
@ -49,8 +53,13 @@ function dropEvent(e) {
|
|||
reader.addEventListener("load", function () {
|
||||
var url = reader.result;
|
||||
url = url.replace(DATA_PREFIX, DATA_PREFIX_8)
|
||||
updateLink(url, true)
|
||||
setContent(' <span class="ib-file" contentEditable="false">📄' + file.name + '</span><br><br>');
|
||||
var length = url.length;
|
||||
compressDataURI(url, function(url){
|
||||
console.log("Compressed to", url.length / length)
|
||||
if (e.altKey) url = url.replace(DATA_PREFIX_BAZE, "!")
|
||||
updateLink(url, true)
|
||||
setContent(' <span class="ib-file" contentEditable="false">📄' + file.name + '</span><br><br>');
|
||||
})
|
||||
}, false);
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
|
@ -59,7 +68,9 @@ function dropEvent(e) {
|
|||
|
||||
function handleKey(e) {
|
||||
var code = e.which;
|
||||
var handled = false;
|
||||
if (e.metaKey && e.altKey) {
|
||||
handled = true;
|
||||
if (code == '1'.charCodeAt(0)) {
|
||||
document.execCommand("formatBlock", true, "<h1>");
|
||||
} else if (code == '2'.charCodeAt(0)) {
|
||||
|
|
@ -68,41 +79,42 @@ function handleKey(e) {
|
|||
document.execCommand("removeFormat");
|
||||
} else if (code == '0'.charCodeAt(0)) {
|
||||
document.execCommand("formatBlock", true, "");
|
||||
} else {
|
||||
handled = false
|
||||
}
|
||||
e.preventDefault()
|
||||
|
||||
} else if (e.metaKey) {
|
||||
if (code == 'K'.charCodeAt(0)) {
|
||||
handled = true;
|
||||
var url = prompt("Add a link", "")
|
||||
if (url) { document.execCommand("createLink", true, url); };
|
||||
}
|
||||
}
|
||||
if (handled) e.preventDefault()
|
||||
};
|
||||
|
||||
function stringToData(string, callback) {
|
||||
if (!string.length) return callback("");
|
||||
var a = new FileReader();
|
||||
a.onload = function(e) { callback(e.target.result.replace()) }
|
||||
a.readAsDataURL(new Blob([string], {encoding:"UTF-8",type:"text/html;charset=UTF-8"}));
|
||||
}
|
||||
|
||||
function dataToString(data, callback) {
|
||||
var blob = dataURItoBlob(data)
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) { callback(reader.result) }
|
||||
reader.readAsText(blob);
|
||||
}
|
||||
|
||||
function dataURItoBlob(dataURI) {
|
||||
var byteString = atob(dataURI.split(',')[1]);
|
||||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||
var arrayBuffer = new ArrayBuffer(byteString.length);
|
||||
var _ia = new Uint8Array(arrayBuffer);
|
||||
for (var i = 0; i < byteString.length; i++) {
|
||||
_ia[i] = byteString.charCodeAt(i);
|
||||
var codepenRE = /(https:\/\/codepen\.io\/[\w]+\/(\w+)\/(\w+))/
|
||||
function handlePaste(e) {
|
||||
var clipboard = window.clipboardData || e.clipboardData
|
||||
var text = clipboard.getData('Text') || clipboard.getData('text/plain')
|
||||
if (match = text.match(codepenRE)) {
|
||||
console.log(match)
|
||||
fetchCodepen(match[0])
|
||||
}
|
||||
var dataView = new DataView(arrayBuffer);
|
||||
var blob = new Blob([dataView], { type: mimeString });
|
||||
return blob;
|
||||
}
|
||||
|
||||
function fetchCodepen(url) {
|
||||
var h, c, j;
|
||||
$.when(
|
||||
$.get(url + ".html", function(html) { h = html; }),
|
||||
$.get(url + ".css", function(css) { c = css; }),
|
||||
$.get(url + ".js", function(js) { j = js; })
|
||||
).then(function() {
|
||||
var string = '<style type="text/css">' + c + '</style>' + h + '<script type="text/javascript">' + j + '</script>'
|
||||
content.innerText = string
|
||||
updateBodyClass()
|
||||
handleInput()
|
||||
});
|
||||
}
|
||||
|
||||
function stripPrefix(url) {
|
||||
|
|
@ -125,10 +137,9 @@ function handleInput(e) {
|
|||
text = content.innerHTML
|
||||
strip = true
|
||||
}
|
||||
stringToData(text, function(hash) {
|
||||
var plain = encodeURIComponent(text)
|
||||
if (strip) hash = stripPrefix(hash);
|
||||
updateLink(hash)
|
||||
|
||||
stringToZip(text, function(zip) {
|
||||
updateLink("!" + zip)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +148,7 @@ var maxLengths = {
|
|||
"#qrcode": 2610,
|
||||
"#bitly": 2048,
|
||||
}
|
||||
|
||||
function updateLink(url, push) {
|
||||
url = "/#" + url
|
||||
var hash = location.hash
|
||||
|
|
@ -145,13 +157,13 @@ function updateLink(url, push) {
|
|||
} else {
|
||||
window.history.replaceState(content.innerHTML, null, url);
|
||||
}
|
||||
|
||||
var length = location.href.length
|
||||
$('#length').innerText = length + " bytes"
|
||||
$('#length').href = url
|
||||
console.log(length)
|
||||
$('#length')[0].innerText = length + " bytes"
|
||||
$('#length')[0].href = url
|
||||
for (var key in maxLengths) {
|
||||
var maxLength = maxLengths[key]
|
||||
$(key).classList.toggle("invalid", length > maxLength)
|
||||
$(key)[0].classList.toggle("invalid", length > maxLength)
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
67
index.html
67
index.html
|
|
@ -1,27 +1,54 @@
|
|||
<html xmanifest="manifest.appcache">
|
||||
<title>itty bitty</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<script src="src/lzma-d-min.js"></script>
|
||||
<script src="data.js"></script>
|
||||
<style type="text/css">
|
||||
#iframe {border:none;position:absolute;top:0;left:0;width:100%;height:100%}
|
||||
#edit {position:absolute;z-index:100;position:absolute;top:10px; right:10px; display:none;}
|
||||
#edit:not(:hover) {border-color:transparent; color:gray;}
|
||||
</style>
|
||||
<iframe id="iframe"></iframe>
|
||||
<button id="edit">Edit</button>
|
||||
|
||||
<script type="text/javascript">
|
||||
var hash = window.location.hash.substring(1)
|
||||
if (hash.length) {
|
||||
window.onload = function() {
|
||||
if (hash.startsWith('!')) {
|
||||
var link = document.getElementById('edit');
|
||||
link.onclick = function() { location.href = "/edit#" + hash }
|
||||
link.style.display = "block";
|
||||
var preamble = "PG1ldGEgY2hhcnNldD0idXRmLTgiPjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgiPjxiYXNlIHRhcmdldD0iX3RvcCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj5ib2R5e21hcmdpbjowIGF1dG87cGFkZGluZzoxMnZtaW4gMTB2bWluO21heC13aWR0aDozNWVtO2xpbmUtaGVpZ2h0OjEuNWVtO2ZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCxzYW5zLXNlcmlmO3dvcmQtd3JhcDogYnJlYWstd29yZDt9PC9zdHlsZT4g"
|
||||
hash = preamble + hash.substring(1)
|
||||
}
|
||||
if (!hash.startsWith("data:")) hash = 'data:text/html;charset=utf-8;base64,' + hash;
|
||||
// location.href = hash // Redirect to data URI in supported browsers
|
||||
var iframe = document.getElementById('iframe');
|
||||
iframe.src = hash;
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
} else {
|
||||
location.href = "/edit"
|
||||
function showEdit() {
|
||||
var link = document.getElementById('edit');
|
||||
link.onclick = function() { location.href = "/edit" + location.hash }
|
||||
link.style.display = "block";
|
||||
}
|
||||
|
||||
var HEAD_TAGS = "PG1ldGEgY2hhcnNldD0idXRmLTgiPjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgiPjxiYXNlIHRhcmdldD0iX3RvcCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj5ib2R5e21hcmdpbjowIGF1dG87cGFkZGluZzoxMnZtaW4gMTB2bWluO21heC13aWR0aDozNWVtO2xpbmUtaGVpZ2h0OjEuNWVtO2ZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCxzYW5zLXNlcmlmO3dvcmQtd3JhcDogYnJlYWstd29yZDt9PC9zdHlsZT4g"
|
||||
|
||||
var hash = window.location.hash.substring(1)
|
||||
if (!hash.length) {
|
||||
location.href = "/edit"
|
||||
} else {
|
||||
var iframe = document.getElementById('iframe');
|
||||
var editable = false;
|
||||
var compressed = false;
|
||||
var preamble = undefined;
|
||||
|
||||
if (hash.charAt(0) == '!') {
|
||||
compressed = true;
|
||||
editable = true;
|
||||
hash = hash.substring(1)
|
||||
preamble = HEAD_TAGS
|
||||
}
|
||||
|
||||
if (!hash.startsWith("data:")) hash = 'data:text/html;charset=utf-8;' + (compressed ? 'baze64,' : 'base64,') + hash;
|
||||
// location.href = hash // Redirect to data URI in supported browsers
|
||||
|
||||
decompressDataURI(hash, preamble, function(hash) {
|
||||
if (hash) iframe.src = hash;
|
||||
if (editable) {
|
||||
var link = document.getElementById('edit');
|
||||
link.onclick = function() { location.href = "/edit" + location.hash }
|
||||
link.style.display = "block";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<iframe id="iframe" style="border:none;position:absolute;top:0;left:0;width:100%;height:100%"></iframe>
|
||||
<button id="edit" style="position:absolute;z-index:100;position:absolute;top:20px;right:20px;display:none;">Edit</button>
|
||||
</html>
|
||||
2
jquery-3.3.1.min.js
vendored
Normal file
2
jquery-3.3.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -2,4 +2,6 @@ CACHE MANIFEST
|
|||
|
||||
CACHE:
|
||||
/
|
||||
/favicon.ico
|
||||
/data.js
|
||||
/favicon.ico
|
||||
/src/lzma-d-min.js
|
||||
22
samples/bully.html
Normal file
22
samples/bully.html
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<pre style="line-height: normal;">
|
||||
__,-----._ ,-.
|
||||
,' ,-. \`---. ,-----<._/
|
||||
(,.-. o:.` )),"\\-._ ,' `.
|
||||
('"-` .\ \`:_ )\ `-;'-._ \
|
||||
,,-. \` ; : \( `-' ) -._ : `:
|
||||
( \ `._\\ ` ; ; ` : )
|
||||
\`. `-. __ , / \ ;, (
|
||||
`.`-.___--' `- / ; | : |
|
||||
`-' `-.`--._ ' ; |
|
||||
(`--._`. ; /\ |
|
||||
\ ' \ , ) :
|
||||
| `--::---- \' ; ;|
|
||||
\ .__,- ( ) : :|
|
||||
\ : `------; \ | | ;
|
||||
\ : / , ) | | (
|
||||
\ \ `-^-| | / , ,\
|
||||
) ) | -^- ; `-^-^'
|
||||
_,' _ ; | |
|
||||
/ , , ,' /---. :
|
||||
`-^-^' ( : :,'
|
||||
`-^--'
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
<style type="text/css">table td{text-align:right;}</style>
|
||||
<b>Itty bitty</b> lets you create tiny sites and apps that are stored in the link itself. To make them, you can edit this text directly, or drag an HTML file in to generate a link.
|
||||
|
||||
<p>Use it to share <a href="http://jabberwocky.bitty.site">poetry</a>, <a href="http://convert.bitty.site">quick reference</a>, <a href="https://calculator.bitty.app">tools</a>, and <a href="http://bully.bitty.site/">more</a>.
|
||||
<p>Use it to share <a href="http://jabberwocky.bitty.site">poetry</a>, <a>quick reference</a>, <a href="https://calculator.bitty.app">tools</a>, <a href="http://bully.bitty.site/">and</a> <a href="http://raven.bitty.site/">more</a>.
|
||||
|
||||
<p>When done, you can share these links through email, twitter, domain redirects and many other places you can post a link. When bookmarked on iOS, they work offline.
|
||||
<p>The content you create here is stored <i>entirely</i> in the link. It isn't even sent to this server, so you have full control of its privacy.
|
||||
|
||||
<p>Note: Each medium has a <a href="" onclick="document.getElementById('more').style.display = 'block'; return false;">maximum size</a> ranging from 1000 to 10000 characters.
|
||||
<p>When done, you can share through email, twitter, qr codes, domain redirects and the many other places you can put a link. Access is entirely based on where you choose to put it. <i>Note: Every medium has a <a href="" onclick="document.getElementById('more').style.display = 'block'; return false;">maximum size</a> usually ranging from 1000 to 10000 bytes.</i>
|
||||
|
||||
<div id="more" style="display:none">
|
||||
<table>
|
||||
<tr><td>Twitter: </td><td>4088</td></tr>
|
||||
<tr><td>Slack:</td><td>4000</td></tr>
|
||||
<tr><td>Chrome:</td><td>10000</td></tr>
|
||||
<tr><td>Bitly:</td><td>2048</td></tr>
|
||||
<tr><td>QR Code:</td><td>2610</td></tr>
|
||||
<tr><td>Chrome:</td><td>10,000 bytes</td></tr>
|
||||
<tr><td>Twitter: </td><td>4,088 bytes</td></tr>
|
||||
<tr><td>Slack:</td><td>4,000 bytes</td></tr>
|
||||
<tr><td>QR Code:</td><td>2,610 bytes</td></tr>
|
||||
<tr><td>Bitly:</td><td>2,048 bytes</td></tr>
|
||||
<tr><td>IE:</td><td>2,048 bytes</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
131
samples/raven.html
Normal file
131
samples/raven.html
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<body style="background-color:#111122; color:#EEDDFF;">
|
||||
<h1 style="color:white;margin-bottom:12px">The Raven</h1>
|
||||
<i style="opacity:0.5">Edgar Allan Poe</i><br>
|
||||
<p><br>
|
||||
Once upon a midnight dreary, while I pondered, weak and weary,<br>
|
||||
Over many a quaint and curious volume of forgotten lore—<br>
|
||||
While I nodded, nearly napping, suddenly there came a tapping,<br>
|
||||
As of some one gently rapping, rapping at my chamber door.<br>
|
||||
“’Tis some visitor,” I muttered, “tapping at my chamber door—<br>
|
||||
Only this and nothing more.”
|
||||
</p><p>
|
||||
Ah, distinctly I remember it was in the bleak December;<br>
|
||||
And each separate dying ember wrought its ghost upon the floor.<br>
|
||||
Eagerly I wished the morrow;—vainly I had sought to borrow<br>
|
||||
From my books surcease of sorrow—sorrow for the lost Lenore—<br>
|
||||
For the rare and radiant maiden whom the angels name Lenore—<br>
|
||||
Nameless here for evermore.
|
||||
</p><p>
|
||||
And the silken, sad, uncertain rustling of each purple curtain<br>
|
||||
Thrilled me—filled me with fantastic terrors never felt before;<br>
|
||||
So that now, to still the beating of my heart, I stood repeating<br>
|
||||
“’Tis some visitor entreating entrance at my chamber door—<br>
|
||||
Some late visitor entreating entrance at my chamber door;—<br>
|
||||
This it is and nothing more.”
|
||||
</p><p>
|
||||
Presently my soul grew stronger; hesitating then no longer,<br>
|
||||
“Sir,” said I, “or Madam, truly your forgiveness I implore;<br>
|
||||
But the fact is I was napping, and so gently you came rapping,<br>
|
||||
And so faintly you came tapping, tapping at my chamber door,<br>
|
||||
That I scarce was sure I heard you”—here I opened wide the door;—<br>
|
||||
Darkness there and nothing more.
|
||||
</p><p>
|
||||
Deep into that darkness peering, long I stood there wondering, fearing,<br>
|
||||
Doubting, dreaming dreams no mortal ever dared to dream before;<br>
|
||||
But the silence was unbroken, and the stillness gave no token,<br>
|
||||
And the only word there spoken was the whispered word, “Lenore?”<br>
|
||||
This I whispered, and an echo murmured back the word, “Lenore!”—<br>
|
||||
Merely this and nothing more.
|
||||
</p><p>
|
||||
Back into the chamber turning, all my soul within me burning,<br>
|
||||
Soon again I heard a tapping somewhat louder than before.<br>
|
||||
“Surely,” said I, “surely that is something at my window lattice;<br>
|
||||
Let me see, then, what thereat is, and this mystery explore—<br>
|
||||
Let my heart be still a moment and this mystery explore;—<br>
|
||||
’Tis the wind and nothing more!”
|
||||
</p><p>
|
||||
Open here I flung the shutter, when, with many a flirt and flutter,<br>
|
||||
In there stepped a stately Raven of the saintly days of yore;<br>
|
||||
Not the least obeisance made he; not a minute stopped or stayed he;<br>
|
||||
But, with mien of lord or lady, perched above my chamber door—<br>
|
||||
Perched upon a bust of Pallas just above my chamber door—<br>
|
||||
Perched, and sat, and nothing more.
|
||||
</p><p>
|
||||
Then this ebony bird beguiling my sad fancy into smiling,<br>
|
||||
By the grave and stern decorum of the countenance it wore,<br>
|
||||
“Though thy crest be shorn and shaven, thou,” I said, “art sure no craven,<br>
|
||||
Ghastly grim and ancient Raven wandering from the Nightly shore—<br>
|
||||
Tell me what thy lordly name is on the Night’s Plutonian shore!”<br>
|
||||
Quoth the Raven “Nevermore.”
|
||||
</p><p>
|
||||
Much I marvelled this ungainly fowl to hear discourse so plainly,<br>
|
||||
Though its answer little meaning—little relevancy bore;<br>
|
||||
For we cannot help agreeing that no living human being<br>
|
||||
Ever yet was blessed with seeing bird above his chamber door—<br>
|
||||
Bird or beast upon the sculptured bust above his chamber door,<br>
|
||||
With such name as “Nevermore.”
|
||||
</p><p>
|
||||
But the Raven, sitting lonely on the placid bust, spoke only<br>
|
||||
That one word, as if his soul in that one word he did outpour.<br>
|
||||
Nothing farther then he uttered—not a feather then he fluttered—<br>
|
||||
Till I scarcely more than muttered “Other friends have flown before—<br>
|
||||
On the morrow he will leave me, as my Hopes have flown before.”<br>
|
||||
Then the bird said “Nevermore.”
|
||||
</p><p>
|
||||
Startled at the stillness broken by reply so aptly spoken,<br>
|
||||
“Doubtless,” said I, “what it utters is its only stock and store<br>
|
||||
Caught from some unhappy master whom unmerciful Disaster<br>
|
||||
Followed fast and followed faster till his songs one burden bore—<br>
|
||||
Till the dirges of his Hope that melancholy burden bore<br>
|
||||
Of ‘Never—nevermore’.”
|
||||
</p><p>
|
||||
But the Raven still beguiling all my fancy into smiling,<br>
|
||||
Straight I wheeled a cushioned seat in front of bird, and bust and door;<br>
|
||||
Then, upon the velvet sinking, I betook myself to linking<br>
|
||||
Fancy unto fancy, thinking what this ominous bird of yore—<br>
|
||||
What this grim, ungainly, ghastly, gaunt, and ominous bird of yore<br>
|
||||
Meant in croaking “Nevermore.”
|
||||
</p><p>
|
||||
This I sat engaged in guessing, but no syllable expressing<br>
|
||||
To the fowl whose fiery eyes now burned into my bosom’s core;<br>
|
||||
This and more I sat divining, with my head at ease reclining<br>
|
||||
On the cushion’s velvet lining that the lamp-light gloated o’er,<br>
|
||||
But whose velvet-violet lining with the lamp-light gloating o’er,<br>
|
||||
She shall press, ah, nevermore!
|
||||
</p><p>
|
||||
Then, methought, the air grew denser, perfumed from an unseen censer<br>
|
||||
Swung by Seraphim whose foot-falls tinkled on the tufted floor.<br>
|
||||
“Wretch,” I cried, “thy God hath lent thee—by these angels he hath sent thee<br>
|
||||
Respite—respite and nepenthe from thy memories of Lenore;<br>
|
||||
Quaff, oh quaff this kind nepenthe and forget this lost Lenore!”<br>
|
||||
Quoth the Raven “Nevermore.”
|
||||
</p><p>
|
||||
“Prophet!” said I, “thing of evil!—prophet still, if bird or devil!—<br>
|
||||
Whether Tempter sent, or whether tempest tossed thee here ashore,<br>
|
||||
Desolate yet all undaunted, on this desert land enchanted—<br>
|
||||
On this home by Horror haunted—tell me truly, I implore—<br>
|
||||
Is there—is there balm in Gilead?—tell me—tell me, I implore!”<br>
|
||||
Quoth the Raven “Nevermore.”
|
||||
</p><p>
|
||||
“Prophet!” said I, “thing of evil!—prophet still, if bird or devil!<br>
|
||||
By that Heaven that bends above us—by that God we both adore—<br>
|
||||
Tell this soul with sorrow laden if, within the distant Aidenn,<br>
|
||||
It shall clasp a sainted maiden whom the angels name Lenore—<br>
|
||||
Clasp a rare and radiant maiden whom the angels name Lenore.”<br>
|
||||
Quoth the Raven “Nevermore.”
|
||||
</p><p>
|
||||
“Be that word our sign of parting, bird or fiend!” I shrieked, upstarting—<br>
|
||||
“Get thee back into the tempest and the Night’s Plutonian shore!<br>
|
||||
Leave no black plume as a token of that lie thy soul hath spoken!<br>
|
||||
Leave my loneliness unbroken!—quit the bust above my door!<br>
|
||||
Take thy beak from out my heart, and take thy form from off my door!”<br>
|
||||
Quoth the Raven “Nevermore.”
|
||||
</p><p>
|
||||
And the Raven, never flitting, still is sitting, still is sitting<br>
|
||||
On the pallid bust of Pallas just above my chamber door;<br>
|
||||
And his eyes have all the seeming of a demon’s that is dreaming,<br>
|
||||
And the lamp-light o’er him streaming throws his shadow on the floor;<br>
|
||||
And my soul from out that shadow that lies floating on the floor<br>
|
||||
Shall be lifted—nevermore!<br>
|
||||
</p>
|
||||
</body>
|
||||
1
src/lzma-c-min.js
vendored
Executable file
1
src/lzma-c-min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
2021
src/lzma-c.js
Executable file
2021
src/lzma-c.js
Executable file
File diff suppressed because it is too large
Load diff
1
src/lzma-d-min.js
vendored
Executable file
1
src/lzma-d-min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
878
src/lzma-d.js
Executable file
878
src/lzma-d.js
Executable file
|
|
@ -0,0 +1,878 @@
|
|||
///NOTE: This file was generated by minify.js from lzma_worker.js. Do not modify.
|
||||
|
||||
/// © 2015 Nathan Rugg <nmrugg@gmail.com> | MIT
|
||||
/// See LICENSE for more details.
|
||||
|
||||
/* jshint noarg:true, boss:true, unused:strict, strict:true, undef:true, noarg: true, forin:true, evil:true, newcap:false, -W041, -W021, worker:true, browser:true, node:true */
|
||||
|
||||
/* global setImmediate, setTimeout, window, onmessage */
|
||||
|
||||
|
||||
|
||||
var LZMA = (function () {
|
||||
|
||||
"use strict";
|
||||
|
||||
var
|
||||
/** ds */
|
||||
action_decompress = 2,
|
||||
/** de */
|
||||
action_progress = 3,
|
||||
wait = typeof setImmediate == "function" ? setImmediate : setTimeout,
|
||||
__4294967296 = 4294967296,
|
||||
N1_longLit = [4294967295, -__4294967296],
|
||||
|
||||
P0_longLit = [0, 0],
|
||||
P1_longLit = [1, 0];
|
||||
|
||||
function update_progress(percent, cbn) {
|
||||
postMessage({
|
||||
action: action_progress,
|
||||
cbn: cbn,
|
||||
result: percent
|
||||
});
|
||||
}
|
||||
|
||||
function initDim(len) {
|
||||
///NOTE: This is MUCH faster than "new Array(len)" in newer versions of v8 (starting with Node.js 0.11.15, which uses v8 3.28.73).
|
||||
var a = [];
|
||||
a[len - 1] = undefined;
|
||||
return a;
|
||||
}
|
||||
|
||||
function add(a, b) {
|
||||
return create(a[0] + b[0], a[1] + b[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function compare(a, b) {
|
||||
var nega, negb;
|
||||
if (a[0] == b[0] && a[1] == b[1]) {
|
||||
return 0;
|
||||
}
|
||||
nega = a[1] < 0;
|
||||
negb = b[1] < 0;
|
||||
if (nega && !negb) {
|
||||
return -1;
|
||||
}
|
||||
if (!nega && negb) {
|
||||
return 1;
|
||||
}
|
||||
if (sub(a, b)[1] < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
function create(valueLow, valueHigh) {
|
||||
var diffHigh, diffLow;
|
||||
valueHigh %= 1.8446744073709552E19;
|
||||
valueLow %= 1.8446744073709552E19;
|
||||
diffHigh = valueHigh % __4294967296;
|
||||
diffLow = Math.floor(valueLow / __4294967296) * __4294967296;
|
||||
valueHigh = valueHigh - diffHigh + diffLow;
|
||||
valueLow = valueLow - diffLow + diffHigh;
|
||||
while (valueLow < 0) {
|
||||
valueLow += __4294967296;
|
||||
valueHigh -= __4294967296;
|
||||
}
|
||||
while (valueLow > 4294967295) {
|
||||
valueLow -= __4294967296;
|
||||
valueHigh += __4294967296;
|
||||
}
|
||||
valueHigh = valueHigh % 1.8446744073709552E19;
|
||||
while (valueHigh > 9223372032559808512) {
|
||||
valueHigh -= 1.8446744073709552E19;
|
||||
}
|
||||
while (valueHigh < -9223372036854775808) {
|
||||
valueHigh += 1.8446744073709552E19;
|
||||
}
|
||||
return [valueLow, valueHigh];
|
||||
}
|
||||
|
||||
|
||||
function fromInt(value) {
|
||||
if (value >= 0) {
|
||||
return [value, 0];
|
||||
} else {
|
||||
return [value + __4294967296, -__4294967296];
|
||||
}
|
||||
}
|
||||
|
||||
function lowBits_0(a) {
|
||||
if (a[0] >= 2147483648) {
|
||||
return ~~Math.max(Math.min(a[0] - __4294967296, 2147483647), -2147483648);
|
||||
} else {
|
||||
return ~~Math.max(Math.min(a[0], 2147483647), -2147483648);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function sub(a, b) {
|
||||
return create(a[0] - b[0], a[1] - b[1]);
|
||||
}
|
||||
|
||||
function $ByteArrayInputStream(this$static, buf) {
|
||||
this$static.buf = buf;
|
||||
this$static.pos = 0;
|
||||
this$static.count = buf.length;
|
||||
return this$static;
|
||||
}
|
||||
|
||||
/** ds */
|
||||
function $read(this$static) {
|
||||
if (this$static.pos >= this$static.count)
|
||||
return -1;
|
||||
return this$static.buf[this$static.pos++] & 255;
|
||||
}
|
||||
/** de */
|
||||
|
||||
|
||||
function $ByteArrayOutputStream(this$static) {
|
||||
this$static.buf = initDim(32);
|
||||
this$static.count = 0;
|
||||
return this$static;
|
||||
}
|
||||
|
||||
function $toByteArray(this$static) {
|
||||
var data = this$static.buf;
|
||||
data.length = this$static.count;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function $write_0(this$static, buf, off, len) {
|
||||
arraycopy(buf, off, this$static.buf, this$static.count, len);
|
||||
this$static.count += len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function arraycopy(src, srcOfs, dest, destOfs, len) {
|
||||
for (var i = 0; i < len; ++i) {
|
||||
dest[destOfs + i] = src[srcOfs + i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** ds */
|
||||
function $init_0(this$static, input, output) {
|
||||
var decoder,
|
||||
hex_length = "",
|
||||
i,
|
||||
properties = [],
|
||||
r,
|
||||
tmp_length;
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
r = $read(input);
|
||||
if (r == -1)
|
||||
throw new Error("truncated input");
|
||||
properties[i] = r << 24 >> 24;
|
||||
}
|
||||
|
||||
decoder = $Decoder({});
|
||||
if (!$SetDecoderProperties(decoder, properties)) {
|
||||
throw new Error("corrupted input");
|
||||
}
|
||||
for (i = 0; i < 64; i += 8) {
|
||||
r = $read(input);
|
||||
if (r == -1)
|
||||
throw new Error("truncated input");
|
||||
r = r.toString(16);
|
||||
if (r.length == 1) r = "0" + r;
|
||||
hex_length = r + "" + hex_length;
|
||||
}
|
||||
|
||||
/// Was the length set in the header (if it was compressed from a stream, the length is all f"s).
|
||||
if (/^0+$|^f+$/i.test(hex_length)) {
|
||||
/// The length is unknown, so set to -1.
|
||||
this$static.length_0 = N1_longLit;
|
||||
} else {
|
||||
///NOTE: If there is a problem with the decoder because of the length, you can always set the length to -1 (N1_longLit) which means unknown.
|
||||
tmp_length = parseInt(hex_length, 16);
|
||||
/// If the length is too long to handle, just set it to unknown.
|
||||
if (tmp_length > 4294967295) {
|
||||
this$static.length_0 = N1_longLit;
|
||||
} else {
|
||||
this$static.length_0 = fromInt(tmp_length);
|
||||
}
|
||||
}
|
||||
|
||||
this$static.chunker = $CodeInChunks(decoder, input, output, this$static.length_0);
|
||||
}
|
||||
|
||||
function $LZMAByteArrayDecompressor(this$static, data) {
|
||||
this$static.output = $ByteArrayOutputStream({});
|
||||
$init_0(this$static, $ByteArrayInputStream({}, data), this$static.output);
|
||||
return this$static;
|
||||
}
|
||||
/** de */
|
||||
|
||||
/** ds */
|
||||
function $CopyBlock(this$static, distance, len) {
|
||||
var pos = this$static._pos - distance - 1;
|
||||
if (pos < 0) {
|
||||
pos += this$static._windowSize;
|
||||
}
|
||||
for (; len != 0; --len) {
|
||||
if (pos >= this$static._windowSize) {
|
||||
pos = 0;
|
||||
}
|
||||
this$static._buffer[this$static._pos++] = this$static._buffer[pos++];
|
||||
if (this$static._pos >= this$static._windowSize) {
|
||||
$Flush_0(this$static);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function $Create_5(this$static, windowSize) {
|
||||
if (this$static._buffer == null || this$static._windowSize != windowSize) {
|
||||
this$static._buffer = initDim(windowSize);
|
||||
}
|
||||
this$static._windowSize = windowSize;
|
||||
this$static._pos = 0;
|
||||
this$static._streamPos = 0;
|
||||
}
|
||||
|
||||
function $Flush_0(this$static) {
|
||||
var size = this$static._pos - this$static._streamPos;
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
$write_0(this$static._stream, this$static._buffer, this$static._streamPos, size);
|
||||
if (this$static._pos >= this$static._windowSize) {
|
||||
this$static._pos = 0;
|
||||
}
|
||||
this$static._streamPos = this$static._pos;
|
||||
}
|
||||
|
||||
function $GetByte(this$static, distance) {
|
||||
var pos = this$static._pos - distance - 1;
|
||||
if (pos < 0) {
|
||||
pos += this$static._windowSize;
|
||||
}
|
||||
return this$static._buffer[pos];
|
||||
}
|
||||
|
||||
function $PutByte(this$static, b) {
|
||||
this$static._buffer[this$static._pos++] = b;
|
||||
if (this$static._pos >= this$static._windowSize) {
|
||||
$Flush_0(this$static);
|
||||
}
|
||||
}
|
||||
|
||||
function $ReleaseStream(this$static) {
|
||||
$Flush_0(this$static);
|
||||
this$static._stream = null;
|
||||
}
|
||||
/** de */
|
||||
|
||||
function GetLenToPosState(len) {
|
||||
len -= 2;
|
||||
if (len < 4) {
|
||||
return len;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
function StateUpdateChar(index) {
|
||||
if (index < 4) {
|
||||
return 0;
|
||||
}
|
||||
if (index < 10) {
|
||||
return index - 3;
|
||||
}
|
||||
return index - 6;
|
||||
}
|
||||
|
||||
|
||||
/** ds */
|
||||
function $Chunker(this$static, decoder) {
|
||||
this$static.decoder = decoder;
|
||||
this$static.encoder = null;
|
||||
this$static.alive = 1;
|
||||
return this$static;
|
||||
}
|
||||
/** de */
|
||||
|
||||
function $processChunk(this$static) {
|
||||
if (!this$static.alive) {
|
||||
throw new Error("bad state");
|
||||
}
|
||||
|
||||
if (this$static.encoder) {
|
||||
throw new Error("No encoding");
|
||||
|
||||
} else {
|
||||
/// co:throw new Error("No decoding");
|
||||
/** ds */
|
||||
$processDecoderChunk(this$static);
|
||||
/** de */
|
||||
}
|
||||
return this$static.alive;
|
||||
}
|
||||
|
||||
/** ds */
|
||||
function $processDecoderChunk(this$static) {
|
||||
var result = $CodeOneChunk(this$static.decoder);
|
||||
if (result == -1) {
|
||||
throw new Error("corrupted input");
|
||||
}
|
||||
this$static.inBytesProcessed = N1_longLit;
|
||||
this$static.outBytesProcessed = this$static.decoder.nowPos64;
|
||||
if (result || compare(this$static.decoder.outSize, P0_longLit) >= 0 && compare(this$static.decoder.nowPos64, this$static.decoder.outSize) >= 0) {
|
||||
$Flush_0(this$static.decoder.m_OutWindow);
|
||||
$ReleaseStream(this$static.decoder.m_OutWindow);
|
||||
this$static.decoder.m_RangeDecoder.Stream = null;
|
||||
this$static.alive = 0;
|
||||
}
|
||||
}
|
||||
/** de */
|
||||
|
||||
|
||||
/** ds */
|
||||
function $CodeInChunks(this$static, inStream, outStream, outSize) {
|
||||
this$static.m_RangeDecoder.Stream = inStream;
|
||||
$ReleaseStream(this$static.m_OutWindow);
|
||||
this$static.m_OutWindow._stream = outStream;
|
||||
$Init_1(this$static);
|
||||
this$static.state = 0;
|
||||
this$static.rep0 = 0;
|
||||
this$static.rep1 = 0;
|
||||
this$static.rep2 = 0;
|
||||
this$static.rep3 = 0;
|
||||
this$static.outSize = outSize;
|
||||
this$static.nowPos64 = P0_longLit;
|
||||
this$static.prevByte = 0;
|
||||
return $Chunker({}, this$static);
|
||||
}
|
||||
|
||||
function $CodeOneChunk(this$static) {
|
||||
var decoder2, distance, len, numDirectBits, posSlot, posState;
|
||||
posState = lowBits_0(this$static.nowPos64) & this$static.m_PosStateMask;
|
||||
if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsMatchDecoders, (this$static.state << 4) + posState)) {
|
||||
decoder2 = $GetDecoder(this$static.m_LiteralDecoder, lowBits_0(this$static.nowPos64), this$static.prevByte);
|
||||
if (this$static.state < 7) {
|
||||
this$static.prevByte = $DecodeNormal(decoder2, this$static.m_RangeDecoder);
|
||||
} else {
|
||||
this$static.prevByte = $DecodeWithMatchByte(decoder2, this$static.m_RangeDecoder, $GetByte(this$static.m_OutWindow, this$static.rep0));
|
||||
}
|
||||
$PutByte(this$static.m_OutWindow, this$static.prevByte);
|
||||
this$static.state = StateUpdateChar(this$static.state);
|
||||
this$static.nowPos64 = add(this$static.nowPos64, P1_longLit);
|
||||
} else {
|
||||
if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepDecoders, this$static.state)) {
|
||||
len = 0;
|
||||
if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG0Decoders, this$static.state)) {
|
||||
if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRep0LongDecoders, (this$static.state << 4) + posState)) {
|
||||
this$static.state = this$static.state < 7?9:11;
|
||||
len = 1;
|
||||
}
|
||||
} else {
|
||||
if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG1Decoders, this$static.state)) {
|
||||
distance = this$static.rep1;
|
||||
} else {
|
||||
if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG2Decoders, this$static.state)) {
|
||||
distance = this$static.rep2;
|
||||
} else {
|
||||
distance = this$static.rep3;
|
||||
this$static.rep3 = this$static.rep2;
|
||||
}
|
||||
this$static.rep2 = this$static.rep1;
|
||||
}
|
||||
this$static.rep1 = this$static.rep0;
|
||||
this$static.rep0 = distance;
|
||||
}
|
||||
if (!len) {
|
||||
len = $Decode(this$static.m_RepLenDecoder, this$static.m_RangeDecoder, posState) + 2;
|
||||
this$static.state = this$static.state < 7?8:11;
|
||||
}
|
||||
} else {
|
||||
this$static.rep3 = this$static.rep2;
|
||||
this$static.rep2 = this$static.rep1;
|
||||
this$static.rep1 = this$static.rep0;
|
||||
len = 2 + $Decode(this$static.m_LenDecoder, this$static.m_RangeDecoder, posState);
|
||||
this$static.state = this$static.state < 7?7:10;
|
||||
posSlot = $Decode_0(this$static.m_PosSlotDecoder[GetLenToPosState(len)], this$static.m_RangeDecoder);
|
||||
if (posSlot >= 4) {
|
||||
numDirectBits = (posSlot >> 1) - 1;
|
||||
this$static.rep0 = (2 | posSlot & 1) << numDirectBits;
|
||||
if (posSlot < 14) {
|
||||
this$static.rep0 += ReverseDecode(this$static.m_PosDecoders, this$static.rep0 - posSlot - 1, this$static.m_RangeDecoder, numDirectBits);
|
||||
} else {
|
||||
this$static.rep0 += $DecodeDirectBits(this$static.m_RangeDecoder, numDirectBits - 4) << 4;
|
||||
this$static.rep0 += $ReverseDecode(this$static.m_PosAlignDecoder, this$static.m_RangeDecoder);
|
||||
if (this$static.rep0 < 0) {
|
||||
if (this$static.rep0 == -1) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
this$static.rep0 = posSlot;
|
||||
}
|
||||
if (compare(fromInt(this$static.rep0), this$static.nowPos64) >= 0 || this$static.rep0 >= this$static.m_DictionarySizeCheck) {
|
||||
return -1;
|
||||
}
|
||||
$CopyBlock(this$static.m_OutWindow, this$static.rep0, len);
|
||||
this$static.nowPos64 = add(this$static.nowPos64, fromInt(len));
|
||||
this$static.prevByte = $GetByte(this$static.m_OutWindow, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function $Decoder(this$static) {
|
||||
this$static.m_OutWindow = {};
|
||||
this$static.m_RangeDecoder = {};
|
||||
this$static.m_IsMatchDecoders = initDim(192);
|
||||
this$static.m_IsRepDecoders = initDim(12);
|
||||
this$static.m_IsRepG0Decoders = initDim(12);
|
||||
this$static.m_IsRepG1Decoders = initDim(12);
|
||||
this$static.m_IsRepG2Decoders = initDim(12);
|
||||
this$static.m_IsRep0LongDecoders = initDim(192);
|
||||
this$static.m_PosSlotDecoder = initDim(4);
|
||||
this$static.m_PosDecoders = initDim(114);
|
||||
this$static.m_PosAlignDecoder = $BitTreeDecoder({}, 4);
|
||||
this$static.m_LenDecoder = $Decoder$LenDecoder({});
|
||||
this$static.m_RepLenDecoder = $Decoder$LenDecoder({});
|
||||
this$static.m_LiteralDecoder = {};
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
this$static.m_PosSlotDecoder[i] = $BitTreeDecoder({}, 6);
|
||||
}
|
||||
return this$static;
|
||||
}
|
||||
|
||||
function $Init_1(this$static) {
|
||||
this$static.m_OutWindow._streamPos = 0;
|
||||
this$static.m_OutWindow._pos = 0;
|
||||
InitBitModels(this$static.m_IsMatchDecoders);
|
||||
InitBitModels(this$static.m_IsRep0LongDecoders);
|
||||
InitBitModels(this$static.m_IsRepDecoders);
|
||||
InitBitModels(this$static.m_IsRepG0Decoders);
|
||||
InitBitModels(this$static.m_IsRepG1Decoders);
|
||||
InitBitModels(this$static.m_IsRepG2Decoders);
|
||||
InitBitModels(this$static.m_PosDecoders);
|
||||
$Init_0(this$static.m_LiteralDecoder);
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
InitBitModels(this$static.m_PosSlotDecoder[i].Models);
|
||||
}
|
||||
$Init(this$static.m_LenDecoder);
|
||||
$Init(this$static.m_RepLenDecoder);
|
||||
InitBitModels(this$static.m_PosAlignDecoder.Models);
|
||||
$Init_8(this$static.m_RangeDecoder);
|
||||
}
|
||||
|
||||
function $SetDecoderProperties(this$static, properties) {
|
||||
var dictionarySize, i, lc, lp, pb, remainder, val;
|
||||
if (properties.length < 5)
|
||||
return 0;
|
||||
val = properties[0] & 255;
|
||||
lc = val % 9;
|
||||
remainder = ~~(val / 9);
|
||||
lp = remainder % 5;
|
||||
pb = ~~(remainder / 5);
|
||||
dictionarySize = 0;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
dictionarySize += (properties[1 + i] & 255) << i * 8;
|
||||
}
|
||||
///NOTE: If the input is bad, it might call for an insanely large dictionary size, which would crash the script.
|
||||
if (dictionarySize > 99999999 || !$SetLcLpPb(this$static, lc, lp, pb)) {
|
||||
return 0;
|
||||
}
|
||||
return $SetDictionarySize(this$static, dictionarySize);
|
||||
}
|
||||
|
||||
function $SetDictionarySize(this$static, dictionarySize) {
|
||||
if (dictionarySize < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (this$static.m_DictionarySize != dictionarySize) {
|
||||
this$static.m_DictionarySize = dictionarySize;
|
||||
this$static.m_DictionarySizeCheck = Math.max(this$static.m_DictionarySize, 1);
|
||||
$Create_5(this$static.m_OutWindow, Math.max(this$static.m_DictionarySizeCheck, 4096));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
function $SetLcLpPb(this$static, lc, lp, pb) {
|
||||
if (lc > 8 || lp > 4 || pb > 4) {
|
||||
return 0;
|
||||
}
|
||||
$Create_0(this$static.m_LiteralDecoder, lp, lc);
|
||||
var numPosStates = 1 << pb;
|
||||
$Create(this$static.m_LenDecoder, numPosStates);
|
||||
$Create(this$static.m_RepLenDecoder, numPosStates);
|
||||
this$static.m_PosStateMask = numPosStates - 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function $Create(this$static, numPosStates) {
|
||||
for (; this$static.m_NumPosStates < numPosStates; ++this$static.m_NumPosStates) {
|
||||
this$static.m_LowCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3);
|
||||
this$static.m_MidCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3);
|
||||
}
|
||||
}
|
||||
|
||||
function $Decode(this$static, rangeDecoder, posState) {
|
||||
if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 0)) {
|
||||
return $Decode_0(this$static.m_LowCoder[posState], rangeDecoder);
|
||||
}
|
||||
var symbol = 8;
|
||||
if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 1)) {
|
||||
symbol += $Decode_0(this$static.m_MidCoder[posState], rangeDecoder);
|
||||
} else {
|
||||
symbol += 8 + $Decode_0(this$static.m_HighCoder, rangeDecoder);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
function $Decoder$LenDecoder(this$static) {
|
||||
this$static.m_Choice = initDim(2);
|
||||
this$static.m_LowCoder = initDim(16);
|
||||
this$static.m_MidCoder = initDim(16);
|
||||
this$static.m_HighCoder = $BitTreeDecoder({}, 8);
|
||||
this$static.m_NumPosStates = 0;
|
||||
return this$static;
|
||||
}
|
||||
|
||||
function $Init(this$static) {
|
||||
InitBitModels(this$static.m_Choice);
|
||||
for (var posState = 0; posState < this$static.m_NumPosStates; ++posState) {
|
||||
InitBitModels(this$static.m_LowCoder[posState].Models);
|
||||
InitBitModels(this$static.m_MidCoder[posState].Models);
|
||||
}
|
||||
InitBitModels(this$static.m_HighCoder.Models);
|
||||
}
|
||||
|
||||
|
||||
function $Create_0(this$static, numPosBits, numPrevBits) {
|
||||
var i, numStates;
|
||||
if (this$static.m_Coders != null && this$static.m_NumPrevBits == numPrevBits && this$static.m_NumPosBits == numPosBits)
|
||||
return;
|
||||
this$static.m_NumPosBits = numPosBits;
|
||||
this$static.m_PosMask = (1 << numPosBits) - 1;
|
||||
this$static.m_NumPrevBits = numPrevBits;
|
||||
numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
|
||||
this$static.m_Coders = initDim(numStates);
|
||||
for (i = 0; i < numStates; ++i)
|
||||
this$static.m_Coders[i] = $Decoder$LiteralDecoder$Decoder2({});
|
||||
}
|
||||
|
||||
function $GetDecoder(this$static, pos, prevByte) {
|
||||
return this$static.m_Coders[((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + ((prevByte & 255) >>> 8 - this$static.m_NumPrevBits)];
|
||||
}
|
||||
|
||||
function $Init_0(this$static) {
|
||||
var i, numStates;
|
||||
numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
|
||||
for (i = 0; i < numStates; ++i) {
|
||||
InitBitModels(this$static.m_Coders[i].m_Decoders);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function $DecodeNormal(this$static, rangeDecoder) {
|
||||
var symbol = 1;
|
||||
do {
|
||||
symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol);
|
||||
} while (symbol < 256);
|
||||
return symbol << 24 >> 24;
|
||||
}
|
||||
|
||||
function $DecodeWithMatchByte(this$static, rangeDecoder, matchByte) {
|
||||
var bit, matchBit, symbol = 1;
|
||||
do {
|
||||
matchBit = matchByte >> 7 & 1;
|
||||
matchByte <<= 1;
|
||||
bit = $DecodeBit(rangeDecoder, this$static.m_Decoders, (1 + matchBit << 8) + symbol);
|
||||
symbol = symbol << 1 | bit;
|
||||
if (matchBit != bit) {
|
||||
while (symbol < 256) {
|
||||
symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (symbol < 256);
|
||||
return symbol << 24 >> 24;
|
||||
}
|
||||
|
||||
function $Decoder$LiteralDecoder$Decoder2(this$static) {
|
||||
this$static.m_Decoders = initDim(768);
|
||||
return this$static;
|
||||
}
|
||||
|
||||
/** de */
|
||||
|
||||
/** ds */
|
||||
function $BitTreeDecoder(this$static, numBitLevels) {
|
||||
this$static.NumBitLevels = numBitLevels;
|
||||
this$static.Models = initDim(1 << numBitLevels);
|
||||
return this$static;
|
||||
}
|
||||
|
||||
function $Decode_0(this$static, rangeDecoder) {
|
||||
var bitIndex, m = 1;
|
||||
for (bitIndex = this$static.NumBitLevels; bitIndex != 0; --bitIndex) {
|
||||
m = (m << 1) + $DecodeBit(rangeDecoder, this$static.Models, m);
|
||||
}
|
||||
return m - (1 << this$static.NumBitLevels);
|
||||
}
|
||||
|
||||
function $ReverseDecode(this$static, rangeDecoder) {
|
||||
var bit, bitIndex, m = 1, symbol = 0;
|
||||
for (bitIndex = 0; bitIndex < this$static.NumBitLevels; ++bitIndex) {
|
||||
bit = $DecodeBit(rangeDecoder, this$static.Models, m);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= bit << bitIndex;
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
function ReverseDecode(Models, startIndex, rangeDecoder, NumBitLevels) {
|
||||
var bit, bitIndex, m = 1, symbol = 0;
|
||||
for (bitIndex = 0; bitIndex < NumBitLevels; ++bitIndex) {
|
||||
bit = $DecodeBit(rangeDecoder, Models, startIndex + m);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= bit << bitIndex;
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
/** de */
|
||||
|
||||
/** ds */
|
||||
function $DecodeBit(this$static, probs, index) {
|
||||
var newBound, prob = probs[index];
|
||||
newBound = (this$static.Range >>> 11) * prob;
|
||||
if ((this$static.Code ^ -2147483648) < (newBound ^ -2147483648)) {
|
||||
this$static.Range = newBound;
|
||||
probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16;
|
||||
if (!(this$static.Range & -16777216)) {
|
||||
this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
|
||||
this$static.Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
this$static.Range -= newBound;
|
||||
this$static.Code -= newBound;
|
||||
probs[index] = prob - (prob >>> 5) << 16 >> 16;
|
||||
if (!(this$static.Range & -16777216)) {
|
||||
this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
|
||||
this$static.Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function $DecodeDirectBits(this$static, numTotalBits) {
|
||||
var i, t, result = 0;
|
||||
for (i = numTotalBits; i != 0; --i) {
|
||||
this$static.Range >>>= 1;
|
||||
t = this$static.Code - this$static.Range >>> 31;
|
||||
this$static.Code -= this$static.Range & t - 1;
|
||||
result = result << 1 | 1 - t;
|
||||
if (!(this$static.Range & -16777216)) {
|
||||
this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
|
||||
this$static.Range <<= 8;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function $Init_8(this$static) {
|
||||
this$static.Code = 0;
|
||||
this$static.Range = -1;
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
|
||||
}
|
||||
}
|
||||
/** de */
|
||||
|
||||
function InitBitModels(probs) {
|
||||
for (var i = probs.length - 1; i >= 0; --i) {
|
||||
probs[i] = 1024;
|
||||
}
|
||||
}
|
||||
|
||||
/** ds */
|
||||
function decode(utf) {
|
||||
var i = 0, j = 0, x, y, z, l = utf.length, buf = [], charCodes = [];
|
||||
for (; i < l; ++i, ++j) {
|
||||
x = utf[i] & 255;
|
||||
if (!(x & 128)) {
|
||||
if (!x) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
charCodes[j] = x;
|
||||
} else if ((x & 224) == 192) {
|
||||
if (i + 1 >= l) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
y = utf[++i] & 255;
|
||||
if ((y & 192) != 128) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
charCodes[j] = ((x & 31) << 6) | (y & 63);
|
||||
} else if ((x & 240) == 224) {
|
||||
if (i + 2 >= l) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
y = utf[++i] & 255;
|
||||
if ((y & 192) != 128) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
z = utf[++i] & 255;
|
||||
if ((z & 192) != 128) {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
charCodes[j] = ((x & 15) << 12) | ((y & 63) << 6) | (z & 63);
|
||||
} else {
|
||||
/// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
|
||||
return utf;
|
||||
}
|
||||
if (j == 16383) {
|
||||
buf.push(String.fromCharCode.apply(String, charCodes));
|
||||
j = -1;
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
charCodes.length = j;
|
||||
buf.push(String.fromCharCode.apply(String, charCodes));
|
||||
}
|
||||
return buf.join("");
|
||||
}
|
||||
/** de */
|
||||
|
||||
|
||||
function toDouble(a) {
|
||||
return a[1] + a[0];
|
||||
}
|
||||
|
||||
|
||||
/** ds */
|
||||
function decompress(byte_arr, on_finish, on_progress) {
|
||||
var this$static = {},
|
||||
percent,
|
||||
cbn, /// A callback number should be supplied instead of on_finish() if we are using Web Workers.
|
||||
has_progress,
|
||||
len,
|
||||
sync = typeof on_finish == "undefined" && typeof on_progress == "undefined";
|
||||
|
||||
if (typeof on_finish != "function") {
|
||||
cbn = on_finish;
|
||||
on_finish = on_progress = 0;
|
||||
}
|
||||
|
||||
on_progress = on_progress || function(percent) {
|
||||
if (typeof cbn == "undefined")
|
||||
return;
|
||||
|
||||
return update_progress(has_progress ? percent : -1, cbn);
|
||||
};
|
||||
|
||||
on_finish = on_finish || function(res, err) {
|
||||
if (typeof cbn == "undefined")
|
||||
return;
|
||||
|
||||
return postMessage({
|
||||
action: action_decompress,
|
||||
cbn: cbn,
|
||||
result: res,
|
||||
error: err
|
||||
});
|
||||
};
|
||||
|
||||
if (sync) {
|
||||
this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);
|
||||
while ($processChunk(this$static.d.chunker));
|
||||
return decode($toByteArray(this$static.d.output));
|
||||
}
|
||||
|
||||
try {
|
||||
this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);
|
||||
|
||||
len = toDouble(this$static.d.length_0);
|
||||
|
||||
///NOTE: If the data was created via a stream, it will not have a length value, and therefore we can't calculate the progress.
|
||||
has_progress = len > -1;
|
||||
|
||||
on_progress(0);
|
||||
} catch (err) {
|
||||
return on_finish(null, err);
|
||||
}
|
||||
|
||||
function do_action() {
|
||||
try {
|
||||
var res, i = 0, start = (new Date()).getTime();
|
||||
while ($processChunk(this$static.d.chunker)) {
|
||||
if (++i % 1000 == 0 && (new Date()).getTime() - start > 200) {
|
||||
if (has_progress) {
|
||||
percent = toDouble(this$static.d.chunker.decoder.nowPos64) / len;
|
||||
/// If about 200 miliseconds have passed, update the progress.
|
||||
on_progress(percent);
|
||||
}
|
||||
|
||||
///NOTE: This allows other code to run, like the browser to update.
|
||||
wait(do_action, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
on_progress(1);
|
||||
|
||||
res = decode($toByteArray(this$static.d.output));
|
||||
|
||||
/// delay so we don’t catch errors from the on_finish handler
|
||||
wait(on_finish.bind(null, res), 0);
|
||||
} catch (err) {
|
||||
on_finish(null, err);
|
||||
}
|
||||
}
|
||||
|
||||
///NOTE: We need to wait to make sure it is always async.
|
||||
wait(do_action, 0);
|
||||
}
|
||||
/** de */
|
||||
|
||||
|
||||
/// If we're in a Web Worker, create the onmessage() communication channel.
|
||||
///NOTE: This seems to be the most reliable way to detect this.
|
||||
if (typeof onmessage != "undefined" && (typeof window == "undefined" || typeof window.document == "undefined")) {
|
||||
(function () {
|
||||
/* jshint -W020 */
|
||||
/// Create the global onmessage function.
|
||||
onmessage = function (e) {
|
||||
if (e && e.data) {
|
||||
|
||||
/// co:if (e.data.action == action_compress) {
|
||||
/// co: LZMA.compress(e.data.data, e.data.mode, e.data.cbn);
|
||||
/// co:}
|
||||
if (e.data.action == action_decompress) {
|
||||
LZMA.decompress(e.data.data, e.data.cbn);
|
||||
}
|
||||
}
|
||||
};
|
||||
}());
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
/// co:compress: compress
|
||||
decompress: decompress
|
||||
};
|
||||
}());
|
||||
|
||||
/// This is used by browsers that do not support web workers (and possibly Node.js).
|
||||
this.LZMA = this.LZMA_WORKER = LZMA;
|
||||
2
src/lzma-min.js
vendored
Executable file
2
src/lzma-min.js
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
//! © 2015 Nathan Rugg <nmrugg@gmail.com> | MIT
|
||||
"undefined"==typeof Worker||"undefined"!=typeof location&&"file:"===location.protocol?"undefined"!=typeof global&&"undefined"!=typeof require?this.LZMA=function(n){return require(n||"./lzma_worker.js").LZMA}:"undefined"!=typeof window&&window.document?!function(){function n(n){var e;return r(n),e={compress:function(n,r,t,i){o.LZMA_WORKER?o.LZMA_WORKER.compress(n,r,t,i):setTimeout(function(){e.compress(n,r,t,i)},50)},decompress:function(n,r,t){o.LZMA_WORKER?o.LZMA_WORKER.decompress(n,r,t):setTimeout(function(){e.decompress(n,r,t)},50)},worker:function(){return null}}}var o,e=this,r=function(o){var r=document.createElement("script");r.type="text/javascript",r.src=o,r.onload=function(){e.LZMA=n},document.getElementsByTagName("head")[0].appendChild(r)};"undefined"!=typeof window?o=window:global&&(o=global),e.LZMA=n}():console.error("Can't load the worker. Sorry."):this.LZMA=function(n){var o=1,e=2,r=3,t={},i=new Worker(n||"./lzma_worker-min.js");return i.onmessage=function(n){n.data.action===r?t[n.data.cbn]&&"function"==typeof t[n.data.cbn].on_progress&&t[n.data.cbn].on_progress(n.data.result):t[n.data.cbn]&&"function"==typeof t[n.data.cbn].on_finish&&(t[n.data.cbn].on_finish(n.data.result,n.data.error),delete t[n.data.cbn])},i.onerror=function(n){var o=Error(n.message+" ("+n.filename+":"+n.lineno+")");for(var e in t)t[e].on_finish(null,o);console.error("Uncaught error in lzma_worker",o)},function(){function n(n,o,e,r,a){var c;do c=Math.floor(1e7*Math.random());while(void 0!==t[c]);t[c]={on_finish:r,on_progress:a},i.postMessage({action:n,cbn:c,data:o,mode:e})}return{compress:function(e,r,t,i){n(o,e,r,t,i)},decompress:function(o,r,t){n(e,o,!1,r,t)},worker:function(){return i}}}()};
|
||||
153
src/lzma.js
Executable file
153
src/lzma.js
Executable file
|
|
@ -0,0 +1,153 @@
|
|||
//! © 2015 Nathan Rugg <nmrugg@gmail.com> | MIT
|
||||
/// See LICENSE for more details.
|
||||
|
||||
// jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true, latedef:true, newcap:true, noarg:true, noempty:true, nonew:true, onevar:true, plusplus:true, quotmark:double, undef:true, unused:strict, browser: true, node: true
|
||||
|
||||
/// Does the environment support web workers? If not, let's load the worker manually (without polluting the global scope).
|
||||
if (typeof Worker === "undefined" || (typeof location !== "undefined" && location.protocol === "file:")) {
|
||||
/// Is this Node.js?
|
||||
if (typeof global !== "undefined" && typeof require !== "undefined") {
|
||||
this.LZMA = function (lzma_path) {
|
||||
return require(lzma_path || "./lzma_worker.js").LZMA;
|
||||
};
|
||||
/// Is this a browser?
|
||||
} else if (typeof window !== "undefined" && window.document) {
|
||||
(function () {
|
||||
var that = this,
|
||||
global_var,
|
||||
req = function req(path) {
|
||||
var script_tag = document.createElement("script");
|
||||
script_tag.type ="text/javascript";
|
||||
script_tag.src = path;
|
||||
script_tag.onload = function () {
|
||||
/// Make sure this LZMA variable doesn't get overwritten by the worker's.
|
||||
that.LZMA = non_worker_lzma;
|
||||
};
|
||||
document.getElementsByTagName("head")[0].appendChild(script_tag);
|
||||
};
|
||||
|
||||
/// Determine the global variable (it's called "window" in browsers, "global" in Node.js).
|
||||
if (typeof window !== "undefined") {
|
||||
global_var = window;
|
||||
} else if (global) {
|
||||
global_var = global;
|
||||
}
|
||||
|
||||
function non_worker_lzma(path) {
|
||||
var fake_lzma;
|
||||
|
||||
req(path);
|
||||
|
||||
fake_lzma = {
|
||||
compress: function compress(mixed, mode, on_finish, on_progress) {
|
||||
if (global_var.LZMA_WORKER) {
|
||||
global_var.LZMA_WORKER.compress(mixed, mode, on_finish, on_progress);
|
||||
} else {
|
||||
/// Wait
|
||||
setTimeout(function ()
|
||||
{
|
||||
fake_lzma.compress(mixed, mode, on_finish, on_progress);
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
decompress: function decompress(byte_arr, on_finish, on_progress) {
|
||||
if (global_var.LZMA_WORKER) {
|
||||
global_var.LZMA_WORKER.decompress(byte_arr, on_finish, on_progress);
|
||||
} else {
|
||||
/// Wait
|
||||
setTimeout(function ()
|
||||
{
|
||||
fake_lzma.decompress(byte_arr, on_finish, on_progress);
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
worker: function worker () {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return fake_lzma;
|
||||
}
|
||||
|
||||
that.LZMA = non_worker_lzma;
|
||||
}());
|
||||
} else {
|
||||
/// It doesn't seem to be either Node.js or a browser.
|
||||
console.error("Can't load the worker. Sorry.");
|
||||
}
|
||||
} else {
|
||||
/// Let's use Web Workers.
|
||||
///NOTE: The "this" keyword is the global context ("window" variable) if loaded via a <script> tag
|
||||
/// or the function context if loaded as a module (e.g., in Node.js).
|
||||
this.LZMA = function (lzma_path) {
|
||||
var action_compress = 1,
|
||||
action_decompress = 2,
|
||||
action_progress = 3,
|
||||
|
||||
callback_obj = {},
|
||||
|
||||
///NOTE: Node.js needs something like "./" or "../" at the beginning.
|
||||
lzma_worker = new Worker(lzma_path || "./lzma_worker-min.js");
|
||||
|
||||
lzma_worker.onmessage = function onmessage(e) {
|
||||
if (e.data.action === action_progress) {
|
||||
if (callback_obj[e.data.cbn] && typeof callback_obj[e.data.cbn].on_progress === "function") {
|
||||
callback_obj[e.data.cbn].on_progress(e.data.result);
|
||||
}
|
||||
} else {
|
||||
if (callback_obj[e.data.cbn] && typeof callback_obj[e.data.cbn].on_finish === "function") {
|
||||
callback_obj[e.data.cbn].on_finish(e.data.result, e.data.error);
|
||||
|
||||
/// Since the (de)compression is complete, the callbacks are no longer needed.
|
||||
delete callback_obj[e.data.cbn];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Very simple error handling.
|
||||
lzma_worker.onerror = function(event) {
|
||||
var err = new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
|
||||
|
||||
for (var cbn in callback_obj) {
|
||||
callback_obj[cbn].on_finish(null, err);
|
||||
}
|
||||
|
||||
console.error('Uncaught error in lzma_worker', err);
|
||||
};
|
||||
|
||||
return (function () {
|
||||
|
||||
function send_to_worker(action, data, mode, on_finish, on_progress) {
|
||||
var cbn;
|
||||
|
||||
do {
|
||||
cbn = Math.floor(Math.random() * (10000000));
|
||||
} while(typeof callback_obj[cbn] !== "undefined");
|
||||
|
||||
callback_obj[cbn] = {
|
||||
on_finish: on_finish,
|
||||
on_progress: on_progress
|
||||
};
|
||||
|
||||
lzma_worker.postMessage({
|
||||
action: action, /// action_compress = 1, action_decompress = 2, action_progress = 3
|
||||
cbn: cbn, /// callback number
|
||||
data: data,
|
||||
mode: mode
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
compress: function compress(mixed, mode, on_finish, on_progress) {
|
||||
send_to_worker(action_compress, mixed, mode, on_finish, on_progress);
|
||||
},
|
||||
decompress: function decompress(byte_arr, on_finish, on_progress) {
|
||||
send_to_worker(action_decompress, byte_arr, false, on_finish, on_progress);
|
||||
},
|
||||
worker: function worker() {
|
||||
return lzma_worker;
|
||||
}
|
||||
};
|
||||
}());
|
||||
};
|
||||
}
|
||||
2
src/lzma_worker-min.js
vendored
Executable file
2
src/lzma_worker-min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
2668
src/lzma_worker.js
Executable file
2668
src/lzma_worker.js
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue