diff --git a/main.js b/main.js
index c869ae3..2b47d9a 100644
--- a/main.js
+++ b/main.js
@@ -56,7 +56,7 @@ app.on('ready', () =>
     is_shown = true;
   })
   // Open the DevTools.
-  win.webContents.openDevTools()
+  // win.webContents.openDevTools()
 })
 
 app.on('window-all-closed', () => 
diff --git a/sources/links/main.css b/sources/links/main.css
index 1637a77..06f2c30 100644
--- a/sources/links/main.css
+++ b/sources/links/main.css
@@ -11,9 +11,9 @@ yu { display:block; }
 #render { z-index:800; position: fixed; }
 #grid { z-index:795;position: fixed; }
 
-
 #ronin { background:#eee; height: 100vh; width:100vw; }
-#commander { position: fixed; bottom:15px; left:5px; width:100vw; height:20px; line-height: 20px;  -webkit-user-select: none;-webkit-app-region: drag; z-index:900;}
-#commander input { background: transparent;width: calc(100vw - 30px);display: block;line-height: 20px;font-size: 11px;color: black; margin-left:20px; }
-#hint { position: fixed; bottom:15px; left:5px; width:100vw; height:20px; line-height: 20px; font-size: 11px;color: #999; margin-left:20px; }
+#commander, #hint { position: fixed;bottom: 0px;left: 0px;width: 100vw;line-height: 40px;-webkit-user-select: none;-webkit-app-region: drag;z-index: 900;height: 40px; font-size:11px;}
+#commander { z-index: 9000 }
+#commander input { background: transparent;width: calc(100vw - 30px);display: block;line-height: 40px;font-size: 11px;color: white; margin-left:20px; }
+#hint { background:black; color:#666; padding-left:20px;}
 #hint b { font-family: 'input_mono_regular' }
\ No newline at end of file
diff --git a/sources/scripts/core/cursor.js b/sources/scripts/core/cursor.js
index f27028f..8f05f90 100644
--- a/sources/scripts/core/cursor.js
+++ b/sources/scripts/core/cursor.js
@@ -59,6 +59,9 @@ function Cursor(rune)
 
     if(ronin.commander.active_module()){
 
+    }
+    else if(e.shiftKey && e.altKey){
+      ronin.brush.pick(ronin.cursor.line);
     }
     else if(e.altKey){
       ronin.brush.erase(ronin.cursor.line);
diff --git a/sources/scripts/core/keyboard.js b/sources/scripts/core/keyboard.js
index 482338b..b03c0b1 100644
--- a/sources/scripts/core/keyboard.js
+++ b/sources/scripts/core/keyboard.js
@@ -43,7 +43,7 @@ function Keyboard()
 
     if(e.key == "o" && (e.ctrlKey || e.metaKey)){
       e.preventDefault();
-      ronin.io.load();
+      ronin.io.methods.import();
     }
 
     if(e.key == "s" && (e.ctrlKey || e.metaKey)){
diff --git a/sources/scripts/core/layer.js b/sources/scripts/core/layer.js
index c467934..678e2ab 100644
--- a/sources/scripts/core/layer.js
+++ b/sources/scripts/core/layer.js
@@ -33,9 +33,9 @@ function Layer()
     return this.context().getImageData(x, y, width * 2, height * 2);
   }
 
-  this.to_base64 = function()
+  this.to_base64 = function(format = 'png', quality = 0.9)
   {
-    return this.el.toDataURL('image/png');
+    return format == 'png' ? this.el.toDataURL('image/png') : this.el.toDataURL('image/jpeg',0.9);
   }
 
   this.to_img = function()
@@ -49,4 +49,20 @@ function Layer()
   {
     this.context().clearRect(0, 0, this.el.width * 2, this.el.height * 2);
   }
+
+  this.fill = function(color = "red")
+  {
+    var ctx = this.context();
+
+    ctx.beginPath();
+    ctx.globalCompositeOperation="source-over";
+    ctx.moveTo(0,0);
+    ctx.lineTo(this.el.width,0);
+    ctx.lineTo(this.el.width,this.el.height);
+    ctx.lineTo(0,this.el.height);
+    ctx.lineTo(0,0);
+    ctx.fillStyle = color;
+    ctx.fill();
+    ctx.closePath();
+  }
 }
\ No newline at end of file
diff --git a/sources/scripts/core/module.js b/sources/scripts/core/module.js
index c175fb8..e088c4b 100644
--- a/sources/scripts/core/module.js
+++ b/sources/scripts/core/module.js
@@ -11,6 +11,11 @@ function Module(name,docs = "Missing documentation.")
   {
     var html = "";
 
+    for(id in this.methods){
+      var v = this.methods[id];
+      html += id+": ";
+    }
+
     for(setting_id in this.settings){
       var setting_value = this.settings[setting_id];
       html += setting_id+"="+setting_value+" ";
diff --git a/sources/scripts/modules/brush.js b/sources/scripts/modules/brush.js
index 05e4f48..c16115e 100644
--- a/sources/scripts/modules/brush.js
+++ b/sources/scripts/modules/brush.js
@@ -97,6 +97,11 @@ function Brush()
     ctx.closePath();
   }
 
+  this.pick = function(line)
+  {
+    var pixel = ronin.render.context().getImageData(line.to.x*2, line.to.y*2, 1, 1).data;
+  }
+
   this.mod_size = function(mod)
   {
     this.settings.size = clamp(this.settings.size+mod,1,100);
diff --git a/sources/scripts/modules/frame.js b/sources/scripts/modules/frame.js
index 2f52d84..8c68efe 100644
--- a/sources/scripts/modules/frame.js
+++ b/sources/scripts/modules/frame.js
@@ -41,6 +41,16 @@ function Frame()
     ronin.render.context().putImageData(data, 0, 0);
   }
 
+  this.methods.clear = function(q)
+  {
+    ronin.render.fill("blue");
+  }
+
+  this.methods.fill = function(q)
+  {
+    ronin.render.fill(q);
+  }
+
   this.resize_to = function(size)
   {
     ronin.frame.settings.width = size.width;
diff --git a/sources/scripts/modules/io.js b/sources/scripts/modules/io.js
index 543a484..d3be174 100644
--- a/sources/scripts/modules/io.js
+++ b/sources/scripts/modules/io.js
@@ -2,7 +2,7 @@ function IO()
 {
   Module.call(this,"io","File import/export tools.");
 
-  this.settings = {anchor:{x:0,y:0,width:0,height:0}};
+  this.settings = {anchor:{x:0,y:0,width:200,height:200}};
 
   this.methods = {};
 
@@ -19,30 +19,63 @@ function IO()
       img.src = filepath[0];
 
       img.onload = function() {
-        ronin.io.draw_image(img,ronin.commander.query());
+        ronin.io.draw_image(ronin.render.context(),img,ronin.commander.query());
       }
     });
   }
 
+  this.image = null;
+
   this.methods.load = function(q)
   {
-    // TODO
+    var filepath = dialog.showOpenDialog({properties: ['openFile']});
+
+    if(!filepath){ console.log("Nothing to load"); return; }
+
+    fs.readFile(filepath[0], 'utf-8', (err, data) => {
+      if(err){ alert("An error ocurred reading the file :" + err.message); return; }
+      
+      var img = new Image();
+      img.src = filepath[0];
+
+      img.onload = function() {
+        ronin.io.image = img;
+        ronin.commander.inject("io draw:20,20|100x100");
+      }
+    });
+  }
+
+  this.methods.draw = function(q)
+  {
+    ronin.io.draw_image(ronin.render.context(),ronin.io.image,ronin.commander.query().methods.draw);
+    ronin.io.image = null;
+    ronin.preview.clear();
   }
   
   this.methods.save = function(q)
   {
     // TODO
+    ronin.io.render();
+  }
+
+  this.preview = function(q)
+  {
+    ronin.preview.clear();
+
+    if(ronin.commander.query().methods.draw && this.image){
+      this.draw_image(ronin.preview.context(),this.image,ronin.commander.query().methods.draw);  
+    }
   }
 
   this.render = function()
   {
     var fs = require('fs');
-    var data = ronin.render.to_base64().replace(/^data:image\/\w+;base64,/, "");
+    var data = ronin.render.to_base64('jpg').replace(/^data:image\/\w+;base64,/, "");
     var buf = new Buffer(data, 'base64');
 
     dialog.showSaveDialog((fileName) => {
       if (fileName === undefined){ return; }
-      fs.writeFile(fileName+'.png', buf);
+      fs.writeFile(fileName+'.jpg', buf);
     }); 
   }
 
@@ -79,24 +112,31 @@ function IO()
     var width = parseInt(img.naturalWidth * 0.5);
     var height = parseInt(img.naturalHeight * 0.5);
 
-    if(height > 900){
-      width *= 0.5;
-      height *= 0.5;
-    }
+    // if(height > 700){
+    //   width *= 0.5;
+    //   height *= 0.5;
+    // }
+    // if(height > 1400){
+    //   width *= 0.25;
+    //   height *= 0.25;
+    // }
+
+    ronin.frame.methods.resize({width:parseInt(width),height:parseInt(height)})
 
     img.onload = function() {
       ronin.render.context().drawImage(img, 0,0,width * 2,height * 2);
     }
   }
 
-  this.draw_image = function(img,params)
+  this.draw_image = function(ctx = ronin.preview.context(),img,params)
   {
-    var anchor = ronin.io.settings.anchor;
+    var anchor = params ? params : ronin.io.settings.anchor;
 
+    console.log("draw",ctx)
     var width = parseInt(img.naturalWidth * 0.5);
     var height = parseInt(img.naturalHeight * 0.5);
     var scale = (anchor.width/width) * 2;
 
-    ronin.render.context().drawImage(img, anchor.x * 2,anchor.y * 2,width * scale,height * scale);    
+    ctx.drawImage(img, anchor.x * 2,anchor.y * 2,width * scale,height * scale);    
   }
 }
\ No newline at end of file
diff --git a/sources/scripts/modules/path.js b/sources/scripts/modules/path.js
index cda8de7..3bb844e 100644
--- a/sources/scripts/modules/path.js
+++ b/sources/scripts/modules/path.js
@@ -20,9 +20,20 @@ function Path()
     ctx.closePath();
   }
 
-  this.methods.fill = function()
+  this.methods.fill = function(q)
   {
-    
+    ronin.preview.clear();
+
+    var path = ronin.path.create_path(q);
+
+    var ctx = ronin.render.context();
+
+    ctx.beginPath();
+    ctx.lineCap = "butt";
+    ctx.lineWidth = 30;
+    ctx.fillStyle = "black";
+    ctx.fill(new Path2D(path));
+    ctx.closePath();
   }
 
   this.preview = function(q)
diff --git a/sources/scripts/ronin.js b/sources/scripts/ronin.js
index a6acde0..4608c2b 100644
--- a/sources/scripts/ronin.js
+++ b/sources/scripts/ronin.js
@@ -79,6 +79,6 @@ function Ronin()
     // this.commander.input_el.value = "path stroke:$+";
 
     // this.commander.input_el.value = "magnet lock:";
-    this.commander.inject("line tween:$&$&$>>$&$&$ step->thickness");
+    // this.commander.inject("line tween:$&$&$>>$&$&$ step->thickness");
   }
 }
\ No newline at end of file