summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulie Lala <jules@okfoc.us>2014-04-10 01:51:53 -0400
committerJulie Lala <jules@okfoc.us>2014-04-10 01:51:53 -0400
commitc928a0084480767b75b6ae02532b062570a88306 (patch)
tree489afdea979e28aefe9b773b928f5c0240dcc204
parente816fe642c10e54d36d839b7a33ed5ecf6a6139b (diff)
drawing/dragging rects
-rw-r--r--assets/javascripts/vendor/kdTree.jsbin0 -> 3693 bytes
-rw-r--r--editor.html (renamed from index.html)0
-rw-r--r--rectagnesl-drag.html246
-rw-r--r--rectangles-borders.html126
-rw-r--r--rectangles-lines.html108
-rw-r--r--rectangles.html283
6 files changed, 697 insertions, 66 deletions
diff --git a/assets/javascripts/vendor/kdTree.js b/assets/javascripts/vendor/kdTree.js
new file mode 100644
index 0000000..8b2a49b
--- /dev/null
+++ b/assets/javascripts/vendor/kdTree.js
Binary files differ
diff --git a/index.html b/editor.html
index c695394..c695394 100644
--- a/index.html
+++ b/editor.html
diff --git a/rectagnesl-drag.html b/rectagnesl-drag.html
new file mode 100644
index 0000000..086ce27
--- /dev/null
+++ b/rectagnesl-drag.html
@@ -0,0 +1,246 @@
+<!doctype html>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="assets/stylesheets/css.css">
+<style type="text/css">
+body > div {
+ float: left;
+}
+</style>
+</head>
+<body>
+
+<div id="map"></div>
+<div id="info">
+ <span id="intersects"></span>
+</div>
+
+</body>
+<script type="text/javascript" src="assets/javascripts/util.js"></script>
+<script type="text/javascript">
+
+function vec2(a,b){
+ this.a = a
+ this.b = b
+}
+vec2.prototype.magnitude = function(){
+ return this.b-this.a
+}
+vec2.prototype.length = function(){
+ return abs(this.b-this.a)
+}
+vec2.prototype.clone = function(){
+ return new vec2(this.a, this.b)
+}
+vec2.prototype.normalize = function(){
+ if (this.b < this.a) {
+ this.a = this.a ^ this.b
+ this.b = this.a ^ this.b
+ this.a = this.a ^ this.b
+ }
+ return this
+}
+vec2.prototype.add = function(n){
+ this.a += n
+ this.b += n
+}
+vec2.prototype.sub = function(n){
+ this.a -= n
+ this.b -= n
+}
+vec2.prototype.mul = function(n){
+ this.a *= n
+ this.b *= n
+}
+vec2.prototype.div = function(n){
+ this.a /= n
+ this.b /= n
+}
+vec2.prototype.contains = function(n){
+ return this.a <= n && n <= this.b
+}
+vec2.prototype.intersects = function(v){
+ return (this.a <= v.a && this.b > v.a) ||
+ (v.a <= this.a && v.b > this.a)
+}
+vec2.prototype.union = function(v){
+ if (this.intersects(v)) {
+ return new vec2( min(this.a,v.a), max(this.b, v.b) )
+ }
+}
+vec2.prototype.intersection = function(v){
+ if (this.intersects(v)) {
+ return new vec2( max(this.a,v.a), min(this.b, v.b) )
+ }
+}
+
+function rect (x0,y0,x1,y1){
+ if (x0 instanceof vec2) {
+ this.x = x0
+ this.y = y0
+ }
+ else if (x1 === undefined) {
+ this.x = new vec2(x0,x0)
+ this.y = new vec2(y0,y0)
+ }
+ else {
+ this.x = new vec2(x0,x1)
+ this.y = new vec2(y0,y1)
+ }
+ this.translation = new vec2(0,0)
+}
+rect.prototype.clone = function(){
+ return new rect( this.x.clone(), this.y.clone() )
+}
+rect.prototype.normalize = function(){
+ this.x.normalize().add(this.translation.a)
+ this.y.normalize().add(this.translation.b)
+ this.translation.a = this.translation.b = 0
+ return this
+}
+rect.prototype.contains = function(x,y){
+ return this.x.contains(x) && this.y.contains(y)
+}
+rect.prototype.intersects = function(r){
+ return this.x.intersects(r.x) && this.y.intersects(r.y)
+}
+rect.prototype.width = function(){ return this.x.length() }
+rect.prototype.height = function(){ return this.y.length() }
+rect.prototype.fill = function(){
+ ctx.fillRect(this.x.a + this.translation.a, this.y.a + this.translation.b, this.x.length(), this.y.length())
+}
+rect.prototype.stroke = function(){
+ ctx.beginPath()
+ ctx.moveTo(this.x.a, this.y.a)
+ ctx.lineTo(this.x.b, this.y.b)
+ ctx.stroke()
+}
+
+
+
+var canvas = document.createElement("canvas")
+var ctx = canvas.getContext("2d")
+var w = canvas.width = 500
+var h = canvas.height = 500
+document.body.appendChild(canvas)
+
+var rects = [
+ new rect(100,100, 300,300),
+ new rect(200,200, 400,400),
+]
+
+var creating = false, dragging = false
+var mouse = new rect(0,0,0,0)
+canvas.addEventListener("mousedown", function(e){
+ var x = e.pageX, y = e.pageY
+ mouse = new rect (x,y)
+
+ var intersects = rects.filter(function(r){ return r.contains(x,y) })
+ console.log(intersects)
+ if (intersects.length){
+ dragging = intersects[0]
+ }
+ else {
+ creating = true
+ }
+
+})
+canvas.addEventListener("mousemove", function(e){
+ mouse.x.b = e.pageX
+ mouse.y.b = e.pageY
+ if (dragging) {
+ dragging.translation.a = mouse.x.magnitude()
+ dragging.translation.b = mouse.y.magnitude()
+ }
+ else if (creating) {
+ mouse.x.b = e.pageX
+ mouse.y.b = e.pageY
+ }
+ else {
+ mouse.x.a = mouse.x.b
+ mouse.y.a = mouse.y.b
+ }
+})
+document.addEventListener("mouseup", function(e){
+ if (creating) {
+ if (mouse.height() != 0 && mouse.width() != 0) {
+ rects.push(mouse.normalize())
+ }
+ }
+ if (dragging) {
+ dragging.normalize()
+ }
+ mouse = new rect(e.pageX, e.pageY)
+ creating = dragging = false
+})
+
+function animate(){
+ requestAnimationFrame(animate)
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ solve_rects()
+ draw_ruler()
+ draw_rects()
+ draw_mouse()
+}
+animate()
+
+function draw_ruler(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ var len = 5
+ for (var i = 0.5; i < w; i += 10) {
+ line(i, 0, i, len)
+ line(0, i, len, i)
+ }
+}
+
+function line (x,y,a,b){
+ ctx.beginPath()
+ ctx.moveTo(x,y)
+ ctx.lineTo(a,b)
+ ctx.stroke()
+}
+
+function solve_rects(){
+ var x_intervals = []
+ var y_intervals = []
+ for (var i = 0; i < rects.length; i++) {
+
+ }
+}
+function draw_regions(){
+}
+function draw_rects(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ // ctx.setLineDash([randint(5)+2,randint(2)+2]);
+ ctx.setLineDash([1,1]);
+
+ for (var i = 0; i < rects.length; i++) {
+ ctx.fillStyle = "rgba(0,200,220,0.5)"
+ rects[i].fill()
+// line(rect.x, 0, rect.x, rect.y)
+// line(0, rect.y, rect.x, rect.y)
+ }
+}
+function draw_mouse(){
+ ctx.fillStyle = "rgba(255,0,0,0.4)";
+ ctx.beginPath();
+ ctx.arc(mouse.x.b, mouse.y.b, 5, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ if (mouse.width() != 0 && mouse.height() != 0) {
+ if (dragging) {
+ mouse.stroke()
+ }
+ else {
+ ctx.fillStyle = "rgba(255,255,0,0.5)"
+ mouse.clone().normalize().fill()
+ }
+ }
+}
+
+</script>
+</html>
diff --git a/rectangles-borders.html b/rectangles-borders.html
new file mode 100644
index 0000000..afc153e
--- /dev/null
+++ b/rectangles-borders.html
@@ -0,0 +1,126 @@
+<!doctype html>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="assets/stylesheets/css.css">
+<style type="text/css">
+</style>
+</head>
+<body>
+
+
+</body>
+<script type="text/javascript" src="assets/javascripts/util.js"></script>
+<script type="text/javascript">
+
+(function(){
+
+ var canvas = document.createElement("canvas")
+ var ctx = canvas.getContext("2d")
+ var w = canvas.width = 500
+ var h = canvas.height = 500
+ document.body.appendChild(canvas)
+
+ var rects = []
+ var dragging = false
+ var mouse = {x:0,y:0,w:0,h:0}
+ canvas.addEventListener("mousedown", function(e){
+ dragging = true
+ mouse.x = e.pageX
+ mouse.y = e.pageY
+ mouse.w = mouse.h = 0
+ })
+ canvas.addEventListener("mousemove", function(e){
+ if (dragging) {
+ mouse.w = e.pageX - mouse.x
+ mouse.h = e.pageY - mouse.y
+ }
+ else {
+ mouse.x = e.pageX
+ mouse.y = e.pageY
+ }
+ })
+ document.addEventListener("mouseup", function(e){
+ if (! dragging) return
+ dragging = false
+ if (mouse.h != 0 && mouse.w != 0) {
+ rects.push(normalize(mouse))
+ }
+ mouse = {x:e.pageX,y:e.pageY,w:0,h:0}
+ })
+
+ function animate(){
+ requestAnimationFrame(animate)
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ solve_rects()
+ draw_ruler()
+ draw_rects()
+ draw_mouse()
+ }
+ animate()
+
+ function normalize(rect){
+ if (rect.w < 0) {
+ rect.x += rect.w
+ rect.w = abs(rect.w)
+ }
+ if (rect.h < 0) {
+ rect.y += rect.h
+ rect.h = abs(rect.h)
+ }
+ return rect
+ }
+ function solve_rects(){
+ }
+ function draw_ruler(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ var len = 5
+ for (var i = 0.5; i < w; i += 10) {
+ line(i, 0, i, len)
+ line(0, i, len, i)
+ }
+ }
+
+ function line (x,y,a,b){
+ ctx.beginPath()
+ ctx.moveTo(x,y)
+ ctx.lineTo(a,b)
+ ctx.stroke()
+ }
+
+ function draw_rects(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ // ctx.setLineDash([randint(5)+2,randint(2)+2]);
+ ctx.setLineDash([1,1]);
+
+ for (var i = 0; i < rects.length; i++) {
+ var rect = rects[i]
+ ctx.fillStyle = "rgba(0,200,220,0.5)"
+ ctx.fillRect(rect.x, rect.y, rect.w, rect.h)
+ ctx.strokeRect(rect.x - 0.5, rect.y - 0.5, rect.w+1, rect.h+1)
+
+// line(rect.x, 0, rect.x, rect.y)
+// line(0, rect.y, rect.x, rect.y)
+
+ }
+ }
+ function draw_mouse(){
+ if (mouse.w == 0 && mouse.h == 0) {
+ ctx.fillStyle = "rgba(255,0,0,0.4)";
+ ctx.beginPath();
+ ctx.arc(mouse.x, mouse.y, 5, 0, 2*Math.PI, false);
+ ctx.fill();
+ }
+ else {
+ ctx.fillStyle = "rgba(255,255,0,0.5)"
+ ctx.fillRect(mouse.x, mouse.y, mouse.w, mouse.h)
+ }
+ }
+
+})()
+
+</script>
+</html>
diff --git a/rectangles-lines.html b/rectangles-lines.html
new file mode 100644
index 0000000..7386046
--- /dev/null
+++ b/rectangles-lines.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="assets/stylesheets/css.css">
+<style type="text/css">
+</style>
+</head>
+<body>
+
+
+</body>
+<script type="text/javascript" src="assets/javascripts/util.js"></script>
+<script type="text/javascript">
+
+(function(){
+
+ var canvas = document.createElement("canvas")
+ var ctx = canvas.getContext("2d")
+ var w = canvas.width = 500
+ var h = canvas.height = 500
+ document.body.appendChild(canvas)
+
+ var rects = []
+ var dragging = false
+ var mouse = {x:0,y:0,w:0,h:0}
+ canvas.addEventListener("mousedown", function(e){
+ dragging = true
+ mouse.x = e.pageX
+ mouse.y = e.pageY
+ mouse.w = mouse.h = 0
+ })
+ canvas.addEventListener("mousemove", function(e){
+ if (dragging) {
+ mouse.w = e.pageX - mouse.x
+ mouse.h = e.pageY - mouse.y
+ }
+ else {
+ mouse.x = e.pageX
+ mouse.y = e.pageY
+ }
+ })
+ document.addEventListener("mouseup", function(e){
+ if (! dragging) return
+ dragging = false
+ rects.push(normalize(mouse))
+ mouse = {x:e.pageX,y:e.pageY,w:0,h:0}
+ })
+
+ function animate(){
+ requestAnimationFrame(animate)
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ solve_rects()
+ draw_ruler()
+ draw_rects()
+ draw_mouse()
+ }
+ animate()
+
+ function normalize(rect){
+ if (rect.w < 0) {
+ rect.x += rect.w
+ rect.w = abs(rect.w)
+ }
+ if (rect.h < 0) {
+ rect.y += rect.h
+ rect.h = abs(rect.h)
+ }
+ return rect
+ }
+ function solve_rects(){
+ }
+ function draw_ruler(){
+ ctx.strokeStyle = "rgba(0,0,0,1.0)"
+ ctx.lineWidth = 1
+ for (var i = 0; i < w; i += 10) {
+ ctx.beginPath()
+ ctx.moveTo(randint(i), randint(i))
+ ctx.lineTo(randint(i), randint(i))
+ ctx.stroke()
+ }
+console.log(i)
+ }
+ function draw_rects(){
+ for (var i = 0; i < rects.length; i++) {
+ var rect = rects[i]
+ ctx.fillStyle = "rgba(0,200,220,0.5)"
+ ctx.fillRect(rect.x, rect.y, rect.w, rect.h)
+ }
+ }
+ function draw_mouse(){
+ if (mouse.w == 0 && mouse.h == 0) {
+ ctx.fillStyle = "rgba(255,0,0,0.4)";
+ ctx.beginPath();
+ ctx.arc(mouse.x, mouse.y, 5, 0, 2*Math.PI, false);
+ ctx.fill();
+ }
+ else {
+ ctx.fillStyle = "rgba(255,255,0,0.5)"
+ ctx.fillRect(mouse.x, mouse.y, mouse.w, mouse.h)
+ }
+ }
+
+})()
+
+</script>
+</html>
diff --git a/rectangles.html b/rectangles.html
index c79b700..086ce27 100644
--- a/rectangles.html
+++ b/rectangles.html
@@ -3,93 +3,244 @@
<head>
<link rel="stylesheet" type="text/css" href="assets/stylesheets/css.css">
<style type="text/css">
+body > div {
+ float: left;
+}
</style>
</head>
<body>
+<div id="map"></div>
+<div id="info">
+ <span id="intersects"></span>
+</div>
</body>
+<script type="text/javascript" src="assets/javascripts/util.js"></script>
<script type="text/javascript">
-(function(){
+function vec2(a,b){
+ this.a = a
+ this.b = b
+}
+vec2.prototype.magnitude = function(){
+ return this.b-this.a
+}
+vec2.prototype.length = function(){
+ return abs(this.b-this.a)
+}
+vec2.prototype.clone = function(){
+ return new vec2(this.a, this.b)
+}
+vec2.prototype.normalize = function(){
+ if (this.b < this.a) {
+ this.a = this.a ^ this.b
+ this.b = this.a ^ this.b
+ this.a = this.a ^ this.b
+ }
+ return this
+}
+vec2.prototype.add = function(n){
+ this.a += n
+ this.b += n
+}
+vec2.prototype.sub = function(n){
+ this.a -= n
+ this.b -= n
+}
+vec2.prototype.mul = function(n){
+ this.a *= n
+ this.b *= n
+}
+vec2.prototype.div = function(n){
+ this.a /= n
+ this.b /= n
+}
+vec2.prototype.contains = function(n){
+ return this.a <= n && n <= this.b
+}
+vec2.prototype.intersects = function(v){
+ return (this.a <= v.a && this.b > v.a) ||
+ (v.a <= this.a && v.b > this.a)
+}
+vec2.prototype.union = function(v){
+ if (this.intersects(v)) {
+ return new vec2( min(this.a,v.a), max(this.b, v.b) )
+ }
+}
+vec2.prototype.intersection = function(v){
+ if (this.intersects(v)) {
+ return new vec2( max(this.a,v.a), min(this.b, v.b) )
+ }
+}
- var canvas = document.createElement("canvas")
- var ctx = canvas.getContext("2d")
- var w = canvas.width = 500
- var h = canvas.height = 500
- document.body.appendChild(canvas)
+function rect (x0,y0,x1,y1){
+ if (x0 instanceof vec2) {
+ this.x = x0
+ this.y = y0
+ }
+ else if (x1 === undefined) {
+ this.x = new vec2(x0,x0)
+ this.y = new vec2(y0,y0)
+ }
+ else {
+ this.x = new vec2(x0,x1)
+ this.y = new vec2(y0,y1)
+ }
+ this.translation = new vec2(0,0)
+}
+rect.prototype.clone = function(){
+ return new rect( this.x.clone(), this.y.clone() )
+}
+rect.prototype.normalize = function(){
+ this.x.normalize().add(this.translation.a)
+ this.y.normalize().add(this.translation.b)
+ this.translation.a = this.translation.b = 0
+ return this
+}
+rect.prototype.contains = function(x,y){
+ return this.x.contains(x) && this.y.contains(y)
+}
+rect.prototype.intersects = function(r){
+ return this.x.intersects(r.x) && this.y.intersects(r.y)
+}
+rect.prototype.width = function(){ return this.x.length() }
+rect.prototype.height = function(){ return this.y.length() }
+rect.prototype.fill = function(){
+ ctx.fillRect(this.x.a + this.translation.a, this.y.a + this.translation.b, this.x.length(), this.y.length())
+}
+rect.prototype.stroke = function(){
+ ctx.beginPath()
+ ctx.moveTo(this.x.a, this.y.a)
+ ctx.lineTo(this.x.b, this.y.b)
+ ctx.stroke()
+}
- var rects = []
- var dragging = false
- var mouse = {x:0,y:0,w:0,h:0}
- canvas.addEventListener("mousedown", function(e){
- dragging = true
- mouse.x = e.pageX
- mouse.y = e.pageY
- mouse.w = mouse.h = 0
- })
- canvas.addEventListener("mousemove", function(e){
- if (dragging) {
- mouse.w = e.pageX - mouse.x
- mouse.h = e.pageY - mouse.y
- }
- else {
- mouse.x = e.pageX
- mouse.y = e.pageY
- }
- })
- document.addEventListener("mouseup", function(e){
- if (! dragging) return
- dragging = false
- rects.push(normalize(mouse))
- mouse = {x:e.pageX,y:e.pageY,w:0,h:0}
- })
-
- function animate(){
- requestAnimationFrame(animate)
- ctx.fillStyle = "#fff"
- ctx.fillRect(0,0,w,h)
-
- solve_rects()
- draw_rects()
- draw_mouse()
+
+
+var canvas = document.createElement("canvas")
+var ctx = canvas.getContext("2d")
+var w = canvas.width = 500
+var h = canvas.height = 500
+document.body.appendChild(canvas)
+
+var rects = [
+ new rect(100,100, 300,300),
+ new rect(200,200, 400,400),
+]
+
+var creating = false, dragging = false
+var mouse = new rect(0,0,0,0)
+canvas.addEventListener("mousedown", function(e){
+ var x = e.pageX, y = e.pageY
+ mouse = new rect (x,y)
+
+ var intersects = rects.filter(function(r){ return r.contains(x,y) })
+ console.log(intersects)
+ if (intersects.length){
+ dragging = intersects[0]
+ }
+ else {
+ creating = true
}
- animate()
- function normalize(rect){
- if (rect.w < 0) {
- rect.x += rect.w
- rect.w = abs(rect.w)
- }
- if (rect.h < 0) {
- rect.y += rect.h
- rect.h = abs(rect.h)
- }
- return rect
+})
+canvas.addEventListener("mousemove", function(e){
+ mouse.x.b = e.pageX
+ mouse.y.b = e.pageY
+ if (dragging) {
+ dragging.translation.a = mouse.x.magnitude()
+ dragging.translation.b = mouse.y.magnitude()
+ }
+ else if (creating) {
+ mouse.x.b = e.pageX
+ mouse.y.b = e.pageY
}
- function solve_rects(){
+ else {
+ mouse.x.a = mouse.x.b
+ mouse.y.a = mouse.y.b
}
- function draw_rects(){
- for (var i = 0; i < rects.length; i++) {
- var rect = rects[i]
- ctx.fillStyle = "rgba(0,200,220,0.5)"
- ctx.fillRect(rect.x, rect.y, rect.w, rect.h)
+})
+document.addEventListener("mouseup", function(e){
+ if (creating) {
+ if (mouse.height() != 0 && mouse.width() != 0) {
+ rects.push(mouse.normalize())
}
}
- function draw_mouse(){
- if (mouse.w == 0 && mouse.h == 0) {
- ctx.fillStyle = "rgba(255,0,0,0.4)";
- ctx.beginPath();
- ctx.arc(mouse.x, mouse.y, 5, 0, 2*Math.PI, false);
- ctx.fill();
+ if (dragging) {
+ dragging.normalize()
+ }
+ mouse = new rect(e.pageX, e.pageY)
+ creating = dragging = false
+})
+
+function animate(){
+ requestAnimationFrame(animate)
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ solve_rects()
+ draw_ruler()
+ draw_rects()
+ draw_mouse()
+}
+animate()
+
+function draw_ruler(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ var len = 5
+ for (var i = 0.5; i < w; i += 10) {
+ line(i, 0, i, len)
+ line(0, i, len, i)
+ }
+}
+
+function line (x,y,a,b){
+ ctx.beginPath()
+ ctx.moveTo(x,y)
+ ctx.lineTo(a,b)
+ ctx.stroke()
+}
+
+function solve_rects(){
+ var x_intervals = []
+ var y_intervals = []
+ for (var i = 0; i < rects.length; i++) {
+
+ }
+}
+function draw_regions(){
+}
+function draw_rects(){
+ ctx.strokeStyle = "rgba(80,80,80,0.5)"
+ ctx.lineWidth = 1
+ // ctx.setLineDash([randint(5)+2,randint(2)+2]);
+ ctx.setLineDash([1,1]);
+
+ for (var i = 0; i < rects.length; i++) {
+ ctx.fillStyle = "rgba(0,200,220,0.5)"
+ rects[i].fill()
+// line(rect.x, 0, rect.x, rect.y)
+// line(0, rect.y, rect.x, rect.y)
+ }
+}
+function draw_mouse(){
+ ctx.fillStyle = "rgba(255,0,0,0.4)";
+ ctx.beginPath();
+ ctx.arc(mouse.x.b, mouse.y.b, 5, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ if (mouse.width() != 0 && mouse.height() != 0) {
+ if (dragging) {
+ mouse.stroke()
}
else {
ctx.fillStyle = "rgba(255,255,0,0.5)"
- ctx.fillRect(mouse.x, mouse.y, mouse.w, mouse.h)
+ mouse.clone().normalize().fill()
}
}
-
-})()
+}
</script>
</html>