Compare commits
54 Commits
Author | SHA1 | Date |
---|---|---|
jeromewu | d6e9177290 | 5 years ago |
jeromewu | 3d1aa49c33 | 5 years ago |
MoeBrowne | a86cb05519 | 5 years ago |
MoeBrowne | 95e74bdbed | 5 years ago |
Jerome Wu | 363ecd7b22 | 5 years ago |
Jerome Wu | 9863bd8f74 | 5 years ago |
jeromewu | 18dde5cbac | 6 years ago |
jeromewu | ebe263ad0f | 6 years ago |
Jerome Wu | 91c39ceaa5 | 6 years ago |
Jerome Wu | 24ebdeacb8 | 6 years ago |
Jerome Wu | d58b778d0b | 6 years ago |
Jerome Wu | 233cc8bdd3 | 6 years ago |
Jerome Wu | b2c819b219 | 6 years ago |
Jerome Wu | 8ef238714b | 6 years ago |
Jerome Wu | 2ec4a0433f | 6 years ago |
jeromewu | 1a4da18407 | 6 years ago |
jeromewu | 232d8e854d | 6 years ago |
jeromewu | 7128fc5572 | 6 years ago |
jeromewu | ab5776f2a9 | 6 years ago |
jeromewu | 8978faa04a | 6 years ago |
jeromewu | ef1ac48467 | 6 years ago |
Guillermo | 8e755745b7 | 8 years ago |
Kevin Kwok | 0709222de3 | 8 years ago |
Kevin Kwok | 2f3fd699d7 | 8 years ago |
Kevin Kwok | d00d676fc9 | 8 years ago |
bijection | 7f23b4c073 | 8 years ago |
Pascal Borreli | 476fa56084 | 8 years ago |
Guillermo | 1896dc0807 | 8 years ago |
Guillermo | 325747e0a7 | 8 years ago |
Kevin Kwok | be29f9ab92 | 8 years ago |
Kevin Kwok | 244d0b98d7 | 8 years ago |
Guillermo | 8a79897546 | 8 years ago |
Guillermo | cb9e2d5928 | 8 years ago |
Guillermo | 200b770c97 | 8 years ago |
Guillermo | 0243eb6bd0 | 8 years ago |
Guillermo | 8527a70b36 | 8 years ago |
Guillermo | 923d75a047 | 9 years ago |
Guillermo | 26d7681e72 | 10 years ago |
Guillermo | 2d85c0fbe8 | 10 years ago |
Guillermo | 5660a8c454 | 10 years ago |
Guillermo | 73f381f595 | 10 years ago |
Guillermo | 5b02e236c1 | 10 years ago |
Guillermo | 1270e278c9 | 10 years ago |
Guillermo | 8d23fa0bdf | 10 years ago |
Guillermo | abf7ae1190 | 10 years ago |
Guillermo | 379781c8a5 | 10 years ago |
Guillermo | e23d75f0a9 | 10 years ago |
bijection | 1073a8ca61 | 10 years ago |
Guillermo | 61415571bd | 10 years ago |
Guillermo | 58b816a40b | 10 years ago |
Guillermo | 78d70d73d4 | 10 years ago |
Guillermo | 3a47aed70f | 10 years ago |
Guillermo | b2ff251c7d | 10 years ago |
Guillermo | 0f0ed005e5 | 10 years ago |
@ -1,2 +1,3 @@
@@ -1,2 +1,3 @@
|
||||
.DS_Store |
||||
node_modules/* |
||||
explorer/.module-cache/* |
@ -1,60 +0,0 @@
@@ -1,60 +0,0 @@
|
||||
var Tesseract = {} |
||||
|
||||
Tesseract.recognize = function(image, options, callback){ |
||||
var lang = options.lang |
||||
if(typeof lang === "undefined"){ |
||||
lang = 'eng' |
||||
} |
||||
|
||||
if (typeof options === 'string') { |
||||
lang = options |
||||
options = {} |
||||
} |
||||
|
||||
if (typeof options === "function") { |
||||
callback = options |
||||
options = {} |
||||
} |
||||
|
||||
|
||||
if(image.getContext){ |
||||
image = image.getContext('2d'); |
||||
}else if(image.tagName == "IMG" || image.tagName == "VIDEO"){ |
||||
var c = document.createElement('canvas'); |
||||
if(image.tagName == "IMG"){ |
||||
c.width = image.naturalWidth; |
||||
c.height = image.naturalHeight; |
||||
}else if(image.tagName == "VIDEO"){ |
||||
c.width = image.videoWidth; |
||||
c.height = image.videoHeight; |
||||
} |
||||
var ctx = c.getContext('2d'); |
||||
ctx.drawImage(image, 0, 0); |
||||
image = ctx; |
||||
} |
||||
if(image.getImageData) image = image.getImageData(0, 0, image.canvas.width, image.canvas.height); |
||||
|
||||
var worker = new Worker('./worker.js') |
||||
|
||||
if(typeof callback === "function"){ |
||||
worker.onmessage = function(e){ |
||||
callback(e.data.err, e.data.result) |
||||
} |
||||
worker.postMessage({image: image, lang: lang}) |
||||
console.log('callback') |
||||
} |
||||
else { |
||||
return new Promise(function(resolve, reject){ |
||||
worker.onmessage = function(e){ |
||||
if(e.data.err){ |
||||
reject(e.data.err) |
||||
} |
||||
else { |
||||
resolve(e.data.result) |
||||
} |
||||
} |
||||
worker.postMessage({image: image, lang: lang, options: options}) |
||||
console.log('promise') |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
var canvas = document.getElementById('logo-canvas'), |
||||
ctx = canvas.getContext('2d'), |
||||
logo_wrap = document.getElementById('logo-wrap'), |
||||
splash = document.getElementById('splash'), |
||||
logo_img = document.getElementById('logo-img'), |
||||
color = "white", |
||||
lasttime, |
||||
freeze |
||||
|
||||
|
||||
function fixdim() { |
||||
dimensions.update() |
||||
|
||||
var displaywidth = Math.sqrt(dimensions.width)*18//dimensions.width > 900 ? 900 : 450
|
||||
|
||||
var doc = document.documentElement; |
||||
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); |
||||
|
||||
// logo_wrap.style.top = top / 2 + 'px'
|
||||
var rect = splash.getBoundingClientRect() |
||||
var bottom = rect.top + rect.height |
||||
|
||||
var fadestart = rect.height/2 |
||||
|
||||
logo_wrap.style.opacity = Math.max(Math.min((bottom-fadestart)/fadestart,1),0) |
||||
|
||||
logo_img.style.width = displaywidth + 'px' |
||||
|
||||
if(!freeze){ |
||||
var displayheight = displaywidth * 4/15 //dimensions.width > 900 ? 250 : 125
|
||||
canvas.width = displayheight*window.devicePixelRatio |
||||
canvas.style.width = displayheight + 'px' |
||||
canvas.height = displayheight*window.devicePixelRatio |
||||
canvas.style.height = displayheight + 'px' |
||||
} |
||||
} |
||||
|
||||
addEventListener('scroll', fixdim) |
||||
|
||||
var gh = .12; |
||||
|
||||
function main (time) { |
||||
fixdim() |
||||
ctx.clearRect(0,0,canvas.width,canvas.height) |
||||
|
||||
var t = time/10000 |
||||
|
||||
ctx.strokeStyle = ctx.fillStyle = color |
||||
var sm = 1 |
||||
|
||||
var m = tesseractwithrotation(t, t*2, t*3, mouse.x/100, mouse.y/100, 0) |
||||
|
||||
drawtesseract(ctx, m, { |
||||
x: canvas.width/2, |
||||
y: canvas.height/2, |
||||
size: gh*canvas.height, |
||||
line_width: 2, |
||||
}) |
||||
|
||||
lasttime = time |
||||
requestAnimationFrame(main) |
||||
} |
||||
|
||||
|
||||
|
||||
requestAnimationFrame(function init(t) { |
||||
fixdim() |
||||
lasttime = t |
||||
requestAnimationFrame(main) |
||||
}) |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
var dimensions = { |
||||
|
||||
width:0, |
||||
|
||||
height:0, |
||||
|
||||
getWidth: function () { |
||||
if (window.innerWidth) { |
||||
return window.innerWidth; |
||||
} |
||||
if (document.documentElement && document.documentElement.clientHeight){ |
||||
return document.documentElement.clientWidth; |
||||
} |
||||
if (document.body) { |
||||
return document.body.clientWidth; |
||||
} |
||||
return 0; |
||||
}, |
||||
|
||||
getHeight: function () { |
||||
if (window.innerWidth) { |
||||
return window.innerHeight; |
||||
} |
||||
if (document.documentElement && document.documentElement.clientHeight){ |
||||
return document.documentElement.clientHeight; |
||||
} |
||||
if (document.body) { |
||||
return document.body.clientHeight; |
||||
} |
||||
return 0; |
||||
}, |
||||
|
||||
update: function () { |
||||
var curW = this.getWidth() |
||||
var curH = this.getHeight() |
||||
if (curW!=this.width||curH!=this.height){ |
||||
this.width=curW |
||||
this.height=curH |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
} |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
function app1(p,a,c1,c2){ |
||||
var l = Math.cos(a)*p[c1]+Math.sin(a)*p[c2] |
||||
var k = -Math.sin(a)*p[c1]+Math.cos(a)*p[c2] |
||||
p[c1] = l |
||||
p[c2] = k |
||||
} |
||||
|
||||
function app2(p,a,c1,c2){ |
||||
var l = Math.cos(a)*p[c1]-Math.sin(a)*p[c2] |
||||
var k = Math.sin(a)*p[c1]+Math.cos(a)*p[c2] |
||||
p[c1] = l |
||||
p[c2] = k |
||||
} |
||||
|
||||
var _edges |
||||
function tesseractedges(){ |
||||
if(!_edges){ |
||||
var m = tesseractwithrotation(0,0,0,0,0,0) |
||||
var edges = [] |
||||
var indicies = ['x','y','z','w'] |
||||
for (var i = 0; i < m.length; i++) { |
||||
for (var j = i+1; j < m.length; j++) { |
||||
var count = 0 |
||||
for (var k = 0; k < 4; k++) { |
||||
if (m[i][indicies[k]] === m[j][indicies[k]]) count++ |
||||
}; |
||||
if (count === 3) edges.push([i,j]) |
||||
} |
||||
} |
||||
_edges = edges |
||||
} |
||||
return _edges |
||||
} |
||||
|
||||
function tesseractwithrotation(a,b,c,d,e,f) { |
||||
var verticies = [] |
||||
for (var i = 0; i < 16; i++) { |
||||
var p = { |
||||
x: (i&1)*2 - 1, |
||||
y: ((i>>1)&1)*2 - 1, |
||||
z: ((i>>2)&1)*2 - 1, |
||||
w: ((i>>3)&1)*2 - 1 |
||||
} |
||||
app1(p,a,'x','y') |
||||
app1(p,b,'y','z') |
||||
app1(p,c,'x','w') |
||||
app2(p,d,'x','z') |
||||
app2(p,e,'y','w') |
||||
app2(p,f,'z','w') |
||||
verticies.push(p) |
||||
} |
||||
return verticies |
||||
} |
||||
|
||||
function project(point, size){ |
||||
return { |
||||
x: (point.x+Math.SQRT2*point.z)*size, |
||||
y: (point.y+Math.SQRT2*point.w)*size |
||||
} |
||||
} |
||||
|
||||
function drawtesseract(ctx, tesseract, opts){ |
||||
var edges = tesseractedges() |
||||
for (var i = 0; i < tesseract.length; i++) { |
||||
var proj = project(tesseract[i], opts.size) |
||||
ctx.beginPath() |
||||
ctx.arc(proj.x + opts.x, proj.y + opts.y, opts.corner_radius, 0, 2 * Math.PI) |
||||
ctx.fill() |
||||
}; |
||||
ctx.lineWidth = opts.line_width || 1 |
||||
ctx.beginPath() |
||||
for (var i = 0; i < edges.length; i++) { |
||||
var v1 = project(tesseract[edges[i][0]], opts.size), |
||||
v2 = project(tesseract[edges[i][1]], opts.size) |
||||
ctx.moveTo(v1.x+opts.x,v1.y+opts.y) |
||||
ctx.lineTo(v2.x+opts.x,v2.y+opts.y) |
||||
}; |
||||
ctx.stroke() |
||||
} |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
var mouse = { |
||||
x: 0, |
||||
y: 0, |
||||
direction:0, |
||||
|
||||
start: { |
||||
x:0, |
||||
y:0 |
||||
}, |
||||
|
||||
dragging: false, |
||||
|
||||
set: function (x,y) { |
||||
mouse.x = x |
||||
mouse.y = y |
||||
mouse.direction = Math.atan2(y-mouse.start.y,x-mouse.start.x) |
||||
}, |
||||
|
||||
coords: function (e) { |
||||
// e.preventDefault();
|
||||
if(e.pageX){ |
||||
mouse.set(e.pageX,e.pageY) |
||||
} |
||||
else if(e.offsetX) { |
||||
mouse.set(e.offsetX,e.offsetY) |
||||
} |
||||
else if(e.layerX) { |
||||
mouse.set(e.layerX,e.layerY) |
||||
} |
||||
else if(e.targetTouches && e.targetTouches.length > 0){ |
||||
mouse.set(e.targetTouches[0].pageX,e.targetTouches[0].pageY) |
||||
} |
||||
}, |
||||
|
||||
down: function (e) { |
||||
mouse.coords(e) |
||||
mouse.start.x=mouse.x |
||||
mouse.start.y=mouse.y |
||||
mouse.dragging = true |
||||
// console.log(e)
|
||||
|
||||
}, |
||||
|
||||
up: function (e) { |
||||
mouse.coords(e) |
||||
mouse.dragging = false |
||||
} |
||||
} |
||||
|
||||
document.addEventListener("touchstart", mouse.down, true); |
||||
document.addEventListener("touchend", mouse.up, true); |
||||
document.addEventListener("touchmove", mouse.coords, true); |
||||
|
||||
document.addEventListener("mousedown", mouse.down, true); |
||||
document.addEventListener("mouseup", mouse.up, true); |
||||
document.addEventListener("mousemove", mouse.coords, true); |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||||
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
|
||||
// MIT license
|
||||
|
||||
;(function() { |
||||
var lastTime = 0; |
||||
var vendors = ['ms', 'moz', 'webkit', 'o']; |
||||
if(typeof window != "undefined"){ |
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { |
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; |
||||
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] |
||||
|| window[vendors[x]+'CancelRequestAnimationFrame']; |
||||
} |
||||
if (!window.requestAnimationFrame) |
||||
window.requestAnimationFrame = function(callback, element) { |
||||
var currTime = new Date().getTime(); |
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); |
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); }, |
||||
timeToCall); |
||||
lastTime = currTime + timeToCall; |
||||
return id; |
||||
}; |
||||
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; |
||||
} |
||||
}()); |
||||
|
@ -0,0 +1,329 @@
@@ -0,0 +1,329 @@
|
||||
/* BASICS */ |
||||
|
||||
.CodeMirror { |
||||
/* Set height, width, borders, and global font properties here */ |
||||
font-family: monospace; |
||||
height: auto; |
||||
color: rgb(156, 154, 193); |
||||
padding: 10px; |
||||
padding-top: 5px; |
||||
} |
||||
|
||||
/* PADDING */ |
||||
|
||||
.CodeMirror-lines { |
||||
padding: 4px 0; /* Vertical padding around content */ |
||||
} |
||||
.CodeMirror pre { |
||||
padding: 0 4px; /* Horizontal padding of content */ |
||||
} |
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { |
||||
background-color: white; /* The little square between H and V scrollbars */ |
||||
} |
||||
|
||||
/* GUTTER */ |
||||
|
||||
.CodeMirror-gutters { |
||||
border-right: 1px solid #ddd; |
||||
background-color: #f7f7f7; |
||||
white-space: nowrap; |
||||
} |
||||
.CodeMirror-linenumbers {} |
||||
.CodeMirror-linenumber { |
||||
padding: 0 3px 0 5px; |
||||
min-width: 20px; |
||||
text-align: right; |
||||
color: #999; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
.CodeMirror-guttermarker { color: black; } |
||||
.CodeMirror-guttermarker-subtle { color: #999; } |
||||
|
||||
/* CURSOR */ |
||||
|
||||
.CodeMirror div.CodeMirror-cursor { |
||||
border-left: 1px solid black; |
||||
} |
||||
/* Shown when moving in bi-directional text */ |
||||
.CodeMirror div.CodeMirror-secondarycursor { |
||||
border-left: 1px solid silver; |
||||
} |
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursor { |
||||
width: auto; |
||||
border: 0; |
||||
background: #7e7; |
||||
} |
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursors { |
||||
z-index: 1; |
||||
} |
||||
|
||||
.cm-animate-fat-cursor { |
||||
width: auto; |
||||
border: 0; |
||||
-webkit-animation: blink 1.06s steps(1) infinite; |
||||
-moz-animation: blink 1.06s steps(1) infinite; |
||||
animation: blink 1.06s steps(1) infinite; |
||||
} |
||||
@-moz-keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
@-webkit-keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
@keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */ |
||||
div.CodeMirror-overwrite div.CodeMirror-cursor {} |
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; } |
||||
|
||||
.CodeMirror-ruler { |
||||
border-left: 1px solid #ccc; |
||||
position: absolute; |
||||
} |
||||
|
||||
/* DEFAULT THEME */ |
||||
|
||||
.cm-s-default .cm-header {color: blue;} |
||||
.cm-s-default .cm-quote {color: #090;} |
||||
.cm-negative {color: #d44;} |
||||
.cm-positive {color: #292;} |
||||
.cm-header, .cm-strong {font-weight: bold;} |
||||
.cm-em {font-style: italic;} |
||||
.cm-link {text-decoration: underline;} |
||||
.cm-strikethrough {text-decoration: line-through;} |
||||
|
||||
.cm-s-default .cm-keyword {color: #0DAEFF;} |
||||
.cm-s-default .cm-atom {color: #219;} |
||||
.cm-s-default .cm-number {color: #164;} |
||||
.cm-s-default .cm-def {color: #00f;} |
||||
.cm-s-default .cm-variable, |
||||
.cm-s-default .cm-punctuation { |
||||
color: black; |
||||
} |
||||
.cm-s-default .cm-property {color: #4CA2F2;} |
||||
.cm-s-default .cm-operator {} |
||||
.cm-s-default .cm-variable-2 {color: #05a;} |
||||
.cm-s-default .cm-variable-3 {color: #085;} |
||||
.cm-s-default .cm-comment {color: #DB0000;} |
||||
.cm-s-default .cm-string {color: #5426C9;} |
||||
.cm-s-default .cm-string-2 {color: #f50;} |
||||
.cm-s-default .cm-meta {color: #555;} |
||||
.cm-s-default .cm-qualifier {color: #555;} |
||||
.cm-s-default .cm-builtin {color: #30a;} |
||||
.cm-s-default .cm-bracket {color: #997;} |
||||
.cm-s-default .cm-tag {color: #050216;} |
||||
.cm-s-default .cm-attribute {color: #00c;} |
||||
.cm-s-default .cm-hr {color: #999;} |
||||
.cm-s-default .cm-link {color: #00c;} |
||||
|
||||
.cm-s-default .cm-error {color: #f00;} |
||||
.cm-invalidchar {color: #f00;} |
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; } |
||||
|
||||
/* Default styles for common addons */ |
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} |
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} |
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } |
||||
.CodeMirror-activeline-background {background: #e8f2ff;} |
||||
|
||||
/* STOP */ |
||||
|
||||
/* The rest of this file contains styles related to the mechanics of |
||||
the editor. You probably shouldn't touch them. */ |
||||
|
||||
.CodeMirror { |
||||
position: relative; |
||||
overflow: hidden; |
||||
background: transparent; |
||||
} |
||||
|
||||
.CodeMirror-scroll { |
||||
overflow: scroll !important; /* Things will break if this is overridden */ |
||||
/* 30px is the magic margin used to hide the element's real scrollbars */ |
||||
/* See overflow: hidden in .CodeMirror */ |
||||
margin-bottom: -30px; margin-right: -30px; |
||||
padding-bottom: 30px; |
||||
/*height: 100%;*/ |
||||
outline: none; /* Prevent dragging from highlighting the element */ |
||||
position: relative; |
||||
} |
||||
.CodeMirror-sizer { |
||||
position: relative; |
||||
border-right: 30px solid transparent; |
||||
} |
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling |
||||
before actuall scrolling happens, thus preventing shaking and |
||||
flickering artifacts. */ |
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { |
||||
position: absolute; |
||||
z-index: 6; |
||||
display: none; |
||||
} |
||||
.CodeMirror-vscrollbar { |
||||
right: 0; top: 0; |
||||
overflow-x: hidden; |
||||
overflow-y: scroll; |
||||
} |
||||
.CodeMirror-hscrollbar { |
||||
bottom: 0; left: 0; |
||||
overflow-y: hidden; |
||||
overflow-x: scroll; |
||||
} |
||||
.CodeMirror-scrollbar-filler { |
||||
right: 0; bottom: 0; |
||||
} |
||||
.CodeMirror-gutter-filler { |
||||
left: 0; bottom: 0; |
||||
} |
||||
|
||||
.CodeMirror-gutters { |
||||
position: absolute; left: 0; top: 0; |
||||
z-index: 3; |
||||
} |
||||
.CodeMirror-gutter { |
||||
white-space: normal; |
||||
height: 100%; |
||||
display: inline-block; |
||||
margin-bottom: -30px; |
||||
/* Hack to make IE7 behave */ |
||||
*zoom:1; |
||||
*display:inline; |
||||
} |
||||
.CodeMirror-gutter-wrapper { |
||||
position: absolute; |
||||
z-index: 4; |
||||
height: 100%; |
||||
} |
||||
.CodeMirror-gutter-elt { |
||||
position: absolute; |
||||
cursor: default; |
||||
z-index: 4; |
||||
} |
||||
.CodeMirror-gutter-wrapper { |
||||
-webkit-user-select: none; |
||||
-moz-user-select: none; |
||||
user-select: none; |
||||
} |
||||
|
||||
.CodeMirror-lines { |
||||
cursor: text; |
||||
min-height: 1px; /* prevents collapsing before first draw */ |
||||
} |
||||
.CodeMirror pre { |
||||
/* Reset some styles that the rest of the page might have set */ |
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; |
||||
border-width: 0; |
||||
background: transparent; |
||||
font-family: inherit; |
||||
font-size: inherit; |
||||
margin: 0; |
||||
white-space: pre; |
||||
word-wrap: normal; |
||||
line-height: inherit; |
||||
color: inherit; |
||||
z-index: 2; |
||||
position: relative; |
||||
overflow: visible; |
||||
-webkit-tap-highlight-color: transparent; |
||||
} |
||||
.CodeMirror-wrap pre { |
||||
word-wrap: break-word; |
||||
white-space: pre-wrap; |
||||
word-break: normal; |
||||
} |
||||
|
||||
.CodeMirror-linebackground { |
||||
position: absolute; |
||||
left: 0; right: 0; top: 0; bottom: 0; |
||||
z-index: 0; |
||||
} |
||||
|
||||
.CodeMirror-linewidget { |
||||
position: relative; |
||||
z-index: 2; |
||||
overflow: auto; |
||||
} |
||||
|
||||
.CodeMirror-widget {} |
||||
|
||||
.CodeMirror-code { |
||||
outline: none; |
||||
} |
||||
|
||||
/* Force content-box sizing for the elements where we expect it */ |
||||
.CodeMirror-scroll, |
||||
.CodeMirror-sizer, |
||||
.CodeMirror-gutter, |
||||
.CodeMirror-gutters, |
||||
.CodeMirror-linenumber { |
||||
-moz-box-sizing: content-box; |
||||
box-sizing: content-box; |
||||
} |
||||
|
||||
.CodeMirror-measure { |
||||
position: absolute; |
||||
width: 100%; |
||||
height: 0; |
||||
overflow: hidden; |
||||
visibility: hidden; |
||||
} |
||||
.CodeMirror-measure pre { position: static; } |
||||
|
||||
.CodeMirror div.CodeMirror-cursor { |
||||
position: absolute; |
||||
border-right: none; |
||||
width: 0; |
||||
} |
||||
|
||||
div.CodeMirror-cursors { |
||||
visibility: hidden; |
||||
position: relative; |
||||
z-index: 3; |
||||
} |
||||
.CodeMirror-focused div.CodeMirror-cursors { |
||||
visibility: visible; |
||||
} |
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; } |
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } |
||||
.CodeMirror-crosshair { cursor: crosshair; } |
||||
.CodeMirror ::selection { background: #d7d4f0; } |
||||
.CodeMirror ::-moz-selection { background: #d7d4f0; } |
||||
|
||||
.cm-searching { |
||||
background: #ffa; |
||||
background: rgba(255, 255, 0, .4); |
||||
} |
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */ |
||||
.CodeMirror span { *vertical-align: text-bottom; } |
||||
|
||||
/* Used to force a border model for a node */ |
||||
.cm-force-border { padding-right: .1px; } |
||||
|
||||
@media print { |
||||
/* Hide the cursor when printing */ |
||||
.CodeMirror div.CodeMirror-cursors { |
||||
visibility: hidden; |
||||
} |
||||
} |
||||
|
||||
/* See issue #2901 */ |
||||
.cm-tab-wrap-hack:after { content: ''; } |
||||
|
||||
/* Help users use markselection to safely style text background */ |
||||
span.CodeMirror-selectedtext { background: none; } |
@ -0,0 +1,704 @@
@@ -0,0 +1,704 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// TODO actually recognize syntax of TypeScript constructs
|
||||
|
||||
(function(mod) { |
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror")); |
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod); |
||||
else // Plain browser env
|
||||
mod(CodeMirror); |
||||
})(function(CodeMirror) { |
||||
"use strict"; |
||||
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) { |
||||
var indentUnit = config.indentUnit; |
||||
var statementIndent = parserConfig.statementIndent; |
||||
var jsonldMode = parserConfig.jsonld; |
||||
var jsonMode = parserConfig.json || jsonldMode; |
||||
var isTS = parserConfig.typescript; |
||||
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; |
||||
|
||||
// Tokenizer
|
||||
|
||||
var keywords = function(){ |
||||
function kw(type) {return {type: type, style: "keyword"};} |
||||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); |
||||
var operator = kw("operator"), atom = {type: "atom", style: "atom"}; |
||||
|
||||
var jsKeywords = { |
||||
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, |
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, |
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"), |
||||
"function": kw("function"), "catch": kw("catch"), |
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), |
||||
"in": operator, "typeof": operator, "instanceof": operator, |
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, |
||||
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), |
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C |
||||
}; |
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
if (isTS) { |
||||
var type = {type: "variable", style: "variable-3"}; |
||||
var tsKeywords = { |
||||
// object-like things
|
||||
"interface": kw("interface"), |
||||
"extends": kw("extends"), |
||||
"constructor": kw("constructor"), |
||||
|
||||
// scope modifiers
|
||||
"public": kw("public"), |
||||
"private": kw("private"), |
||||
"protected": kw("protected"), |
||||
"static": kw("static"), |
||||
|
||||
// types
|
||||
"string": type, "number": type, "bool": type, "any": type |
||||
}; |
||||
|
||||
for (var attr in tsKeywords) { |
||||
jsKeywords[attr] = tsKeywords[attr]; |
||||
} |
||||
} |
||||
|
||||
return jsKeywords; |
||||
}(); |
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|~^]/; |
||||
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; |
||||
|
||||
function readRegexp(stream) { |
||||
var escaped = false, next, inSet = false; |
||||
while ((next = stream.next()) != null) { |
||||
if (!escaped) { |
||||
if (next == "/" && !inSet) return; |
||||
if (next == "[") inSet = true; |
||||
else if (inSet && next == "]") inSet = false; |
||||
} |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
} |
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content; |
||||
function ret(tp, style, cont) { |
||||
type = tp; content = cont; |
||||
return style; |
||||
} |
||||
function tokenBase(stream, state) { |
||||
var ch = stream.next(); |
||||
if (ch == '"' || ch == "'") { |
||||
state.tokenize = tokenString(ch); |
||||
return state.tokenize(stream, state); |
||||
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { |
||||
return ret("number", "number"); |
||||
} else if (ch == "." && stream.match("..")) { |
||||
return ret("spread", "meta"); |
||||
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { |
||||
return ret(ch); |
||||
} else if (ch == "=" && stream.eat(">")) { |
||||
return ret("=>", "operator"); |
||||
} else if (ch == "0" && stream.eat(/x/i)) { |
||||
stream.eatWhile(/[\da-f]/i); |
||||
return ret("number", "number"); |
||||
} else if (/\d/.test(ch)) { |
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); |
||||
return ret("number", "number"); |
||||
} else if (ch == "/") { |
||||
if (stream.eat("*")) { |
||||
state.tokenize = tokenComment; |
||||
return tokenComment(stream, state); |
||||
} else if (stream.eat("/")) { |
||||
stream.skipToEnd(); |
||||
return ret("comment", "comment"); |
||||
} else if (state.lastType == "operator" || state.lastType == "keyword c" || |
||||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { |
||||
readRegexp(stream); |
||||
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); |
||||
return ret("regexp", "string-2"); |
||||
} else { |
||||
stream.eatWhile(isOperatorChar); |
||||
return ret("operator", "operator", stream.current()); |
||||
} |
||||
} else if (ch == "`") { |
||||
state.tokenize = tokenQuasi; |
||||
return tokenQuasi(stream, state); |
||||
} else if (ch == "#") { |
||||
stream.skipToEnd(); |
||||
return ret("error", "error"); |
||||
} else if (isOperatorChar.test(ch)) { |
||||
stream.eatWhile(isOperatorChar); |
||||
return ret("operator", "operator", stream.current()); |
||||
} else if (wordRE.test(ch)) { |
||||
stream.eatWhile(wordRE); |
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; |
||||
return (known && state.lastType != ".") ? ret(known.type, known.style, word) : |
||||
ret("variable", "variable", word); |
||||
} |
||||
} |
||||
|
||||
function tokenString(quote) { |
||||
return function(stream, state) { |
||||
var escaped = false, next; |
||||
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ |
||||
state.tokenize = tokenBase; |
||||
return ret("jsonld-keyword", "meta"); |
||||
} |
||||
while ((next = stream.next()) != null) { |
||||
if (next == quote && !escaped) break; |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
if (!escaped) state.tokenize = tokenBase; |
||||
return ret("string", "string"); |
||||
}; |
||||
} |
||||
|
||||
function tokenComment(stream, state) { |
||||
var maybeEnd = false, ch; |
||||
while (ch = stream.next()) { |
||||
if (ch == "/" && maybeEnd) { |
||||
state.tokenize = tokenBase; |
||||
break; |
||||
} |
||||
maybeEnd = (ch == "*"); |
||||
} |
||||
return ret("comment", "comment"); |
||||
} |
||||
|
||||
function tokenQuasi(stream, state) { |
||||
var escaped = false, next; |
||||
while ((next = stream.next()) != null) { |
||||
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { |
||||
state.tokenize = tokenBase; |
||||
break; |
||||
} |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
return ret("quasi", "string-2", stream.current()); |
||||
} |
||||
|
||||
var brackets = "([{}])"; |
||||
// This is a crude lookahead trick to try and notice that we're
|
||||
// parsing the argument patterns for a fat-arrow function before we
|
||||
// actually hit the arrow token. It only works if the arrow is on
|
||||
// the same line as the arguments and there's no strange noise
|
||||
// (comments) in between. Fallback is to only notice when we hit the
|
||||
// arrow, and not declare the arguments as locals for the arrow
|
||||
// body.
|
||||
function findFatArrow(stream, state) { |
||||
if (state.fatArrowAt) state.fatArrowAt = null; |
||||
var arrow = stream.string.indexOf("=>", stream.start); |
||||
if (arrow < 0) return; |
||||
|
||||
var depth = 0, sawSomething = false; |
||||
for (var pos = arrow - 1; pos >= 0; --pos) { |
||||
var ch = stream.string.charAt(pos); |
||||
var bracket = brackets.indexOf(ch); |
||||
if (bracket >= 0 && bracket < 3) { |
||||
if (!depth) { ++pos; break; } |
||||
if (--depth == 0) break; |
||||
} else if (bracket >= 3 && bracket < 6) { |
||||
++depth; |
||||
} else if (wordRE.test(ch)) { |
||||
sawSomething = true; |
||||
} else if (/["'\/]/.test(ch)) { |
||||
return; |
||||
} else if (sawSomething && !depth) { |
||||
++pos; |
||||
break; |
||||
} |
||||
} |
||||
if (sawSomething && !depth) state.fatArrowAt = pos; |
||||
} |
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; |
||||
|
||||
function JSLexical(indented, column, type, align, prev, info) { |
||||
this.indented = indented; |
||||
this.column = column; |
||||
this.type = type; |
||||
this.prev = prev; |
||||
this.info = info; |
||||
if (align != null) this.align = align; |
||||
} |
||||
|
||||
function inScope(state, varname) { |
||||
for (var v = state.localVars; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
for (var cx = state.context; cx; cx = cx.prev) { |
||||
for (var v = cx.vars; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
} |
||||
} |
||||
|
||||
function parseJS(state, style, type, content, stream) { |
||||
var cc = state.cc; |
||||
// Communicate our context to the combinators.
|
||||
// (Less wasteful than consing up a hundred closures on every call.)
|
||||
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; |
||||
|
||||
if (!state.lexical.hasOwnProperty("align")) |
||||
state.lexical.align = true; |
||||
|
||||
while(true) { |
||||
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; |
||||
if (combinator(type, content)) { |
||||
while(cc.length && cc[cc.length - 1].lex) |
||||
cc.pop()(); |
||||
if (cx.marked) return cx.marked; |
||||
if (type == "variable" && inScope(state, content)) return "variable-2"; |
||||
return style; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Combinator utils
|
||||
|
||||
var cx = {state: null, column: null, marked: null, cc: null}; |
||||
function pass() { |
||||
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); |
||||
} |
||||
function cont() { |
||||
pass.apply(null, arguments); |
||||
return true; |
||||
} |
||||
function register(varname) { |
||||
function inList(list) { |
||||
for (var v = list; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
return false; |
||||
} |
||||
var state = cx.state; |
||||
if (state.context) { |
||||
cx.marked = "def"; |
||||
if (inList(state.localVars)) return; |
||||
state.localVars = {name: varname, next: state.localVars}; |
||||
} else { |
||||
if (inList(state.globalVars)) return; |
||||
if (parserConfig.globalVars) |
||||
state.globalVars = {name: varname, next: state.globalVars}; |
||||
} |
||||
} |
||||
|
||||
// Combinators
|
||||
|
||||
var defaultVars = {name: "this", next: {name: "arguments"}}; |
||||
function pushcontext() { |
||||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; |
||||
cx.state.localVars = defaultVars; |
||||
} |
||||
function popcontext() { |
||||
cx.state.localVars = cx.state.context.vars; |
||||
cx.state.context = cx.state.context.prev; |
||||
} |
||||
function pushlex(type, info) { |
||||
var result = function() { |
||||
var state = cx.state, indent = state.indented; |
||||
if (state.lexical.type == "stat") indent = state.lexical.indented; |
||||
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) |
||||
indent = outer.indented; |
||||
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); |
||||
}; |
||||
result.lex = true; |
||||
return result; |
||||
} |
||||
function poplex() { |
||||
var state = cx.state; |
||||
if (state.lexical.prev) { |
||||
if (state.lexical.type == ")") |
||||
state.indented = state.lexical.indented; |
||||
state.lexical = state.lexical.prev; |
||||
} |
||||
} |
||||
poplex.lex = true; |
||||
|
||||
function expect(wanted) { |
||||
function exp(type) { |
||||
if (type == wanted) return cont(); |
||||
else if (wanted == ";") return pass(); |
||||
else return cont(exp); |
||||
}; |
||||
return exp; |
||||
} |
||||
|
||||
function statement(type, value) { |
||||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); |
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); |
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex); |
||||
if (type == "{") return cont(pushlex("}"), block, poplex); |
||||
if (type == ";") return cont(); |
||||
if (type == "if") { |
||||
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) |
||||
cx.state.cc.pop()(); |
||||
return cont(pushlex("form"), expression, statement, poplex, maybeelse); |
||||
} |
||||
if (type == "function") return cont(functiondef); |
||||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); |
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel); |
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), |
||||
block, poplex, poplex); |
||||
if (type == "case") return cont(expression, expect(":")); |
||||
if (type == "default") return cont(expect(":")); |
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), |
||||
statement, poplex, popcontext); |
||||
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); |
||||
if (type == "class") return cont(pushlex("form"), className, poplex); |
||||
if (type == "export") return cont(pushlex("form"), afterExport, poplex); |
||||
if (type == "import") return cont(pushlex("form"), afterImport, poplex); |
||||
return pass(pushlex("stat"), expression, expect(";"), poplex); |
||||
} |
||||
function expression(type) { |
||||
return expressionInner(type, false); |
||||
} |
||||
function expressionNoComma(type) { |
||||
return expressionInner(type, true); |
||||
} |
||||
function expressionInner(type, noComma) { |
||||
if (cx.state.fatArrowAt == cx.stream.start) { |
||||
var body = noComma ? arrowBodyNoComma : arrowBody; |
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); |
||||
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); |
||||
} |
||||
|
||||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; |
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); |
||||
if (type == "function") return cont(functiondef, maybeop); |
||||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); |
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); |
||||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); |
||||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); |
||||
if (type == "{") return contCommasep(objprop, "}", null, maybeop); |
||||
if (type == "quasi") { return pass(quasi, maybeop); } |
||||
return cont(); |
||||
} |
||||
function maybeexpression(type) { |
||||
if (type.match(/[;\}\)\],]/)) return pass(); |
||||
return pass(expression); |
||||
} |
||||
function maybeexpressionNoComma(type) { |
||||
if (type.match(/[;\}\)\],]/)) return pass(); |
||||
return pass(expressionNoComma); |
||||
} |
||||
|
||||
function maybeoperatorComma(type, value) { |
||||
if (type == ",") return cont(expression); |
||||
return maybeoperatorNoComma(type, value, false); |
||||
} |
||||
function maybeoperatorNoComma(type, value, noComma) { |
||||
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; |
||||
var expr = noComma == false ? expression : expressionNoComma; |
||||
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); |
||||
if (type == "operator") { |
||||
if (/\+\+|--/.test(value)) return cont(me); |
||||
if (value == "?") return cont(expression, expect(":"), expr); |
||||
return cont(expr); |
||||
} |
||||
if (type == "quasi") { return pass(quasi, me); } |
||||
if (type == ";") return; |
||||
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); |
||||
if (type == ".") return cont(property, me); |
||||
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); |
||||
} |
||||
function quasi(type, value) { |
||||
if (type != "quasi") return pass(); |
||||
if (value.slice(value.length - 2) != "${") return cont(quasi); |
||||
return cont(expression, continueQuasi); |
||||
} |
||||
function continueQuasi(type) { |
||||
if (type == "}") { |
||||
cx.marked = "string-2"; |
||||
cx.state.tokenize = tokenQuasi; |
||||
return cont(quasi); |
||||
} |
||||
} |
||||
function arrowBody(type) { |
||||
findFatArrow(cx.stream, cx.state); |
||||
return pass(type == "{" ? statement : expression); |
||||
} |
||||
function arrowBodyNoComma(type) { |
||||
findFatArrow(cx.stream, cx.state); |
||||
return pass(type == "{" ? statement : expressionNoComma); |
||||
} |
||||
function maybelabel(type) { |
||||
if (type == ":") return cont(poplex, statement); |
||||
return pass(maybeoperatorComma, expect(";"), poplex); |
||||
} |
||||
function property(type) { |
||||
if (type == "variable") {cx.marked = "property"; return cont();} |
||||
} |
||||
function objprop(type, value) { |
||||
if (type == "variable" || cx.style == "keyword") { |
||||
cx.marked = "property"; |
||||
if (value == "get" || value == "set") return cont(getterSetter); |
||||
return cont(afterprop); |
||||
} else if (type == "number" || type == "string") { |
||||
cx.marked = jsonldMode ? "property" : (cx.style + " property"); |
||||
return cont(afterprop); |
||||
} else if (type == "jsonld-keyword") { |
||||
return cont(afterprop); |
||||
} else if (type == "[") { |
||||
return cont(expression, expect("]"), afterprop); |
||||
} |
||||
} |
||||
function getterSetter(type) { |
||||
if (type != "variable") return pass(afterprop); |
||||
cx.marked = "property"; |
||||
return cont(functiondef); |
||||
} |
||||
function afterprop(type) { |
||||
if (type == ":") return cont(expressionNoComma); |
||||
if (type == "(") return pass(functiondef); |
||||
} |
||||
function commasep(what, end) { |
||||
function proceed(type) { |
||||
if (type == ",") { |
||||
var lex = cx.state.lexical; |
||||
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; |
||||
return cont(what, proceed); |
||||
} |
||||
if (type == end) return cont(); |
||||
return cont(expect(end)); |
||||
} |
||||
return function(type) { |
||||
if (type == end) return cont(); |
||||
return pass(what, proceed); |
||||
}; |
||||
} |
||||
function contCommasep(what, end, info) { |
||||
for (var i = 3; i < arguments.length; i++) |
||||
cx.cc.push(arguments[i]); |
||||
return cont(pushlex(end, info), commasep(what, end), poplex); |
||||
} |
||||
function block(type) { |
||||
if (type == "}") return cont(); |
||||
return pass(statement, block); |
||||
} |
||||
function maybetype(type) { |
||||
if (isTS && type == ":") return cont(typedef); |
||||
} |
||||
function maybedefault(_, value) { |
||||
if (value == "=") return cont(expressionNoComma); |
||||
} |
||||
function typedef(type) { |
||||
if (type == "variable") {cx.marked = "variable-3"; return cont();} |
||||
} |
||||
function vardef() { |
||||
return pass(pattern, maybetype, maybeAssign, vardefCont); |
||||
} |
||||
function pattern(type, value) { |
||||
if (type == "variable") { register(value); return cont(); } |
||||
if (type == "[") return contCommasep(pattern, "]"); |
||||
if (type == "{") return contCommasep(proppattern, "}"); |
||||
} |
||||
function proppattern(type, value) { |
||||
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { |
||||
register(value); |
||||
return cont(maybeAssign); |
||||
} |
||||
if (type == "variable") cx.marked = "property"; |
||||
return cont(expect(":"), pattern, maybeAssign); |
||||
} |
||||
function maybeAssign(_type, value) { |
||||
if (value == "=") return cont(expressionNoComma); |
||||
} |
||||
function vardefCont(type) { |
||||
if (type == ",") return cont(vardef); |
||||
} |
||||
function maybeelse(type, value) { |
||||
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); |
||||
} |
||||
function forspec(type) { |
||||
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); |
||||
} |
||||
function forspec1(type) { |
||||
if (type == "var") return cont(vardef, expect(";"), forspec2); |
||||
if (type == ";") return cont(forspec2); |
||||
if (type == "variable") return cont(formaybeinof); |
||||
return pass(expression, expect(";"), forspec2); |
||||
} |
||||
function formaybeinof(_type, value) { |
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } |
||||
return cont(maybeoperatorComma, forspec2); |
||||
} |
||||
function forspec2(type, value) { |
||||
if (type == ";") return cont(forspec3); |
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } |
||||
return pass(expression, expect(";"), forspec3); |
||||
} |
||||
function forspec3(type) { |
||||
if (type != ")") cont(expression); |
||||
} |
||||
function functiondef(type, value) { |
||||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} |
||||
if (type == "variable") {register(value); return cont(functiondef);} |
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); |
||||
} |
||||
function funarg(type) { |
||||
if (type == "spread") return cont(funarg); |
||||
return pass(pattern, maybetype, maybedefault); |
||||
} |
||||
function className(type, value) { |
||||
if (type == "variable") {register(value); return cont(classNameAfter);} |
||||
} |
||||
function classNameAfter(type, value) { |
||||
if (value == "extends") return cont(expression, classNameAfter); |
||||
if (type == "{") return cont(pushlex("}"), classBody, poplex); |
||||
} |
||||
function classBody(type, value) { |
||||
if (type == "variable" || cx.style == "keyword") { |
||||
if (value == "static") { |
||||
cx.marked = "keyword"; |
||||
return cont(classBody); |
||||
} |
||||
cx.marked = "property"; |
||||
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); |
||||
return cont(functiondef, classBody); |
||||
} |
||||
if (value == "*") { |
||||
cx.marked = "keyword"; |
||||
return cont(classBody); |
||||
} |
||||
if (type == ";") return cont(classBody); |
||||
if (type == "}") return cont(); |
||||
} |
||||
function classGetterSetter(type) { |
||||
if (type != "variable") return pass(); |
||||
cx.marked = "property"; |
||||
return cont(); |
||||
} |
||||
function afterModule(type, value) { |
||||
if (type == "string") return cont(statement); |
||||
if (type == "variable") { register(value); return cont(maybeFrom); } |
||||
} |
||||
function afterExport(_type, value) { |
||||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } |
||||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } |
||||
return pass(statement); |
||||
} |
||||
function afterImport(type) { |
||||
if (type == "string") return cont(); |
||||
return pass(importSpec, maybeFrom); |
||||
} |
||||
function importSpec(type, value) { |
||||
if (type == "{") return contCommasep(importSpec, "}"); |
||||
if (type == "variable") register(value); |
||||
if (value == "*") cx.marked = "keyword"; |
||||
return cont(maybeAs); |
||||
} |
||||
function maybeAs(_type, value) { |
||||
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } |
||||
} |
||||
function maybeFrom(_type, value) { |
||||
if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
||||
} |
||||
function arrayLiteral(type) { |
||||
if (type == "]") return cont(); |
||||
return pass(expressionNoComma, maybeArrayComprehension); |
||||
} |
||||
function maybeArrayComprehension(type) { |
||||
if (type == "for") return pass(comprehension, expect("]")); |
||||
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); |
||||
return pass(commasep(expressionNoComma, "]")); |
||||
} |
||||
function comprehension(type) { |
||||
if (type == "for") return cont(forspec, comprehension); |
||||
if (type == "if") return cont(expression, comprehension); |
||||
} |
||||
|
||||
function isContinuedStatement(state, textAfter) { |
||||
return state.lastType == "operator" || state.lastType == "," || |
||||
isOperatorChar.test(textAfter.charAt(0)) || |
||||
/[,.]/.test(textAfter.charAt(0)); |
||||
} |
||||
|
||||
// Interface
|
||||
|
||||
return { |
||||
startState: function(basecolumn) { |
||||
var state = { |
||||
tokenize: tokenBase, |
||||
lastType: "sof", |
||||
cc: [], |
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), |
||||
localVars: parserConfig.localVars, |
||||
context: parserConfig.localVars && {vars: parserConfig.localVars}, |
||||
indented: 0 |
||||
}; |
||||
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") |
||||
state.globalVars = parserConfig.globalVars; |
||||
return state; |
||||
}, |
||||
|
||||
token: function(stream, state) { |
||||
if (stream.sol()) { |
||||
if (!state.lexical.hasOwnProperty("align")) |
||||
state.lexical.align = false; |
||||
state.indented = stream.indentation(); |
||||
findFatArrow(stream, state); |
||||
} |
||||
if (state.tokenize != tokenComment && stream.eatSpace()) return null; |
||||
var style = state.tokenize(stream, state); |
||||
if (type == "comment") return style; |
||||
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; |
||||
return parseJS(state, style, type, content, stream); |
||||
}, |
||||
|
||||
indent: function(state, textAfter) { |
||||
if (state.tokenize == tokenComment) return CodeMirror.Pass; |
||||
if (state.tokenize != tokenBase) return 0; |
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; |
||||
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
||||
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { |
||||
var c = state.cc[i]; |
||||
if (c == poplex) lexical = lexical.prev; |
||||
else if (c != maybeelse) break; |
||||
} |
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; |
||||
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") |
||||
lexical = lexical.prev; |
||||
var type = lexical.type, closing = firstChar == type; |
||||
|
||||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); |
||||
else if (type == "form" && firstChar == "{") return lexical.indented; |
||||
else if (type == "form") return lexical.indented + indentUnit; |
||||
else if (type == "stat") |
||||
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); |
||||
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) |
||||
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); |
||||
else if (lexical.align) return lexical.column + (closing ? 0 : 1); |
||||
else return lexical.indented + (closing ? 0 : indentUnit); |
||||
}, |
||||
|
||||
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, |
||||
blockCommentStart: jsonMode ? null : "/*", |
||||
blockCommentEnd: jsonMode ? null : "*/", |
||||
lineComment: jsonMode ? null : "//", |
||||
fold: "brace", |
||||
closeBrackets: "()[]{}''\"\"``", |
||||
|
||||
helperType: jsonMode ? "json" : "javascript", |
||||
jsonldMode: jsonldMode, |
||||
jsonMode: jsonMode |
||||
}; |
||||
}); |
||||
|
||||
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); |
||||
|
||||
CodeMirror.defineMIME("text/javascript", "javascript"); |
||||
CodeMirror.defineMIME("text/ecmascript", "javascript"); |
||||
CodeMirror.defineMIME("application/javascript", "javascript"); |
||||
CodeMirror.defineMIME("application/x-javascript", "javascript"); |
||||
CodeMirror.defineMIME("application/ecmascript", "javascript"); |
||||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); |
||||
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); |
||||
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); |
||||
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); |
||||
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); |
||||
|
||||
}); |
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) { |
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror")); |
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod); |
||||
else // Plain browser env
|
||||
mod(CodeMirror); |
||||
})(function(CodeMirror) { |
||||
"use strict"; |
||||
|
||||
CodeMirror.runMode = function(string, modespec, callback, options) { |
||||
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); |
||||
var ie = /MSIE \d/.test(navigator.userAgent); |
||||
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); |
||||
|
||||
if (callback.nodeType == 1) { |
||||
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; |
||||
var node = callback, col = 0; |
||||
node.innerHTML = ""; |
||||
callback = function(text, style) { |
||||
if (text == "\n") { |
||||
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
|
||||
// Emitting a carriage return makes everything ok.
|
||||
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); |
||||
col = 0; |
||||
return; |
||||
} |
||||
var content = ""; |
||||
// replace tabs
|
||||
for (var pos = 0;;) { |
||||
var idx = text.indexOf("\t", pos); |
||||
if (idx == -1) { |
||||
content += text.slice(pos); |
||||
col += text.length - pos; |
||||
break; |
||||
} else { |
||||
col += idx - pos; |
||||
content += text.slice(pos, idx); |
||||
var size = tabSize - col % tabSize; |
||||
col += size; |
||||
for (var i = 0; i < size; ++i) content += " "; |
||||
pos = idx + 1; |
||||
} |
||||
} |
||||
|
||||
if (style) { |
||||
var sp = node.appendChild(document.createElement("span")); |
||||
sp.className = "cm-" + style.replace(/ +/g, " cm-"); |
||||
sp.appendChild(document.createTextNode(content)); |
||||
} else { |
||||
node.appendChild(document.createTextNode(content)); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); |
||||
for (var i = 0, e = lines.length; i < e; ++i) { |
||||
if (i) callback("\n"); |
||||
var stream = new CodeMirror.StringStream(lines[i]); |
||||
if (!stream.string && mode.blankLine) mode.blankLine(state); |
||||
while (!stream.eol()) { |
||||
var style = mode.token(stream, state); |
||||
callback(stream.current(), style, i, stream.start, state); |
||||
stream.start = stream.pos; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
}); |
@ -0,0 +1,384 @@
@@ -0,0 +1,384 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) { |
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror")); |
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod); |
||||
else // Plain browser env
|
||||
mod(CodeMirror); |
||||
})(function(CodeMirror) { |
||||
"use strict"; |
||||
|
||||
CodeMirror.defineMode("xml", function(config, parserConfig) { |
||||
var indentUnit = config.indentUnit; |
||||
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; |
||||
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag; |
||||
if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true; |
||||
|
||||
var Kludges = parserConfig.htmlMode ? { |
||||
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, |
||||
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, |
||||
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, |
||||
'track': true, 'wbr': true, 'menuitem': true}, |
||||
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, |
||||
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, |
||||
'th': true, 'tr': true}, |
||||
contextGrabbers: { |
||||
'dd': {'dd': true, 'dt': true}, |
||||
'dt': {'dd': true, 'dt': true}, |
||||
'li': {'li': true}, |
||||
'option': {'option': true, 'optgroup': true}, |
||||
'optgroup': {'optgroup': true}, |
||||
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, |
||||
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, |
||||
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, |
||||
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, |
||||
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, |
||||
'rp': {'rp': true, 'rt': true}, |
||||
'rt': {'rp': true, 'rt': true}, |
||||
'tbody': {'tbody': true, 'tfoot': true}, |
||||
'td': {'td': true, 'th': true}, |
||||
'tfoot': {'tbody': true}, |
||||
'th': {'td': true, 'th': true}, |
||||
'thead': {'tbody': true, 'tfoot': true}, |
||||
'tr': {'tr': true} |
||||
}, |
||||
doNotIndent: {"pre": true}, |
||||
allowUnquoted: true, |
||||
allowMissing: true, |
||||
caseFold: true |
||||
} : { |
||||
autoSelfClosers: {}, |
||||
implicitlyClosed: {}, |
||||
contextGrabbers: {}, |
||||
doNotIndent: {}, |
||||
allowUnquoted: false, |
||||
allowMissing: false, |
||||
caseFold: false |
||||
}; |
||||
var alignCDATA = parserConfig.alignCDATA; |
||||
|
||||
// Return variables for tokenizers
|
||||
var type, setStyle; |
||||
|
||||
function inText(stream, state) { |
||||
function chain(parser) { |
||||
state.tokenize = parser; |
||||
return parser(stream, state); |
||||
} |
||||
|
||||
var ch = stream.next(); |
||||
if (ch == "<") { |
||||
if (stream.eat("!")) { |
||||
if (stream.eat("[")) { |
||||
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); |
||||
else return null; |
||||
} else if (stream.match("--")) { |
||||
return chain(inBlock("comment", "-->")); |
||||
} else if (stream.match("DOCTYPE", true, true)) { |
||||
stream.eatWhile(/[\w\._\-]/); |
||||
return chain(doctype(1)); |
||||
} else { |
||||
return null; |
||||
} |
||||
} else if (stream.eat("?")) { |
||||
stream.eatWhile(/[\w\._\-]/); |
||||
state.tokenize = inBlock("meta", "?>"); |
||||
return "meta"; |
||||
} else { |
||||
type = stream.eat("/") ? "closeTag" : "openTag"; |
||||
state.tokenize = inTag; |
||||
return "tag bracket"; |
||||
} |
||||
} else if (ch == "&") { |
||||
var ok; |
||||
if (stream.eat("#")) { |
||||
if (stream.eat("x")) { |
||||
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); |
||||
} else { |
||||
ok = stream.eatWhile(/[\d]/) && stream.eat(";"); |
||||
} |
||||
} else { |
||||
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); |
||||
} |
||||
return ok ? "atom" : "error"; |
||||
} else { |
||||
stream.eatWhile(/[^&<]/); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
function inTag(stream, state) { |
||||
var ch = stream.next(); |
||||
if (ch == ">" || (ch == "/" && stream.eat(">"))) { |
||||
state.tokenize = inText; |
||||
type = ch == ">" ? "endTag" : "selfcloseTag"; |
||||
return "tag bracket"; |
||||
} else if (ch == "=") { |
||||
type = "equals"; |
||||
return null; |
||||
} else if (ch == "<") { |
||||
state.tokenize = inText; |
||||
state.state = baseState; |
||||
state.tagName = state.tagStart = null; |
||||
var next = state.tokenize(stream, state); |
||||
return next ? next + " tag error" : "tag error"; |
||||
} else if (/[\'\"]/.test(ch)) { |
||||
state.tokenize = inAttribute(ch); |
||||
state.stringStartCol = stream.column(); |
||||
return state.tokenize(stream, state); |
||||
} else { |
||||
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); |
||||
return "word"; |
||||
} |
||||
} |
||||
|
||||
function inAttribute(quote) { |
||||
var closure = function(stream, state) { |
||||
while (!stream.eol()) { |
||||
if (stream.next() == quote) { |
||||
state.tokenize = inTag; |
||||
break; |
||||
} |
||||
} |
||||
return "string"; |
||||
}; |
||||
closure.isInAttribute = true; |
||||
return closure; |
||||
} |
||||
|
||||
function inBlock(style, terminator) { |
||||
return function(stream, state) { |
||||
while (!stream.eol()) { |
||||
if (stream.match(terminator)) { |
||||
state.tokenize = inText; |
||||
break; |
||||
} |
||||
stream.next(); |
||||
} |
||||
return style; |
||||
}; |
||||
} |
||||
function doctype(depth) { |
||||
return function(stream, state) { |
||||
var ch; |
||||
while ((ch = stream.next()) != null) { |
||||
if (ch == "<") { |
||||
state.tokenize = doctype(depth + 1); |
||||
return state.tokenize(stream, state); |
||||
} else if (ch == ">") { |
||||
if (depth == 1) { |
||||
state.tokenize = inText; |
||||
break; |
||||
} else { |
||||
state.tokenize = doctype(depth - 1); |
||||
return state.tokenize(stream, state); |
||||
} |
||||
} |
||||
} |
||||
return "meta"; |
||||
}; |
||||
} |
||||
|
||||
function Context(state, tagName, startOfLine) { |
||||
this.prev = state.context; |
||||
this.tagName = tagName; |
||||
this.indent = state.indented; |
||||
this.startOfLine = startOfLine; |
||||
if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) |
||||
this.noIndent = true; |
||||
} |
||||
function popContext(state) { |
||||
if (state.context) state.context = state.context.prev; |
||||
} |
||||
function maybePopContext(state, nextTagName) { |
||||
var parentTagName; |
||||
while (true) { |
||||
if (!state.context) { |
||||
return; |
||||
} |
||||
parentTagName = state.context.tagName; |
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || |
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { |
||||
return; |
||||
} |
||||
popContext(state); |
||||
} |
||||
} |
||||
|
||||
function baseState(type, stream, state) { |
||||
if (type == "openTag") { |
||||
state.tagStart = stream.column(); |
||||
return tagNameState; |
||||
} else if (type == "closeTag") { |
||||
return closeTagNameState; |
||||
} else { |
||||
return baseState; |
||||
} |
||||
} |
||||
function tagNameState(type, stream, state) { |
||||
if (type == "word") { |
||||
state.tagName = stream.current(); |
||||
setStyle = "tag"; |
||||
return attrState; |
||||
} else { |
||||
setStyle = "error"; |
||||
return tagNameState; |
||||
} |
||||
} |
||||
function closeTagNameState(type, stream, state) { |
||||
if (type == "word") { |
||||
var tagName = stream.current(); |
||||
if (state.context && state.context.tagName != tagName && |
||||
Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) |
||||
popContext(state); |
||||
if (state.context && state.context.tagName == tagName) { |
||||
setStyle = "tag"; |
||||
return closeState; |
||||
} else { |
||||
setStyle = "tag error"; |
||||
return closeStateErr; |
||||
} |
||||
} else { |
||||
setStyle = "error"; |
||||
return closeStateErr; |
||||
} |
||||
} |
||||
|
||||
function closeState(type, _stream, state) { |
||||
if (type != "endTag") { |
||||
setStyle = "error"; |
||||
return closeState; |
||||
} |
||||
popContext(state); |
||||
return baseState; |
||||
} |
||||
function closeStateErr(type, stream, state) { |
||||
setStyle = "error"; |
||||
return closeState(type, stream, state); |
||||
} |
||||
|
||||
function attrState(type, _stream, state) { |
||||
if (type == "word") { |
||||
setStyle = "attribute"; |
||||
return attrEqState; |
||||
} else if (type == "endTag" || type == "selfcloseTag") { |
||||
var tagName = state.tagName, tagStart = state.tagStart; |
||||
state.tagName = state.tagStart = null; |
||||
if (type == "selfcloseTag" || |
||||
Kludges.autoSelfClosers.hasOwnProperty(tagName)) { |
||||
maybePopContext(state, tagName); |
||||
} else { |
||||
maybePopContext(state, tagName); |
||||
state.context = new Context(state, tagName, tagStart == state.indented); |
||||
} |
||||
return baseState; |
||||
} |
||||
setStyle = "error"; |
||||
return attrState; |
||||
} |
||||
function attrEqState(type, stream, state) { |
||||
if (type == "equals") return attrValueState; |
||||
if (!Kludges.allowMissing) setStyle = "error"; |
||||
return attrState(type, stream, state); |
||||
} |
||||
function attrValueState(type, stream, state) { |
||||
if (type == "string") return attrContinuedState; |
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;} |
||||
setStyle = "error"; |
||||
return attrState(type, stream, state); |
||||
} |
||||
function attrContinuedState(type, stream, state) { |
||||
if (type == "string") return attrContinuedState; |
||||
return attrState(type, stream, state); |
||||
} |
||||
|
||||
return { |
||||
startState: function() { |
||||
return {tokenize: inText, |
||||
state: baseState, |
||||
indented: 0, |
||||
tagName: null, tagStart: null, |
||||
context: null}; |
||||
}, |
||||
|
||||
token: function(stream, state) { |
||||
if (!state.tagName && stream.sol()) |
||||
state.indented = stream.indentation(); |
||||
|
||||
if (stream.eatSpace()) return null; |
||||
type = null; |
||||
var style = state.tokenize(stream, state); |
||||
if ((style || type) && style != "comment") { |
||||
setStyle = null; |
||||
state.state = state.state(type || style, stream, state); |
||||
if (setStyle) |
||||
style = setStyle == "error" ? style + " error" : setStyle; |
||||
} |
||||
return style; |
||||
}, |
||||
|
||||
indent: function(state, textAfter, fullLine) { |
||||
var context = state.context; |
||||
// Indent multi-line strings (e.g. css).
|
||||
if (state.tokenize.isInAttribute) { |
||||
if (state.tagStart == state.indented) |
||||
return state.stringStartCol + 1; |
||||
else |
||||
return state.indented + indentUnit; |
||||
} |
||||
if (context && context.noIndent) return CodeMirror.Pass; |
||||
if (state.tokenize != inTag && state.tokenize != inText) |
||||
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; |
||||
// Indent the starts of attribute names.
|
||||
if (state.tagName) { |
||||
if (multilineTagIndentPastTag) |
||||
return state.tagStart + state.tagName.length + 2; |
||||
else |
||||
return state.tagStart + indentUnit * multilineTagIndentFactor; |
||||
} |
||||
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; |
||||
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter); |
||||
if (tagAfter && tagAfter[1]) { // Closing tag spotted
|
||||
while (context) { |
||||
if (context.tagName == tagAfter[2]) { |
||||
context = context.prev; |
||||
break; |
||||
} else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) { |
||||
context = context.prev; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
} else if (tagAfter) { // Opening tag spotted
|
||||
while (context) { |
||||
var grabbers = Kludges.contextGrabbers[context.tagName]; |
||||
if (grabbers && grabbers.hasOwnProperty(tagAfter[2])) |
||||
context = context.prev; |
||||
else |
||||
break; |
||||
} |
||||
} |
||||
while (context && !context.startOfLine) |
||||
context = context.prev; |
||||
if (context) return context.indent + indentUnit; |
||||
else return 0; |
||||
}, |
||||
|
||||
electricInput: /<\/[\s\w:]+>$/, |
||||
blockCommentStart: "<!--", |
||||
blockCommentEnd: "-->", |
||||
|
||||
configuration: parserConfig.htmlMode ? "html" : "xml", |
||||
helperType: parserConfig.htmlMode ? "html" : "xml" |
||||
}; |
||||
}); |
||||
|
||||
CodeMirror.defineMIME("text/xml", "xml"); |
||||
CodeMirror.defineMIME("application/xml", "xml"); |
||||
if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) |
||||
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); |
||||
|
||||
}); |
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
#explorer { |
||||
max-height: 500px; |
||||
white-space: nowrap; |
||||
overflow: scroll; |
||||
padding: 10px; |
||||
/*border: 1px solid #eee;*/ |
||||
border-radius: 5px; |
||||
font-family: monospace; |
||||
background-color: #fff; |
||||
} |
||||
|
||||
|
||||
.textNode { |
||||
display: inline-block; |
||||
max-width: 400px; |
||||
vertical-align: middle; |
||||
white-space: pre; |
||||
overflow: scroll; |
||||
margin-bottom: 1px; |
||||
margin-top: 1px; |
||||
} |
||||
|
||||
.textNode { |
||||
background-color: rgb(255, 238, 174); |
||||
color: rgb(48, 48, 97); |
||||
padding: 2px; |
||||
border-radius: 3px; |
||||
} |
||||
|
||||
.html { |
||||
background-color: #F5F5F5; |
||||
} |
||||
|
||||
.comma, .ellipsis { |
||||
color: grey; |
||||
} |
||||
|
||||
.nullNode { |
||||
color: grey; |
||||
} |
||||
|
||||
.numberNode { |
||||
color: rgb(203, 48, 48); |
||||
} |
||||
|
||||
.booleanNode { |
||||
color: rgb(174, 44, 164); |
||||
} |
||||
|
||||
.label { |
||||
color: rgb(76, 162, 242); |
||||
} |
||||
|
||||
.clickable { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.indent { |
||||
padding-left: 30px; |
||||
display: inline-block; |
||||
} |
||||
|
||||
|
||||
/*.collapsed, .expanded { |
||||
position: relative; |
||||
} |
||||
*/ |
||||
/*.collapsed::before { |
||||
content: "▶"; |
||||
position: absolute; |
||||
left: -16px; |
||||
} |
||||
|
||||
.expanded::before { |
||||
content: "▼"; |
||||
position: absolute; |
||||
left: -16px; |
||||
} |
||||
|
||||
.swiper{ |
||||
padding-left: 40px; |
||||
margin-top: 8px; |
||||
} |
||||
*/ |
@ -0,0 +1,313 @@
@@ -0,0 +1,313 @@
|
||||
body, html{ |
||||
position: absolute; |
||||
top: 0; |
||||
margin: 0; |
||||
width: 100%; |
||||
font-family: Lato; |
||||
font-weight: 300; |
||||
} |
||||
|
||||
#slogan { |
||||
text-align: center; |
||||
margin-top: -26px; |
||||
color: #fff; |
||||
} |
||||
|
||||
#splash { |
||||
overflow: hidden; |
||||
background-color: #425565; |
||||
background: url(../img/bg.jpg); |
||||
background-size: cover; |
||||
background-position: center; |
||||
} |
||||
|
||||
#logo-wrap { |
||||
margin-top: 50px; |
||||
text-align: center; |
||||
position: relative; |
||||
} |
||||
|
||||
#demo-instructions { |
||||
display: none; |
||||
} |
||||
|
||||
#logo-canvas { |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
pointer-events: none; |
||||
z-index: 0; |
||||
position: absolute; |
||||
} |
||||
|
||||
#logo-img { |
||||
max-width: 100%; |
||||
} |
||||
|
||||
.get-started-wrap { |
||||
text-align: center; |
||||
position: relative; |
||||
padding: 0 20px; |
||||
} |
||||
|
||||
.get-started { |
||||
display: inline-block; |
||||
color: #714d26; |
||||
background: #fff; |
||||
padding: 17px 25px; |
||||
font-size: 30px; |
||||
margin: 50px 0; |
||||
border-radius: 7px; |
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); |
||||
} |
||||
|
||||
#demo-title { |
||||
padding: 40px 0; |
||||
color: #714d26; |
||||
font-size: 30px; |
||||
// text-align: center; |
||||
} |
||||
|
||||
|
||||
#options { |
||||
display: flex; |
||||
justify-content: space-around; |
||||
font-size: 20px; |
||||
color: #3580c0; |
||||
padding: 0 15px; |
||||
max-width: 700px; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.option { |
||||
padding: 10px; |
||||
border-radius: 5px; |
||||
cursor: pointer; |
||||
text-align: center; |
||||
} |
||||
|
||||
.option.selected { |
||||
color: #3580c0; |
||||
background: #d8edff; |
||||
font-weight: 400; |
||||
} |
||||
|
||||
#input { |
||||
max-width: 100%; |
||||
box-sizing: border-box; |
||||
padding: 20px; |
||||
margin-top: 30px; |
||||
border: 1px solid #ddd; |
||||
} |
||||
|
||||
#input-overlay { |
||||
position: absolute; |
||||
max-width: 100%; |
||||
box-sizing: border-box; |
||||
margin-top: 30px; |
||||
padding: 20px; |
||||
} |
||||
|
||||
#github { |
||||
height: 1em; |
||||
width: 1em; |
||||
margin-bottom: -3px; |
||||
margin-right: 10px; |
||||
} |
||||
|
||||
#github path { |
||||
fill: #826f5c; |
||||
} |
||||
|
||||
#demo-content > #arrow { |
||||
text-align: center; |
||||
font-size: 30px; |
||||
color: #826f5c; |
||||
flex: 0; |
||||
} |
||||
|
||||
#arrow::before { |
||||
content: '\2193' |
||||
} |
||||
|
||||
#output { |
||||
max-width: 100%; |
||||
box-sizing: border-box; |
||||
padding: 20px; |
||||
} |
||||
|
||||
#output-overlay { |
||||
white-space: pre; |
||||
font-family: Monaco, monospace; |
||||
position: absolute; |
||||
height: 100%; |
||||
width: 100%; |
||||
overflow: scroll; |
||||
border: 20px solid transparent; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
#clickme { |
||||
color: #2374b7; |
||||
text-decoration: underline; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
#footer { |
||||
color: #826f5c; |
||||
background-color: #f6f6f6; |
||||
text-align: right; |
||||
padding: 0 20px; |
||||
} |
||||
|
||||
#lengle { |
||||
margin-top: 8%; |
||||
margin-bottom: 8%; |
||||
|
||||
line-height: normal; |
||||
display: inline-block; |
||||
vertical-align: middle; |
||||
} |
||||
|
||||
#lengle img { |
||||
height: .7em; |
||||
} |
||||
|
||||
#demo-content > div { |
||||
position: relative; |
||||
flex: 1; |
||||
border: 20px solid transparent; |
||||
} |
||||
|
||||
#drop-instructions-main { |
||||
display: none; |
||||
} |
||||
|
||||
.commentary { |
||||
position: relative; |
||||
padding: 20px; |
||||
max-width: 700px; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
line-height: 180%; |
||||
letter-spacing: .5 px; |
||||
} |
||||
|
||||
#output-text { |
||||
margin: 0px; |
||||
width: 100%; |
||||
min-height: 200px; |
||||
box-sizing: border-box; |
||||
padding: 20px; |
||||
border: 1px solid #ddd; |
||||
} |
||||
|
||||
#demo-instructions { |
||||
border: 1px solid #dadada; |
||||
padding: 20px; |
||||
} |
||||
|
||||
#log > div { |
||||
color: #313131; |
||||
border-top: 1px solid #dadada; |
||||
padding: 10px 0; |
||||
display: flex; |
||||
} |
||||
#log > div:first-child { |
||||
border: 0; |
||||
} |
||||
|
||||
|
||||
#log .status { |
||||
min-width: 250px; |
||||
} |
||||
#log { |
||||
border: 1px solid #dadada; |
||||
padding: 20px; |
||||
overflow: auto; |
||||
} |
||||
|
||||
#log progress { |
||||
display: block; |
||||
width: 100%; |
||||
transition: opacity 0.5s linear; |
||||
} |
||||
#log progress[value="1"] { |
||||
opacity: 0.5; |
||||
} |
||||
|
||||
|
||||
#footer { |
||||
color: #ffffff; |
||||
background-color: #f6f6f6; |
||||
text-align: right; |
||||
padding: 0 20px; |
||||
background-color: #425565; |
||||
background: url(../img/bg.jpg); |
||||
background-size: cover; |
||||
background-position: bottom; |
||||
} |
||||
|
||||
#footer a { |
||||
color: white !important; |
||||
|
||||
} |
||||
|
||||
@media (min-width: 900px) { |
||||
|
||||
#drop-instructions-main { |
||||
display: block; |
||||
text-align: center; |
||||
color: #b1a79c; |
||||
} |
||||
|
||||
#demo-content { |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
|
||||
#input, #input-overlay { |
||||
margin-top: 0; |
||||
} |
||||
|
||||
#arrow::before { |
||||
content: '\2192'; |
||||
} |
||||
|
||||
#options { |
||||
margin: 40px auto; |
||||
} |
||||
|
||||
// #demo-title { |
||||
// width: 250px; |
||||
// background: #fff; |
||||
// margin-top: -70px; |
||||
// margin-left: 40px; |
||||
// position: relative; |
||||
// padding: 20px 0; |
||||
// } |
||||
|
||||
// #demo-title::after { |
||||
// border-right: 40px solid transparent; |
||||
// border-bottom: 70px solid white; |
||||
// content: ' '; |
||||
// position: absolute; |
||||
// top: 0; |
||||
// left: 100%; |
||||
// } |
||||
|
||||
// #demo-title::before { |
||||
// border-left: 40px solid transparent; |
||||
// border-bottom: 70px solid white; |
||||
// content: ' '; |
||||
// position: absolute; |
||||
// top: 0; |
||||
// left: -40px; |
||||
// } |
||||
|
||||
// body { |
||||
// box-sizing: border-box; |
||||
// border: 20px solid #425565; |
||||
// } |
||||
} |
@ -0,0 +1,435 @@
@@ -0,0 +1,435 @@
|
||||
@import 'explorer.css'; |
||||
.fullscreen { |
||||
width: 100%; |
||||
min-height: 100%; |
||||
} |
||||
|
||||
.stretch { |
||||
max-width: 100% |
||||
} |
||||
|
||||
.langpair { |
||||
display: inline-block; |
||||
padding: -1px; |
||||
font-family: monospace; |
||||
text-align: center; |
||||
/*border: 1px solid #F3F3F3;*/ |
||||
margin-bottom: 10px; |
||||
margin-right: 5px; |
||||
font-size: initial; |
||||
line-height: 1.5em; |
||||
flex-grow:1; |
||||
-webkit-flex-grow:1; |
||||
} |
||||
|
||||
.footer { |
||||
width: 100%; |
||||
color: #fff; |
||||
background-color: #6A6A6A; |
||||
text-align: right; |
||||
} |
||||
|
||||
.lengle { |
||||
margin-top: 8%; |
||||
margin-bottom: 8%; |
||||
|
||||
line-height: normal; |
||||
display: inline-block; |
||||
vertical-align: middle; |
||||
} |
||||
|
||||
.lengle img { |
||||
height: .7em; |
||||
} |
||||
|
||||
.shortlang { |
||||
/*background-color: #FFEEAE;*/ |
||||
} |
||||
|
||||
.longlang { |
||||
background-color: #59C6FF; |
||||
color:#fff; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
border-radius: 3px; |
||||
} |
||||
.explorersection{ |
||||
background-color: rgba(102, 142, 195, 0.19); |
||||
width: 100%; |
||||
padding-top: 8%; |
||||
padding-bottom: 8%; |
||||
} |
||||
.noheight{ |
||||
height: 0; |
||||
} |
||||
.columnwrap { |
||||
max-width: 1100; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
} |
||||
.column { |
||||
padding-left: 8%; |
||||
padding-right: 8%; |
||||
} |
||||
.smalllogo { |
||||
height: 50px; |
||||
vertical-align: middle; |
||||
position: absolute; |
||||
left: 3%; |
||||
opacity: 0; |
||||
} |
||||
.stickyheader { |
||||
position: absolute; |
||||
width: 100%; |
||||
z-index: 3; |
||||
text-align: right; |
||||
line-height: 50px; |
||||
} |
||||
.headernav { |
||||
padding-right: 3%; |
||||
color: #fff; |
||||
} |
||||
.run, |
||||
.running { |
||||
width: 100%; |
||||
height: 47px; |
||||
text-align: center; |
||||
position: relative; |
||||
} |
||||
.running { |
||||
display: none |
||||
} |
||||
#wow .notrunning { |
||||
display: none |
||||
} |
||||
#wow .running { |
||||
display: block |
||||
} |
||||
.runbutton { |
||||
padding-top: 9px; |
||||
padding-bottom: 10px; |
||||
font-weight: 500; |
||||
text-align: center; |
||||
color: #FFFFFF; |
||||
cursor: pointer; |
||||
-webkit-transition: all 0.7s ease; |
||||
transition: all 0.7s ease; |
||||
width: 100px; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
background-color: #6A6A6A; |
||||
border-radius: 5px; |
||||
margin-bottom: 9px; |
||||
} |
||||
.runbutton:hover { |
||||
text-shadow: 0px 0px 10px #27C6F9; |
||||
} |
||||
a { |
||||
text-decoration: none; |
||||
color: #5BA9F2; |
||||
/*font-weight: bold;*/ |
||||
} |
||||
.display { |
||||
// position: absolute; |
||||
/*background: rgba(0,0,255,.1);*/ |
||||
} |
||||
svg { |
||||
height: 100% |
||||
} |
||||
.marterial { |
||||
/*position: absolute;*/ |
||||
width: 100%; |
||||
z-index: -1; |
||||
overflow: hidden; |
||||
background-color: #668EC3; |
||||
/*background-image: url(../img/stars.jpeg);*/ |
||||
background-size: cover; |
||||
background-position: bottom; |
||||
} |
||||
.out { |
||||
padding: 10px; |
||||
padding-bottom: 0px; |
||||
text-align: center; |
||||
font-family: monospace; |
||||
} |
||||
.hint { |
||||
text-align: left; |
||||
padding-left: 14px; |
||||
font-size: 10px; |
||||
color: #56607D; |
||||
} |
||||
.langlabel { |
||||
display: inline-block; |
||||
flex-grow: 1; |
||||
-webkit-flex-grow: 1; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
|
||||
cursor: pointer; |
||||
color: #fff; |
||||
background-color: #6A6A6A; |
||||
} |
||||
|
||||
.selected { |
||||
background-color: #668EC3; |
||||
} |
||||
|
||||
.bookend { |
||||
display: inline-block; |
||||
} |
||||
.prog { |
||||
height: 4px; |
||||
width: 100%; |
||||
position: absolute; |
||||
bottom:0; |
||||
background-color: #6a6a6a; |
||||
} |
||||
.prog div{ |
||||
height: 100%; |
||||
background-color: #5BA9F2; |
||||
} |
||||
|
||||
.demofooter { |
||||
padding: 10px; |
||||
/*padding-top: 0px;*/ |
||||
|
||||
text-align: center; |
||||
/*display: flex*/ |
||||
} |
||||
|
||||
#wow .demofooter { |
||||
display: flex; |
||||
display: -webkit-flex; |
||||
padding: 0px; |
||||
justify-content: space-between; |
||||
-webkit-justify-content: space-between; |
||||
align-items: center; |
||||
-webkit-align-items: center; |
||||
} |
||||
#logo { |
||||
text-align: center; |
||||
margin-top: 6%; |
||||
margin-bottom: 6%; |
||||
height: 182px; |
||||
position: relative; |
||||
/*z-index: 4;*/ |
||||
} |
||||
.to_ocr { |
||||
width: 100%; |
||||
} |
||||
|
||||
.demo { |
||||
border-radius: 5px; |
||||
width: 500px; |
||||
max-width: 100%; |
||||
text-align: left; |
||||
top:-50px; |
||||
|
||||
overflow: hidden; |
||||
box-shadow: 0px 40px 60px 10px rgba(0, 0, 0, .2); |
||||
position: relative; |
||||
background-color: #fff; |
||||
opacity: 1; |
||||
-webkit-transition: .7s ease-out; |
||||
-moz-transition: .7s ease-out; |
||||
-ms-transition: .7s ease-out; |
||||
-o-transition: .7s ease-out; |
||||
transition: .7s ease-out; |
||||
} |
||||
|
||||
/*.opaque { |
||||
top:-30; |
||||
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, .2); |
||||
}*/ |
||||
|
||||
.demoheader { |
||||
overflow: hidden; |
||||
border-radius: 5px 5px 0px 0px; |
||||
font-size: 8.3px; |
||||
} |
||||
#canvas { |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
pointer-events: none; |
||||
z-index: 0; |
||||
position: absolute; |
||||
/* background-image: url(../img/logowhite.png); |
||||
background-size: cover; |
||||
*/} |
||||
|
||||
.desc { |
||||
text-align: left; |
||||
font-size: 21px; |
||||
color: #343E70; |
||||
} |
||||
.vr { |
||||
display: inline-block; |
||||
height: 40px; |
||||
border-left: 1px solid #5C5C5C; |
||||
} |
||||
.getStarted { |
||||
display: inline-block; |
||||
background-color: #668EC3; |
||||
color: white; |
||||
font-size: 40px; |
||||
padding: 20px; |
||||
padding-left: 50px; |
||||
border-radius: 5px; |
||||
margin-top: 40; |
||||
padding-right: 50px; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.randombold |
||||
{ |
||||
font-size: 18px; |
||||
/*font-family: Georgia;*/ |
||||
|
||||
letter-spacing: .8px; |
||||
line-height: 37px; |
||||
} |
||||
.rant { |
||||
padding-left: 8%; |
||||
padding-right: 8%; |
||||
} |
||||
.npm { |
||||
margin-top: 20px; |
||||
padding-left: 15px; |
||||
background-color: #F3F3F3; |
||||
border-radius: 5px; |
||||
margin-bottom: 0px; |
||||
padding-top: 10px; |
||||
padding-bottom: 10px; |
||||
border-left: 6px solid #303061; |
||||
color: rgb(48, 48, 97); |
||||
font-size: 19px; |
||||
font-family: monospace; |
||||
} |
||||
.longasstag { |
||||
text-align: left; |
||||
white-space: normal; |
||||
word-break: break-all; |
||||
} |
||||
#code { |
||||
text-align: center; |
||||
width: 335px; |
||||
border-radius: 5px; |
||||
margin-top: 80px; |
||||
margin-bottom: 80px; |
||||
max-width: 100%; |
||||
} |
||||
.woloasdf { |
||||
padding-top: 8%; |
||||
} |
||||
.fork { |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
border: 0; |
||||
z-index: 2; |
||||
} |
||||
.fork img { |
||||
width: 149px; |
||||
} |
||||
.two { |
||||
width: 100%; |
||||
display: -webkit-flex; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
-webkit-flex-wrap: wrap; |
||||
justify-content: space-between; |
||||
-webkit-justify-content: space-between; |
||||
max-width: 1100px; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
} |
||||
.demoheader .CodeMirror { |
||||
padding-bottom: 9px; |
||||
padding-top: 9px; |
||||
padding-left: 13px; |
||||
background-color: rgb(255, 238, 174); |
||||
} |
||||
hr { |
||||
border: none; |
||||
border-top: 1px solid #ddd; |
||||
margin: 0px; |
||||
} |
||||
.ocroutput { |
||||
position: relative; |
||||
z-index: 2; |
||||
} |
||||
.manylangs{ |
||||
display: flex; |
||||
display: -webkit-flex; |
||||
|
||||
flex-wrap: wrap; |
||||
-webkit-flex-wrap: wrap; |
||||
} |
||||
body { |
||||
padding: 0px; |
||||
margin: 0px; |
||||
font-family: Lato; |
||||
/*, Helvetica, Arial, sans-serif;*/ |
||||
|
||||
font-weight: 300; |
||||
background-color: white; |
||||
} |
||||
button { |
||||
height: 60px; |
||||
width: 240px; |
||||
margin-top: 10px; |
||||
font: inherit; |
||||
font-size: 30px; |
||||
-webkit-transition: all 0.7s ease; |
||||
transition: all 0.7s ease; |
||||
outline: 0; |
||||
color: #FFF; |
||||
background: #5A4E60; |
||||
border-radius: 5px; |
||||
border: solid 1px #fff; |
||||
} |
||||
button:hover { |
||||
cursor: pointer; |
||||
background: rgba(255, 255, 255, 1); |
||||
border: solid 1px #ddd; |
||||
} |
||||
@media (max-width: 1015px) { |
||||
button { |
||||
color: #fff; |
||||
background-color: rgba(0, 0, 0, 0) |
||||
} |
||||
/* .desc { |
||||
color: #FFFFFF; |
||||
text-shadow: 0px 0px 3px rgba(58, 58, 58, 1); |
||||
} |
||||
.desc a { |
||||
color: #FFEEAE; |
||||
} |
||||
*/ |
||||
.getStarted { |
||||
font-size: 33px; |
||||
} |
||||
.noheight { |
||||
height: auto; |
||||
} |
||||
.demo { |
||||
top:0; |
||||
margin-bottom: 20px; |
||||
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, .2); |
||||
} |
||||
#logo { |
||||
height: auto; |
||||
} |
||||
.two { |
||||
justify-content: space-around; |
||||
-webkit-justify-content: space-around; |
||||
} |
||||
#code { |
||||
margin-top: 20px; |
||||
margin-bottom: 20px; |
||||
width: 400px; |
||||
} |
||||
#fork { |
||||
width: 28%; |
||||
} |
||||
} |
@ -0,0 +1,229 @@
@@ -0,0 +1,229 @@
|
||||
var input = document.getElementById('input') |
||||
var input_overlay = document.getElementById('input-overlay') |
||||
var ioctx = input_overlay.getContext('2d') |
||||
// var output = document.getElementById('output')
|
||||
// var output_overlay = document.getElementById('output-overlay')
|
||||
var output_text = document.getElementById('log') |
||||
|
||||
var demo_instructions = document.getElementById('demo-instructions') |
||||
|
||||
var drop_instructions = [].slice.call(document.querySelectorAll('.drop-instructions')) |
||||
var options = [].slice.call(document.querySelectorAll('.option')) |
||||
|
||||
// var octx = output.getContext('2d')
|
||||
var language = 'eng' |
||||
var demoStarted = false |
||||
var lang_demo_images = { |
||||
eng: 'img/eng_bw.png', |
||||
chi_sim: 'img/chi_sim.png', |
||||
rus: 'img/rus.png' |
||||
} |
||||
|
||||
var lang_drop_instructions = { |
||||
eng: 'an English', |
||||
chi_sim: 'a Chinese', |
||||
rus: 'a Russian' |
||||
} |
||||
|
||||
var worker = new Tesseract.createWorker({ |
||||
logger: progressUpdate, |
||||
}); |
||||
|
||||
function setUp(){ |
||||
input_overlay.width = input.naturalWidth |
||||
input_overlay.height = input.naturalHeight |
||||
|
||||
output_text.style.height = input.height + 'px' |
||||
} |
||||
|
||||
setUp() |
||||
input.onload = setUp |
||||
|
||||
|
||||
function isOutputVisible(){ |
||||
return output_text.getBoundingClientRect().top < dimensions.height |
||||
} |
||||
|
||||
function startDemoIfVisible(argument) { |
||||
if(isOutputVisible() && !demoStarted) startDemo(); |
||||
} |
||||
|
||||
function startDemo(){ |
||||
demoStarted = true |
||||
|
||||
async function start(){ |
||||
await worker.load(); |
||||
await worker.loadLanguage('eng'); |
||||
await worker.initialize('eng'); |
||||
const { data } = await worker.recognize(input); |
||||
result(data); |
||||
|
||||
input.removeEventListener('load', start) |
||||
} |
||||
|
||||
if(input.complete) start(); |
||||
else input.addEventListener('load', start) |
||||
} |
||||
|
||||
// function progress(p){
|
||||
// var text = JSON.stringify(p)
|
||||
|
||||
// // octx.clearRect(0, 0, output.width, output.height)
|
||||
|
||||
// // octx.textAlign = 'center'
|
||||
// // octx.fillText(text, output.width/2, output.height/2)
|
||||
// output_overlay.style.display = 'block'
|
||||
// output_overlay.innerHTML += output_overlay.innerHTML.length ? "\n" + text : text
|
||||
// output_overlay.scrollTop = output_overlay.scrollHeight;
|
||||
// }
|
||||
|
||||
|
||||
function progressUpdate(packet){ |
||||
var log = document.getElementById('log'); |
||||
|
||||
if(log.firstChild && log.firstChild.status === packet.status){ |
||||
if('progress' in packet){ |
||||
var progress = log.firstChild.querySelector('progress') |
||||
progress.value = packet.progress |
||||
} |
||||
}else{ |
||||
var line = document.createElement('div'); |
||||
line.status = packet.status; |
||||
var status = document.createElement('div') |
||||
status.className = 'status' |
||||
status.appendChild(document.createTextNode(packet.status)) |
||||
line.appendChild(status) |
||||
|
||||
if('progress' in packet){ |
||||
var progress = document.createElement('progress') |
||||
progress.value = packet.progress |
||||
progress.max = 1 |
||||
line.appendChild(progress) |
||||
} |
||||
|
||||
|
||||
if(packet.status == 'done'){ |
||||
var pre = document.createElement('pre') |
||||
pre.appendChild(document.createTextNode(packet.data.text)) |
||||
line.innerHTML = '' |
||||
line.appendChild(pre) |
||||
|
||||
} |
||||
|
||||
log.insertBefore(line, log.firstChild) |
||||
} |
||||
} |
||||
|
||||
function result(res){ |
||||
// octx.clearRect(0, 0, output.width, output.height)
|
||||
// octx.textAlign = 'left'
|
||||
|
||||
console.log('result was:', res) |
||||
// output_overlay.style.display = 'none'
|
||||
// output_text.innerHTML = res.text
|
||||
|
||||
progressUpdate({ status: 'done', data: res }) |
||||
|
||||
res.words.forEach(function(w){ |
||||
var b = w.bbox; |
||||
|
||||
ioctx.strokeWidth = 2 |
||||
|
||||
ioctx.strokeStyle = 'red' |
||||
ioctx.strokeRect(b.x0, b.y0, b.x1-b.x0, b.y1-b.y0) |
||||
ioctx.beginPath() |
||||
ioctx.moveTo(w.baseline.x0, w.baseline.y0) |
||||
ioctx.lineTo(w.baseline.x1, w.baseline.y1) |
||||
ioctx.strokeStyle = 'green' |
||||
ioctx.stroke() |
||||
|
||||
|
||||
// octx.font = '20px Times';
|
||||
// octx.font = 20 * (b.x1 - b.x0) / octx.measureText(w.text).width + "px Times";
|
||||
// octx.fillText(w.text, b.x0, w.baseline.y0);
|
||||
}) |
||||
} |
||||
|
||||
|
||||
document.addEventListener('scroll', startDemoIfVisible) |
||||
startDemoIfVisible() |
||||
|
||||
|
||||
function clearOverLayAndOutput(){ |
||||
ioctx.clearRect(0,0, input_overlay.width, input_overlay.height) |
||||
|
||||
output_text.style.display = 'none' |
||||
|
||||
demo_instructions.style.display = 'block' |
||||
|
||||
// octx.clearRect(0,0,output.width, output.height)
|
||||
} |
||||
|
||||
|
||||
// function displayPlayButtonFor(lang){
|
||||
// output.addEventListener('click', function play(){
|
||||
// output.removeEventListener('click', play)
|
||||
|
||||
// tessWorker.recognize(input, lang)
|
||||
// .progress( progress )
|
||||
// .then( result )
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
async function play(){ |
||||
|
||||
demo_instructions.style.display = 'none' |
||||
output_text.style.display = 'block' |
||||
output_text.innerHTML = '' |
||||
// output_overlay.innerHTML = ''
|
||||
|
||||
await worker.load(); |
||||
await worker.loadLanguage(language); |
||||
await worker.initialize(language); |
||||
const { data } = await worker.recognize(input); |
||||
result(data); |
||||
} |
||||
|
||||
options.forEach(function(option){ |
||||
option.addEventListener('click', function(){ |
||||
|
||||
clearOverLayAndOutput() |
||||
|
||||
|
||||
drop_instructions.forEach(function(di){ |
||||
di.innerHTML = lang_drop_instructions[option.lang] |
||||
}) |
||||
|
||||
language = option.lang |
||||
|
||||
options.forEach(function(option){option.className = 'option'}) |
||||
option.className = 'option selected' |
||||
if(option.lang in lang_demo_images){ |
||||
input.src = lang_demo_images[option.lang] |
||||
// displayPlayButtonFor(option.lang)
|
||||
} |
||||
}) |
||||
}) |
||||
|
||||
|
||||
document.body.addEventListener('drop', async function(e){ |
||||
e.stopPropagation(); |
||||
e.preventDefault(); |
||||
var file = e.dataTransfer.files[0] |
||||
var reader = new FileReader(); |
||||
reader.onload = function(e){ |
||||
input.src = e.target.result; |
||||
input.onload = function(){ |
||||
|
||||
setUp(); |
||||
|
||||
} |
||||
}; |
||||
reader.readAsDataURL(file); |
||||
await worker.load(); |
||||
await worker.loadLanguage(language); |
||||
await worker.initialize(language); |
||||
const { data } = await worker.recognize(file); |
||||
result(data); |
||||
}) |
@ -1,17 +0,0 @@
@@ -1,17 +0,0 @@
|
||||
<canvas id="c"></canvas> |
||||
<script type="text/javascript" src="./Tesseract.js"></script> |
||||
<script type="text/javascript"> |
||||
var canvas = document.getElementById('c') |
||||
canvas.width = 400 |
||||
canvas.height = 400 |
||||
var ctx = canvas.getContext('2d'); |
||||
ctx.font = '30px "Arial Black"' |
||||
ctx.fillText('Hell0 World', 100, 40) |
||||
// ctx.fillText("囚犯離奇掙脫囚犯離奇掙脫", 100, 40) |
||||
ctx.font = '30px "Times New Roman"' |
||||
ctx.fillText('from beyond', 100, 80) |
||||
// ctx.fillText('2小時可換乘2次2小時可換乘2次', 100, 80) |
||||
ctx.font = '30px sans-serif' |
||||
ctx.fillText('the Cosmic Void', 100, 120) |
||||
Tesseract.recognize(canvas,{tessedit_char_blacklist:'e'}).then( function(d){ console.log(d) } ) |
||||
</script> |
@ -0,0 +1,392 @@
@@ -0,0 +1,392 @@
|
||||
"use strict"; |
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); |
||||
|
||||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; |
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } |
||||
|
||||
function array_join(array, glue) { |
||||
var new_array = []; |
||||
for (var i = 0; i < array.length; i++) { |
||||
new_array.push(array[i]); |
||||
if (i != array.length - 1) new_array.push(glue); |
||||
} |
||||
return new_array; |
||||
} |
||||
|
||||
var Node = (function (_React$Component) { |
||||
_inherits(Node, _React$Component); |
||||
|
||||
function Node(props) { |
||||
var _this = this; |
||||
|
||||
_classCallCheck(this, Node); |
||||
|
||||
_get(Object.getPrototypeOf(Node.prototype), "constructor", this).call(this, props); |
||||
|
||||
this.toggleExpand = function (e) { |
||||
_this.setState({ expanded: !_this.state.expanded }); |
||||
}; |
||||
|
||||
this.state = { |
||||
expanded: props.expanded |
||||
}; |
||||
} |
||||
|
||||
_createClass(Node, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var _props = this.props; |
||||
var node = _props.node; |
||||
var label = _props.label; |
||||
var expanded = this.state.expanded; |
||||
|
||||
var rep; |
||||
if (typeof node === "string") { |
||||
rep = React.createElement(TextNode, { html: label === "html", node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded }); |
||||
} else if (typeof node === "boolean") { |
||||
rep = React.createElement(BooleanNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded }); |
||||
} else if (typeof node === "number") { |
||||
rep = React.createElement(NumberNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded }); |
||||
} else if (Array.isArray(node)) { |
||||
rep = React.createElement(ListNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded }); |
||||
} else { |
||||
rep = React.createElement(ObjectNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded }); |
||||
} |
||||
|
||||
if (!label) { |
||||
return rep; |
||||
} |
||||
|
||||
return React.createElement( |
||||
"span", |
||||
null, |
||||
React.createElement( |
||||
"span", |
||||
{ className: "label clickable", onClick: this.toggleExpand }, |
||||
label |
||||
), |
||||
": ", |
||||
rep |
||||
); |
||||
} |
||||
}]); |
||||
|
||||
return Node; |
||||
})(React.Component); |
||||
|
||||
var TextNode = (function (_React$Component2) { |
||||
_inherits(TextNode, _React$Component2); |
||||
|
||||
function TextNode() { |
||||
_classCallCheck(this, TextNode); |
||||
|
||||
_get(Object.getPrototypeOf(TextNode.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(TextNode, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var _props2 = this.props; |
||||
var node = _props2.node; |
||||
var expanded = _props2.expanded; |
||||
var html = _props2.html; |
||||
var toggleExpand = _props2.toggleExpand; |
||||
|
||||
if (expanded) { |
||||
var content = node; |
||||
if (html) { |
||||
var content = []; |
||||
CodeMirror.runMode(node, { name: 'xml', htmlMode: true }, function (text, className) { |
||||
content.push(React.createElement( |
||||
"span", |
||||
{ className: "cm-" + className }, |
||||
text |
||||
)); |
||||
}); |
||||
} |
||||
return React.createElement( |
||||
"span", |
||||
{ className: (html ? "cm-s-default html " : "") + "textNode expanded clickable", onClick: toggleExpand }, |
||||
content |
||||
); |
||||
} else { |
||||
return React.createElement( |
||||
"span", |
||||
null, |
||||
React.createElement( |
||||
"span", |
||||
{ className: (html ? "html " : "") + "textNode clickable", onClick: toggleExpand }, |
||||
node.substring(0, 30) |
||||
), |
||||
node.length > 30 ? React.createElement(Ellipsis, null) : '' |
||||
); |
||||
} |
||||
} |
||||
}]); |
||||
|
||||
return TextNode; |
||||
})(React.Component); |
||||
|
||||
var BooleanNode = (function (_React$Component3) { |
||||
_inherits(BooleanNode, _React$Component3); |
||||
|
||||
function BooleanNode() { |
||||
_classCallCheck(this, BooleanNode); |
||||
|
||||
_get(Object.getPrototypeOf(BooleanNode.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(BooleanNode, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var node = this.props.node; |
||||
|
||||
return React.createElement( |
||||
"span", |
||||
{ className: "booleanNode" }, |
||||
JSON.stringify(node) |
||||
); |
||||
} |
||||
}]); |
||||
|
||||
return BooleanNode; |
||||
})(React.Component); |
||||
|
||||
var NumberNode = (function (_React$Component4) { |
||||
_inherits(NumberNode, _React$Component4); |
||||
|
||||
function NumberNode() { |
||||
_classCallCheck(this, NumberNode); |
||||
|
||||
_get(Object.getPrototypeOf(NumberNode.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(NumberNode, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var node = this.props.node; |
||||
|
||||
return React.createElement( |
||||
"span", |
||||
{ className: "numberNode" }, |
||||
JSON.stringify(node) |
||||
); |
||||
} |
||||
}]); |
||||
|
||||
return NumberNode; |
||||
})(React.Component); |
||||
|
||||
var ListNode = (function (_React$Component5) { |
||||
_inherits(ListNode, _React$Component5); |
||||
|
||||
function ListNode() { |
||||
_classCallCheck(this, ListNode); |
||||
|
||||
_get(Object.getPrototypeOf(ListNode.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(ListNode, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var _props3 = this.props; |
||||
var node = _props3.node; |
||||
var expanded = _props3.expanded; |
||||
var toggleExpand = _props3.toggleExpand; |
||||
|
||||
if (expanded) { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "listNode expanded" }, |
||||
React.createElement( |
||||
"span", |
||||
{ className: "clickable", onClick: toggleExpand }, |
||||
"[" |
||||
), |
||||
React.createElement("br", null), |
||||
React.createElement( |
||||
"span", |
||||
{ className: "indent" }, |
||||
array_join(node.map(function (e, i) { |
||||
return React.createElement(Node, { node: e, key: i }); |
||||
}), React.createElement(Comma, { br: true })) |
||||
), |
||||
React.createElement("br", null), |
||||
React.createElement( |
||||
"span", |
||||
{ onClick: toggleExpand }, |
||||
"]" |
||||
) |
||||
); |
||||
} else { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "listNode clickable", onClick: toggleExpand }, |
||||
"[", |
||||
node.length, |
||||
"]" |
||||
); |
||||
} |
||||
} |
||||
}]); |
||||
|
||||
return ListNode; |
||||
})(React.Component); |
||||
|
||||
var ObjectNode = (function (_React$Component6) { |
||||
_inherits(ObjectNode, _React$Component6); |
||||
|
||||
function ObjectNode() { |
||||
_classCallCheck(this, ObjectNode); |
||||
|
||||
_get(Object.getPrototypeOf(ObjectNode.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(ObjectNode, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var _props4 = this.props; |
||||
var node = _props4.node; |
||||
var expanded = _props4.expanded; |
||||
var toggleExpand = _props4.toggleExpand; |
||||
|
||||
if (null === node) { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "nullNode" }, |
||||
"null" |
||||
); |
||||
} else if (expanded) { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "objectNode expanded" }, |
||||
React.createElement( |
||||
"span", |
||||
{ className: "clickable", onClick: toggleExpand }, |
||||
"{" |
||||
), |
||||
React.createElement("br", null), |
||||
React.createElement( |
||||
"span", |
||||
{ className: "indent" }, |
||||
array_join(Object.keys(node).map(function (key) { |
||||
return React.createElement(Node, { node: node[key], label: key, key: key }); |
||||
}), React.createElement(Comma, { br: true })) |
||||
), |
||||
React.createElement("br", null), |
||||
React.createElement( |
||||
"span", |
||||
{ onClick: toggleExpand }, |
||||
"}" |
||||
) |
||||
); |
||||
} else { |
||||
var keys = Object.keys(node), |
||||
toolong = false; |
||||
if (keys.length > 4) { |
||||
keys = keys.slice(0, 4); |
||||
toolong = true; |
||||
} |
||||
var contents = array_join(keys.map(function (k) { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "label" }, |
||||
k |
||||
); |
||||
}), React.createElement(Comma, null)); |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "objectNode clickable", onClick: toggleExpand }, |
||||
"{", |
||||
contents, |
||||
toolong ? React.createElement(Ellipsis, null) : '', |
||||
"}" |
||||
); |
||||
} |
||||
} |
||||
}]); |
||||
|
||||
return ObjectNode; |
||||
})(React.Component); |
||||
|
||||
var Comma = (function (_React$Component7) { |
||||
_inherits(Comma, _React$Component7); |
||||
|
||||
function Comma() { |
||||
_classCallCheck(this, Comma); |
||||
|
||||
_get(Object.getPrototypeOf(Comma.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(Comma, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
var br = this.props.br; |
||||
|
||||
return React.createElement( |
||||
"span", |
||||
{ className: "comma" }, |
||||
", ", |
||||
br ? React.createElement("br", null) : '' |
||||
); |
||||
} |
||||
}]); |
||||
|
||||
return Comma; |
||||
})(React.Component); |
||||
|
||||
var Ellipsis = (function (_React$Component8) { |
||||
_inherits(Ellipsis, _React$Component8); |
||||
|
||||
function Ellipsis() { |
||||
_classCallCheck(this, Ellipsis); |
||||
|
||||
_get(Object.getPrototypeOf(Ellipsis.prototype), "constructor", this).apply(this, arguments); |
||||
} |
||||
|
||||
_createClass(Ellipsis, [{ |
||||
key: "render", |
||||
value: function render() { |
||||
return React.createElement( |
||||
"span", |
||||
{ className: "ellipsis" }, |
||||
"..." |
||||
); |
||||
} |
||||
}]); |
||||
|
||||
return Ellipsis; |
||||
})(React.Component); |
||||
|
||||
var simplething = { |
||||
hello: 42, |
||||
derp: 324, |
||||
wumbo: [1, 2, 3, 4, "hello", { |
||||
blah: 32, |
||||
asdf: [], |
||||
walp: 32, |
||||
strings: "asdfsd" |
||||
}], |
||||
merp: { |
||||
blah: 32, |
||||
asdf: [], |
||||
walp: 32, |
||||
strings: "asdfsd" |
||||
}, |
||||
strings: "asdfsd", |
||||
asdoijfo: { |
||||
strings: "asdfsd", |
||||
adfds: { |
||||
asdf: { |
||||
asdfadsf: {}, |
||||
merp: 32 |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
// React.render(<Node node={simplething} />, document.getElementById('explorer'))
|
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 276 KiB |
After Width: | Height: | Size: 261 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 141 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 5.6 MiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 183 KiB |
After Width: | Height: | Size: 953 KiB |
After Width: | Height: | Size: 357 KiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 1.1 MiB |
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
<title>Tesseract.js | Pure Javascript OCR for 100 Languages!</title> |
||||
<link rel="stylesheet" type="text/css" href="css/main.css"> |
||||
<link href='https://fonts.googleapis.com/css?family=Lato:300,400' rel='stylesheet' type='text/css'> |
||||
<script> |
||||
if (location.protocol === "http:" && !location.host.startsWith('localhost')) { |
||||
location.replace("https" + window.location.href.slice(4)); |
||||
} |
||||
</script> |
||||
</head> |
||||
<body ondragover="return false"> |
||||
|
||||
<div id="splash"> |
||||
<div id="logo-wrap" class="header"> |
||||
<canvas id="logo-canvas"></canvas> |
||||
<img id="logo-img" src="img/logowhite.png"> |
||||
<div id='slogan'>Pure Javascript Multilingual OCR</div> |
||||
</div> |
||||
<div class='get-started-wrap'> |
||||
<a href="https://github.com/naptha/tesseract.js#tesseractjs"> |
||||
<div class='get-started'> |
||||
<svg id="github" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg> |
||||
Get Started |
||||
</div> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
|
||||
<div id='demo'> |
||||
<!-- <div class="commentary"> |
||||
<div id='demo-title'>Demo</div> |
||||
<p>Wherein we show you that Tesseract.js works, and let you try it with your own images.</p> |
||||
</div> |
||||
|
||||
--> |
||||
<div class='commentary'> |
||||
<p><b>Tesseract.js</b> is a pure Javascript port of the popular <a href='https://github.com/tesseract-ocr/tesseract'>Tesseract OCR engine</a>. </p> |
||||
<p>This library supports <b>more than 100 languages</b>, automatic text <b>orientation and script detection</b>, a simple interface for reading paragraph, word, and character <b>bounding boxes</b>. Tesseract.js can run either in a <b>browser</b> and on a server with <b>NodeJS</b>. </p> |
||||
|
||||
<p>Check out the <a href='https://github.com/naptha/tesseract.js#tesseractjs'>Example code and API docs on GitHub</a>.</p> |
||||
</div> |
||||
<div id='demo-body'> |
||||
<div id='options'> |
||||
<div class="option selected" lang='eng'>English Demo</div> |
||||
<div class="option" lang='chi_sim'>Chinese Demo</div> |
||||
<div class="option" lang='rus'>Russian Demo</div> |
||||
</div> |
||||
<div id='drop-instructions-main'><p>Drop <span class='drop-instructions'>an English</span> image on this page to OCR it!</p></div> |
||||
<div id='demo-content'> |
||||
<div> |
||||
<canvas id='input-overlay'></canvas> |
||||
<img id='input' src="img/eng_bw.png"/> |
||||
</div> |
||||
<div id='arrow'></div> |
||||
<div> |
||||
<!-- <div id='output-overlay'></div> --> |
||||
<!-- <textarea id='output-text'></textarea> --> |
||||
|
||||
<div id='log'></div> |
||||
<div id='demo-instructions'> |
||||
<span id='clickme' onclick='play()'>Click here to recognize text in the demo image</span>, or drop <span class='drop-instructions'>an English</span> image anywhere on this page. |
||||
</div> |
||||
<!-- <canvas id='output'></canvas> --> |
||||
</div> |
||||
</div> |
||||
<div class='get-started-wrap'> |
||||
<br/> |
||||
<a href="https://github.com/naptha/tesseract.js#tesseractjs"> |
||||
<div class='get-started'> |
||||
<svg id="github" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg> |
||||
Actually Get Started |
||||
</div> |
||||
</a> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<div id='footer'> |
||||
<span id="lengle">“Speaking of ways, pet, by the way, <b>there <i>is</i> such a thing as a tesseract</b>.” |
||||
<br> |
||||
<br> |
||||
<!-- Made with <img src="img/keyboard.png"> --> By <a href="https://twitter.com/biject">@biject</a>, <a href="https://twitter.com/antimatter15">@antimatter15</a> and <a href="https://github.com/jeromewu">@jeromewu</a></span> |
||||
</div> |
||||
|
||||
<script src="animation/raf.js"></script> |
||||
<script src="animation/mouse.js"></script> |
||||
<script src="animation/dimensions.js"></script> |
||||
<script src="animation/hypercube.js"></script> |
||||
<script src="animation/animate.js"></script> |
||||
|
||||
<script src="https://unpkg.com/tesseract.js@2.0.0/dist/tesseract.min.js" integrity="sha384-MTEb82ufpBJ2VCTmPZlD/+vgiT5z6zmOwqU/uDO9IobYm9xCOUEN0WH3czf6ppl8" crossorigin="anonymous"></script> |
||||
<script src="demo.js"></script> |
||||
<script> |
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); |
||||
|
||||
ga('create', 'UA-83153710-3', 'auto', 'origin'); |
||||
ga('origin.send', 'pageview'); |
||||
ga('create', 'UA-139963961-1', 'auto', 'addon'); |
||||
ga('addon.send', 'pageview'); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,242 @@
@@ -0,0 +1,242 @@
|
||||
'use strict'; |
||||
|
||||
function builddemo(id, val) { |
||||
var demo = document.getElementById(id); |
||||
var prog = demo.querySelector('.prog'); |
||||
var out = demo.querySelector('.out'); |
||||
|
||||
var disp = demo.querySelector('.display'); |
||||
var dctx = disp.getContext('2d'); |
||||
disp.width = 0; |
||||
disp.height = 0; |
||||
|
||||
demo.querySelector('.runbutton').onclick = function () { |
||||
setrunning(0); |
||||
run(editor); |
||||
editor.clear(); |
||||
prog.setValue(0); |
||||
}; |
||||
|
||||
prog.setValue = function (v) { |
||||
prog.querySelector('div').style.width = v * 100 + '%'; |
||||
}; |
||||
|
||||
function show_progress(p) { |
||||
|
||||
setrunning(0); |
||||
console.log(p); |
||||
if (p.loaded_lang_model) prog.setValue(p.loaded_lang_model); |
||||
if (p.recognized) prog.setValue(p.recognized); |
||||
out.innerText = JSON.stringify(p); |
||||
} |
||||
|
||||
function setrunning(v) { |
||||
if (v == 1) { |
||||
demo.querySelector('.running').style.display = 'none'; |
||||
demo.querySelector('.notrunning').style.display = 'block'; |
||||
// out.style.visibility = 'hidden'
|
||||
} else { |
||||
demo.querySelector('.running').style.display = 'block'; |
||||
demo.querySelector('.notrunning').style.display = 'none'; |
||||
} |
||||
} |
||||
|
||||
function display(result) { |
||||
|
||||
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff" }), document.getElementById("explorer")); |
||||
|
||||
setrunning(1); |
||||
|
||||
out.innerText = "Lightning Speeeeeeed"; |
||||
prog.value = 0; |
||||
|
||||
console.log(result); |
||||
|
||||
disp.width = demo.querySelector('.to_ocr').naturalWidth; |
||||
disp.height = demo.querySelector('.to_ocr').naturalHeight; |
||||
|
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth; |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight; |
||||
|
||||
// dctx.shadowColor = "rgba(255,255,255,.1)";
|
||||
// dctx.shadowOffsetX = 0;
|
||||
// dctx.shadowOffsetY = 0;
|
||||
// dctx.shadowBlur = 10;
|
||||
|
||||
// dctx.fillRect(0, 0, disp.width, disp.height);
|
||||
|
||||
var m = result.words.map(function (w) { |
||||
|
||||
var b = w.bbox; |
||||
dctx.font = '20px Times'; |
||||
var font = 20 * (b.x1 - b.x0) / dctx.measureText(w.text).width + "px Times"; |
||||
|
||||
return function k() { |
||||
dctx.font = font; |
||||
// dctx.font = '40px Times';
|
||||
dctx.fillText(w.text, b.x0, w.baseline.y0); |
||||
// dctx.fillStyle='rgba(255,255,255,.3)'
|
||||
// dctx.fillRect(b.x0, b.y0, b.x1 - b.x0, b.y1 - b.y0);
|
||||
return font; |
||||
}; |
||||
}); |
||||
|
||||
var times = 0; |
||||
var maxtimes = m.length + 100; |
||||
function draw(i) { |
||||
|
||||
times++; |
||||
// dctx.fillStyle="rgba(30, 29, 49, .8)"
|
||||
dctx.fillStyle = "rgba(0, 219, 157, " + Math.min(i / 100, 1) + ")"; |
||||
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
|
||||
// dctx.globalAlpha = .1;
|
||||
|
||||
dctx.clearRect(0, 0, disp.width, disp.height); |
||||
// dctx.fillRect(0, 0, disp.width, disp.height);
|
||||
|
||||
for (var j = 0; j < Math.min(i, m.length); j++) { |
||||
var asdf = Math.min(Math.max(i - j, 0), 100); |
||||
dctx.fillStyle = "rgba(0,0,0," + asdf * .01 + ")"; |
||||
m[j](); |
||||
}; |
||||
|
||||
if (i < maxtimes) { |
||||
setTimeout(function () { |
||||
draw(i + 1); |
||||
}, 10); |
||||
} else { |
||||
console.log('done'); |
||||
} |
||||
} |
||||
draw(0); |
||||
result.words.forEach(function (word, index) { |
||||
var wdiv = document.createElement('div'); |
||||
wdiv.innerText = word.text + ' '; |
||||
wdiv.style['font-family'] = "Times"; |
||||
wdiv.style.position = 'absolute'; |
||||
var to_ocr = document.querySelector('.to_ocr'); |
||||
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight; |
||||
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale; |
||||
wdiv.style.color = "rgba(0,0,0,0)"; |
||||
wdiv.style.top = word.bbox.y0 * scale; |
||||
wdiv.style.left = word.bbox.x0 * scale; |
||||
wdiv.style.height = (word.bbox.y1 - word.bbox.y0) * scale; |
||||
wdiv.style.width = (word.bbox.x1 - word.bbox.x0) * scale; |
||||
document.querySelector('.ocroutput').appendChild(wdiv); |
||||
}); |
||||
} |
||||
|
||||
window.addEventListener('resize', function () { |
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth; |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight; |
||||
}); |
||||
|
||||
function run(c) { |
||||
eval(c.getValue()); |
||||
} |
||||
|
||||
var editor = CodeMirror(demo.querySelector('.editor'), { |
||||
// lineNumbers: true,
|
||||
viewportMargin: Infinity, |
||||
value: val |
||||
}); |
||||
|
||||
var sc = demo.querySelector('.demoheader'); |
||||
// var scdiv = document.createElement('div');
|
||||
// sc.appendChild(scdiv);
|
||||
// scdiv.className = 'CodeMirror cm-s-default';
|
||||
// // scdiv.className = 'cm-s-default'
|
||||
// CodeMirror.runMode('<script src="http://tenso.rs/tesseract.js"></script>', {
|
||||
// name: 'xml',
|
||||
// htmlMode: true
|
||||
// }, scdiv);
|
||||
|
||||
// var scripttag = CodeMirror(,{
|
||||
// mode: {name: 'xml', htmlMode: true},
|
||||
// readOnly: 'nocursor',
|
||||
// value:
|
||||
// });
|
||||
editor.clear = function () { |
||||
dctx.clearRect(0, 0, disp.width, disp.height); |
||||
disp.style.height = 0; |
||||
document.querySelector('.ocroutput').innerHTML = ''; |
||||
}; |
||||
|
||||
editor.img = demo.querySelector('.to_ocr'); |
||||
|
||||
editor.run = function () { |
||||
|
||||
if (editor.img.complete) { |
||||
run(editor); |
||||
} else { |
||||
editor.img.onload = function () { |
||||
run(editor); |
||||
editor.img.onload = function () {}; |
||||
}; |
||||
} |
||||
}; |
||||
|
||||
return editor; |
||||
} |
||||
|
||||
setTimeout(function () { |
||||
document.getElementById('wow').className += ' opaque'; |
||||
}, 100); |
||||
|
||||
var wow = builddemo('wow', |
||||
["var img = demo.querySelector('img.to_ocr')", |
||||
"Tesseract", |
||||
" .recognize( img )", |
||||
" .progress( show_progress )", |
||||
" .then( display ) // scroll down for full output", |
||||
" // you can edit this code"].join('\n')); |
||||
|
||||
wow.run(); |
||||
|
||||
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel')); |
||||
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab')); |
||||
var langs = ['eng', 'chi_sim', 'rus', 'meme']; |
||||
var langims = langs.map(function (lang) { |
||||
var limg = new Image(); |
||||
limg.src = 'img/' + lang + '.png'; |
||||
return limg; |
||||
}); |
||||
|
||||
function setlang(i) { |
||||
tabs.forEach(function (t) { |
||||
t.className = 'langlabel'; |
||||
}); |
||||
tabs[i].className = 'langlabel selected'; |
||||
console.log(tabs[i]); |
||||
wow.setValue(["var img = demo.querySelector('img.to_ocr')", |
||||
"Tesseract", |
||||
" .recognize( img, '"+langs[i]+"' )", |
||||
" .progress( show_progress )", |
||||
" .then( display ) // scroll down for full output", |
||||
" // you can edit this code"].join('\n')); |
||||
wow.img.src = 'img/' + langs[i] + '.png'; |
||||
wow.clear(); |
||||
wow.run() |
||||
} |
||||
|
||||
ltabs.forEach(function (ltab, i) { |
||||
ltab.onclick = function () { |
||||
setlang(i); |
||||
}; |
||||
}); |
||||
|
||||
tabs.forEach(function (tab, i) { |
||||
tab.onclick = function () { |
||||
setlang(i); |
||||
}; |
||||
}); |
||||
// document.querySelector('.getStarted')[0].onclick = function(){
|
||||
// location.href = '#'
|
||||
// location.href = '#get_started'
|
||||
// }
|
||||
|
||||
// builddemo('demo2',
|
||||
// "var img = demo.querySelector('img.to_ocr')\n\n\
|
||||
// Tesseract\n\
|
||||
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
|
||||
// .then( display )")
|
@ -0,0 +1,227 @@
@@ -0,0 +1,227 @@
|
||||
'use strict'; |
||||
|
||||
function builddemo(id, val) { |
||||
var demo = document.getElementById(id); |
||||
var prog = demo.querySelector('.prog'); |
||||
var out = demo.querySelector('.out'); |
||||
|
||||
var disp = demo.querySelector('.display'); |
||||
var dctx = disp.getContext('2d'); |
||||
disp.width = 0; |
||||
disp.height = 0; |
||||
|
||||
demo.querySelector('.runbutton').onclick = function () { |
||||
setrunning(0); |
||||
run(editor); |
||||
editor.clear(); |
||||
prog.setValue(0); |
||||
}; |
||||
|
||||
prog.setValue = function (v) { |
||||
prog.querySelector('div').style.width = v * 100 + '%'; |
||||
}; |
||||
|
||||
function show_progress(p) { |
||||
|
||||
setrunning(0); |
||||
console.log(p); |
||||
if (p.loaded_lang_model) prog.setValue(p.loaded_lang_model); |
||||
if (p.recognized) prog.setValue(p.recognized); |
||||
out.innerText = JSON.stringify(p); |
||||
} |
||||
|
||||
function setrunning(v) { |
||||
if (v == 1) { |
||||
demo.querySelector('.running').style.display = 'none'; |
||||
demo.querySelector('.notrunning').style.display = 'block'; |
||||
// out.style.visibility = 'hidden'
|
||||
} else { |
||||
demo.querySelector('.running').style.display = 'block'; |
||||
demo.querySelector('.notrunning').style.display = 'none'; |
||||
} |
||||
} |
||||
|
||||
function display(result) { |
||||
|
||||
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff" }), document.getElementById("explorer")); |
||||
|
||||
setrunning(1); |
||||
|
||||
out.innerText = "Lightning Speeeeeeed"; |
||||
prog.value = 0; |
||||
|
||||
console.log(result); |
||||
|
||||
disp.width = demo.querySelector('.to_ocr').naturalWidth; |
||||
disp.height = demo.querySelector('.to_ocr').naturalHeight; |
||||
|
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth; |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight; |
||||
|
||||
dctx.shadowColor = "rgba(255,255,255,.1)"; |
||||
dctx.shadowOffsetX = 0; |
||||
dctx.shadowOffsetY = 0; |
||||
dctx.shadowBlur = 10; |
||||
|
||||
dctx.fillRect(0, 0, disp.width, disp.height); |
||||
|
||||
var m = result.words.map(function (w) { |
||||
|
||||
var b = w.bbox; |
||||
dctx.font = '20px Times'; |
||||
var font = 20 * (b.x1 - b.x0) / dctx.measureText(w.text).width + "px Times"; |
||||
|
||||
var k = function k() { |
||||
dctx.font = font; |
||||
dctx.fillText(w.text, b.x0, w.baseline.y0); |
||||
return font; |
||||
}; |
||||
|
||||
return k; |
||||
}); |
||||
|
||||
var times = 0; |
||||
var maxtimes = m.length + 100; |
||||
function draw(i) { |
||||
|
||||
times++; |
||||
// dctx.fillStyle="rgba(30, 29, 49, .8)"
|
||||
dctx.fillStyle = "rgba(0, 219, 157, " + Math.min(i / 100, 1) + ")"; |
||||
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
|
||||
// dctx.globalAlpha = .1;
|
||||
dctx.clearRect(0, 0, disp.width, disp.height); |
||||
dctx.fillRect(0, 0, disp.width, disp.height); |
||||
|
||||
for (var j = 0; j < Math.min(i, m.length); j++) { |
||||
var asdf = Math.min(Math.max(i - j, 0), 100); |
||||
dctx.fillStyle = "rgba(255,255,255," + asdf * .01 + ")"; |
||||
m[j](); |
||||
}; |
||||
|
||||
if (i < maxtimes) { |
||||
setTimeout(function () { |
||||
draw(i + 1); |
||||
}, 10); |
||||
} else { |
||||
console.log('done'); |
||||
} |
||||
} |
||||
draw(0); |
||||
result.words.forEach(function (word, index) { |
||||
var wdiv = document.createElement('div'); |
||||
wdiv.innerText = word.text + ' '; |
||||
wdiv.style['font-family'] = "Times"; |
||||
wdiv.style.position = 'absolute'; |
||||
var to_ocr = document.querySelector('.to_ocr'); |
||||
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight; |
||||
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale; |
||||
wdiv.style.color = "rgba(0,0,0,0)"; |
||||
wdiv.style.top = word.bbox.y0 * scale; |
||||
wdiv.style.left = word.bbox.x0 * scale; |
||||
wdiv.style.height = (word.bbox.y1 - word.bbox.y0) * scale; |
||||
wdiv.style.width = (word.bbox.x1 - word.bbox.x0) * scale; |
||||
document.querySelector('.ocroutput').appendChild(wdiv); |
||||
}); |
||||
} |
||||
|
||||
window.addEventListener('resize', function () { |
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth; |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight; |
||||
}); |
||||
|
||||
function run(c) { |
||||
eval(c.getValue()); |
||||
} |
||||
|
||||
var editor = CodeMirror(demo.querySelector('.editor'), { |
||||
// lineNumbers: true,
|
||||
viewportMargin: Infinity, |
||||
value: val |
||||
}); |
||||
|
||||
var sc = demo.querySelector('.demoheader'); |
||||
var scdiv = document.createElement('div'); |
||||
sc.appendChild(scdiv); |
||||
scdiv.className = 'CodeMirror cm-s-default'; |
||||
// scdiv.className = 'cm-s-default'
|
||||
CodeMirror.runMode('<script src="http://localhost:1234/master/lib/Tesseract_dev.js"></script>', { |
||||
name: 'xml', |
||||
htmlMode: true |
||||
}, scdiv); |
||||
|
||||
// var scripttag = CodeMirror(,{
|
||||
// mode: {name: 'xml', htmlMode: true},
|
||||
// readOnly: 'nocursor',
|
||||
// value:
|
||||
// });
|
||||
editor.clear = function () { |
||||
dctx.clearRect(0, 0, disp.width, disp.height); |
||||
document.querySelector('.ocroutput').innerHTML = ''; |
||||
}; |
||||
|
||||
editor.img = demo.querySelector('.to_ocr'); |
||||
|
||||
editor.run = function () { |
||||
|
||||
if (editor.img.complete) { |
||||
run(editor); |
||||
} else { |
||||
editor.img.onload = function () { |
||||
run(editor); |
||||
editor.img.onload = function () {}; |
||||
}; |
||||
} |
||||
}; |
||||
|
||||
return editor; |
||||
} |
||||
|
||||
setTimeout(function () { |
||||
document.getElementById('wow').className += ' opaque'; |
||||
}, 100); |
||||
|
||||
var wow = builddemo('wow', "var img = demo.querySelector('img.to_ocr')\n\n" + "Tesseract\n" + " .recognize( img, {\n" + " progress: show_progress} )\n" + " .then( display ) // scroll down for full output\n" + " // you can edit this code"); |
||||
|
||||
wow.run(); |
||||
|
||||
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel')); |
||||
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab')); |
||||
var langs = ['eng', 'chi_sim', 'rus', 'meme']; |
||||
var langims = langs.map(function (lang) { |
||||
var limg = new Image(); |
||||
limg.src = 'img/' + lang + '.png'; |
||||
return limg; |
||||
}); |
||||
|
||||
function setlang(i) { |
||||
tabs.forEach(function (t) { |
||||
t.className = 'langlabel'; |
||||
}); |
||||
tabs[i].className = 'langlabel selected'; |
||||
console.log(tabs[i]); |
||||
wow.setValue("var img = demo.querySelector('img.to_ocr')\n\n" + "Tesseract\n" + " .recognize( img, {\n" + " progress: show_progress, lang: '" + langs[i] + "'} )\n" + " .then( display ) // scroll down for full output\n" + " // you can edit this code"); |
||||
wow.img.src = 'img/' + langs[i] + '.png'; |
||||
wow.clear(); |
||||
} |
||||
|
||||
ltabs.forEach(function (ltab, i) { |
||||
ltab.onclick = function () { |
||||
setlang(i); |
||||
}; |
||||
}); |
||||
|
||||
tabs.forEach(function (tab, i) { |
||||
tab.onclick = function () { |
||||
setlang(i); |
||||
}; |
||||
}); |
||||
// document.querySelector('.getStarted')[0].onclick = function(){
|
||||
// location.href = '#'
|
||||
// location.href = '#get_started'
|
||||
// }
|
||||
|
||||
// builddemo('demo2',
|
||||
// "var img = demo.querySelector('img.to_ocr')\n\n\
|
||||
// Tesseract\n\
|
||||
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
|
||||
// .then( display )")
|
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
{ |
||||
"name": "tesseract.js", |
||||
"version": "1.0.0", |
||||
"description": "", |
||||
"main": "Tesseract.js", |
||||
"dependencies": { |
||||
"pako": "^0.2.7" |
||||
}, |
||||
"devDependencies": {}, |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/naptha/tesseract.js.git" |
||||
}, |
||||
"author": "", |
||||
"license": "ISC", |
||||
"bugs": { |
||||
"url": "https://github.com/naptha/tesseract.js/issues" |
||||
}, |
||||
"homepage": "https://github.com/naptha/tesseract.js" |
||||
} |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
var svg = (function(colors){ |
||||
var canvas = document.createElement('canvas'), |
||||
ctx = canvas.getContext('2d'); |
||||
|
||||
canvas.width = 10 |
||||
canvas.height = 2 |
||||
var upscale = 10 |
||||
|
||||
var im = ctx.getImageData(0,0,canvas.width,canvas.height) |
||||
for (var i = 0; i < im.data.length; i+=4) { |
||||
im.data[i] = Math.round(Math.random()*255) |
||||
im.data[i+1] = Math.round(Math.random()*255) |
||||
im.data[i+2] = Math.round(Math.random()*255) |
||||
im.data[i+3] = 255 |
||||
}; |
||||
ctx.putImageData(im,0,0) |
||||
var url = canvas.toDataURL() |
||||
im = new Image() |
||||
im.src = url |
||||
canvas.width *= upscale |
||||
canvas.height *= upscale |
||||
ctx.drawImage(im,0,0,canvas.width, canvas.height) |
||||
im = ctx.getImageData(0,0,canvas.width,canvas.height) |
||||
|
||||
var xmlns = "http://www.w3.org/2000/svg"; |
||||
var svg = document.createElementNS(xmlns, 'svg') |
||||
svg.setAttribute('viewBox',"0 0 "+im.width+" "+im.height) |
||||
for (var i = 0; i < im.data.length; i+=4) { |
||||
var mindist = 195075 |
||||
var mincolor = [0,0,0] |
||||
var pix = [im.data[i],im.data[i+1],im.data[i+2]] |
||||
for (var j = 0; j < colors.length; j++) { |
||||
var color = colors[j] |
||||
var d0 = color[0] - pix[0] |
||||
var d1 = color[1] - pix[1] |
||||
var d2 = color[2] - pix[2] |
||||
var d = Math.abs(d0)+Math.abs(d1)+Math.abs(d2) |
||||
if (d<mindist) { |
||||
mindist = d |
||||
mincolor = color |
||||
} |
||||
}; |
||||
|
||||
var n = i/4 |
||||
var elem = document.createElementNS(xmlns, "rect"); |
||||
elem.setAttributeNS(null,"x",n%im.width); |
||||
elem.setAttributeNS(null,"y",Math.floor(n/im.width)); |
||||
elem.setAttributeNS(null,"width",1.5); |
||||
elem.setAttributeNS(null,"height",1.5); |
||||
elem.setAttributeNS(null,"fill", 'rgba('+Math.min(mincolor[0]+0%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)'); |
||||
|
||||
svg.appendChild(elem); |
||||
}; |
||||
return svg |
||||
})([ |
||||
[39, 198, 249], |
||||
[6, 188, 249], |
||||
// [154, 218, 198],
|
||||
[116, 218, 251], |
||||
[91, 211, 251]]) |
||||
document.getElementById('marterial').appendChild(svg) |
@ -0,0 +1,191 @@
@@ -0,0 +1,191 @@
|
||||
function array_join(array, glue){ |
||||
var new_array = [] |
||||
for(var i = 0; i < array.length; i++){ |
||||
new_array.push(array[i]) |
||||
if(i != array.length - 1) new_array.push(glue); |
||||
} |
||||
return new_array |
||||
} |
||||
|
||||
|
||||
class Node extends React.Component { |
||||
constructor(props){ |
||||
super(props) |
||||
this.state = { |
||||
expanded: props.expanded |
||||
} |
||||
} |
||||
|
||||
toggleExpand = e => { |
||||
this.setState({expanded: !this.state.expanded}) |
||||
} |
||||
|
||||
render(){ |
||||
var {node, label} = this.props |
||||
var {expanded} = this.state |
||||
|
||||
var rep |
||||
if(typeof node === "string"){ |
||||
rep = <TextNode html={label === "html"} node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/> |
||||
} |
||||
else if(typeof node === "boolean"){ |
||||
rep = <BooleanNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/> |
||||
} |
||||
else if(typeof node === "number"){ |
||||
rep = <NumberNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/> |
||||
} |
||||
else if(Array.isArray(node)){ |
||||
rep = <ListNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/> |
||||
} |
||||
else { |
||||
rep = <ObjectNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/> |
||||
} |
||||
|
||||
if(!label){ |
||||
return rep |
||||
} |
||||
|
||||
return <span><span className="label clickable" onClick={this.toggleExpand}>{label}</span>: {rep}</span> |
||||
|
||||
} |
||||
} |
||||
|
||||
class TextNode extends React.Component { |
||||
render(){ |
||||
var {node, expanded, html, toggleExpand} = this.props |
||||
if(expanded){ |
||||
var content = node |
||||
if (html) { |
||||
var content = [] |
||||
CodeMirror.runMode(node, {name: 'xml', htmlMode: true}, (text, className) => { |
||||
content.push(<span className={"cm-"+className}>{text}</span>) |
||||
}) |
||||
} |
||||
return <span className={(html ? "cm-s-default html ":"") + "textNode expanded clickable"} onClick={toggleExpand} >{content}</span> |
||||
} |
||||
else{ |
||||
return <span> |
||||
<span className={(html? "html " : "")+"textNode clickable"} onClick={toggleExpand} >{node.substring(0,30)}</span> |
||||
{node.length > 30 ? <Ellipsis /> : ''} |
||||
</span> |
||||
} |
||||
} |
||||
} |
||||
|
||||
class BooleanNode extends React.Component { |
||||
render(){ |
||||
var {node} = this.props |
||||
return <span className="booleanNode">{JSON.stringify(node)}</span> |
||||
} |
||||
} |
||||
|
||||
class NumberNode extends React.Component { |
||||
render(){ |
||||
var {node} = this.props |
||||
return <span className="numberNode">{JSON.stringify(node)}</span> |
||||
} |
||||
} |
||||
|
||||
class ListNode extends React.Component { |
||||
render(){ |
||||
var {node, expanded, toggleExpand} = this.props |
||||
if(expanded){ |
||||
return <span className="listNode expanded"> |
||||
<span className="clickable" onClick={toggleExpand}>[</span> |
||||
<br /> |
||||
<span className="indent"> |
||||
{array_join(node.map((e, i) => |
||||
<Node node={e} key={i}/> |
||||
),<Comma br/>)} |
||||
|
||||
</span> |
||||
<br /> |
||||
<span onClick={toggleExpand}>]</span> |
||||
</span> |
||||
} |
||||
else{ |
||||
return <span className="listNode clickable" onClick={toggleExpand}>[{node.length}]</span> |
||||
} |
||||
} |
||||
} |
||||
|
||||
class ObjectNode extends React.Component { |
||||
render(){ |
||||
var {node, expanded, toggleExpand} = this.props |
||||
|
||||
if(null === node){ |
||||
return <span className="nullNode">null</span> |
||||
} |
||||
else if(expanded){ |
||||
return <span className="objectNode expanded"> |
||||
<span className="clickable" onClick={toggleExpand}>{"{"}</span> |
||||
<br /> |
||||
<span className="indent"> |
||||
{array_join(Object.keys(node).map( |
||||
key => <Node node={node[key]} label={key} key={key}/> |
||||
),<Comma br/>)} |
||||
</span> |
||||
<br /> |
||||
<span onClick={toggleExpand}>{"}"}</span> |
||||
</span> |
||||
} |
||||
else{ |
||||
var keys = Object.keys(node), toolong = false |
||||
if (keys.length > 4) { |
||||
keys = keys.slice(0,4) |
||||
toolong = true |
||||
} |
||||
var contents = array_join(keys.map(k => <span className="label">{k}</span>), <Comma />) |
||||
return <span className="objectNode clickable" onClick={toggleExpand} >{"{"}{contents}{toolong?<Ellipsis /> : ''}{"}"}</span> |
||||
} |
||||
} |
||||
} |
||||
|
||||
class Comma extends React.Component { |
||||
render(){ |
||||
var {br} = this.props |
||||
return <span className="comma">, {br?<br />:''}</span> |
||||
} |
||||
} |
||||
|
||||
class Ellipsis extends React.Component { |
||||
render(){ |
||||
return <span className="ellipsis">...</span> |
||||
} |
||||
} |
||||
|
||||
var simplething = { |
||||
hello: 42, |
||||
derp: 324, |
||||
wumbo: [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
"hello", |
||||
{ |
||||
blah: 32, |
||||
asdf: [], |
||||
walp: 32, |
||||
strings: "asdfsd", |
||||
} |
||||
], |
||||
merp: { |
||||
blah: 32, |
||||
asdf: [], |
||||
walp: 32, |
||||
strings: "asdfsd", |
||||
}, |
||||
strings: "asdfsd", |
||||
asdoijfo: { |
||||
strings: "asdfsd", |
||||
adfds: { |
||||
asdf: { |
||||
asdfadsf: {}, |
||||
merp: 32 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// React.render(<Node node={simplething} />, document.getElementById('explorer'))
|
@ -0,0 +1,247 @@
@@ -0,0 +1,247 @@
|
||||
function builddemo(id, val){ |
||||
var demo = document.getElementById(id) |
||||
var prog = demo.querySelector('.prog') |
||||
var out = demo.querySelector('.out') |
||||
|
||||
var disp = demo.querySelector('.display') |
||||
var dctx = disp.getContext('2d') |
||||
disp.width = 0 |
||||
disp.height = 0 |
||||
|
||||
demo.querySelector('.runbutton').onclick = function(){ |
||||
setrunning(0) |
||||
run(editor) |
||||
editor.clear() |
||||
prog.setValue(0) |
||||
} |
||||
|
||||
prog.setValue = function(v){ |
||||
prog.querySelector('div').style.width = v*100+'%' |
||||
} |
||||
|
||||
function show_progress(p){ |
||||
|
||||
setrunning(0) |
||||
console.log(p) |
||||
if(p.loaded_lang_model) prog.setValue(p.loaded_lang_model) |
||||
if(p.recognized) prog.setValue(p.recognized) |
||||
out.innerText = JSON.stringify(p) |
||||
|
||||
} |
||||
|
||||
function setrunning(v){ |
||||
if (v == 1) { |
||||
demo.querySelector('.running').style.display = 'none' |
||||
demo.querySelector('.notrunning').style.display = 'block' |
||||
// out.style.visibility = 'hidden'
|
||||
} |
||||
else { |
||||
demo.querySelector('.running').style.display = 'block' |
||||
demo.querySelector('.notrunning').style.display = 'none' |
||||
} |
||||
} |
||||
|
||||
function display(result) { |
||||
|
||||
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff"}), document.getElementById("explorer")); |
||||
|
||||
setrunning(1) |
||||
|
||||
out.innerText = "Lightning Speeeeeeed" |
||||
prog.value = 0 |
||||
|
||||
console.log(result) |
||||
|
||||
disp.width = demo.querySelector('.to_ocr').naturalWidth |
||||
disp.height = demo.querySelector('.to_ocr').naturalHeight |
||||
|
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight |
||||
|
||||
|
||||
dctx.shadowColor = "rgba(255,255,255,.1)" |
||||
dctx.shadowOffsetX = 0; |
||||
dctx.shadowOffsetY = 0; |
||||
dctx.shadowBlur = 10; |
||||
|
||||
dctx.fillRect(0,0,disp.width, disp.height) |
||||
|
||||
var m = result.words.map(function(w){ |
||||
|
||||
var b = w.bbox |
||||
dctx.font = '20px Times' |
||||
var font = 20*(b.x1-b.x0)/dctx.measureText(w.text).width+"px Times" |
||||
|
||||
|
||||
var k = function(){ |
||||
dctx.font = font |
||||
dctx.fillText(w.text, b.x0, w.baseline.y0); |
||||
return font |
||||
} |
||||
|
||||
return k |
||||
}) |
||||
|
||||
var times = 0 |
||||
var maxtimes = m.length + 100 |
||||
function draw(i){ |
||||
|
||||
times++ |
||||
// dctx.fillStyle="rgba(30, 29, 49, .8)"
|
||||
dctx.fillStyle="rgba(0, 219, 157, "+Math.min(i/100,1)+")" |
||||
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
|
||||
// dctx.globalAlpha = .1;
|
||||
dctx.clearRect(0,0,disp.width, disp.height) |
||||
dctx.fillRect(0,0,disp.width, disp.height) |
||||
|
||||
for (var j = 0; j < Math.min(i,m.length); j++) { |
||||
var asdf = Math.min(Math.max(i - j,0), 100) |
||||
dctx.fillStyle = "rgba(255,255,255,"+asdf*.01+")" |
||||
m[j]() |
||||
}; |
||||
|
||||
if(i<maxtimes){ |
||||
setTimeout(function(){ |
||||
draw(i+1) |
||||
},10) |
||||
} |
||||
else{ |
||||
console.log('done') |
||||
} |
||||
} |
||||
draw(0) |
||||
result.words.forEach(function(word, index){ |
||||
var wdiv = document.createElement('div') |
||||
wdiv.innerText = word.text+' ' |
||||
wdiv.style['font-family'] = "Times" |
||||
wdiv.style.position = 'absolute' |
||||
var to_ocr = document.querySelector('.to_ocr') |
||||
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight |
||||
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale |
||||
wdiv.style.color = "rgba(0,0,0,0)" |
||||
wdiv.style.top = word.bbox.y0 * scale |
||||
wdiv.style.left = word.bbox.x0 * scale |
||||
wdiv.style.height = (word.bbox.y1 - word.bbox.y0)*scale |
||||
wdiv.style.width = (word.bbox.x1 - word.bbox.x0)*scale |
||||
document.querySelector('.ocroutput').appendChild(wdiv) |
||||
}) |
||||
} |
||||
|
||||
window.addEventListener('resize', function() { |
||||
disp.style.width = demo.querySelector('.to_ocr').offsetWidth |
||||
disp.style.height = demo.querySelector('.to_ocr').offsetHeight |
||||
}) |
||||
|
||||
function run(c){ |
||||
eval(c.getValue()) |
||||
} |
||||
|
||||
var editor = CodeMirror(demo.querySelector('.editor'),{ |
||||
// lineNumbers: true,
|
||||
viewportMargin: Infinity, |
||||
value: val |
||||
}); |
||||
|
||||
var sc = demo.querySelector('.demoheader') |
||||
var scdiv = document.createElement('div') |
||||
sc.appendChild(scdiv) |
||||
scdiv.className = 'CodeMirror cm-s-default' |
||||
// scdiv.className = 'cm-s-default'
|
||||
CodeMirror.runMode('<script src="__tesseractjs__"></script>', { |
||||
name: 'xml', |
||||
htmlMode: true |
||||
}, scdiv) |
||||
|
||||
// var scripttag = CodeMirror(,{
|
||||
// mode: {name: 'xml', htmlMode: true},
|
||||
// readOnly: 'nocursor',
|
||||
// value:
|
||||
// });
|
||||
editor.clear = function(){ |
||||
dctx.clearRect(0,0,disp.width, disp.height) |
||||
document.querySelector('.ocroutput').innerHTML = '' |
||||
|
||||
} |
||||
|
||||
editor.img = demo.querySelector('.to_ocr') |
||||
|
||||
editor.run = function(){ |
||||
|
||||
if (editor.img.complete) { |
||||
run(editor) |
||||
} else{ |
||||
editor.img.onload = function(){ |
||||
run(editor) |
||||
editor.img.onload = function(){} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return editor |
||||
} |
||||
|
||||
setTimeout(function(){ |
||||
document.getElementById('wow').className += ' opaque' |
||||
}, 100) |
||||
|
||||
var wow = builddemo('wow', |
||||
"var img = demo.querySelector('img.to_ocr')\n\n" |
||||
+"Tesseract\n" |
||||
+" .recognize( img, {\n" |
||||
+" progress: show_progress} )\n" |
||||
+" .then( display ) // scroll down for full output\n" |
||||
+" // you can edit this code") |
||||
|
||||
wow.run() |
||||
|
||||
|
||||
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel')) |
||||
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab')) |
||||
var langs = ['eng', 'chi_sim', 'rus', 'meme'] |
||||
var langims = langs.map(lang => { |
||||
var limg = new Image() |
||||
limg.src = 'img/'+lang+'.png' |
||||
return limg |
||||
}) |
||||
|
||||
function setlang(i){ |
||||
tabs.forEach(function(t){ |
||||
t.className = 'langlabel' |
||||
}) |
||||
tabs[i].className = 'langlabel selected' |
||||
console.log(tabs[i]) |
||||
wow.setValue( |
||||
"var img = demo.querySelector('img.to_ocr')\n\n" |
||||
+"Tesseract\n" |
||||
+" .recognize( img, {\n" |
||||
+" progress: show_progress, lang: '"+langs[i]+"'} )\n" |
||||
+" .then( display ) // scroll down for full output\n" |
||||
+" // you can edit this code") |
||||
wow.img.src = 'img/'+langs[i]+'.png' |
||||
wow.clear() |
||||
|
||||
} |
||||
|
||||
|
||||
ltabs.forEach(function(ltab,i){ |
||||
ltab.onclick = function(){ |
||||
setlang(i) |
||||
} |
||||
}) |
||||
|
||||
|
||||
tabs.forEach(function(tab,i){ |
||||
tab.onclick = function(){ |
||||
setlang(i) |
||||
} |
||||
}) |
||||
// document.querySelector('.getStarted')[0].onclick = function(){
|
||||
// location.href = '#'
|
||||
// location.href = '#get_started'
|
||||
// }
|
||||
|
||||
// builddemo('demo2',
|
||||
// "var img = demo.querySelector('img.to_ocr')\n\n\
|
||||
// Tesseract\n\
|
||||
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
|
||||
// .then( display )")
|
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
<html> |
||||
<head> |
||||
<title></title> |
||||
<style type="text/css"> |
||||
body { |
||||
margin: 0px |
||||
} |
||||
</style> |
||||
</head> |
||||
<body> |
||||
<script type="text/javascript"> |
||||
|
||||
var svg = (function(colors){ |
||||
var canvas = document.createElement('canvas'), |
||||
ctx = canvas.getContext('2d'); |
||||
|
||||
canvas.width = 10 |
||||
canvas.height = 5 |
||||
var upscale = 10 |
||||
|
||||
var im = ctx.getImageData(0,0,canvas.width,canvas.height) |
||||
for (var i = 0; i < im.data.length; i+=4) { |
||||
im.data[i] = Math.round(Math.random()*255) |
||||
im.data[i+1] = Math.round(Math.random()*255) |
||||
im.data[i+2] = Math.round(Math.random()*255) |
||||
im.data[i+3] = 255 |
||||
}; |
||||
ctx.putImageData(im,0,0) |
||||
var url = canvas.toDataURL() |
||||
im = new Image() |
||||
im.src = url |
||||
canvas.width *= upscale |
||||
canvas.height *= upscale |
||||
ctx.drawImage(im,0,0,canvas.width, canvas.height) |
||||
im = ctx.getImageData(0,0,canvas.width,canvas.height) |
||||
|
||||
var xmlns = "http://www.w3.org/2000/svg"; |
||||
var svg = document.createElementNS(xmlns, 'svg') |
||||
svg.setAttribute('viewBox',"0 0 "+im.width+" "+im.height) |
||||
for (var i = 0; i < im.data.length; i+=4) { |
||||
var mindist = 195075 |
||||
var mincolor = [0,0,0] |
||||
var pix = [im.data[i],im.data[i+1],im.data[i+2]] |
||||
for (var j = 0; j < colors.length; j++) { |
||||
var color = colors[j] |
||||
var d0 = color[0] - pix[0] |
||||
var d1 = color[1] - pix[1] |
||||
var d2 = color[2] - pix[2] |
||||
var d = Math.abs(d0)+Math.abs(d1)+Math.abs(d2) |
||||
if (d<mindist) { |
||||
mindist = d |
||||
mincolor = color |
||||
} |
||||
}; |
||||
|
||||
var n = i/4 |
||||
ctx.fillStyle = 'rgba('+Math.min(mincolor[0]+n%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)' |
||||
var elem = document.createElementNS(xmlns, "rect"); |
||||
|
||||
elem.setAttributeNS(null,"x",n%im.width); |
||||
elem.setAttributeNS(null,"y",Math.floor(n/im.width)); |
||||
elem.setAttributeNS(null,"width",1.5); |
||||
elem.setAttributeNS(null,"height",1.5); |
||||
elem.setAttributeNS(null,"fill", 'rgba('+Math.min(mincolor[0]+n%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)'); |
||||
|
||||
svg.appendChild(elem); |
||||
}; |
||||
return svg |
||||
})([[39, 198, 249], [6, 188, 249], [116, 218, 251], [91, 211, 251]]) |
||||
|
||||
document.body.appendChild(svg) |
||||
// wrap.appendChild(svg) |
||||
|
||||
// document.body.style.backgroundImage = "url(data:image/svg+xml;utf8,"+wrap.innerHTML+")" |
||||
// document.styleSheets[0].insertRule("body {background: url('data:image/svg+xml;utf8,"+wrap.innerHTML+"')}",0) |
||||
|
||||
// ctx.putImageData(im,0,0) |
||||
// canvas.style.width = 2000 |
||||
// canvas.style.height = 2000 |
||||
|
||||
// document.body.appendChild(canvas) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script> |
||||
<!-- <script type="text/javascript" src="wolo.js"></script> --> |
||||
</body> |
||||
</html> |
@ -1,324 +0,0 @@
@@ -1,324 +0,0 @@
|
||||
importScripts('madeline.js') |
||||
|
||||
var filesizes = { |
||||
"afr": 1079573, |
||||
"ara": 1701536, |
||||
"aze": 1420865, |
||||
"bel": 1276820, |
||||
"ben": 6772012, |
||||
"bul": 1605615, |
||||
"cat": 1652368, |
||||
"ces": 1035441, |
||||
"chi_sim": 17710414, |
||||
"chi_tra": 24717749, |
||||
"chr": 320649, |
||||
"dan-frak": 677656, |
||||
"dan": 1972936, |
||||
"deu-frak": 822644, |
||||
"deu": 991656, |
||||
"ell": 859719, |
||||
"eng": 9453554, |
||||
"enm": 619254, |
||||
"epo": 1241212, |
||||
"equ": 821130, |
||||
"est": 1905040, |
||||
"eus": 1641190, |
||||
"fin": 979418, |
||||
"fra": 1376221, |
||||
"frk": 5912963, |
||||
"frm": 5147082, |
||||
"glg": 1674938, |
||||
"grc": 3012615, |
||||
"heb": 1051501, |
||||
"hin": 6590065, |
||||
"hrv": 1926995, |
||||
"hun": 3074473, |
||||
"ind": 1874776, |
||||
"isl": 1634041, |
||||
"ita": 948593, |
||||
"ita_old": 3436571, |
||||
"jpn": 13507168, |
||||
"kan": 4390317, |
||||
"kor": 5353098, |
||||
"lav": 1843944, |
||||
"lit": 1779240, |
||||
"mal": 5966263, |
||||
"meme": 88453, |
||||
"mkd": 1163087, |
||||
"mlt": 1463001, |
||||
"msa": 1665427, |
||||
"nld": 1134708, |
||||
"nor": 2191610, |
||||
"osd": 4274649, |
||||
"pol": 7024662, |
||||
"por": 909359, |
||||
"ron": 915680, |
||||
"rus": 5969957, |
||||
"slk-frak": 289885, |
||||
"slk": 2217342, |
||||
"slv": 1611338, |
||||
"spa": 883170, |
||||
"spa_old": 5647453, |
||||
"sqi": 1667041, |
||||
"srp": 1770244, |
||||
"swa": 757916, |
||||
"swe": 2451917, |
||||
"tam": 3498763, |
||||
"tel": 5795246, |
||||
"tgl": 1496256, |
||||
"tha": 3811136, |
||||
"tur": 3563264, |
||||
"ukr": 937566, |
||||
"vie": 2195922 |
||||
} |
||||
|
||||
var recognize = (function createTesseractInstance(){ |
||||
|
||||
var Module = Tesseract304({ |
||||
TOTAL_MEMORY: 90e6, |
||||
TesseractProgress: function(percent){ |
||||
console.log('recognized',percent+'%') |
||||
} |
||||
}) |
||||
|
||||
var base = new Module.TessBaseAPI() |
||||
var loaded_langs = [] |
||||
var loadLanguage = (function(){ |
||||
|
||||
return (function loadLanguage(lang, cb){ // NodeJS style callback
|
||||
if(loaded_langs.indexOf(lang) != -1){ |
||||
cb(null, lang) |
||||
} |
||||
else{ |
||||
Module.FS_createPath("/","tessdata",true,true) |
||||
var xhr = new XMLHttpRequest(); |
||||
xhr.open('GET', 'https://cdn.rawgit.com/naptha/tessdata/gh-pages/3.02/'+lang+'.traineddata.gz', true); |
||||
xhr.responseType = 'arraybuffer'; |
||||
xhr.onerror = function(){ cb(xhr, null) } |
||||
xhr.onprogress = function(e){console.log('loading',lang,'language model:',Math.round(e.loaded/filesizes[lang]*100)+'%')} |
||||
xhr.onload = function(){ |
||||
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { |
||||
console.log('unzipping language model...') |
||||
var data = new Uint8Array(unzip(new Uint8Array(xhr.response))) |
||||
console.log(lang +".traineddata", 'sucessfully unzipped') |
||||
Module.FS_createDataFile('tessdata', lang +".traineddata", data, true, false); |
||||
loaded_langs.push(lang) |
||||
cb(null, lang) |
||||
} else cb(xhr, null); |
||||
} |
||||
xhr.send(null) |
||||
} |
||||
}) |
||||
})() |
||||
|
||||
function DumpLiterallyEverything(){ |
||||
var ri = base.GetIterator(); |
||||
var blocks = []; |
||||
var block, para, textline, word, symbol; |
||||
|
||||
function enumToString(value, prefix){ |
||||
return (Object.keys(Module) |
||||
.filter(function(e){ return e.startsWith(prefix + '_') }) |
||||
.filter(function(e){ return Module[e] === value }) |
||||
.map(function(e){ return e.slice(prefix.length + 1) })[0]) |
||||
} |
||||
|
||||
do { |
||||
if(ri.IsAtBeginningOf(Module.RIL_BLOCK)){ |
||||
var poly = ri.BlockPolygon(); |
||||
var polygon = null; |
||||
// BlockPolygon() returns null when automatic page segmentation is off
|
||||
if(Module.getPointer(poly) > 0){ |
||||
var n = poly.get_n(), |
||||
px = poly.get_x(), |
||||
py = poly.get_y(), |
||||
polygon = []; |
||||
for(var i = 0; i < n; i++){ |
||||
polygon.push([px.getValue(i), py.getValue(i)]); |
||||
} |
||||
Module._ptaDestroy(Module.getPointer(poly)); |
||||
} |
||||
|
||||
block = { |
||||
paragraphs: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_BLOCK), |
||||
confidence: ri.Confidence(Module.RIL_BLOCK), |
||||
baseline: ri.getBaseline(Module.RIL_BLOCK), |
||||
bbox: ri.getBoundingBox(Module.RIL_BLOCK), |
||||
|
||||
blocktype: enumToString(ri.BlockType(), 'PT'), |
||||
polygon: polygon |
||||
} |
||||
blocks.push(block) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_PARA)){ |
||||
para = { |
||||
lines: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_PARA), |
||||
confidence: ri.Confidence(Module.RIL_PARA), |
||||
baseline: ri.getBaseline(Module.RIL_PARA), |
||||
bbox: ri.getBoundingBox(Module.RIL_PARA), |
||||
|
||||
is_ltr: !!ri.ParagraphIsLtr() |
||||
} |
||||
block.paragraphs.push(para) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_TEXTLINE)){ |
||||
textline = { |
||||
words: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_TEXTLINE), |
||||
confidence: ri.Confidence(Module.RIL_TEXTLINE), |
||||
baseline: ri.getBaseline(Module.RIL_TEXTLINE), |
||||
bbox: ri.getBoundingBox(Module.RIL_TEXTLINE) |
||||
} |
||||
para.lines.push(textline) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_WORD)){ |
||||
var fontInfo = ri.getWordFontAttributes(), |
||||
wordDir = ri.WordDirection(); |
||||
word = { |
||||
symbols: [], |
||||
choices: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_WORD), |
||||
confidence: ri.Confidence(Module.RIL_WORD), |
||||
baseline: ri.getBaseline(Module.RIL_WORD), |
||||
bbox: ri.getBoundingBox(Module.RIL_WORD), |
||||
|
||||
is_numeric: !!ri.WordIsNumeric(), |
||||
in_dictionary: !!ri.WordIsFromDictionary(), |
||||
direction: enumToString(wordDir, 'DIR'), |
||||
language: ri.WordRecognitionLanguage(), |
||||
|
||||
is_bold: fontInfo.is_bold, |
||||
is_italic: fontInfo.is_italic, |
||||
is_underlined: fontInfo.is_underlined, |
||||
is_monospace: fontInfo.is_monospace, |
||||
is_serif: fontInfo.is_serif, |
||||
is_smallcaps: fontInfo.is_smallcaps, |
||||
font_size: fontInfo.pointsize, |
||||
font_id: fontInfo.font_id, |
||||
font_name: fontInfo.font_name, |
||||
} |
||||
var wc = new Module.WordChoiceIterator(ri); |
||||
do { |
||||
word.choices.push({ |
||||
text: wc.GetUTF8Text(), |
||||
confidence: wc.Confidence() |
||||
}) |
||||
} while (wc.Next()); |
||||
Module.destroy(wc) |
||||
textline.words.push(word) |
||||
} |
||||
|
||||
var image = null; |
||||
// var pix = ri.GetBinaryImage(Module.RIL_SYMBOL)
|
||||
// var image = pix2array(pix);
|
||||
// // for some reason it seems that things stop working if you destroy pics
|
||||
// Module._pixDestroy(Module.getPointer(pix));
|
||||
|
||||
symbol = { |
||||
choices: [], |
||||
image: image, |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_SYMBOL), |
||||
confidence: ri.Confidence(Module.RIL_SYMBOL), |
||||
baseline: ri.getBaseline(Module.RIL_SYMBOL), |
||||
bbox: ri.getBoundingBox(Module.RIL_SYMBOL), |
||||
|
||||
is_superscript: !!ri.SymbolIsSuperscript(), |
||||
is_subscript: !!ri.SymbolIsSubscript(), |
||||
is_dropcap: !!ri.SymbolIsDropcap(), |
||||
} |
||||
word.symbols.push(symbol) |
||||
var ci = new Module.ChoiceIterator(ri); |
||||
do { |
||||
symbol.choices.push({ |
||||
text: ci.GetUTF8Text(), |
||||
confidence: ci.Confidence() |
||||
}) |
||||
} while (ci.Next()); |
||||
Module.destroy(ci) |
||||
} while (ri.Next(Module.RIL_SYMBOL)); |
||||
Module.destroy(ri) |
||||
|
||||
return { |
||||
text: base.GetUTF8Text(), |
||||
html: base.GetHOCRText(), |
||||
|
||||
confidence: base.MeanTextConf(), |
||||
|
||||
blocks: blocks, |
||||
|
||||
psm: enumToString(base.GetPageSegMode(), 'PSM'), |
||||
oem: enumToString(base.oem(), 'OEM'), |
||||
version: base.Version(), |
||||
} |
||||
} |
||||
|
||||
function recognize(image, lang, options,cb){ |
||||
var width, height; |
||||
if(image.data){ |
||||
var src = image.data; |
||||
width = image.width, height = image.height; |
||||
var dst = new Uint8Array(width * height); |
||||
var srcLength = src.length | 0, srcLength_16 = (srcLength - 16) | 0; |
||||
|
||||
var coeff_r = 4899, coeff_g = 9617, coeff_b = 1868; |
||||
|
||||
for (var i = 0, j = 0; i <= srcLength_16; i += 16, j += 4) { |
||||
// convert to grayscale 4 pixels at a time;
|
||||
// add 8192 = 1<<13 so for int n, float k >= .5, ((n + k)*(1<<14) >> 14) = 1 + ((n)*(1<<14) >> 14)
|
||||
dst[j] = src[i+3] //(((src[i] * coeff_r + src[i+1] * coeff_g + src[i+2] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
|
||||
dst[j + 1] = src[i+4+3]//(((src[i+4] * coeff_r + src[i+5] * coeff_g + src[i+6] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
|
||||
dst[j + 2] = src[i+8+3]//(((src[i+8] * coeff_r + src[i+9] * coeff_g + src[i+10] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
|
||||
dst[j + 3] = src[i+12+3]//(((src[i+12] * coeff_r + src[i+13] * coeff_g + src[i+14] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
|
||||
} |
||||
for (; i < srcLength; i += 4, ++j) //finish up
|
||||
dst[j] = (src[i] * coeff_r + src[i+1] * coeff_g + src[i+2] * coeff_b + 8192) >> 14; |
||||
|
||||
image = dst; |
||||
// for(var i = 0; i < image.length; i++) image[i] = image[i] > 128;
|
||||
} |
||||
else { |
||||
throw 'Expected ImageData' |
||||
} |
||||
var ptr = Module.allocate(image, 'i8', Module.ALLOC_NORMAL); |
||||
|
||||
loadLanguage(lang, function(err, result){ |
||||
if(err){ |
||||
console.error("error loading", lang); |
||||
cb(err, null) |
||||
} |
||||
base.Init(null, lang) |
||||
for (var option in options) { |
||||
if (options.hasOwnProperty(option)) { |
||||
base.SetVariable(option, options[option]); |
||||
console.log('setting', option, '=', options[option]); |
||||
} |
||||
} |
||||
|
||||
|
||||
base.SetImage(Module.wrapPointer(ptr), width, height, 1, width) |
||||
base.SetRectangle(0, 0, width, height) |
||||
base.GetUTF8Text() |
||||
var everything = DumpLiterallyEverything() |
||||
base.End(); |
||||
Module._free(ptr); |
||||
cb(null, everything) |
||||
}) |
||||
} |
||||
|
||||
// base._simple = _simple
|
||||
return recognize |
||||
})() |
||||
|
||||
onmessage = function(e) { |
||||
|
||||
recognize(e.data.image, e.data.lang, e.data.options, function(err, result){ |
||||
postMessage({err:err, result: result}) |
||||
}) |
||||
} |