AndrewHaxalot

Sketchpad

Apr 30th, 2014
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 205.13 KB | None | 0 0
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" manifest="sketchpad.appcache">
  3. <head>
  4.  <title>Sketchpad - Online Paint/Drawing application</title>
  5.  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6.  <meta name="description" content="Sketchpad is an online drawing application -- written in &lt;canvas&gt;." />
  7.  <meta name="keywords" content="" />
  8.  <link rel="shortcut icon" href="http://mudcu.be/media/gui/favicon.ico" type="image/x-icon" />
  9.  <link rel="icon" href="http://mudcu.be/sketchpad/media/gui/favicon.png" type="image/x-icon" />
  10.  <link rel="chrome-application-definition" href="http://mudcu.be/sketchpad/sketchpad.json" />
  11.  <link rel="chrome-webstore-item"
  12.    href="https://chrome.google.com/webstore/detail/lkllajgbhondgjjnhmmgbjndmogapinp" />
  13.  <link href="http://mudcu.be/sketchpad/inc/Sketchpad.css" rel="stylesheet" type="text/css" />
  14. <!--[if lt IE 9]>
  15. <OBJECT ID="canvasFactory"  CLASSID="clsid:785740C4-DD04-4B91-8AD7-44CC9FFB4984"></OBJECT>
  16. <style>
  17. canvas {
  18.     behavior: url(#canvasFactory);
  19.     width: 300px; height: 150px; display: block;
  20.     margin: 0; border: 0; background: transparent!important;
  21. }
  22. </style>
  23. <canvas id="CanvasRenderingContext2D" style="display: none" />
  24. <script>
  25. // CanvasRenderingContext2D.prototype = CanvasRenderingContext2D.getContext('2d').prototype;
  26. if(0) document._createElement = document.createElement;
  27. if(0) document.createElement = function(tagName) {
  28.  var tag = document._createElement(tagName);
  29.  if(tagName.toUpperCase() == 'CANVAS') tag.addBehavior("#canvasFactory");
  30.  return tag;
  31. };
  32. </script>
  33. <![endif]-->
  34. <script type="text/javascript">
  35.   marqueeID = false;
  36.   mixin = function(o) { // dojo.mixin
  37.       var len = arguments.length;
  38.       for(var i = 1; i < len; i++)
  39.           for(var j in arguments[i])
  40.               o[j] = arguments[i][j];
  41.       return o;
  42.  };
  43.  var dtx2D = document.createElement("canvas");
  44.  var ctx2D; try { ctx2D = dtx2D.getContext('2d'); } catch(e) {};
  45.  var data2pattern = function(obj, data) {
  46.       // if(dtx2D.parentNode === null) document.body.appendChild(dtx2D);
  47.       if(ctx2D == null) ctx2D = dtx2D.getContext('2d');
  48.       function createPattern(src, id) {
  49.           var image = new Image();
  50.           image.onload = function() {
  51.               obj[id] = ctx2D.createPattern(image, "repeat");
  52.           };
  53.           image.src = src;
  54.       };
  55.       for(var key in data) {
  56.           createPattern(data[key], key);
  57.       }
  58.  };
  59. </script>
  60.  <script type="text/javascript">/* GUI */
  61. gui = {
  62.     // Options
  63.     'options': function () {
  64.         var r = [],
  65.         fu = N.format;
  66.         cF = {
  67.             'inner_radius_spirograph': {
  68.                 type: 'X',
  69.                 val: [1, 100, 10]
  70.             },
  71.             'outer_radius_spirograph': {
  72.                 type: 'X',
  73.                 val: [1, 100, 10]
  74.             },
  75.             'diameter_spirograph': {
  76.                 type: 'X',
  77.                 val: [1, 500, 10]
  78.             },
  79.             'speed_spirograph': {
  80.                 type: 'X',
  81.                 val: [2, 250, 10]
  82.             },
  83.             'resolution_spirograph': {
  84.                 type: 'X',
  85.                 val: [1, 1000, 10]
  86.             },
  87.             'stroke_text': {
  88.                 type: 'X',
  89.                 val: [0, 20, 2]
  90.             },
  91.             'fontSize': {
  92.                 type: 'X',
  93.                 val: [16, 256, 64]
  94.             },
  95.             'kerning': {
  96.                 type: 'X',
  97.                 val: [0, 2, 1, 'float']
  98.             },
  99.             'diameter_pencil': {
  100.                 type: 'X',
  101.                 val: [1, 15, 10]
  102.             },
  103.             'opacity_fill': {
  104.                 type: 'X',
  105.                 val: [1, 100, 100],
  106.                 fu: infc.opacity
  107.             },
  108.             'lineOpacity': {
  109.                 type: 'X',
  110.                 val: [2, 100, 1]
  111.             },
  112.             'sides_shape': {
  113.                 type: 'X',
  114.                 val: [2, 100, 1]
  115.             },
  116.             'slope_shape': {
  117.                 type: 'X',
  118.                 val: [0.2, 10, 1, 'float']
  119.             },
  120.             'sides_marquee': {
  121.                 type: 'X',
  122.                 val: [2, 100, 1]
  123.             },
  124.             'slope_marquee': {
  125.                 type: 'X',
  126.                 val: [0.2, 10, 1, 'float']
  127.             },
  128.             'stampSize': {
  129.                 type: 'X',
  130.                 val: [1, 200, 100]
  131.             },
  132.             'leading': {
  133.                 type: 'X',
  134.                 val: [0, 2, 1, 'float']
  135.             },
  136.             'rand': {
  137.                 type: 'X',
  138.                 val: {
  139.                     '_min': [0, 100, 50],
  140.                     '_max': [0, 100, 50]
  141.                 }
  142.             },
  143.             'fill': {
  144.                 type: 'menu',
  145.                 val: ['Color', 'Gradient', 'Pattern']
  146.             },
  147.             'marquee': {
  148.                 type: 'menu',
  149.                 val: ['Ellipses', 'Polygon', 'Star', 'Burst', 'Gear']
  150.             },
  151.             'spirograph': {
  152.                 type: 'menu',
  153.                 val: ['Hypotrochoid', 'Epitrochoid']
  154.             },
  155.             'shape': {
  156.                 type: 'menu',
  157.                 val: ['Ellipses', 'Polygon', 'Star', 'Burst', 'Gear']
  158.             },
  159.             'crop': {
  160.                 type: 'menu',
  161.                 val: ['Display (' + fu(screen.width) + 'x' + fu(screen.height) + ')', 'Original (' + fu(canvas.W) + 'x' + fu(canvas.H) + ')', '2x3', '3x5', '4x3 (DVD)', '4x3 (Book)', '4x6 (Postcard)', '5x7 (L, 2L)', '8x10', '16x9 (HD)', '16x20', '20x30 (Poster)', 'Square']
  162.             },
  163.             'draw': {
  164.                 type: 'menu',
  165.                 val: ['Pencil', 'Brush', 'Calligraphy']
  166.             },
  167.             'lineClose': {
  168.                 type: 'check',
  169.                 val: ["lineClose", 'true', 'false']
  170.             },
  171.             'constrain': {
  172.                 type: 'check',
  173.                 val: ["constrain", 'true', 'false']
  174.             },
  175.             'preview': {
  176.                 type: 'check',
  177.                 val: ["preview", 'true', 'false']
  178.             },
  179.             'marqType': {
  180.                 type: 'radio',
  181.                 val: ["marquee", 'lasso', 'ellipses', 'rectangle', 'star', 'burst', 'gear']
  182.             },
  183.             'aspect': {
  184.                 type: 'radio',
  185.                 val: ["aspect", 'landscape', 'portrait']
  186.             },
  187.             'lineCap': {
  188.                 type: 'radio',
  189.                 val: ["lineCap", 'butt', 'round', 'square']
  190.             },
  191.             'corner': {
  192.                 type: 'radio',
  193.                 val: ["lineJoin", 'round', 'miter', 'bevel']
  194.             }
  195.         };
  196.         r = ["marquee", "text", "line", "ellipses", "polygon", "star", "burst", "gear", "brush", "calligraphy", "pencil", "stamp", "fill", "eraser"];
  197.         for (var i in r) {
  198.             cF["movement_" + r[i]] = {
  199.                 type: "radio",
  200.                 val: ["movement_" + r[i], "anchored", "freedraw", "active"]
  201.             };
  202.         }
  203.         function z(r, v) {
  204.             for (var i in r) {
  205.                 cF[v + "_" + r[i]] = {
  206.                     type: "X",
  207.                     val: [1, 100, 100]
  208.                 };
  209.             }
  210.         };
  211.         z(["ellipses", "polygon", "star", "burst", "gear", "line"], "stroke");
  212.         z(["brush", "calligraphy", "eraser", "pencil", "stamp"], "opacity");
  213.         z(["brush", "calligraphy", "eraser"], "diameter");
  214.         z(["brush", "calligraphy", "eraser", "stamp"], "flow");
  215.         z(["brush", "eraser"], "hardness");
  216.         var j = 0,
  217.         r = [];
  218.         for (var i in stamp.r) {
  219.             r[j++] = i;
  220.         }
  221.         cF.stamp = {
  222.             type: "menu",
  223.             val: r
  224.         };
  225.         if (!gui.menu.cur) {
  226.             if (!vars.crop) {
  227.                 vars.crop = "Original (" + fu(canvas.W) + "x" + fu(canvas.H) + ")";
  228.             }
  229.             gui.menu.cur = {};
  230.             gui.menu.key = {};
  231.             gui.menu.key.stamp = vars.stamp;
  232.             gui.menu.key.font = vars.font;
  233.             gui.menu.key.draw = vars.draw;
  234.             gui.menu.key.shape = vars.shape;
  235.             gui.menu.key.marquee = vars.marquee;
  236.             gui.menu.key.crop = vars.crop;
  237.             gui.menu.key.fill = vars.fill;
  238.             gui.menu.key.spirograph = vars.spirograph;
  239.             gui.menu.key['PT*'] = vars['PT*'];
  240.             gui.menu.key['GD*'] = vars['GD*'];
  241.             gui.menu.key['CO*'] = vars['CO*'];
  242.             for (var i in gui.menu.key) {
  243.                 gui.menu.cur[i] = String(gui.menu.key[i]);
  244.             }
  245.             gui.menu.klean("crop", vars.crop);
  246.         }
  247.     },
  248.     //* Check Box
  249.     'check': {
  250.         'build': function (v, c, r) {
  251.             return ('<div id="' + c + '_check" class="check">' + ' <span>' + v + '</span><br>' + ' <div onclick="gui.check.click(this,\'' + r[0] + '\')"' + (vars[r[0]] == 'true' ? 'class="cur"' : '') + '>' + vars[r[0]] + '</div>' + '</div>');
  252.         },
  253.         'click': function (o, v) {
  254.             function z(a, b, c, d) {
  255.                 vars[v] = c;
  256.                 o.innerHTML = c;
  257.                 o.className = d;
  258.             }
  259.             if (o.className == 'cur') z('block', 'none', 'false', '');
  260.             else z('none', 'block', 'true', 'cur');
  261.             crop.click();
  262.         }
  263.     },
  264.     //* Radio Button
  265.     'radio': {
  266.         'build': function (v, c, r) {
  267.             var b = '';
  268.             for (var i = 1; i < r.length; i++) b += '<div class="' + (((vars[r[0]] == r[i] && vars.type != 'crop') || (vars[r[0]] == r[i] && vars.type == 'crop' && !crop.force(vars.crop))) ? ' cur' : '') + '" onclick="gui.radio.click(this,\'' + r[0] + '\')">' + r[i] + '</div><br>';
  269.             return ('<div' + ((crop.force(vars.crop) && vars.type == 'crop') ? ' style="opacity: 0.6"' : '') + ' class="radio" id="' + c + '_radio"><span>' + v + '</span><br>' + b + '</div>');
  270.         },
  271.         'click': function (o, v) {
  272.             if (!$C("cur", o.parentNode)[0]) {
  273.                 return;
  274.             }
  275.             var i = o.innerHTML,
  276.             cur = vars[v];
  277.             $C("cur", o.parentNode)[0].className = "";
  278.             o.className = "cur";
  279.             vars[v] = i;
  280.             if (v == "marquee") {
  281.                 var b = $C("Marquee_" + cur, "tools")[0];
  282.                 if (i == "lasso" || cur == "lasso") {
  283.                     marquee.reset("", 1);
  284.                 }
  285.                 b.src = "media/gui/Marquee_" + i + "_2.png";
  286.                 b.className = "Marquee_" + i;
  287.                 gui_tools.prev = b.className;
  288.                 vars.tool = "Marquee_" + i;
  289.             }
  290.             vars.cache(1);
  291.             crop.click();
  292.         }
  293.     },
  294.     //* Select Menu
  295.     'menu': {
  296.         'build': function (c, r) {
  297.             var z = '',
  298.             length = 0,
  299.             o = gui.menu;
  300.             if (typeof(r) == 'object' && !r.length) for (var i in r) {
  301.                 length++;
  302.             } else length = r.length;
  303.             for (var i in r) {
  304.                 var style = (i == 0) ? 'style="border-top: none;"' : ((parseInt(i) + 1) == length ? 'style="border-bottom: none;"' : '');
  305.                 if (r[i].toLowerCase() == o.cur[c].toLowerCase() || (!o.cur[c] && i == 0)) {
  306.                     className = 'class="sel"';
  307.                     var position = 'style="top:-' + (o.cellHeight * i) + 'px"';
  308.                 } else {
  309.                     className = '';
  310.                 }
  311.                 z += '<li onmousedown="gui.menu.toggle(this)" onmouseup="gui.menu.select(this)" onmouseover="gui.menu.okClose(this.parentNode.parentNode)" ' + style + ' ' + className + '>' + r[i] + '</li>';
  312.             }
  313.             return ('<div class="menuWrap" id="' + c + '_opt">' + ' <div class="t"><div class="l"></div><div class="r"></div><div class="c"></div></div>' + ' <div class="menuBox">' + '  <ul ' + position + '>' + '   <li class="top"><div class="l"></div><div class="r"></div><div class="c"></div></li>' + z + '   <li class="bottom"><div class="l"></div><div class="c"></div><div class="r"></div></li>' + '  </ul>' + ' </div>' + ' <div class="b"><div class="l"></div><div class="r"></div><div class="c"></div></div>' + '</div>');
  314.         },
  315.         'fu': {
  316.             'z': function (c, o) {
  317.                 gui.menu.klean(c, o.innerHTML);
  318.             },
  319.             'crop': function (c, o) {
  320.                 gui.menu.fu.z(c, o);
  321.                 $T('div', 'constrain_check')[0].innerHTML = 'true';
  322.                 $T('div', 'constrain_check')[0].className = 'cur';
  323.                 vars.constrain = 'true';
  324.                 crop.click();
  325.                 vars.cache(1);
  326.             },
  327.             'fill': function (c, o) {
  328.                 gui.menu.fu.z(c, o);
  329.                 gui_palette.click("fill");
  330.                 gui_swatch.cur({
  331.                     "Gradient": "GD",
  332.                     "Color": "CO",
  333.                     "Pattern": "PT"
  334.                 }[o.innerHTML]);
  335.             },
  336.             'stamp': function (c, o) {
  337.                 gui.menu.fu.z(c, o);
  338.                 stamp.fileNumber = 1;
  339.                 stop = 1;
  340.                 var o = gui.Y;
  341.                 o.cur.stamp = 1;
  342.                 o.prev.stamp = null;
  343.                 o.id = 'stamp';
  344.                 o.stamp();
  345.                 o.kontrol_update('stamp');
  346.                 vars.cache(1);
  347.             },
  348.             'draw': function (c, o) {
  349.                 gui.menu.fu.z(c, o);
  350.                 var b = o.innerHTML;
  351.                 vars.draw = b;
  352.                 $C(vars.draw, 'tools')[0].title = b;
  353.                 gui_tools.imageCurrent(b);
  354.             },
  355.             'spirograph': function (c, o) {
  356.                 gui.menu.fu.z(c, o);
  357.                 var b = o.innerHTML;
  358.                 vars.type_spirograph = b;
  359.             },
  360.             'sw': function (c, o, v1, v2) {
  361.                 gui.menu.fu.z(c, o);
  362.                 var i = vars.id + v1;
  363.                 vars[v1] = Q[v1][o.innerHTML];
  364.                 gui_swatch.n[i] = Math.min(gui_swatch.n[i], vars[v1].length);
  365.                 vars[i] = vars[v1][gui_swatch.n[i] - 1];
  366.                 var o = gui.Y;
  367.                 gui_swatch.cur(v1);
  368.                 o.prev[v1] = null;
  369.                 o.sw(1);
  370.                 o.kontrol_update(v1);
  371.                 vars.cache(1);
  372.                 $('author_'+gui_swatch.id).innerHTML = gui_swatch.author();
  373.             },
  374.             'CO*': function (c, o) {
  375.                 gui.menu.fu.sw(c, o, 'CO', 'solid');
  376.             },
  377.             'GD*': function (c, o) {
  378.                 gui.menu.fu.sw(c, o, 'GD', 'gradient');
  379.             },
  380.             'PT*': function (c, o) {
  381.                 gui.menu.fu.z(c, o);
  382.                 vars.PT = Q.PT[o.innerHTML];
  383.                 var i = vars.id + 'PT',
  384.                 n = vars.PT.length - (gui_swatch.n[i] = Math.min(gui_swatch.n[i], vars.PT.length));
  385.                 vars.PT[n + 1] = new Image();
  386.                 vars.PT[n + 1].src = gui_pattern.dir + vars['PT*'] + '/' + n + '-live.jpg';
  387.                 vars[vars.id + 'PT'] = vars.PT[n + 1];
  388.                 vars[vars.id + 'PT'].onload = function () {
  389.                     vars[vars.id + 'PT'].opacity = 1;
  390.                     var o = gui.Y;
  391.                     gui_swatch.cur('PT');
  392.                     o.prev.PT = null;
  393.                     o.sw(1);
  394.                     o.kontrol_update('PT');
  395.                     vars.cache(1);
  396.                 }
  397.                 $('author_'+gui_swatch.id).innerHTML = gui_swatch.author();
  398.             },
  399.             'shape': function (c, o) {
  400.                 gui.menu.fu.z(c, o);
  401.                 gui_tools.imageCurrent(vars.tool = 'Shape_' + (vars.shape = vars.shape.toLowerCase()));
  402.             },
  403.             'marquee': function (c, o) {
  404.                 gui.menu.fu.z(c, o);
  405.                 gui_tools.imageCurrent(vars.tool = 'Marquee_' + (vars.marquee = vars.marquee.toLowerCase()));
  406.             }
  407.         },
  408.         'klean': function (v, o) {
  409.             gui.menu.cur[v] = o;
  410.             vars[v] = o;
  411.             var a = o,
  412.             b = a.substr(0, a.indexOf('(') != -1 ? a.indexOf('(') - 1 : a.length);
  413.             gui.menu.key[v] = b;
  414.         },
  415.         // Data
  416.         'cellHeight': 17,
  417.         'parent': {},
  418.         'prev': {},
  419.         'toggle': function (n) {
  420.             var p = n.parentNode.parentNode,
  421.             o = gui.menu;
  422.             if (p.opened != true) {
  423.                 if (o.parent.opened == true) o.close();
  424.                 stop = 0;
  425.                 o.prev = n;
  426.                 o.parent = p;
  427.                 var c = p.parentNode.id.replace('_opt', '');
  428.                 win.id = p.parentNode.parentNode.parentNode.parentNode.parentNode;
  429.                 if (c == 'CO*' || c == 'GD*' || c == 'PT*') {
  430.                     win.id = win.id.parentNode.parentNode;
  431.                 }
  432.                 zindex(win.id);
  433.                 var offset = parseInt(n.parentNode.style.top);
  434.                 if (!isNaN(offset)) {
  435.                     offset = (offset / o.cellHeight) * (o.cellHeight + 2);
  436.                     var d = -1 * offset - abPos(p).Y + 3;
  437.                     if (d > 0) {
  438.                         n.parentNode.style.top = (offset + d) + 'px';
  439.                     } else n.parentNode.style.top = (offset - 3) + 'px';
  440.                 }
  441.                 p.style.overflow = 'visible';
  442.                 n.parentNode.className += 'opened';
  443.                 window.setTimeout(function () {
  444.                     p.opened = true;
  445.                 },
  446.                 100);
  447.                 window.onmousedown = o.close;
  448.             } else o.doSelect(n, p);
  449.         },
  450.         'doSelect': function (n, s) {
  451.             var p = n.parentNode.parentNode;
  452.             stop = 1;
  453.             var o = $T('li', p);
  454.             p.style.overflow = 'hidden';
  455.             for (var x = 0; x < o.length; x++) {
  456.                 o[x].className = trim(o[x].className.replace('sel', ''));
  457.                 if (o[x] == n) {
  458.                     n.className += ' sel';
  459.                     n.parentNode.style.top = -((x - 1) * gui.menu.cellHeight) + 'px';
  460.                 }
  461.             }
  462.             n.parentNode.className = trim(n.parentNode.className.replace('opened', ''));
  463.             p.opened = p.okClose = false;
  464.             window.onmousedown = null;
  465.             var c = p.parentNode.id.replace('_opt', '');
  466.             gui.menu.fu[c](c, n, s);
  467.         },
  468.         'close': function () {
  469.             if (gui.menu.parent.opened == true) gui.menu.doSelect(gui.menu.prev)
  470.         },
  471.         'select': function (n, s) {
  472.             var p = n.parentNode.parentNode;
  473.             if (p.okClose == true) gui.menu.doSelect(n, s);
  474.         },
  475.         'okClose': function (p) {
  476.             if (p.opened) p.okClose = true;
  477.         }
  478.     },
  479.    
  480.     //* Y-Scroll
  481.     'Y': {
  482.         'id': 'stamp',
  483.         'cur': {
  484.             'stamp': 1,
  485.             'hi': 1,
  486.             'CO': 1,
  487.             'GD': 1,
  488.             'PT': 1
  489.         },
  490.         'prev': {
  491.             'stamp': 10,
  492.             'hi': 10,
  493.             'CO': 10,
  494.             'GD': 10,
  495.             'PT': 10
  496.         },
  497.         'fu': {
  498.             'stamp': 'gui.Y.stamp',
  499.             'hi': 'gui.Y.hi',
  500.             'CO': 'gui.Y.sw',
  501.             'GD': 'gui.Y.sw',
  502.             'PT': 'gui.Y.sw'
  503.         },
  504.         'r': {
  505.             'stamp': {
  506.                 'Y': 110,
  507.                 'n': function () {
  508.                     return (stamp.r[vars.stamp]);
  509.                 },
  510.                 'display': 12,
  511.                 'col': 4,
  512.                 'row': 3
  513.             },
  514.             'hi': {
  515.                 'Y': 135,
  516.                 'n': function () {
  517.                     var r = canvas.history_r;
  518.                     return (1 + r.z - r.a);
  519.                 },
  520.                 'display': 7,
  521.                 'col': 1,
  522.                 'row': 7
  523.             },
  524.             'CO': {
  525.                 'Y': 106,
  526.                 'n': function () {
  527.                     return (vars['CO'].length);
  528.                 },
  529.                 'display': 28,
  530.                 'col': 7,
  531.                 'row': 4
  532.             },
  533.             'GD': {
  534.                 'Y': 106,
  535.                 'n': function () {
  536.                     return (vars['GD'].length);
  537.                 },
  538.                 'display': 28,
  539.                 'col': 7,
  540.                 'row': 4
  541.             },
  542.             'PT': {
  543.                 'Y': 106,
  544.                 'n': function () {
  545.                     return (vars['PT'].length);
  546.                 },
  547.                 'display': 28,
  548.                 'col': 7,
  549.                 'row': 4
  550.             }
  551.         },
  552.        
  553.         // WHEEL
  554.         'wheel': function (event) {
  555.             var o = gui.Y,
  556.             r = o.r[o.id];
  557.             if (event.wheelDelta) {
  558.                 var v = event.wheelDelta / 120;
  559.                 if (window.opera) {
  560.                     v = -v;
  561.                 }
  562.                 // OPERA + IE
  563.             } else if (event.detail) {
  564.                 var v = -event.detail / 3;
  565.                 // MOZ
  566.             }
  567.             var n = Math.max(2.5, (r.n() / (r.col * r.row)) / r.row * 4),
  568.             v = (v <= 0) ? Math.floor(v + 0.2) : Math.ceil(v + 0.5); //- JUNK
  569.             o.cord(v * n);
  570.             eval(o.fu[o.id] + "()");
  571.         },
  572.         'cord': function (v) {
  573.             var o = gui.Y,
  574.             r = o.r[o.id];
  575.             var Y2 = r.Y - o.height(o.id),
  576.             n = r.n() - r.display,
  577.             cur = o.cur[o.id];
  578.             if (o.id == 'hi') cur -= canvas.history_r.a + 1;
  579.             v = Math.round(Math.max(0, Math.min(n, cur - v)));
  580.             $S(o.id + 'Slide').top = Math.round(1 / n * Y2 * v) + 'px';
  581.             if (o.id == 'hi') v += canvas.history_r.a + 1;
  582.             o.cur[o.id] = v;
  583.         },
  584.        
  585.         // SLIDE
  586.         'kontrol': function (i, n) {
  587.             var o = gui.Y,
  588.             r = o.r[i],
  589.             H = o.height(i);
  590.             return ('<div id="' + i + 'Kontrol" onmousedown="gui.Y.slide_fu(event,\'' + i + '\')" class="slideY" style="top: ' + (!isNaN(n) ? n : 35) + 'px; height: ' + r.Y + 'px; display:' + (r.n() <= r.display ? 'none' : 'block') + '">' + ' <span class="rT"></span><span class="rB" style="top:' + r.Y + 'px;"></span>' + ' <div id="' + i + 'Slide" class="slider" style="position: relative; height:' + o.height(i) + 'px; top:' + o.top(o, r) + 'px;">' + '  <div class="rT"></div><div class="rB" style="top:' + H + 'px"></div>' + ' </div>' + '</div>');
  591.         },
  592.         'kontrol_update': function (v, s) {
  593.             var o = gui.Y,
  594.             r = o.r[v],
  595.             i = $(v + 'Slide');
  596.             var H = o.height(v),
  597.             b = i.style;
  598.             $S(v + 'Kontrol').display = 'none';
  599.             b.height = H + 'px';
  600.             i.childNodes[2].style.top = H + 'px';
  601.             b.top = o.top(o, r) + 'px';
  602.             $S(v + 'Kontrol').display = (r.n() <= r.display) ? 'none' : 'block';
  603.         },
  604.         'slide': function (a, b, m) {
  605.             var o = gui.Y,
  606.             r = o.r[o.id],
  607.             n = r.n() - r.display;
  608.             $S(o.id + 'Slide').top = b.Y + 'px';
  609.             var a = Math.round(Math.max(0, Math.min(n, (b.Y / (r.Y - o.height(o.id))) * n)));
  610.             if (o.id == 'hi') a += canvas.history_r.a + 1;
  611.             o.cur[o.id] = a;
  612.             eval(o.fu[o.id] + "()");
  613.         },
  614.         'slide_fu': function (e, i) {
  615.             var o = gui.Y,
  616.             H = o.height(i);
  617.             o.id = i;
  618.             core.fu(i + 'Slide', e, {
  619.                 fu: core.Y,
  620.                 oX: 0,
  621.                 oY: -(H / 2),
  622.                 Y1: 0,
  623.                 Y2: o.r[i].Y - H
  624.             },
  625.             o.slide);
  626.         },
  627.         'height': function (i) {
  628.             var o = gui.Y.r[i];
  629.             return (Math.round(o.row / Math.ceil(o.n() / o.col) * o.Y));
  630.         },
  631.         'top': function (o, r) {
  632.             var cur = o.cur[o.id],
  633.             n = r.row,
  634.             H = o.height(o.id);
  635.             if (o.id == 'hi') cur -= canvas.history_r.a - 6;
  636.             return (cur <= 1 ? 0 : Math.round((cur / ((r.n() - r.display) + n)) * (r.Y - H)));
  637.         },
  638.         // ACTIVE SCROLL
  639.         'active': function (o, n, n1, n2, fu, s) {
  640.             var z = '',
  641.             v = '',
  642.             r = gui.Y;
  643.             if (s) r.prev[r.id] = null;
  644.             while (Math.round(r.cur[r.id] - 1) % n != 0) {
  645.                 r.cur[r.id]++;
  646.                 n1++;
  647.                 n2++;
  648.             }
  649.             if (r.cur[r.id] != r.prev[r.id]) {
  650.                 if (fu.change) fu.change();
  651.                 for (var i = n1; i <= n2; i++) {
  652.                     var v = fu.each(i, fu.vars);
  653.                     if (v) z += v;
  654.                 }
  655.                 o.innerHTML = z;
  656.                 r.prev[r.id] = r.cur[r.id];
  657.                 return true;
  658.             }
  659.         },
  660.         'sw': function (s) {
  661.             var r = gui.Y,
  662.             c = r.cur;
  663.             function fu(i, r) {
  664.                 if (i <= r.length) {
  665.                     if (gui_swatch.id == 'PT') {
  666.                         vars.PT[i - 1] = new Image();
  667.                         vars.PT[i - 1].id = i;
  668.                         vars.PT[i - 1].src = gui_pattern.dir + vars['PT*'] + '/' + String(vars.PT.length - i) + '-live.jpg';
  669.                     }
  670.                     return ('<canvas id="' + vars.id + gui_swatch.id + i + '" height="16" width="16"' + (r.n == i ? 'class="cur"' : '') + ' onmousedown="gui_swatch.click(this)" title="' + String(vars.PT.length - i) + '"></canvas>');
  671.                 }
  672.             }
  673.             if (r.active($(gui_swatch.id), 7, c[gui_swatch.id], c[gui_swatch.id] + 27, {
  674.                 'each': fu,
  675.                 'vars': {
  676.                     'length': vars[gui_swatch.id].length,
  677.                     'n': gui_swatch.n[vars.id + gui_swatch.id]
  678.                 }
  679.             },
  680.             s)) {
  681.                 if (gui_swatch.id == 'PT') {
  682.                     for (var i = c[gui_swatch.id]; i <= c[gui_swatch.id] + 27; i++) if (i <= vars[gui_swatch.id].length && vars.PT[i - 1]) vars.PT[i - 1].onload = function () {
  683.                         gui_swatch.update(this.id);
  684.                     }
  685.                 } else gui_swatch.update(this.id);
  686.             }
  687.         },
  688.         'stamp': function (s) {
  689.             var r = gui.Y,
  690.             c = r.cur;
  691.             function fu(i, r) {
  692.                 if (i <= r.length) {
  693.                     stamp.src[i] = new Image();
  694.                     stamp.src[i].src = 'media/glyph/' + vars.stamp + '/' + (i - 1) + '-thumb.png';
  695.                     stamp.src[i].id = i;
  696.                     return ('<canvas width="34" height="34" onmousedown="if(this.id.substr(5)!=stamp.fileNumber) { stamp.current(this); co.glyph(stamp.uri(\'live\'),this.id); }" id="stamp' + i + '"' + (stamp.fileNumber == i ? ' class="cur"' : '') + '></canvas>');
  697.                 }
  698.             }
  699.             if($('brush_author')) {
  700.                 var stampSet = Resources.Brushes[vars.stamp];
  701.                 if(!stampSet) {
  702.                     $('brush_author').innerHTML = '';              
  703.                 } else {
  704.                     $('brush_author').innerHTML = '<i style="-moz-user-select: none; -khtml-user-select: none; user-select: none; ">by:&nbsp; <a href="'+stampSet.url+'" target="_blank">'+stampSet.name+'</a></i><div style="background: #555; height: 1px; margin: 6px 0 2px; "></div>';
  705.                 }
  706.             }
  707.             if (r.active($('stamp'), 4, c[r.id], c[r.id] + 11, {
  708.                 'change': function () {
  709.                     stamp.src = [];
  710.                 },
  711.                 'each': fu,
  712.                 'vars': {
  713.                     'length': stamp.r[vars.stamp]
  714.                 }
  715.             },
  716.             s)) {
  717.                 for (var i in stamp.src) stamp.src[i].onload = function () {
  718.                     stamp.preview(this.id);
  719.                 };
  720.             }
  721.         },
  722.         'hi': function (s) {
  723.             var r = gui.Y,
  724.             c = r.cur;
  725.             r.id = 'hi';
  726.             function fu(i) {
  727.                 var r = canvas.history_r;
  728.                 i--;
  729.                 if (i <= r.z && i >= r.a) {
  730.                     var v = r.data[r.r[i]];
  731.                     if (v) {
  732.                         v = v[3] ? {
  733.                             'img': v[3],
  734.                             'type': v[4] ? v[4] : v[2],
  735.                             'n': 1
  736.                         } : {
  737.                             'img': 'Original',
  738.                             'type': 'original'
  739.                         };
  740.                         return ('<div onmousedown="gui.Y.prev[gui.Y.id]=null; canvas.history_set(canvas.history_r.n=' + i + ',1)" class="' + (r.n == i ? 'cur' : (i <= r.n ? 'keep' : 'discard')) + '">' + ' <div style="float: left">' + '  <div style="background: url(media/gui/tools/' + v.img + '.png); opacity: ' + (i <= r.n ? 1.00 : 0.65) + '"></div>' + ' </div>' + ' <div style="float: left; margin-left: 3px;">' + v.type + '</div>' + ' <span>' + (v.n ? '#' + i : '') + '</span>' + '</div>');
  741.                     }
  742.                 }
  743.             }
  744.             r.active($C('z', 'history')[0], 1, c[r.id], c[r.id] + 7, {
  745.                 'each': fu
  746.             }, s);
  747.         }
  748.     },
  749.    
  750.     //* X-Slide
  751.     'X': {
  752.         'html': function (o, r, n, m) {
  753.             if (r[3]) vars[o] = Math.round(Math.max(r[0], n * r[1]) * 100) / 100;
  754.             else vars[o] = Math.round(Math.max(r[0], n * r[1]));
  755.             $(o + 'CurV').innerHTML = vars[o];
  756.             if (m == 'up') co.glyph();
  757.         },
  758.         'left': function (o, n) {
  759.             $S(o + 'Cur').left = Math.max(0, n) + 'px';
  760.         },
  761.         'build': function (v, o, r) {
  762.             var a = '',
  763.             b = '',
  764.             n = 0;
  765.             if (!isNaN(r[0])) {
  766.                 r = {
  767.                     '': r
  768.                 };
  769.                 d = 'slideX';
  770.             } else {
  771.                 d = 'slideXX';
  772.             }
  773.             for (var i in r) {
  774.                 n++;
  775.                 a = '<div id="' + o + i + 'Cur" class="' + i + '" style="left: ' + Math.round(vars[o + i] / (i ? cF[o].val[i] : cF[o].val)[1] * 112) + 'px"></div>' + a;
  776.                 b = '<div id="' + o + i + 'CurV" class="v">' + Math.round(vars[o + i]) + '</div>' + (b ? '<div class="u">/</div>' : '') + b;
  777.             }
  778.             return ('<div class="' + d + '"><span>' + v + '</span><br><div onmousedown="gui.X.' + (n > 1 ? 'xxSwitch' : 'xRun') + '(\'' + o + '\',event,this)" class="slide_div">' + (n > 1 ? '<div id="' + o + 'cCur" class="slide_center"></div>' : '') + a + '</div>' + b + '<br></div>' + (d == 'slideXX' ? '<div style="margin-top: 42px; clear: both;"></div>' : ''));
  779.         },
  780.         'xRun': function (o, e) {
  781.             core.fu(o + 'Cur', e, {
  782.                 fu: core.X,
  783.                 oX: -6,
  784.                 X1: 0,
  785.                 X2: 110,
  786.                 oY: 0
  787.             },
  788.             function (a, b, m) {
  789.                 var i = cF[o];
  790.                 if (i.fu) {
  791.                     i.fu(o, i.val, b.X, m);
  792.                 } else {
  793.                     gui.X.html(o, i.val, b.X / 110, m);
  794.                 }
  795.                 gui.X.left(o, b.X);
  796.                 if (m == 'up') vars.cache(1);
  797.             });
  798.         },
  799.         'xxSwitch': function (o, e, v) {
  800.             var n = (XY(e, 'X') - abPos(v).X - 7);
  801.             gui.X.xxID = o;
  802.             function z(v1, v2) {
  803.                 $S(o + v1 + 'Cur').zIndex = 1;
  804.                 $S(o + v2 + 'Cur').zIndex = 0;
  805.                 core.fu(o + v1 + 'Cur', e, {
  806.                     fu: core.X,
  807.                     oX: v1 == '_min' ? 0 : -7,
  808.                     X1: 0,
  809.                     X2: 115,
  810.                     oY: 0
  811.                 },
  812.                 function (a, b, m) {
  813.                     gui.X.xxRun(a, b, m, v1);
  814.                     if (m == 'up') vars.cache(1);
  815.                 });
  816.             }
  817.             var a = zero($S(o + '_maxCur').left),
  818.             b = zero($S(o + '_minCur').left);
  819.             if (Math.abs(n - a) < Math.abs(n - b) || (Math.abs(n - a) == Math.abs(n - b) && n <= a)) z('_max', '_min');
  820.             else z('_min', '_max');
  821.         },
  822.         'range': function (v, i, n) {
  823.             var a = (i == '_min') ? n : parseInt($S(v + '_minCur').left),
  824.                 z = (i == '_max') ? n : parseInt($S(v + '_maxCur').left);
  825.             $S(v + 'cCur').left = (z + 7) + 'px';
  826.             $S(v + 'cCur').width = Math.max(0, a - z - 7) + 'px';
  827.         },
  828.         'xxRun': function (a, b, m, i) {
  829.             var o = gui.X,
  830.             v = o.xxID;
  831.             function z(i, b) {
  832.                 o.html(v + i, cF[v].val[i], b / 115, m);
  833.                 o.left(v + i, b);
  834.                 o.range(v, i, b);
  835.             }
  836.             if (i == '_max' && zero($S(v + '_minCur').left) < (b.X + 1)) z('_min', Math.min(115, b.X + 1));
  837.             else if (i == '_min' && zero($S(v + '_maxCur').left) > (b.X - 1)) z('_max', Math.max(0, b.X - 1));
  838.             z(i, b.X);
  839.         },
  840.         'xxID': 0
  841.     }
  842. };
  843.  
  844. // WINDOW
  845.  
  846. win = {
  847.  
  848.     // Mouse
  849.     'close': function (v, s) {
  850.         win.tog(v, {
  851.             display: 'none',
  852.             effect: true
  853.         });
  854.         if (s) {
  855.             setTimeout("var v=$('i" + v + "'); v.className=(v.className=='cur')?'':'cur'; v.opened=false;", 190);
  856.         }
  857.     },
  858.     'tab': function (o, v) {
  859.         var d = $(o.id.substr(1));
  860.         if (o.opened == false) {
  861.             var i = o.id.substr(0, 2);
  862.             i = gui_swatch.L2S[i];
  863.             if (i) gui_swatch.cur(i);
  864.         }
  865.         if (o.opened == false && !d.interval) {
  866.             o.opened = true;
  867.             o.className = '';
  868.             win.tog(v, {
  869.                 display: 'block',
  870.                 effect: true
  871.             });
  872.         } else if (!d.interval) {
  873.             o.opened = false;
  874.             o.className = 'cur';
  875.             win.tog(v, {
  876.                 display: 'none',
  877.                 effect: true
  878.             });
  879.         }
  880.     },
  881.     'tog': function (v, s, r) {
  882.         if ($(v)) {
  883.             var o = $(v),
  884.             d = $S(v),
  885.             n = win.getCenter();
  886.             if (typeof(s) != 'object') {
  887.                 s = {
  888.                     display: s,
  889.                     effect: false
  890.                 };
  891.             }
  892.             if (win && isNaN(win)) {
  893.                 d.left = (win.r[v][1] + n) + 'px';
  894.                 d.top = win.r[v][2] + 'px';
  895.             }
  896.             if ($('i' + v)) {
  897.                 var a, b;
  898.                 if (!o.start) o.start = {
  899.                     'top': 20,
  900.                     'left': $('i' + v).offsetLeft + (String($('i' + v).innerHTML).length * 2.5) + 8 - n,
  901.                     'width': 1,
  902.                     'height': 1,
  903.                     'opacity': 10
  904.                 };
  905.                 o.end = {
  906.                     'top': parseInt(win.r[v][2]),
  907.                     'left': parseInt(win.r[v][1]),
  908.                     'width': 216,
  909.                     'height': parseInt(win.r[v][3]),
  910.                     'opacity': 100
  911.                 };
  912.                 if (s.display == 'block' && s.display != d.display) {
  913.                     if (s.effect) {
  914.                         a = o.start;
  915.                         b = o.end;
  916.                     } else {
  917.                         a = o.end;
  918.                     }
  919.                 } else if (s.display == 'none' && d.display == 'block') {
  920.                     if (s.effect) {
  921.                         a = o.end;
  922.                         b = o.start;
  923.                     } else {
  924.                         a = o.start;
  925.                     }
  926.                 }
  927.                 if (b) {
  928.                     win.apply(o, a);
  929.                     win.go(o, b, .4);
  930.                 } else {
  931.                     win.apply(o, a);
  932.                 }
  933.             } else {
  934.                 o.start = o.end = {
  935.                     'opacity': 100
  936.                 };
  937.                 win.apply(o, o.start);
  938.             }
  939.             win.r[v][0] = s.display;
  940.             win.cp(1);
  941.         }
  942.     },
  943.    
  944.     // Create
  945.     'feed': function () {
  946.         win.r = {
  947.             'canvas': ['block', -10, 19, ],
  948.             'solid': ['block', 588, 49, 256],
  949.             'gradient': ['none', 338, 382, 230],
  950.             'pattern': ['none', 338, 152, 219],
  951.             'swatch': ['none', 589, 306, 217],
  952.             'tools': ['block', -102, 19, 279],
  953.             'options': ['block', -103, 296, 200],
  954.             'history': ['none', 138, 416, 187]
  955.         };
  956.         if (r = cookieGrab('windows')) win.mk(r);
  957.         else win.mk(win.cp());
  958.     },
  959.     'mk': function (r) {
  960.         var n = win.getCenter(),
  961.         r = r.split(':');
  962.         for (var i in r) {
  963.             var v = r[i].split(','),
  964.             o = '';
  965.             if(!v[0]) continue; //- there's a missing name being passed somewhere...
  966.             win.r[v[0]] = [v[1], parseInt(v[2]), v[3], v[4]];
  967.             win.tog(v[0], v[1], [n + parseInt(v[2]), v[3], v[4]]);
  968.             if (o = $('i' + v[0])) {
  969.                 o.opened = (v[1] == 'none') ? false : true;
  970.                 o.className = (v[1] == 'none') ? 'cur' : '';
  971.             } //            TEST("'"+v[0]+"':['"+v[1]+"',"+v[2]+","+v[3]+","+v[4]+"],",1);
  972.         }
  973.     },
  974.     'cp': function (o, r) {
  975.         var z = '';
  976.         if (r) {
  977.             r[1] -= win.getCenter();
  978.             win.r[o] = deObject(r);
  979.         }
  980.         for (var i in win.r) {
  981.             z += i + ',' + win.r[i] + ':';
  982.         }
  983.         if (o) {
  984.             cookieStab('windows', z);
  985.         } else {
  986.             return (z);
  987.         }
  988.     },
  989.    
  990.     // Visualizer
  991.     'apply': function (o, r) {
  992.         var d = o.style,
  993.         n = win.getCenter();
  994.         for (i in r) {
  995.             if (i == 'opacity') {
  996.                 var b = r[i] / 100;
  997.                 d.filter = 'alpha(opacity=' + r[i] + ')';
  998.                 d.MozOpacity = b;
  999.                 d.opacity = b;
  1000.                 d.KhtmlOpacity = b;
  1001.                 if (r[i] <= o.start.opacity && r[i] != o.end.opacity) d.display = 'none';
  1002.                 else d.display = 'block';
  1003.             } else if (i == 'left') {
  1004.                 d[i] = (r[i] + n) + 'px';
  1005.             } else {
  1006.                 d[i] = r[i] + 'px';
  1007.             }
  1008.             o[i] = r[i];
  1009.         }
  1010.     },
  1011.     'go': function (o, r, n) {
  1012.         stop = 0;
  1013.         zindex(o);
  1014.         if (o.interval) {
  1015.             window.clearInterval(o.interval);
  1016.         } // .01 (super slow) to 1 (instant)
  1017.         win.overflow(o, 'hidden');
  1018.         o.style.cursor = 'pointer';
  1019.         o.interval = window.setInterval(function () {
  1020.             var done = true,
  1021.             A = [],
  1022.             Z = [];
  1023.             for (i in r) {
  1024.                 A[i] = Math.round((r[i] - o[i]) * n);
  1025.             }
  1026.             for (i in A) {
  1027.                 Z[i] = o[i] + A[i];
  1028.                 if (A[i] == 0 || (A[i] > 0 && Z[i] > r[i]) || (A[i] < 0 && Z[i] < r[i])) {
  1029.                     Z[i] = r[i];
  1030.                 } else {
  1031.                     done = false;
  1032.                 }
  1033.             }
  1034.             win.apply(o, Z);
  1035.             if (done) {
  1036.                 window.clearInterval(o.interval);
  1037.                 o.interval = null;
  1038.                 stop = 1;
  1039.                 o.style.cursor = 'move';
  1040.                 win.overflow(o, 'visible');
  1041.             }
  1042.         },
  1043.         35);
  1044.     },
  1045.     'overflow': function (o, v) {
  1046.         o.style.overflow = v;
  1047.         function fu(d) {
  1048.             d.style.overflow = v;
  1049.         }
  1050.         fu($C('z', o)[0]);
  1051.         var d = $C('TML', o)[0];
  1052.         if (d) fu(d);
  1053.         var d = $C('TRx', o)[0];
  1054.         if (d) fu(d);
  1055.     },
  1056.    
  1057.     // Data
  1058.     'zindex': 3,
  1059.     'getCenter': function () {
  1060.         return (zero((XYwin('X') - 710) / 2));
  1061.     }
  1062. };
  1063.  
  1064. // WINDOW RESIZE
  1065.  
  1066. win_size = {
  1067.  
  1068.     // Mouse
  1069.     'core': function (e) {
  1070.         function fu(o, m, a) {
  1071.             var Y = Math.max(100, (a.Y - r.Y) + r.H),
  1072.             X = Math.max(212, (a.X - r.X) + r.W);
  1073.             var o = {
  1074.                 W: X - 32,
  1075.                 H: Y - 40
  1076.             };
  1077.             win_size.fu(o, r);
  1078.             if (m == 'up') {
  1079.                 vars.cache(1);
  1080.             }
  1081.         }
  1082.         var r = win_size.construct({
  1083.             'X': $('canvas').offsetLeft,
  1084.             'Y': $('canvas').offsetTop,
  1085.             'W': parseInt($S('canvas').width),
  1086.             'H': parseInt($S('canvas').height)
  1087.         });
  1088.         core.fu('canvas', e, {
  1089.             fu: fu
  1090.         });
  1091.     },
  1092.     'tog': function (v) {
  1093.         var o = $S('canvas');
  1094.         win_size[v]();
  1095.         vars.winMax = (v == 'max') ? 1 : 0;
  1096.         vars.cache(1);
  1097.         win.cp('canvas', ['block', zero(o.left), zero(o.top), parseInt(win.r['canvas'][3])]);
  1098.     },
  1099.     'max': function () {
  1100.         var o = win_size;
  1101.         o.fu({
  1102.             cT: 19,
  1103.             cL: -8,
  1104.             W: XYwin('X') - 16,
  1105.             H: XYwin('Y') - 56
  1106.         },
  1107.         o.construct({}));
  1108.     },
  1109.     'min': function () {
  1110.         var o = win_size;
  1111.         o.fu({
  1112.             cT: 19,
  1113.             cL: (document.body.scrollWidth - (canvas.W + 30)) / 2,
  1114.             W: canvas.W,
  1115.             H: canvas.H
  1116.         },
  1117.         o.construct({}));
  1118.     },
  1119.    
  1120.     // Create
  1121.     'fu': function (o, c) {
  1122.         var d = $S('canvas');
  1123.         vars.winW = o.W;
  1124.         vars.winH = o.H;
  1125.         if (o.cT) {
  1126.             d.top = o.cT + 'px';
  1127.             d.left = o.cL + 'px';
  1128.         }
  1129.         d.width = (o.W + 32) + 'px';
  1130.         d.height = (o.H + 40) + 'px';
  1131.         var d = $S('cBound');
  1132.         d.height = o.H + 'px';
  1133.         d.width = o.W + 'px';
  1134.         c['ML'].height = o.H + 'px';
  1135.         c['MM'].height = o.H + 'px';
  1136.         c['MR'].height = o.H + 'px';
  1137.         c['TM'].width = o.W + 'px';
  1138.         c['MM'].width = o.W + 'px';
  1139.         c['BM'].width = o.W + 'px';
  1140.         var o = win_size.LT(),
  1141.         r = ['ctx_box', 'ctx_temp', 'ctx_marquee', 'ctx_active', 'ctx_mouse'];
  1142.         for (var i in r) {
  1143.             var d = $S(r[i]);
  1144.             d.left = o.L + 'px';
  1145.             d.top = o.T + 'px';
  1146.         };
  1147.     },
  1148.     'LT': function () {
  1149.         return ({
  1150.             L: Math.round((vars.winW - canvas.W) / 2),
  1151.             T: Math.round((vars.winH - canvas.H) / 2)
  1152.         });
  1153.     },
  1154.     'construct': function (o) {
  1155.         var d = $('canvas'),
  1156.         r = ['ML', 'MM', 'MR', 'TM', 'BM'];
  1157.         for (var i in r) {
  1158.             i = r[i];
  1159.             o[i] = $C(i, d)[0].style;
  1160.         }
  1161.         return (o);
  1162.     }
  1163. };/*
  1164.  
  1165.     // Canvas2D : v0.3 : 2009.01.16
  1166.     --------------------------------
  1167.     1) Retrofits older browsers that don't support HTML 5.0
  1168.         * IECanvas, an ActiveX module which emulates <canvas>, retrofits IE: code.google.com/p/iecanvas/
  1169.         * Retrofits prototyping up to Safari 3.  IE is fixed externally in /lib/HTMLElement.htc
  1170.         * Retrofits arcTo up to (which browsers don't work???)
  1171.         * Retrofits fillText / strokeText up to Safari 4, Firefox 3.1, and Opera
  1172.         * Retrofits transform / setTransform up to Safari 4, Firefox 3.1 (+?)
  1173.  
  1174.     2) Parses and Implements SVG:
  1175.         * Parses <font> attributes and paths then converts to FOB for fast access.  In the process of emulating more attributes in <canvas>.
  1176.         * Parses <path> [ M, m, L, l, C, c, Q, q, Z, H, h, V, v, A, a ] and converts to VOB [ M, L, C, Q, Z ] for fast access
  1177.         * Implements Shapes: circle, ellipse, line, path, polygon, polyline, rect
  1178.  
  1179.     3) Adds non-standardized features:
  1180.         * Pixel: colorMatrix, colorTransform (browser must support getImageData / putImageData)
  1181.         * Path: arc, roundRect, star, polygon, burst, arrow, wedge, gear, spiral, superformula, drawVector, drawVOB
  1182.         * Typeface: drawText
  1183.  
  1184.  
  1185.     * Breaking down the libraries:
  1186.     -------------------------------
  1187.     Canvas2D.js // add, remove, fix (browser fixes), ect
  1188.     Canvas2D.Pixel.js // ColorMatrix + ConvolutionMatrix + CustomFilter mixing and applying (maybe a few other default filters, such as DisplacementMap)
  1189.     Canvas2D.Raster.js // reflect, straighten, flip, rotate, resize
  1190.     Canvas2D.Record.js // sets up functions for recording native functions
  1191.     Canvas2D.StyleSheet.js // importing, exporting, converting, and storing:  patterns, gradients, colors, and native styles (i.e. miterLimit, font, ect)
  1192.     Canvas2D.SVG.js // parse SVG into VOB (fonts and paths)
  1193.     Canvas2D.Transform.js // geometric TransformationMatrix + Decompose
  1194.     Canvas2D.Typeface.js // text building and styles
  1195.     Canvas2D.Vector.js // shapes and broken native path functions (optionally caches in VOB)
  1196.     Canvas2D.VOB.js // v2.0 is pretty complex, ties in layers + groups w/ vector objects, so gets it's own .js
  1197.  
  1198.    
  1199.     * Listing functions supported by the library:
  1200.     ----------------------------------------------
  1201.     Canvas2D.add // create new <canvas> element
  1202.     Canvas2D.remove // remove specific <canvas> element
  1203.  
  1204.  
  1205.     HTMLCanvasElement (HTML 5.0)
  1206.     -----------------------------
  1207.     attribute unsigned long width;
  1208.     attribute unsigned long height;
  1209.    
  1210.     DOMString toDataURL([Optional] in DOMString type); // converts <canvas> in a base64 string of image type
  1211.     DOMObject getContext(in DOMString contextId); // returns CanvasRenderingContext2D
  1212.    
  1213.  
  1214.     State Stack (HTML 5.0)
  1215.     --------------------------
  1216.     void save(); // push state on state stack
  1217.     void restore(); // pop state stack and restore state
  1218.    
  1219.     void getPath(); // returns current path *
  1220.  
  1221.  
  1222.     Style API
  1223.     -----------------------
  1224.     Composition (HTML 5.0)
  1225.     -----------------------
  1226.     attribute float globalAlpha; // (default 1.0)
  1227.     attribute DOMString globalCompositeOperation; // (default source-over)
  1228.    
  1229.     Colors & Styles (HTML 5.0)
  1230.     --------------------------
  1231.     attribute any strokeStyle; // (default black)
  1232.     attribute any fillStyle; // (default black)
  1233.    
  1234.     Line Caps & Joins (HTML 5.0)
  1235.     ----------------------------
  1236.     attribute float lineWidth; // (default 1)
  1237.     attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
  1238.     attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
  1239.     attribute float miterLimit; // (default 10)
  1240.    
  1241.     Shadows: supported in Firefox 3.1, Safari 3, Opera 10
  1242.     -----------------------------------------
  1243.     attribute float shadowOffsetX; // (default 0)
  1244.     attribute float shadowOffsetY; // (default 0)
  1245.     attribute float shadowBlur; // (default 0)
  1246.     attribute DOMString shadowColor; // (default transparent black)
  1247.  
  1248.     CanvasGradient (HTML 5.0)
  1249.     -------------------------
  1250.     createLinearGradient(float x0, float y0, float x1, float y1);
  1251.     createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
  1252.    
  1253.     interface { void addColorStop(float offset, DOMString color); };
  1254.    
  1255.  
  1256.     Patterns (HTML 5.0)
  1257.     -------------------
  1258.     CanvasPattern createPattern(HTMLImageElement image, DOMString repetition);
  1259.     CanvasPattern createPattern(HTMLCanvasElement image, DOMString repetition);
  1260.    
  1261.    
  1262.     Transformation API (HTML 5.0)
  1263.     ------------------------------
  1264.     void scale(float x, float y);
  1265.     void rotate(float angle);
  1266.     void translate(float x, float y);
  1267.     void transform(float m11, float m12, float m21, float m22, float dx, float dy);
  1268.     void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
  1269.  
  1270.    
  1271.     Pixel API (HTML 5.0)
  1272.     ------------------------
  1273.     ImageData createImageData(float sw, float sh);
  1274.     ImageData getImageData(float sx, float sy, float sw, float sh); // Opera 9.5+, Firefox 2.0+, Safari 4.0+
  1275.  
  1276.     void putImageData(ImageData imagedata, float dx, float dy);
  1277.     void putImageData(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
  1278.  
  1279.     Addon: Filters (seperate file contains filters, cause this is a lot of information)
  1280.  
  1281.     void getPixel();
  1282.     void setPixel();
  1283.    
  1284.    
  1285.     Raster API (HTML 5.0)
  1286.     ------------------------
  1287.     void drawImage(HTMLImageElement image, float dx, float dy, [Optional] float dw, float dh);
  1288.     void drawImage(HTMLImageElement image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
  1289.     void drawImage(HTMLCanvasElement image, float dx, float dy, [Optional] float dw, float dh);
  1290.     void drawImage(HTMLCanvasElement image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
  1291.    
  1292.  
  1293.     Vector API (HTML 5.0)
  1294.     ----------------------
  1295.     boolean isPointInPath(float x, float y);
  1296.  
  1297.     void beginPath();
  1298.     void closePath();
  1299.     void moveTo(float x, float y);
  1300.     void lineTo(float x, float y);
  1301.     void arcTo(float x1, float y1, float x2, float y2, float radius); // don't punish for not having arcTo native
  1302.     void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
  1303.     void quadraticCurveTo(float cpx, float cpy, float x, float y);
  1304.     void arc(float x, float y, float radius, float startAngle, float endAngle, boolean anticlockwise); // openlaszlo.org/jira/browse/LPP-3491
  1305.     void rect(float x, float y, float w, float h);
  1306.     void clearRect(float x, float y, float w, float h);
  1307.     void fillRect(float x, float y, float w, float h);
  1308.     void strokeRect(float x, float y, float w, float h);
  1309.     void fill();
  1310.     void stroke();
  1311.     void clip();
  1312.    
  1313.     // Addon: SVG Shapes @ w3.org/TR/SVG11/shapes.html
  1314.  
  1315.     void circle(float cx, float cy, float r) // defines a circle based on a center point and a radius
  1316.     void ellipse(float cx, float cy, float rx, float ry) // defines an ellipse based on a center point and two radii
  1317.     void line(float x1, float y1, float x2, float y2) // defines a line segment that starts at one point and ends at another
  1318.     void path(string d) // SVG instructions, contains the moveto, line, cubic, quadratic, arc, and closepath: "M5,5 C5,45 45,45 45,5"
  1319.  
  1320.     // Addon: Path Shapes
  1321.  
  1322.     void roundRect(float x, float y, float width, float height, float rad) // circular rounded-rectangle
  1323.     void roundRect(float x, float y, float width, float height, float rx, float ry) // elliptical rounded-rectangle (two radii)
  1324.     void wedge(float x, float y, float radius, float startAngle, float endAngle, boolean anticlockwise); // en.wikipedia.org/wiki/Wedge_%28geometry%29
  1325.     void polygon(x, y, radius, sides) // en.wikipedia.org/wiki/Regular_polygon
  1326.     void gear(float x, float y, float radius, int sides, float slope); // en.wikipedia.org/wiki/Gear
  1327.     void star(float x, float y, float radius, int sides, float slope);
  1328.     void burst(float x, float y, float radius, int sides, float slope);
  1329.     void spiral(x, y, radius, sides, coils) // en.wikipedia.org/wiki/Archimedean_spiral
  1330.     void superformula(x, y, radius, points, m, n1, n2, n3) // en.wikipedia.org/wiki/Superformula
  1331.  
  1332.  
  1333.     Typeface API (HTML 5.0)  -- Firefox 3.1+ and Safari 4.0+
  1334.     ------------------------
  1335.     attribute DOMString font; // (default 10px sans-serif)
  1336.     attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
  1337.     attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
  1338.  
  1339.     void fillText(DOMString text, float x, float y, [Optional] float maxWidth);
  1340.     void strokeText(DOMString text, float x, float y, [Optional] float maxWidth);
  1341.     void measureText(DOMString text); // returns { width: 100 }
  1342.    
  1343.     // Addon: Mozilla
  1344.    
  1345.     void drawText(DOMString text, float x, float y, [Optional] float maxWidth); // rhino-canvas.sourceforge.net/www/drawstring.html
  1346.  
  1347. */
  1348. if (typeof Canvas2D == 'undefined') {
  1349.     var Canvas2D = {};
  1350. }
  1351. (function () {
  1352. var surface = {}; // canvas array
  1353. Canvas2D = mixin(Canvas2D, { // Global functions
  1354.     add: function (attr, height, id, style) { // add <canvas> element
  1355.         if (typeof attr == "number") { // accepts Canvas2D.add(width, height, id, style)
  1356.             attr = {
  1357.                 width: attr,
  1358.                 height: height,
  1359.                 id: id,
  1360.                 style: style
  1361.             };
  1362.         }
  1363.         if (attr) { // check whether surface exists
  1364.             if (typeof attr == "string") {
  1365.                 attr = { // convert to object
  1366.                     id: attr
  1367.                 };
  1368.             }
  1369.             if (attr && attr.id && surface[attr.id]) {
  1370.                 return surface[attr.id];
  1371.             }
  1372.         }
  1373.         var d = document.createElement('canvas'),
  1374.         ctx = d.getContext('2d');
  1375.         if (typeof attr == "object") {
  1376.             for (var key in attr) {
  1377.                 switch (key) { // type of attribute
  1378.                     case "style":
  1379.                         if (typeof attr[key] == "object") {
  1380.                             for (var type in attr[key]) // style object
  1381.                             d.style[type] = attr[key][type];
  1382.                             break;
  1383.                         }
  1384.                         else { // string
  1385.                             d.setAttribute(key, attr[key]);
  1386.                             break;
  1387.                         }
  1388.                     default:
  1389.                         //-
  1390.                         d[key] = attr[key];
  1391.                         break;
  1392.                 }
  1393.             }
  1394.         }
  1395.         document.body.appendChild(d);
  1396.         if (attr.id) { // cache surface
  1397.             surface[attr.id] = ctx;
  1398.         }
  1399.         return ctx;
  1400.     },
  1401.     remove: function (id) { // remove <canvas> element
  1402.         if (!surface[id]) {
  1403.             return;
  1404.         }
  1405.         delete surface[id]; // delete reference
  1406.         document.body.removeChild($("#" + id)); // remove DOM
  1407.     }
  1408. });
  1409. })();(function() {
  1410.  
  1411. // Debugging
  1412.  
  1413. TEST = { };
  1414.  
  1415. TEST = (function() {
  1416.     var max,
  1417.         depth = 0,
  1418.         INDENT = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
  1419.     function valueToStr(value, depth) {
  1420.         switch(typeof value) {
  1421.             case "object":
  1422.                 return objectToStr(value, depth + 1);
  1423.             case "function":
  1424.                 return "function";
  1425.             case "string":
  1426.                 return "'"+value+"'";
  1427.             default:        
  1428.                 return value;
  1429.         }
  1430.     };
  1431.     function objectToStr(object, depth) {
  1432.         if(depth > max)
  1433.             return false;
  1434.         var type = Object.prototype.toString.call(object),
  1435.             output = "\n",
  1436.             indent = INDENT.substr(0, depth);
  1437.         for(var key in object)
  1438.             output += indent + valueToStr(key) + ": " + valueToStr(object[key], depth) + ",\n";
  1439.         indent = INDENT.substr(0, depth - 1);
  1440.         switch(type) {
  1441.             case "[object Object]":
  1442.                 return "{ " + output.substr(0, output.length - 2) + "\n" + indent + "}";  
  1443.             case "[object Array]":
  1444.                 return "[ " + output.substr(0, output.length - 2) + "\n" + indent + "]";  
  1445.             default:
  1446.                 return;
  1447.         }
  1448.     };
  1449.     return function(value, aggregate, MAX) {
  1450.         var d = document.getElementById("TEST");
  1451.         if(!d) { // element does not exist
  1452.             var d = document.createElement("div");
  1453.             d.id = "TEST";
  1454.             document.body.appendChild(d);
  1455.         }
  1456.         // recurse
  1457.         max = MAX || 2;
  1458.         if(typeof value != "string")
  1459.             value = valueToStr(value, depth);
  1460.         var br = Object.prototype.toString.call(d) == "[object HTMLDivElement]" ? "<br>" : "\n";
  1461.         d.innerHTML = aggregate ? d.innerHTML + br + value : value;
  1462.     };
  1463. })();
  1464.  
  1465. TEST.element = function(type, style) {
  1466.     var d = document.getElementById("TEST");
  1467.     if(d) // remove element
  1468.         document.body.removeChild(d);
  1469.     var d = document.createElement(type);
  1470.     d.id = "TEST";
  1471.     if(style)
  1472.         d.setAttribute("style", style);
  1473.     document.body.appendChild(d);
  1474.     if(type == "textarea") {
  1475.         d.style.width = (window.innerWidth - d.offsetLeft - 6) + "px";
  1476.         d.style.height = (window.innerHeight - d.offsetTop - 6) + "px";
  1477.     }
  1478.     return d;
  1479. };
  1480.  
  1481. TEST.speed = function(a, b, n) {
  1482.     var T1, T2, Z1, Z2;
  1483.     T1 = now();
  1484.     for(var i = 0; i<= n; i++) a();
  1485.     Z1 = now()-T1;
  1486.     T2 = now();
  1487.     for(var i = 0; i<= n; i++) b();
  1488.     Z2 = now()-T2;
  1489.     TEST('A: '+Z1+', B: '+Z2+' = '+(Math.round(Z2/Z1*1000)/1000), 1);
  1490. };
  1491.  
  1492. // Class: Dump
  1493. // Author: Shuns (www.netgrow.com.au/files)
  1494. // Last Updated: 10/10/06
  1495. // Version: 1.1
  1496.  
  1497. dump = function(object, aggregate, showTypes) {
  1498.  var dump = '';
  1499.  var st = typeof showTypes == 'undefined' ? true : showTypes;
  1500.  var winName = 'dumpWin';
  1501.   var browser = _dumpIdentifyBrowser();
  1502.  var w = 760;
  1503.  var h = 500;
  1504.  var leftPos = screen.width ? (screen.width - w) / 2 : 0;
  1505.  var topPos = screen.height ? (screen.height - h) / 2 : 0;
  1506.  var settings = 'height=' + h + ',width=' + w + ',top=' + topPos + ',left=' + leftPos + ',scrollbars=yes,menubar=yes,status=yes,resizable=yes';
  1507.  var title = 'Dump';
  1508.   var script = 'function tRow(s) {t = s.parentNode.lastChild;tTarget(t, tSource(s)) ;}function tTable(s) {var switchToState = tSource(s) ;var table = s.parentNode.parentNode;for (var i = 1; i < table.childNodes.length; i++) {t = table.childNodes[i] ;if (t.style) {tTarget(t, switchToState);}}}function tSource(s) {if (s.style.fontStyle == "italic" || s.style.fontStyle == null) {s.style.fontStyle = "normal";s.title = "click to collapse";return "open";} else {s.style.fontStyle = "italic";s.title = "click to expand";return "closed" ;}}function tTarget (t, switchToState) {if (switchToState == "open") {t.style.display = "";} else {t.style.display = "none";}}';      
  1509.  
  1510.  dump += (/string|number|undefined|boolean/.test(typeof(object)) || object == null) ? object : recurse(object, typeof object);
  1511.  
  1512.  var d = document.getElementById("TEST");
  1513.  if(!d) { // TEST does not exist
  1514.       var d = document.createElement("div");
  1515.       d.id = "TEST";
  1516.       document.body.appendChild(d);
  1517.  }
  1518.  d.innerHTML = aggregate ? d.innerHTML + dump : dump;
  1519.  
  1520.  function recurse(o, type) {
  1521.    var i;
  1522.     var j = 0;
  1523.     var r = '';
  1524.     type = _dumpType(o);
  1525.     switch (type) {    
  1526.       case 'regexp':
  1527.         var t = type;
  1528.         r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
  1529.         r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>RegExp: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';  
  1530.         j++;
  1531.         break;
  1532.       case 'date':
  1533.         var t = type;
  1534.         r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
  1535.         r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>Date: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';  
  1536.         j++;
  1537.         break;
  1538.       case 'function':
  1539.         var t = type;
  1540.         var a = o.toString().match(/^.*function.*?\((.*?)\)/im);
  1541.         var args = (a == null || typeof a[1] == 'undefined' || a[1] == '') ? 'none' : a[1];
  1542.         r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
  1543.         r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>Arguments: </i></td><td' + _dumpStyles(type,'td-value') + '>' + args + '</td></tr><tr><td' + _dumpStyles('arguments','td-key') + '><i>Function: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';  
  1544.         j++;
  1545.         break;
  1546.       case 'domelement':
  1547.         var t = type;
  1548.         r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
  1549.         r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Name: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeName.toLowerCase() + '</td></tr>';  
  1550.         r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Type: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeType + '</td></tr>';
  1551.         r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Value: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeValue + '</td></tr>';                   
  1552.         r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>innerHTML: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.innerHTML + '</td></tr>';  
  1553.         j++;
  1554.         break;     
  1555.     }
  1556.     if (/object|array/.test(type)) {
  1557.       for (i in o) {
  1558.         var t = _dumpType(o[i]);
  1559.         if (j < 1) {
  1560.           r += '<table' + _dumpStyles(type,'table') + '><tr><th colspan="2"' + _dumpStyles(type,'th') + '>' + type + '</th></tr>';
  1561.           j++;   
  1562.         }
  1563.         if (typeof o[i] == 'object' && o[i] != null) {
  1564.           r += '<tr><td' + _dumpStyles(type,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + recurse(o[i], t) + '</td></tr>';  
  1565.         } else if (typeof o[i] == 'function') {
  1566.           r += '<tr><td' + _dumpStyles(type ,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + recurse(o[i], t) + '</td></tr>';     
  1567.         } else {
  1568.           r += '<tr><td' + _dumpStyles(type,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + o[i] + '</td></tr>';  
  1569.         }
  1570.       }
  1571.     }
  1572.     if (j == 0) {
  1573.       r += '<table' + _dumpStyles(type,'table') + '><tr><th colspan="2"' + _dumpStyles(type,'th') + '>' + type + ' [empty]</th></tr>';  
  1574.     }
  1575.     r += '</table>';
  1576.     return r;
  1577.   };   
  1578. };
  1579.  
  1580. dump.object = function(o) {
  1581.     doc = o;
  1582. };
  1583.  
  1584. var _dumpStyles = function(type, use) {
  1585.   var r = '';
  1586.   var table = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;cell-spacing:2px;';
  1587.   var th = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;text-align:left;color: white;padding: 5px;vertical-align :top;cursor:hand;cursor:pointer;';
  1588.   var td = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;vertical-align:top;padding:3px;';
  1589.   var thScript = 'onClick="tTable(this);" title="click to collapse"';
  1590.   var tdScript = 'onClick="tRow(this);" title="click to collapse"';
  1591.   switch (type) {
  1592.     case 'string':
  1593.     case 'number':
  1594.     case 'boolean':
  1595.     case 'undefined':
  1596.     case 'object':
  1597.       switch (use) {
  1598.         case 'table':  
  1599.           r = ' style="' + table + 'background-color:#0000cc;"';
  1600.           break;
  1601.         case 'th':
  1602.           r = ' style="' + th + 'background-color:#4444cc;"' + thScript;
  1603.           break;
  1604.         case 'td-key':
  1605.           r = ' style="' + td + 'background-color:#ccddff;cursor:hand;cursor:pointer;"' + tdScript;
  1606.           break;
  1607.         case 'td-value':
  1608.           r = ' style="' + td + 'background-color:#fff;"';
  1609.           break;
  1610.       }
  1611.       break;
  1612.     case 'array':
  1613.       switch (use) {
  1614.         case 'table':  
  1615.           r = ' style="' + table + 'background-color:#006600;"';
  1616.           break;
  1617.         case 'th':
  1618.           r = ' style="' + th + 'background-color:#009900;"' + thScript;
  1619.           break;
  1620.         case 'td-key':
  1621.           r = ' style="' + td + 'background-color:#ccffcc;cursor:hand;cursor:pointer;"' + tdScript;
  1622.           break;
  1623.         case 'td-value':
  1624.           r = ' style="' + td + 'background-color:#fff;"';
  1625.           break;
  1626.       }
  1627.       break;
  1628.     case 'function':
  1629.       switch (use) {
  1630.         case 'table':  
  1631.           r = ' style="' + table + 'background-color:#aa4400;"';
  1632.           break;
  1633.         case 'th':
  1634.           r = ' style="' + th + 'background-color:#cc6600;"' + thScript;
  1635.           break;
  1636.         case 'td-key':
  1637.           r = ' style="' + td + 'background-color:#fff;cursor:hand;cursor:pointer;"' + tdScript;
  1638.           break;
  1639.         case 'td-value':
  1640.           r = ' style="' + td + 'background-color:#fff;"';
  1641.           break;
  1642.       }
  1643.       break;
  1644.     case 'arguments':
  1645.       switch (use) {
  1646.         case 'table':  
  1647.           r = ' style="' + table + 'background-color:#dddddd;cell-spacing:3;"';
  1648.           break;
  1649.         case 'td-key':
  1650.           r = ' style="' + th + 'background-color:#eeeeee;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
  1651.           break;     
  1652.       }
  1653.       break;
  1654.     case 'regexp':
  1655.       switch (use) {
  1656.         case 'table':  
  1657.           r = ' style="' + table + 'background-color:#CC0000;cell-spacing:3;"';
  1658.           break;
  1659.         case 'th':
  1660.           r = ' style="' + th + 'background-color:#FF0000;"' + thScript;
  1661.           break;
  1662.         case 'td-key':
  1663.           r = ' style="' + th + 'background-color:#FF5757;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
  1664.           break;
  1665.         case 'td-value':
  1666.           r = ' style="' + td + 'background-color:#fff;"';
  1667.           break;         
  1668.       }
  1669.       break;
  1670.     case 'date':
  1671.       switch (use) {
  1672.         case 'table':  
  1673.           r = ' style="' + table + 'background-color:#663399;cell-spacing:3;"';
  1674.           break;
  1675.         case 'th':
  1676.           r = ' style="' + th + 'background-color:#9966CC;"' + thScript;
  1677.           break;
  1678.         case 'td-key':
  1679.           r = ' style="' + th + 'background-color:#B266FF;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
  1680.           break;
  1681.         case 'td-value':
  1682.           r = ' style="' + td + 'background-color:#fff;"';
  1683.           break;         
  1684.       }
  1685.       break;
  1686.     case 'domelement':
  1687.       switch (use) {
  1688.         case 'table':  
  1689.           r = ' style="' + table + 'background-color:#FFCC33;cell-spacing:3;"';
  1690.           break;
  1691.         case 'th':
  1692.           r = ' style="' + th + 'background-color:#FFD966;"' + thScript;
  1693.           break;
  1694.         case 'td-key':
  1695.           r = ' style="' + th + 'background-color:#FFF2CC;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
  1696.           break;
  1697.         case 'td-value':
  1698.           r = ' style="' + td + 'background-color:#fff;"';
  1699.           break;         
  1700.       }
  1701.       break;     
  1702.   }
  1703.   return r;
  1704. };
  1705.  
  1706. var _dumpIdentifyBrowser = function() {
  1707.   var agent = navigator.userAgent.toLowerCase();
  1708.   if (typeof window.opera != 'undefined') {
  1709.     return 'opera';
  1710.   } else if (typeof document.all != 'undefined') {
  1711.     if (typeof document.getElementById != 'undefined') {
  1712.       var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, '$1').replace(/ /, '');
  1713.       if (typeof document.uniqueID != 'undefined') {
  1714.         if (browser.indexOf('5.5') != -1) {
  1715.           return browser.replace(/(.*5\.5).*/, '$1');
  1716.         } else {
  1717.           return browser.replace(/(.*)\..*/, '$1');
  1718.         }
  1719.       } else {
  1720.         return 'ie5mac';
  1721.       }
  1722.     }
  1723.   } else if (typeof document.getElementById != 'undefined') {
  1724.     if (navigator.vendor.indexOf('Apple Computer, Inc.') != -1) {
  1725.       return 'safari';
  1726.     } else if (agent.indexOf('gecko') != -1) {
  1727.       return 'mozilla';
  1728.     }
  1729.   }
  1730.   return false;
  1731. };
  1732.  
  1733. var _dumpType = function (obj) {
  1734.   var t = typeof(obj);
  1735.   if (t == 'function') {
  1736.     var f = obj.toString();
  1737.     if ( ( /^\/.*\/[gi]??[gi]??$/ ).test(f)) {
  1738.       return 'regexp';
  1739.     } else if ((/^\[object.*\]$/i ).test(f)) {
  1740.       t = 'object'
  1741.     }
  1742.   }
  1743.   if (t != 'object') {
  1744.     return t;
  1745.   }
  1746.   switch (obj) {
  1747.     case null:
  1748.       return 'null';
  1749.     case window:
  1750.       return 'window';
  1751.     case document:
  1752.       return document;
  1753.     case window.event:
  1754.       return 'event';
  1755.   }
  1756.   if (window.event && (event.type == obj.type)) {
  1757.    return 'event';
  1758.   }
  1759.   var c = obj.constructor;
  1760.   if (c != null) {
  1761.     switch(c) {
  1762.       case Array:
  1763.         t = 'array';
  1764.         break;
  1765.       case Date:
  1766.         return 'date';
  1767.       case RegExp:
  1768.         return 'regexp';
  1769.       case Object:
  1770.         t = 'object';  
  1771.       break;
  1772.       case ReferenceError:
  1773.         return 'error';
  1774.       default:
  1775.         var sc = c.toString();
  1776.         var m = sc.match(/\s*function (.*)\(/);
  1777.         if(m != null) {
  1778.           return 'object';
  1779.         }
  1780.     }
  1781.   }
  1782.   var nt = obj.nodeType;
  1783.   if (nt != null) {
  1784.     switch(nt) {
  1785.       case 1:
  1786.         if(obj.item == null) {
  1787.           return 'domelement';
  1788.         }
  1789.         break;
  1790.       case 3:
  1791.         return 'string';
  1792.     }
  1793.   }
  1794.   if (obj.toString != null) {
  1795.     var ex = obj.toString();
  1796.     var am = ex.match(/^\[object (.*)\]$/i);
  1797.     if(am != null) {
  1798.       var am = am[1];
  1799.       switch(am.toLowerCase()) {
  1800.         case 'event':
  1801.           return 'event';
  1802.         case 'nodelist':
  1803.         case 'htmlcollection':
  1804.         case 'elementarray':
  1805.           return 'array';
  1806.         case 'htmldocument':
  1807.           return 'htmldocument';
  1808.       }
  1809.     }
  1810.   }
  1811.   return t;
  1812. };
  1813.  
  1814. })();/* GENERIC */
  1815. function $(v, o) {
  1816.     if (!v) return;
  1817.     return ((typeof(o) == 'object' ? o : document).getElementById(v));
  1818. }
  1819. function $2D(o) {
  1820.     return ($(o).getContext('2d'));
  1821. }
  1822. function $S(o) {
  1823.     return ($(o).style);
  1824. }
  1825. function $SS(n) {
  1826.     var o = document.styleSheets[0];
  1827.     if (o.cssRules) o = o.cssRules;
  1828.     else o = o.rules;
  1829.     return (o[n].style);
  1830. }
  1831. function $T(v, o) {
  1832.     return ((typeof(o) == 'object' ? o : $(o)).getElementsByTagName(v));
  1833. }
  1834. function abPos(o) {
  1835.     var o = (typeof(o) == 'object' ? o : $(o)),
  1836.     i = {
  1837.         X: 0,
  1838.         Y: 0
  1839.     };
  1840.     while (o != null) {
  1841.         i.X += o.offsetLeft;
  1842.         i.Y += o.offsetTop;
  1843.         o = o.offsetParent;
  1844.     };
  1845.     return (i);
  1846. }
  1847. function agent(v) {
  1848.     return (Math.max(navigator.userAgent.toLowerCase().indexOf(v), 0));
  1849. }
  1850. function cookieStab(f, v) {
  1851.     document.cookie = f + "=" + v + "; path=/";
  1852. }
  1853. function cookieGrab(f) {
  1854.     var b = f + "=",
  1855.     d = document.cookie.split(';');
  1856.     for (var i = 0; i < d.length; i++) {
  1857.         var c = d[i];
  1858.         while (c.charAt(0) == ' ') c = c.substring(1, c.length);
  1859.         if (c.indexOf(b) == 0) return (c.substring(b.length, c.length));
  1860.     }
  1861. }
  1862. function getTime() {
  1863.     return ((new Date()).getTime());
  1864. }
  1865. function isset(v) {
  1866.     return ((typeof(v) == 'undefined' || v.length == 0) ? v : '');
  1867. }
  1868. function noMove() {
  1869.     if (stop) {
  1870.         stop = 0;
  1871.         document.onmouseup = function () {
  1872.             document.onmouseup = '';
  1873.             stop = 1;
  1874.         };
  1875.     }
  1876.     return false;
  1877. }
  1878. function trim(s) {
  1879.     return (s.replace(/^\s+|\s+$/g, ''));
  1880. }
  1881. function ucletter(v) {
  1882.     return (v.substr(0,1).toUpperCase());
  1883. }
  1884. function ucword(v) {
  1885.     return (v.substr(0,1).toUpperCase() + v.substr(1));
  1886. }
  1887. function XYwin(v) {
  1888.     var o = agent('msie') ? {
  1889.         'X': document.body.clientWidth,
  1890.         'Y': document.body.clientHeight
  1891.     } : {
  1892.         'X': window.innerWidth,
  1893.         'Y': window.innerHeight
  1894.     };
  1895.     return (v ? o[v] : o);
  1896. }
  1897. function XY(e, v) {
  1898.     var o = agent('msie') ? {
  1899.         'X': event.clientX + document.body.scrollLeft,
  1900.         'Y': event.clientY + document.body.scrollTop
  1901.     } : {
  1902.         'X': e.pageX,
  1903.         'Y': e.pageY
  1904.     };
  1905.     return (v ? o[v] : o);
  1906. }
  1907. function zindex(d) {
  1908.     d.style.zIndex = win.zindex++;
  1909. }
  1910. /* CLASSNAME */
  1911. function $C(v, o) { // GET CLASS
  1912.     var o = (typeof(o) == 'object' ? o : $(o)).getElementsByTagName("*"),
  1913.     rx = new RegExp('\\b' + v + '\\b'),
  1914.     z = [];
  1915.     for (var i = 0; i < o.length; i++) {
  1916.         if (rx.test(o[i].className)) z.push(o[i]);
  1917.     }
  1918.     return (z);
  1919. };
  1920. function C$(v, o) { // SET CLASS
  1921.     if (!$(v)) {
  1922.         return false;
  1923.     }
  1924.     var d = $(v),
  1925.     c = d.className;
  1926.     if (o['+']) {
  1927.         d.className = c + ' ' + o['+'];
  1928.     }
  1929.     if (o['-']) {
  1930.         var ob = o['-'].split(' '),
  1931.         r = {};
  1932.         for (var i in ob) {
  1933.             r[ob[i]] = 1;
  1934.         }
  1935.         var c = c.split(' '),
  1936.         z = '';
  1937.         for (var i in c) {
  1938.             i = c[i];
  1939.             if (!r[i]) z += i + ' ';
  1940.         };
  1941.         d.className = z;
  1942.     }
  1943. };
  1944. /* EVENT */
  1945. Event = {
  1946.     'add': function (o, v, fu) {
  1947.         if (typeof(v) != 'object') v = {
  1948.             el: v,
  1949.             e: v
  1950.         };
  1951.         if (o.addEventListener) o.addEventListener(v.el, fu, false);
  1952.         else if (o.attachEvent) {
  1953.             v = v.e;
  1954.             o["e" + v + fu] = fu;
  1955.             o[v + fu] = function () {
  1956.                 o["e" + v + fu](window.event);
  1957.             };
  1958.             o.attachEvent("on" + v, o[v + fu]);
  1959.         }
  1960.     },
  1961.     'rm': function (o, v, fu) {
  1962.         if (typeof(v) != 'object') v = {
  1963.             el: v,
  1964.             e: v
  1965.         };
  1966.         if (o.removeEventListener) o.removeEventListener(v.el, fu, false);
  1967.         else if (o.detachEvent) {
  1968.             v = v.e;
  1969.             o.detachEvent("on" + v, o[v + fu]);
  1970.             o[v + fu] = null;
  1971.             o["e" + v + fu] = null;
  1972.         }
  1973.     }
  1974. };
  1975. /* MOVEMENT */
  1976. var aXY = {},
  1977. bXY = {},
  1978. oXY = {},
  1979. cXY = {},
  1980. mXY = '',
  1981. moXY = {},
  1982. mcXY = {},
  1983. stop = 1;
  1984. core = {
  1985.     'X': function (o, m, a, x) {
  1986.         a.X = Math.max(x.X1, x.X2 ? Math.min(x.X2, a.X + x.X1) : a.X + x.X1);
  1987.         return (a);
  1988.     },
  1989.     'Y': function (o, m, a, x) {
  1990.         a.Y = Math.max(x.Y1, x.Y2 ? Math.min(x.Y2, a.Y + x.Y1) : a.Y + x.Y1);
  1991.         return (a);
  1992.     },
  1993.     'XY': function (o, m, a, x) {
  1994.         a.X = x.X2 ? Math.min(a.X + x.X1, x.X2 - x.X1) : a.X + x.X1;
  1995.         a.Y = x.Y2 ? Math.min(a.Y + x.Y1, x.Y2 - x.Y1) : a.Y + x.Y1;
  1996.         return (a);
  1997.     },
  1998.     'fu': function (o, e, C, F) {
  1999.         if (stop) {
  2000.             var oX = abPos($(o)).X,
  2001.                 oY = abPos($(o)).Y,
  2002.                 r = XY(e);
  2003.             function c(e, m) {
  2004.                 r = XY(e);
  2005.                 if (C) r = C.fu(o, m, {
  2006.                     'X': r.X - oX,
  2007.                     'Y': r.Y - oY
  2008.                 },
  2009.                 C);
  2010.                 return (r);
  2011.             }
  2012.             function f(e, m) {
  2013.                 c(e, m);
  2014.                 if (F) F(oXY, r, m, e);
  2015.                 return (r);
  2016.             }
  2017.             function p(e, m) {
  2018.                 r = XY(e);
  2019.                 return ((m == 'down' ? 'P' : ' ') + (r.X - oX) + ' ' + (r.Y - oY) + (m == 'up' ? 'z' : ''));
  2020.             }
  2021.             if (isNaN(C.oX)) {
  2022.                 oX = r.X - oX;
  2023.             } else {
  2024.                 oX = oX - C.oX - zero($S(o).left);
  2025.             }
  2026.             if (isNaN(C.oY)) {
  2027.                 oY = r.Y - oY;
  2028.             } else {
  2029.                 oY = oY - C.oY - zero($S(o).top);
  2030.             }
  2031.             stop = 0;
  2032.             oXY = c(e);
  2033.             cXY = f(e, mXY = 'down');
  2034.             core.time = getTime();
  2035.             var tool = 'T' + vars.type + ' rgba(' + vars['fillCO'].join(",") + ') rgba(' + vars['strokeCO'].join(",") + ')';
  2036.             var i = '',
  2037.             t = [],
  2038.             v = {};
  2039.             if ((vars.type in gui_options.modules) && ('vars' in gui_options.modules[vars.type])) {
  2040.                 v = gui_options.modules[vars.type].vars;
  2041.                 for (i in v) if (i in vars) t.push(i + '(' + vars[i] + ')');
  2042.                 if (t.length) tool += ' ' + t.join(' ');
  2043.             }
  2044.             document.onmousemove = function (e) {
  2045.                 if(typeof(e) == 'undefined') var e = event;
  2046.                 if (!stop) {
  2047.                     cXY = f(e, 'move');
  2048.                 }
  2049.             }
  2050.             document.onmouseup = function (e) {
  2051.                 if(typeof(e) == 'undefined') var e = event;
  2052.                 stop = 1;
  2053.                 document.onmousemove = '';
  2054.                 document.onmouseup = '';
  2055.                 cXY = f(e, mXY = 'up');
  2056.             };
  2057.             document.onselectstart = function () {
  2058.                 return false;
  2059.             }
  2060.         }
  2061.     },
  2062.     'win': function (o, m, a, x) {
  2063.         a.X = (!isNaN(x.X1) ? Math.max(a.X, x.X1) : a.X);
  2064.         a.Y = (!isNaN(x.Y1) ? Math.max(a.Y, x.Y1) : a.Y);
  2065.         var d = $S(o);
  2066.         if (m == 'down') {
  2067.             if (x.z) {
  2068.                 zindex($(o));
  2069.             }
  2070.             core.win.stop = 0;
  2071.             setTimeout("if(!core.win.stop) { core.win_visible('" + o + "','hidden'); }", 500);
  2072.         } else if (m == 'move') {
  2073.             if (!core.win.stop) core.win_visible(o, 'hidden');
  2074.             core.win.stop = 1;
  2075.         }
  2076.         if (E.sh && oXY) { // SNAP TO XY
  2077.             if (Math.abs(a.X - oXY.X) < Math.abs(a.Y - oXY.Y)) {
  2078.                 d.top = a.Y + 'px';
  2079.                 d.left = oXY.X + 'px';
  2080.             } else {
  2081.                 d.left = a.X + 'px';
  2082.                 d.top = oXY.Y + 'px';
  2083.             }
  2084.         } else {
  2085.             d.left = a.X + 'px';
  2086.             d.top = a.Y + 'px';
  2087.         }
  2088.         if (m == 'up') {
  2089.             if (win.r[o]) {
  2090.                 win.cp(o, ['block', zero(d.left), zero(d.top), parseInt(win.r[o][3])]);
  2091.             }
  2092.             core.win.stop = 1;
  2093.             core.win_visible(o, 'visible');
  2094.         }
  2095.         return (a);
  2096.     },
  2097.     'win_visible': function (o, s) {
  2098.         var op = (s == 'visible') ? 1 : 0.5;
  2099.         if ($C('TMM', o)[0]) {
  2100.             $C('TMM', o)[0].style.opacity = op;
  2101.         } else if ($C('west', $C('TM', o)[0])[0]) {
  2102.             $C('west', o)[0].style.opacity = op;
  2103.             $C('east', o)[0].style.opacity = op;
  2104.         } else if ($C('TRx', o)[0]) {
  2105.             $C('TRx', o)[0].style.opacity = op;
  2106.             $C('TML', o)[0].style.opacity = op;
  2107.         } //        $S(o).overflow=s;
  2108.     }
  2109. };
  2110. /* MATH */
  2111. N = {
  2112.     'format': function (n) {
  2113.         n = String(n);
  2114.         var x = n.split('.'),
  2115.         x1 = x[0],
  2116.         x2 = x.length > 1 ? '.' + x[1] : '',
  2117.         rgx = /(\d+)(\d{3})/;
  2118.         while (rgx.test(x1)) {
  2119.             x1 = x1.replace(rgx, '$1' + ',' + '$2');
  2120.         }
  2121.         return (x1 + x2);
  2122.     },
  2123.     'between': function (n, a, z) {
  2124.         return ((n >= a && n <= z) ? true : false);
  2125.     },
  2126.     'rand': function (n) {
  2127.         return (Math.floor(Math.random() * n));
  2128.     }
  2129. };
  2130. function exp(a, z, n, d) {
  2131.     if (n <= 1) n *= 100;
  2132.     if (d == 'low') var y = Math.pow(2, n / 15.019);
  2133.     else var y = -105.78 * Math.pow(2, -1 * n / 15) + 102;
  2134.     return ((y / 100) * (z - a) + a - (.01 * z))
  2135. };
  2136. function zero(n) {
  2137.     return (!isNaN(n = parseFloat(n)) ? n : 0);
  2138. }
  2139. /* JUNK */
  2140. function deObject(o) {
  2141.     var z = [];
  2142.     for (var i in o) {
  2143.         if (typeof(o[i]) == 'object') {
  2144.             z[i] = [];
  2145.             for (var ii in o[i]) {
  2146.                 if (!isNaN(o[i][ii])) z[i][ii] = Number(o[i][ii]); // NUMBERS
  2147.                 else if (typeof(o[i][ii]) == 'object') z[i][ii] = String(o[i][ii]).split(','); // ARRAYS
  2148.                 else if (typeof(o[i][ii]) == 'string') z[i][ii] = o[i][ii]; // STRINGS
  2149.                 //- should accept objects, and null values
  2150.             }
  2151.         } else z = '';
  2152.     }
  2153.     return (z ? z : String(o).split(','));
  2154. };
  2155. function typeOf(v) {
  2156.     var z = typeof(v);
  2157.     if (z === 'object') {
  2158.         if (v) {
  2159.             if (v instanceof Array) {
  2160.                 z = 'array';
  2161.             }
  2162.         } else {
  2163.             z = 'null';
  2164.         }
  2165.     }
  2166.     return (z);
  2167. };
  2168. /* SETTINGS */
  2169.  
  2170. var co = { },
  2171.     vars = { };
  2172.  
  2173. (function() {
  2174.  
  2175. vars = {
  2176.     'id': 'fill',
  2177.     'draw': 'Brush',
  2178.     'font': 'Arial',
  2179.     'gradient': 'fixed',
  2180.     'marquee': 'polygon',
  2181.     'shape': 'ellipses',
  2182.     'stamp': 'Default',
  2183. // Splatter',
  2184.     'PT*': 'Squidfingers',
  2185.     'GD*': 'Web v2.0',
  2186.     'CO*': 'Oxygen',
  2187.     'constrain': 'false',
  2188.     'fillPT': new Image(),
  2189.     'fill': 'solid',
  2190.     'lineCap': 'round',
  2191.     'lineClose': 'false',
  2192.     'lineJoin': 'miter',
  2193.     'strokePT': new Image(),
  2194.     'stroke': 'solid',
  2195.     'type': 'Brush',
  2196.     'zoom': 100
  2197. };
  2198. vars.updateTool = function () {
  2199.     var b = vars.type;
  2200.     vars.tool = ucword(b) + (b == 'shape' || b == 'marquee' ? '_' + vars[b] : '');
  2201. };
  2202. (vars.cache = function (s) {
  2203.     var c = cookieGrab('settings');
  2204.     if (!vars.tool) {
  2205.         vars.updateTool();
  2206.     }
  2207.     if (c && !s) {
  2208.         var z = c.split(','); // OPEN
  2209.         for (var i in z) {
  2210.             var v = z[i].split(':');
  2211.             if (!isNaN(parseInt(v[1]))) v[1] = parseInt(v[1]);
  2212.             if (v[0] != 'zoom') vars[v[0]] = v[1];
  2213.         }
  2214.     } else {
  2215.         var z = '',
  2216.         r = {
  2217.             'object': 1,
  2218.             'function': 1
  2219.         }; // SAVE
  2220.         for (var i in vars) {
  2221.             if (!r[typeof(vars[i])]) {
  2222.                 z += i + ':' + vars[i] + ',';
  2223.             }
  2224.         }
  2225.         z = z.substr(0, z.length - 1);
  2226.         cookieStab('settings', z);
  2227.     }
  2228. })();
  2229. /* SHAPES */
  2230. co.polygon=function(a,b,c,s) {
  2231.     var T=!isNaN(s)?'marquee':'shape', o=co.constrain(a,b,s), scale=co.scale(a,b,s);
  2232.     var rad=Math.sqrt(Math.pow(a.X-o.X,2)+Math.pow(a.Y-o.Y,2))/2, sides=vars['sides_'+T];
  2233.     var x=o.X-((o.X-a.X)/2), y=o.Y-((o.Y-a.Y)/2), step=(Math.PI*2)/sides;
  2234.     var angle=E.ctrl?Math.atan2(o.X-a.X,o.Y-a.Y):(Math.PI/180*45), j=0;
  2235.     var check=(isNaN(s) && mXY=='up' && Math.abs(a.X-b.X)>0 && Math.abs(a.Y-b.Y)>0);
  2236.    
  2237.     function fu_x() {
  2238.         return x+Math.cos(angle+(step*n))*rad*scale.X;
  2239.     }
  2240.     function fu_y() { return(y-Math.sin(angle+(step*n))*rad*scale.Y); }
  2241.  
  2242.     var n=0;
  2243.     c.moveTo(fu_x(), fu_y());
  2244.  
  2245.     for(var n=1; n<=sides; n++) {
  2246.  
  2247.         c.lineTo(fu_x(), fu_y());
  2248.    
  2249.     }
  2250.    
  2251.     c.closePath();
  2252.  
  2253. };
  2254.  
  2255. co.star=function(a,b,c,s) { var T=!isNaN(s)?'marquee':'shape', o=co.constrain(a,b,s), scale=co.scale(a,b,s);
  2256.     var rad=Math.sqrt(Math.pow(a.X-o.X,2)+Math.pow(a.Y-o.Y,2))/2, rad2=rad/vars['slope_'+T], sides=vars['sides_'+T];
  2257.  
  2258.     var x=o.X-((o.X-a.X)/2), y=o.Y-((o.Y-a.Y)/2), step=(Math.PI*2)/sides, halfStep=step/2;
  2259.  
  2260.     var r=(Math.PI/180), angle=E.ctrl?Math.atan2(o.X-a.X,o.Y-a.Y):r*45, j=0;
  2261.  
  2262.     var check=(isNaN(s) && mXY=='up' && Math.abs(a.X-b.X)>0 && Math.abs(a.Y-b.Y)>0);
  2263.    
  2264.     function fu1(v) { return((v=='X')?(x+Math.cos(angle+(step*n)-halfStep)*rad*scale.X):(y-Math.sin(angle+(step*n)-halfStep)*rad*scale.Y)); }
  2265.     function fu2(v) { return((v=='X')?(x+Math.cos(angle+(step*n))*rad2*scale.X):(y-Math.sin(angle+(step*n))*rad2*scale.Y)); }
  2266.  
  2267.     var n=0; c.moveTo(fu2('X'), fu2('Y'));
  2268.  
  2269.     for(var n=1; n<=sides; n++) {
  2270.    
  2271.         c.lineTo(fu1('X'), fu1('Y')); c.lineTo(fu2('X'), fu2('Y'));
  2272.  
  2273.     }
  2274.    
  2275.     c.closePath();
  2276.  
  2277. };
  2278.  
  2279. co.burst=function(a,b,c,s) { var T=!isNaN(s)?'marquee':'shape', o=co.constrain(a,b,s), scale=co.scale(a,b,s);
  2280.  
  2281.     var rad=Math.sqrt(Math.pow(a.X-o.X,2)+Math.pow(a.Y-o.Y,2))/2, rad2=rad/vars['slope_'+T], sides=vars['sides_'+T];
  2282.  
  2283.     var x=o.X-((o.X-a.X)/2), y=o.Y-((o.Y-a.Y)/2), step=(Math.PI*2)/sides, halfStep=step/2, qtrStep=step/4;
  2284.  
  2285.     var angle=E.ctrl?Math.atan2(o.X-a.X,o.Y-a.Y):(Math.PI/180*45), j=0;
  2286.  
  2287.     var check=(isNaN(s) && mXY=='up' && Math.abs(a.X-b.X)>0 && Math.abs(a.Y-b.Y)>0);
  2288.  
  2289.     c.moveTo(x+(Math.cos(angle)*rad)*scale.X, y-(Math.sin(angle)*rad)*scale.Y);
  2290.  
  2291.     for(var n=1; n<=sides; n++) {
  2292.  
  2293.         c.quadraticCurveTo(x+Math.cos(angle+(step*n)-(qtrStep*3))*(rad2/Math.cos(qtrStep))*scale.X, y-Math.sin(angle+(step*n)-(qtrStep*3))*(rad2/Math.cos(qtrStep))*scale.Y, x+Math.cos(angle+(step*n)-halfStep)*rad2*scale.X, y-Math.sin(angle+(step*n)-halfStep)*rad2*scale.Y);
  2294.         c.quadraticCurveTo(x+Math.cos(angle+(step*n)-qtrStep)*(rad2/Math.cos(qtrStep))*scale.X, y-Math.sin(angle+(step*n)-qtrStep)*(rad2/Math.cos(qtrStep))*scale.Y, x+Math.cos(angle+(step*n))*rad*scale.X, y-Math.sin(angle+(step*n))*rad*scale.Y);
  2295.     }
  2296.  
  2297.     c.closePath();
  2298.  
  2299. };
  2300.  
  2301. co.gear=function(a,b,c,s) { var T=!isNaN(s)?'marquee':'shape', o=co.constrain(a,b,s), scale=co.scale(a,b,s);
  2302.  
  2303.     var rad=Math.sqrt(Math.pow(a.X-o.X,2)+Math.pow(a.Y-o.Y,2))/2, rad2=rad/vars['slope_'+T], sides=vars['sides_'+T];
  2304.  
  2305.     var x=o.X-((o.X-a.X)/2), y=o.Y-((o.Y-a.Y)/2), step=(Math.PI*2)/sides, halfStep=step/2, qtrStep=step/4;
  2306.  
  2307.     var angle=E.ctrl?Math.atan2(o.X-a.X,o.Y-a.Y):(Math.PI/180*45), j=0;
  2308.  
  2309.     var check=(isNaN(s) && mXY=='up' && Math.abs(a.X-b.X)>0 && Math.abs(a.Y-b.Y)>0);
  2310.    
  2311.     c.moveTo(x+(Math.cos(angle)*rad2)*scale.X, y-(Math.sin(angle)*rad2)*scale.Y);
  2312.  
  2313.     for(var n=1; n<=sides; n++) {
  2314.    
  2315.         c.lineTo(x+Math.cos(angle+(step*n)-(qtrStep*3))*rad*scale.X, y-Math.sin(angle+(step*n)-(qtrStep*3))*rad*scale.Y);
  2316.         c.lineTo(x+Math.cos(angle+(step*n)-(qtrStep*2))*rad*scale.X, y-Math.sin(angle+(step*n)-(qtrStep*2))*rad*scale.Y);
  2317.         c.lineTo(x+Math.cos(angle+(step*n)-qtrStep)*rad2*scale.X, y-Math.sin(angle+(step*n)-qtrStep)*rad2*scale.Y);
  2318.         c.lineTo(x+Math.cos(angle+(step*n))*rad2*scale.X, y-Math.sin(angle+(step*n))*rad2*scale.Y);
  2319.  
  2320.     }
  2321.    
  2322.     c.closePath();
  2323.  
  2324. };
  2325.  
  2326. co.ellipses=function(a,b,c,s) {
  2327.     var T=!isNaN(s)?'marquee':'shape', o=co.constrain(a,b,s), scale=co.scale(a,b,s);
  2328.     var rad=Math.sqrt(Math.pow(a.X-o.X,2)+Math.pow(a.Y-o.Y,2))/2, sides=150;
  2329.     var x=o.X-((o.X-a.X)/2), y=o.Y-((o.Y-a.Y)/2), step=(Math.PI*2)/sides;
  2330.     var angle=E.ctrl?Math.atan2(o.X-a.X,o.Y-a.Y):(Math.PI/180*45), j=0;
  2331.     var check=(isNaN(s) && mXY=='up' && Math.abs(a.X-b.X)>0 && Math.abs(a.Y-b.Y)>0);
  2332.     function fu_x() {
  2333.         return x+Math.cos(angle+(step*n))*rad*scale.X;
  2334.     }
  2335.     function fu_y() { return(y-Math.sin(angle+(step*n))*rad*scale.Y); }
  2336.     var n=0;
  2337.     c.moveTo(fu_x(), fu_y());
  2338.     for(var n=1; n<=sides; n++) {
  2339.         c.lineTo(fu_x(), fu_y());
  2340.     }
  2341.     c.closePath();
  2342. };
  2343.  
  2344. co.circle = function (a, b, c) {
  2345.     var d = {
  2346.         'X': Math.max(a.X, b.X) - Math.abs(a.X - b.X) / 2,
  2347.         'Y': Math.max(a.Y, b.Y) - Math.abs(a.Y - b.Y) / 2
  2348.     };
  2349.     var r = Math.sqrt(Math.pow(a.X - b.X, 2) + Math.pow(a.Y - b.Y, 2)) / 2;
  2350.     c.arc(d.X, d.Y, r, 0, Math.PI * 2, true);
  2351.     c.closePath();
  2352. };
  2353.  
  2354. co.rectangle = function (a, b, c, s) {
  2355.     var o = co.constrain(a, b, s);
  2356.     if ((a.X - o.X <= 0) != (a.Y - o.Y <= 0)) {
  2357.         c.moveTo(a.X, a.Y);
  2358.         c.lineTo(o.X, a.Y);
  2359.         c.lineTo(o.X, o.Y);
  2360.         c.lineTo(a.X, o.Y);
  2361.     } else {
  2362.         c.moveTo(a.X, a.Y);
  2363.         c.lineTo(a.X, o.Y);
  2364.         c.lineTo(o.X, o.Y);
  2365.         c.lineTo(o.X, a.Y);
  2366.     }
  2367.     c.closePath();
  2368. };
  2369.  
  2370. /* CACHE */
  2371.  
  2372. co.brush = function () {
  2373.     if (vars.type == 'brush' || vars.type == 'eraser' || vars.type == 'pencil') {
  2374.         var c = $2D('ctx_brush'),
  2375.             D = vars['diameter_' + vars.type],
  2376.             D2 = D * 2;
  2377.         $('ctx_brush').width = D2;
  2378.         $('ctx_brush').height = D2;
  2379.         co.del(c);
  2380.         c.globalCompositeOperation = 'source-over';
  2381.         var r = c.createRadialGradient(D, D, (vars.type == 'pencil') ? D - 1 : vars['hardness_' + vars.type] / 100 * D - 1, D, D, D);
  2382.         r.addColorStop(0, 'rgba(0,0,0,' + (vars['opacity_' + vars.type] / 100) + ')');
  2383.         r.addColorStop(0.95, 'rgba(0,0,0,0)'); // prevent aggregation of semi-opaque pixels
  2384.         r.addColorStop(1, 'rgba(0,0,0,0)');
  2385.         c.fillStyle = r;
  2386.         c.fillRect(0, 0, D2, D2);
  2387.         c.globalCompositeOperation = 'source-in';
  2388.         c.rect(0, 0, D2, D2);
  2389.         co.style[vars.fill]({
  2390.             'X': 0,
  2391.             'Y': 0
  2392.         },
  2393.         {
  2394.             'X': D2,
  2395.             'Y': D2
  2396.         },
  2397.         c, 'fill');
  2398.     }
  2399. };
  2400.  
  2401. co.glyph = function (v, o) {
  2402.     co.brush();
  2403.     if(!v) {
  2404.         co.stamp();
  2405.         return;
  2406.     }
  2407.     co.stamp.image = new Image();
  2408.     co.stamp.image.src = v;
  2409.     ///
  2410.     if ($(o)) {
  2411.         if ($(stamp.o)) {
  2412.             $(stamp.o).className = '';
  2413.         }
  2414.         co.del(o);
  2415.         C$(o, {
  2416.             '+': 'load'
  2417.         });
  2418.         stamp.o = o;
  2419.     }
  2420.     co.stamp.image.onload = function () {
  2421.         var o = co.stamp.image;
  2422.         stamp.loaded = true;
  2423.         var id = stamp.fileNumber;
  2424.         C$('stamp' + id, { '-': 'load' });
  2425.         stamp.preview(id, 'move');
  2426.         co.stamp.r = {
  2427.             W: o.width,
  2428.             H: o.height
  2429.         };
  2430.         co.stamp();
  2431.     }
  2432. };
  2433.  
  2434. co.stamp = function () {
  2435.     if ((vars.type == 'calligraphy' || vars.type == 'stamp') && co.stamp.image.src) {
  2436.         var c = $2D('ctx_stamp'),
  2437.             i = co.stamp.image,
  2438.             n = vars.type == 'stamp' ? vars.rand_min / 100 : 1,
  2439.             o = co.stamp.r = {
  2440.                 W: Math.round(i.width * n),
  2441.                 H: Math.round(i.height * n)
  2442.             };
  2443.         $('ctx_stamp').width = o.W;
  2444.         $('ctx_stamp').height = o.H;
  2445.         c.save();
  2446.         c.clearRect(0, 0, canvas.W, canvas.H);
  2447.         c.globalAlpha = vars['opacity_' + vars.type] / 100;
  2448.         c.globalCompositeOperation = 'source-over';
  2449.         c.drawImage(i, 0, 0, o.W, o.H);
  2450.         c.globalCompositeOperation = 'source-atop';
  2451.         c.rect(0, 0, o.W, o.H);
  2452.         style(c, "fillStyle", "fill", { X: 0, Y: 0 }, { X: o.W, Y: o.H });
  2453.         c.fill();
  2454.         c.restore();
  2455.     }
  2456. };
  2457. co.stamp.image=new Image();
  2458. co.stamp.r={};
  2459.  
  2460. /* EXTENDED */
  2461.  
  2462. co.core = function (e, fu) {
  2463.     var d = win_size.LT();
  2464.     core.fu('cBound', e, {
  2465.         fu: core.XY,
  2466.         X1: 0,
  2467.         Y1: 0,
  2468.         oX: -1 - d.L,
  2469.         oY: -1 - d.T
  2470.     },
  2471.     fu);
  2472. };
  2473.  
  2474. co.copy = function (a, b) {
  2475.     $2D(b).drawImage($(a), 0, 0, canvas.W, canvas.H);
  2476. };
  2477.  
  2478. co.del = function (c) {
  2479.     if (c.length) c = $2D(c);
  2480.     c.clearRect(0, 0, canvas.W, canvas.H);
  2481. };
  2482.  
  2483. co.path = function (c, r) {
  2484.     c.moveTo(r[0].X, r[0].Y);
  2485.     for (var i in r) {
  2486.         c.lineTo(r[i].X, r[i].Y);
  2487.     }
  2488. };
  2489.  
  2490. /* TRANSFORMATION */
  2491.  
  2492. co.constrain = function (a, b, s) {
  2493.     if (((E.sh || !isNaN(s)) && s == 1) || (E.sh && isNaN(s)) && !E.ctrl) {
  2494.         var X = (b.X - a.X) ? (b.X - a.X) : 1,
  2495.             Y = (b.Y - a.Y) ? (b.Y - a.Y) : 1,
  2496.         Z = {
  2497.             X: Math.abs(X),
  2498.             Y: Math.abs(Y)
  2499.         };
  2500.         if (Z.X < Z.Y) return ({
  2501.             X: a.X + (X / Z.X * Z.Y),
  2502.             Y: b.Y
  2503.         });
  2504.         else return ({
  2505.             Y: a.Y + (Y / Z.Y * Z.X),
  2506.             X: b.X
  2507.         });
  2508.     } else {
  2509.         return (b);
  2510.     }
  2511. };
  2512.  
  2513. co.scale = function (a, b, s) {
  2514.     if ((((E.sh || !isNaN(s)) && s == 1) || (E.sh && isNaN(s)))) {
  2515.         return ({
  2516.             X: 1,
  2517.             Y: 1
  2518.         });
  2519.     } else if (Math.abs(a.X - b.X) > Math.abs(a.Y - b.Y)) {
  2520.         return ({
  2521.             X: 1,
  2522.             Y: zero(Math.abs(a.Y - b.Y) / Math.abs(a.X - b.X))
  2523.         });
  2524.     } else {
  2525.         return ({
  2526.             X: zero(Math.abs(a.X - b.X) / Math.abs(a.Y - b.Y)),
  2527.             Y: 1
  2528.         });
  2529.     }
  2530. };
  2531.  
  2532. /* STYLE */
  2533.  
  2534. co.style = { };
  2535. co.style.fill = function (c, s) {
  2536.     c.fillStyle = s;
  2537.     c.fill();
  2538. };
  2539. co.style.stroke = function (c, s) {
  2540.     c.strokeStyle = s;
  2541.     c.stroke();
  2542. };
  2543. co.style.solid = function (a, b, c, v, s) {
  2544.     co.style[v](c, 'rgba(' + vars[((s && isNaN(s)) ? s : v) + 'CO'].join(",") + ')');
  2545. };
  2546. co.style.pattern = function (a, b, c, v, s) {
  2547.     co.style[v](c, vars[((s && isNaN(s)) ? s : v)+'PT~']);
  2548. };
  2549. co.style.gradient = {};
  2550. co.style.gradient = function (a, b, c, v, s) {
  2551.     co.style.gradient[vars.gradient](a, b, c, v, s);
  2552. };
  2553. co.style.gradient.fixed = function (a, b, c, v, s) {
  2554.     co.gradient(a, b, c, vars[((s && isNaN(s)) ? s : v) + 'GD'], v, s);
  2555. };
  2556. co.style.gradient.relative = function (a, b, c, v, s) {
  2557.     co.gradient(cXY, b, c, vars[((s && isNaN(s)) ? s : v) + 'GD'], v, s);
  2558. };
  2559. co.style.gradient.absolute = function (a, b, c, v, s) {
  2560.     co.gradient({
  2561.         X: 0,
  2562.         Y: 0
  2563.     },
  2564.     {
  2565.         X: canvas.W,
  2566.         Y: canvas.H
  2567.     },
  2568.     c, vars[((s && isNaN(s)) ? s : v) + 'GD'], v, s);
  2569. };
  2570. co.gradient = function (a, b, c, r, v, s) {
  2571.     var g;
  2572.     if (!s) { // ROTATE
  2573.         var W = Math.sqrt(Math.pow(b.X - a.X, 2)),
  2574.         W2 = W / 2,
  2575.         rad = gui_gradient.rotate,
  2576.         mX = Math.min(b.X, a.X),
  2577.         mY = Math.min(b.Y, a.Y);
  2578.         var s1 = Math.abs((Math.sin(rad) * W2) + W2),
  2579.         s2 = Math.abs((Math.cos(rad) * W2) - W2);
  2580.         var x1 = Math.abs((Math.sin(rad + Math.PI) * W2) + W2),
  2581.         y1 = Math.abs((Math.cos(rad + Math.PI) * W2) - W2);
  2582.         g = c.createLinearGradient(s1 + mX, s2 + mY, x1 + mX, y1 + mY);
  2583.     } else g = c.createLinearGradient(a.X, a.Y, b.X, b.Y);
  2584.     for (var i in r) {
  2585.         if (!r[i][2]) {
  2586.             g.addColorStop(r[i][0], 'rgba(' + r[i][1].join(",") + ')');
  2587.         }
  2588.     }
  2589.     co.style[v](c, g);
  2590. };
  2591.  
  2592. })();
  2593. /*
  2594.     GUI Interface / 0.1 /
  2595.     -------------------------
  2596.     gui_tools
  2597.     gui_palette
  2598.     gui_color
  2599.     gui_gradient
  2600.     gui_pattern
  2601.     gui_swatch
  2602.  
  2603. */
  2604.  
  2605. // TOOLS window
  2606.  
  2607. gui_tools = {
  2608.     imagePos: {}, // y-pos of backgroundPosition (all tools are in media/GUI/Tools.png
  2609.     imageMap: function () { // create image mapping
  2610.         var elements = $T('div', $C('tools', 'tools')[0]),
  2611.             icons = [
  2612.                 'Brush',
  2613.                 'Calligraphy',
  2614.                 'Crop',
  2615.                 'Eraser',
  2616.                 'Fill',
  2617.                 'Marquee_burst',
  2618.                 'Marquee_ellipses',
  2619.                 'Marquee_gear',
  2620.                 'Marquee_lasso',
  2621.                 'Marquee_polygon',
  2622.                 'Marquee_rectangle',
  2623.                 'Marquee_star',
  2624.                 'Original',
  2625.                 'Pencil',
  2626.                 'Picker',
  2627.                 'Select',
  2628.                 'Shape_burst',
  2629.                 'Shape_ellipses',
  2630.                 'Shape_gear',
  2631.                 'Shape_polygon',
  2632.                 'Shape_rectangle',
  2633.                 'Shape_star',
  2634.                 'Stamp',
  2635.                 'Text',
  2636.                 'Zoom',
  2637.                 'Spirograph'
  2638.             ];
  2639.         for (var n in icons) {
  2640.             gui_tools.imagePos[icons[n]] = n * 26 - 5;
  2641.         }
  2642.         for (var image in elements) {
  2643.             image = elements[image];
  2644.             if (typeof(image) == 'object') {
  2645.                 var o = $T('img', image);
  2646.                 if (o[0]) {
  2647.                     o = (o[1] && o[1].className != 'plus') ? o[1] : o[0];
  2648.                     var o = o.className.split(' ')[0];
  2649.                     var u = o.split('_')[0];
  2650.                     if (u == 'Marquee' || u == 'Shape') {
  2651.                         o = u + '_' + vars[u.toLowerCase()];
  2652.                     } else if (u == 'Brush') {
  2653.                         o = ucword(vars['draw']);
  2654.                     }
  2655.                     image.style.backgroundImage = 'url(media/gui/tools/Tools.png)';
  2656.                     image.style.backgroundPosition = '5px ' + (-gui_tools.imagePos[o]) + 'px';
  2657.                     image.title = o.split('_')[0];
  2658.                     image.onmousedown = function (event) {
  2659.                         event.preventDefault();
  2660.                     };
  2661.                 }
  2662.             }
  2663.         }
  2664.     },
  2665.     imageSize: function (v, i, end) { // image animation (switching tools)
  2666.         var o = $C(v, 'tools')[0],
  2667.         d = o.style;
  2668.         d.width = (15 + i) + 'px';
  2669.         d.height = (15 + i) + 'px';
  2670.         d.top = (-(i / 2)) + 'px';
  2671.         d.left = (-(i / 2)) + 'px';
  2672.         if (i == end) {
  2673.             var d = o.parentNode.style;
  2674.             d.backgroundPosition = '5px ' + (-gui_tools.imagePos[v]) + 'px';
  2675.             if (i == 25) {
  2676.                 o.style.display = "block";
  2677.                 o.src = 'media/gui/tools/' + v + '_2.png';
  2678.                 d.backgroundImage = '';
  2679.             } else if (i == 0) {
  2680.                 o.src = '';
  2681.                 o.style.display = "none";
  2682.                 d.backgroundImage = 'url(media/gui/tools/Tools.png)';
  2683.             }
  2684.         } else if ((i == 0 && end == 25) || (i == 25 && end == 0)) {
  2685.             var o = $T('img', o.parentNode);
  2686.             if (o[1]) {
  2687.                 o[0].style.display = (i == 0) ? 'none' : 'block';
  2688.             }
  2689.         }
  2690.     },
  2691.     imageCurrent: function (v) {
  2692.         function getRoot(v) {
  2693.             return (v.indexOf('_') != -1 ? v.substr(0, v.indexOf('_')) : v).toLowerCase();
  2694.         };
  2695.         var prev = gui_tools.prev,
  2696.             p = getRoot(prev ? prev : vars.type),
  2697.             c = getRoot(v);
  2698.         vars.type = c;
  2699.         vars.typeImg = v;
  2700.         if (prev != v) { // tool has switched
  2701.             function zoom(o, n) {
  2702.                 setTimeout("gui_tools.imageSize('" + o + "'," + i + "," + n + ")", (timer++) * 4);
  2703.             };
  2704.             if (c == 'marquee' || c == 'crop') {
  2705.                 marquee.reset();
  2706.             }
  2707.             if (p == 'crop') {
  2708.                 crop.reset();
  2709.             }
  2710.             if (prev) {
  2711.                 var timer = 0,
  2712.                 img1 = new Image();
  2713.                 img1.src = 'media/gui/tools/' + prev + '.png';
  2714.                 for (var i = 25; i >= 0; i--) {
  2715.                     zoom(prev, 0);
  2716.                 }
  2717.             }
  2718.             var timer = 0,
  2719.             img2 = new Image();
  2720.             img2.src = 'media/gui/tools/' + v + '_2.png';
  2721.             for (var i = 0; i <= 25; i++) {
  2722.                 zoom(v, 25);
  2723.             }
  2724.             gui_tools.prev = v;
  2725.             gui_options.forge(vars.type); // build "OPTIONS" window
  2726.             vars.updateTool(); //
  2727.             vars.cache(1);
  2728.         }
  2729.     }
  2730. };
  2731.  
  2732. // "OPTIONS" window
  2733.  
  2734. gui_options = {
  2735.     modulesObject: function () {
  2736.         gui_options.modules = {
  2737.             'marquee': {
  2738.                 build: ['sides_marquee', 'slope_marquee'],
  2739.                 vars: {
  2740.                     'movement_marquee': 'anchored',
  2741.                     'slope_marquee': 2,
  2742.                     'sides_marquee': 7
  2743.                 },
  2744.                 head: 'marquee',
  2745.                 size: {
  2746.                     'ellipses': 15,
  2747.                     'polygon': 40,
  2748.                     '': 85
  2749.                 }
  2750.             },
  2751.             'crop': {
  2752.                 build: ['constrain', 'aspect'],
  2753.                 vars: {
  2754.                     'constrain': 'false',
  2755.                     'aspect': 'landscape'
  2756.                 },
  2757.                 head: 'crop',
  2758.                 size: 58
  2759.             },
  2760.             'text': {
  2761.                 build: ['fontSize', 'stroke_text'],//'kerning', 'leading',
  2762.                 vars: {
  2763.                     'movement_text': 'active',
  2764.                     'fontSize': 90,
  2765.                     'kerning': 1,
  2766.                     'leading': 1.2,
  2767.                     'stroke_text': 3
  2768.                 },
  2769.                 size: 140
  2770.             },
  2771.             'shape': {
  2772.                 build: ['movement_' + vars.shape, 'corner', 'sides_shape', 'slope_shape', 'stroke_' + vars.shape],
  2773.                 vars: {
  2774.                     'movement_shape': 'anchored',
  2775.                     'stroke_shape': 7,
  2776.                     'gradient': 'fixed',
  2777.                     'slope_shape': 2,
  2778.                     'sides_shape': 7
  2779.                 },
  2780.                 head: 'shape',
  2781.                 size: {
  2782.                     'ellipses': 130,
  2783.                     'polygon': 170,
  2784.                     '': 210
  2785.                 }
  2786.             },
  2787.             'pencil': {
  2788.                 build: ['diameter_pencil', 'opacity_pencil'],
  2789.                 vars: {
  2790.                     'movement_pencil': 'freedraw',
  2791.                     'lineJoin': 'round',
  2792.                     'gradient': 'absolute',
  2793.                     'diameter_pencil': 10,
  2794.                     'flow_pencil': 100,
  2795.                     'opacity_pencil': 80
  2796.                 },
  2797.                 head: 'draw',
  2798.                 size: 85,
  2799.                 glyph: 1
  2800.             },
  2801.             'brush': {
  2802.                 build: ['diameter_brush', 'hardness_brush', 'flow_brush', 'opacity_brush'],
  2803.                 vars: {
  2804.                     'movement_brush': 'freedraw',
  2805.                     'diameter_brush': 25,
  2806.                     'hardness_brush': 60,
  2807.                     'flow_brush': 92,
  2808.                     'opacity_brush': 70
  2809.                 },
  2810.                 head: 'draw',
  2811.                 size: 165,
  2812.                 glyph: 1
  2813.             },
  2814.             'calligraphy': {
  2815.                 build: ['diameter_calligraphy', 'opacity_calligraphy'],
  2816.                 vars: {
  2817.                     'movement_calligraphy': 'freedraw',
  2818.                     'lineJoin': 'round',
  2819.                     'gradient': 'absolute',
  2820.                     'diameter_calligraphy': 50,
  2821.                     'flow_calligraphy': 100,
  2822.                     'opacity_calligraphy': 90
  2823.                 },
  2824.                 head: 'draw',
  2825.                 size: 80,
  2826.                 glyph: 1
  2827.             },
  2828.             'spirograph': {
  2829.                 build: ['inner_radius_spirograph', 'outer_radius_spirograph', 'diameter_spirograph','speed_spirograph','resolution_spirograph'],
  2830.                 vars: {
  2831.                     'inner_radius_spirograph': 29,
  2832.                     'outer_radius_spirograph': 79,
  2833.                     'diameter_spirograph': 30,
  2834.                     'speed_spirograph': 100,
  2835.                     'resolution_spirograph': 364,
  2836.                     'type_spirograph': 'Hypotrochoid'
  2837.                 },
  2838.                 head: 'spirograph',
  2839.                 size: 205,
  2840.                 glyph: 1
  2841.             },
  2842.             'stamp': {
  2843.                 build: ['rand', 'flow_stamp', 'opacity_stamp'],
  2844.                 vars: {
  2845.                     'movement_stamp': 'freedraw',
  2846.                     'flow_stamp': 10,
  2847.                     'opacity_stamp': 100,
  2848.                     'rand_min': 70,
  2849.                     'rand_max': 25
  2850.                 },
  2851.                 size: 275,
  2852.                 head: 'stamp'
  2853.             },
  2854.             'fill': {
  2855.                 build: ['opacity_fill'],
  2856.                 vars: {
  2857.                     'movement_fill': 'anchored',
  2858.                     'opacity_fill': 70
  2859.                 },
  2860.                 size: 40,
  2861.                 head: 'fill'
  2862.             },
  2863.             'eraser': {
  2864.                 build: ['diameter_eraser', 'hardness_eraser', 'flow_eraser', 'opacity_eraser'],
  2865.                 vars: {
  2866.                     'movement_eraser': 'freedraw',
  2867.                     'diameter_eraser': 25,
  2868.                     'flow_eraser': 90,
  2869.                     'hardness_eraser': 60,
  2870.                     'opacity_eraser': 30
  2871.                 },
  2872.                 size: 165,
  2873.                 glyph: 1
  2874.             },
  2875.             'picker': {
  2876.                 size: 75
  2877.             }
  2878.         }
  2879.     },
  2880.     forge: function (v) { // build "OPTIONS" window
  2881.         if (!gui_options.modules || v == 'shape') {
  2882.             gui_options.modulesObject();
  2883.         };
  2884.         var r = gui_options.modules[v],
  2885.             z = '';
  2886.         for (var i in r.vars) { // BUILD CONTENT
  2887.             if (!vars[i]) var b = r.vars[i];
  2888.             if (i == 'movement_shape') {
  2889.                 i = 'movement_' + vars.shape;
  2890.             } else if (i == 'stroke_shape') {
  2891.                 i = 'stroke_' + vars.shape;
  2892.             }
  2893.             if (!vars[i]) {
  2894.                 vars[i] = b;
  2895.             }
  2896.         }
  2897.         if (v == 'shape' || v == 'marquee') {
  2898.             var d = vars[v];
  2899.             gui_options.resize(r.size[d] ? r.size[d] : r.size['']);
  2900.         } else {
  2901.             gui_options.resize(r.size);
  2902.         };
  2903.         for (var i in r.build) {
  2904.             i = r.build[i];
  2905.             var o = i.indexOf('_') != -1 ? i.substr(0, i.indexOf('_')) : i,
  2906.                 title = o.replace('_', ' ').replace('line', '').replace('rand', 'diameter &middot; min, max').replace('font', '').replace('marq', '').replace('shape', '').toLowerCase(),
  2907.                 fu = (i == 'br') ? '<br>' : gui[cF[i].type].build(title, i, cF[i].val);
  2908.             if (v == 'shape') {
  2909.                 if ((d != 'ellipses' && d != 'polygon') || (d == 'ellipses' && i != 'corner' && i != 'sides_shape' && i != 'slope_shape') || (d == 'polygon' && i != 'slope_shape')) {
  2910.                     z += (i == 'stroke_ellipses' ? '<br>' : '') + fu;
  2911.                 }
  2912.             } else if (v == 'marquee') {
  2913.                 if ((d != 'ellipses' && d != 'polygon') || (d == 'polygon' && i != 'slope_marquee')) {
  2914.                     z += fu;
  2915.                 }
  2916.             } else {
  2917.                 z += fu;
  2918.             }
  2919.         }
  2920.         if(v == 'fill' || v =='brush' || v == 'pencil' || v == 'calligraphy' || v == 'stamp') { // these tools use only the "fill" property
  2921.             gui_palette.click('fill')      
  2922.         } else if(v == 'spirograph') { // these ones use only the "stroke" property
  2923.             gui_palette.click('stroke')    
  2924.         }
  2925.         switch(v) { // extra stuff
  2926.             case 'picker':
  2927.                 z = '<img src="media/gui/loupe.png" onmousedown="return(noMove())" class="loupe" alt="...">'+
  2928.                     '<canvas id="picker" height="106" width="149" style="height: 106px; width: 149px"></canvas>'+
  2929.                     '<div class="picker"><div>R<br>G<br>B<br>A</div><div id="picker_hex">0<br>0<br>0<br>0</div></div>'+
  2930.                     '<canvas id="picker1x1" height="1" width="1"></canvas>';
  2931.                 break;
  2932.             case 'stamp':
  2933.                 z = '<div id="stamp"></div>' + gui.Y.kontrol('stamp') +
  2934.                     "<span style=\"position: relative; top: -6px; border: 0\" id=\"brush_author\"></span>" + z;
  2935.                 break;
  2936.             case 'text':
  2937.                 if(!vars.textMessage) {
  2938.                     vars.textMessage = "hello!";
  2939.                 }
  2940.                 z = '<div id="text" style="padding-bottom: 13px">' +
  2941.                     ' <span style="font-size: 11px; -moz-user-select: none; -khtml-user-select: none; user-select: none; ">MESSAGE</span><br>' +
  2942.                     ' <input type="text" onmousedown="preventDefault = false;" onkeydown="vars.textMessage=this.value;" onkeyup="vars.textMessage=this.value;" style="width: 90%; font-size: 16px" value="'+vars.textMessage+'">' +
  2943.                     '</div>' + z;
  2944.                 break;
  2945.         }
  2946.         var d = $('options');
  2947.         $C('TML', d)[0].innerHTML = '<span style="-moz-user-select: none; -khtml-user-select: none; user-select: none; ">'+(r.head ? gui.menu.build(r.head, cF[r.head].val) : v)+'</div>';
  2948.         $C('MM', d)[0].innerHTML = '<div class="z" style="display: none; margin-top:1px;">' + z + '</div>';
  2949.         if (v == 'stamp') {
  2950.             stamp.reset();
  2951.         } else if (v == 'calligraphy') {
  2952.             co.glyph('media/glyph/Calligraphy/0-live.png');
  2953.         }
  2954.         if (r.glyph) {
  2955.             co.glyph();
  2956.         }
  2957.         if (!$('ioptions').opened) {
  2958.             win.tab($('ioptions'), 'options');
  2959.         }
  2960.         $C('z', d)[0].style.display = 'block';
  2961.     },
  2962.     resize: function (n) { // resize "OPTIONS" window
  2963.         function fu(o) {
  2964.             o.style.height = n + "px";
  2965.         };
  2966.         var o = $('options'),
  2967.             l = $C('ML', o)[0],
  2968.             m = $C('MM', o)[0],
  2969.             r = $C('MR', o)[0];
  2970.         fu(l);
  2971.         fu(r);
  2972.         fu(m);
  2973.         $S('options').height = (n + 40) + 'px';
  2974.         win.r['options'][3] = n + 40;
  2975.     }
  2976. };
  2977.  
  2978. // PALETTE
  2979.  
  2980. gui_palette = {
  2981.  
  2982.     click: function (v) {
  2983.         if(vars.id == v) {
  2984.             return;
  2985.         }
  2986.         gui_palette.zindex(v);
  2987.         gui_palette.run(gui_swatch.L2S[vars[vars.id = v]]);
  2988.     },
  2989.     zindex: function (v) {
  2990.         var r = {
  2991.             'fill': 'stroke',
  2992.             'stroke': 'fill'
  2993.         };
  2994.         function fu(v, c, i) {
  2995.             var o = $(v).parentNode.style;
  2996.             o.zIndex = i;
  2997.             o.cursor = c;
  2998.             $S(v).cursor = c;
  2999.         }
  3000.         fu(v, 'default', 2);
  3001.         fu(r[v], 'pointer', 1);
  3002.         $('swap').innerHTML = v.substr(0,1).toUpperCase();
  3003.     },
  3004.     current: function () {
  3005.         var q = gui_swatch.L2S,
  3006.             r = {
  3007.                 'CO': 1,
  3008.                 'GD': 1,
  3009.                 'PT': 1
  3010.             },
  3011.             b;
  3012.         for (var i in r) {
  3013.             b = gui_swatch.n['fill' + i];
  3014.             gui_swatch.n['fill' + i] = gui_swatch.n['stroke' + i];
  3015.             gui_swatch.n['stroke' + i] = b;
  3016.         }
  3017.         var z = (vars.id == 'fill'),
  3018.             a = z ? 'stroke' : 'fill',
  3019.             b = z ? 'fill' : 'stroke',
  3020.         z = '';
  3021.         if (vars.fill == 'pattern' || vars.stroke == 'pattern') {
  3022.             gui_pattern.o[a] = vars[b + 'PT'];
  3023.             gui_pattern.o[b] = vars[a + 'PT'];
  3024.             gui_pattern.create();
  3025.         }
  3026.         z = vars[a];
  3027.         vars[a] = vars[b];
  3028.         vars[b] = z;
  3029.         z = vars[a + 'CO'];
  3030.         vars[a + 'CO'] = vars[b + 'CO'];
  3031.         vars[b + 'CO'] = z;
  3032.         z = vars[a + 'GD'];
  3033.         vars[a + 'GD'] = vars[b + 'GD'];
  3034.         vars[b + 'GD'] = z;
  3035.         z = vars[a + 'PT'];
  3036.         vars[a + 'PT'] = vars[b + 'PT'];
  3037.         vars[b + 'PT'] = z;
  3038.         gui_palette.update(a);
  3039.         gui_palette.run(q[vars[vars.id]]);
  3040.     },
  3041.     // Visualizer
  3042.     run: function (n) {
  3043.         if (n != 'GD') gui_gradient.mk(1);
  3044.         gui_swatch.cur(n);
  3045.         co.glyph();
  3046.         vars.cache(1);
  3047.     },
  3048.     create: function (v) {
  3049.         if (v) vars[vars.id] = v;
  3050.         gui_palette.update();
  3051.         co.glyph();
  3052.     },
  3053.     update: function (b, m) {
  3054.         stamp.preview(stamp.fileNumber, m);
  3055.         var id = b || vars.id,
  3056.             d = $(id),
  3057.         c = d.getContext('2d');
  3058.         c.clearRect(0, 0, d.width = 34, d.height = 23);
  3059.         style(c, "fillStyle", id, { X: 0, Y: 0 }, { X: 34, Y: 23 });
  3060.         c.fillRect(0, 0, 34, 23);
  3061.     }
  3062. };
  3063.  
  3064. // EDIT COLOR
  3065.  
  3066. gui_color = {
  3067.     // Mouse
  3068.     'core': function (o, e, fu) {
  3069.         if (gui_swatch.id == 'PT') gui_swatch.cur('CO');
  3070.         core.fu(o, e, {
  3071.             fu: core.X,
  3072.             oX: -13.5,
  3073.             X1: 0,
  3074.             X2: 121,
  3075.             oY: 0
  3076.         },
  3077.         fu);
  3078.     },
  3079.     'cur': function (n, v, i, m) {
  3080.         var b = gui_color[v+"_"][i],
  3081.             n = Math.max(0, n) / 121;
  3082.         gui_color[v][i[0]] = (i == 'Alpha') ? n : Math.round((1 - n) * b);
  3083.         gui_color.run(i);
  3084.         if (m == 'up') gui_palette.create();
  3085.         else gui_palette.update('', m);
  3086.     },
  3087.     'pos': function (r, v, i) {
  3088.         var s = (i == 'Alpha'),
  3089.         n = r[i[0]];
  3090.         n = s ? (1 - n) * 100 : n;
  3091.         $S(i + 'Cur').left = parseInt((121 - (n / gui_color[v+"_"][i]) * 121) + 10) + 'px';
  3092.         $(i + 'Me').innerHTML = Math.round(s ? 100 - n : n);
  3093.     },
  3094.     // Create
  3095.     'mk': function () {
  3096.         var z = '',
  3097.         o = $C('MM', 'solid')[0];
  3098.         var R = {
  3099.             'Hue': 'HSV',
  3100.             'Saturation': 'HSV',
  3101.             'Value': 'HSV',
  3102.             'Red': 'RGB',
  3103.             'Green': 'RGB',
  3104.             'Blue': 'RGB',
  3105.             'Alpha': 'RGB'
  3106.         };
  3107.         for (var i in R) {
  3108.             var v = 'gui_color.core(\'' + i + 'Cur\',event,function(a,b,m) { gui_color.cur(b.X,\'' + R[i] + '\',\'' + i + '\',m); })';
  3109.             z += '<div title="' + i.substr(0,1).toUpperCase() + i.substr(1) + '">' + ' <div class="west" id="' + i + 'T">' + i.substr(0,1).toUpperCase() + '</div>' +
  3110.                  ' <span class="east" id="' + i + 'Me"></span>' + ' <div onmousedown="' + v + '; return false;" id="' + i + 'Cur" class="cur"></div>' +
  3111.                  ' <canvas id="' + i + '" onmousedown="' + v + '" height="18" width="120"></canvas><br>' +
  3112.                  '</div>';
  3113.         }
  3114.         o.innerHTML = '<div class="z">' + z + '</div>';
  3115.     },
  3116.     // Visualizer
  3117.     'run': function (m, r) {
  3118.         if (m == 'set') {
  3119.             m = 'Red';
  3120.         }
  3121.         if (r) {
  3122.             var r = gui_color.RGB = {
  3123.                 R: r[0],
  3124.                 G: r[1],
  3125.                 B: r[2],
  3126.                 A: r[3]
  3127.             },
  3128.             h = gui_color.HSV = Color.RGB_HSV(gui_color.RGB);
  3129.         } else {
  3130.             var r = gui_color.RGB,
  3131.                 h = gui_color.HSV;
  3132.         }
  3133.         if (gui_color.HSV_[m]) {
  3134.             var t = Color.HSV_RGB(h);
  3135.                 t.A = r.A;
  3136.                 r = gui_color.RGB = t;
  3137.         } else if (gui_color.RGB_[m]) {
  3138.             h = gui_color.HSV = Color.RGB_HSV(r);
  3139.         }
  3140.         var R = {
  3141.             'Hue': [
  3142.                 [0, { H: 0, S: h.S, V: h.V }],
  3143.                 [0.15, { H: 300, S: h.S, V: h.V}],
  3144.                 [0.30, { H: 240, S: h.S, V: h.V}],
  3145.                 [0.50, { H: 180, S: h.S, V: h.V}],
  3146.                 [0.65, { H: 120, S: h.S, V: h.V}],
  3147.                 [0.85, { H: 60, S: h.S, V: h.V}],
  3148.                 [1, { H: 0, S: h.S, V: h.V}]],
  3149.             'Saturation': [
  3150.                 [0, { H: h.H, S: 100, V: h.V}],
  3151.                 [1, { H: h.H, S: 0, V: h.V}]],
  3152.             'Value': [
  3153.                 [0, { H: h.H, S: h.S, V: 100}],
  3154.                 [1, { H: h.H, S: h.S, V: 0}]],
  3155.             'Red': [
  3156.                 [0, { R: 255, G: r.G, B: r.B, A: r.A }],
  3157.                 [1, { R: 0, G: r.G, B: r.B, A: r.A }]],
  3158.             'Green': [
  3159.                 [0, { R: r.R, G: 255, B: r.B, A: r.A }],
  3160.                 [1, { R: r.R, G: 0, B: r.B, A: r.A }]],
  3161.             'Blue': [
  3162.                 [0, { R: r.R, G: r.G, B: 255, A: r.A }],
  3163.                 [1, { R: r.R, G: r.G, B: 0, A: r.A }]],
  3164.             'Alpha': [
  3165.                 [0, { R: r.R, G: r.G, B: r.B, A: 0 }],
  3166.                 [1, { R: r.R, G: r.G, B: r.B, A: 1 }]]
  3167.         };
  3168.         for (var i in R) {
  3169.             var c = $2D(i),
  3170.                 g = c.createLinearGradient(0, 0, 120, 18);
  3171.             c.globalCompositeOperation = 'copy';
  3172.             for (var j in R[i]) {
  3173.                 var j = R[i][j],
  3174.                     k = j[1];
  3175.                 if (gui_color.HSV_[i]) {
  3176.                     k = Color.HSV_RGB(k);
  3177.                     k.A = r.A;
  3178.                 }
  3179.                 var rgb = gui_color.mode(k, isNaN(k.A) ? 1 : 0);
  3180.                 rgb = rgb.R + ',' + rgb.G + ',' + rgb.B + ',' + rgb.A;
  3181.                 g.addColorStop(j[0], 'rgba(' + rgb + ')');
  3182.             }
  3183.             c.rect(0,0,120,18);
  3184.             co.style.fill(c, g);
  3185.             if (gui_color.HSV_[i]) {
  3186.                 gui_color.pos(h, 'HSV', i);
  3187.             } else {
  3188.                 gui_color.pos(r, 'RGB', i);
  3189.             }
  3190.         }
  3191.         var r = gui_color.mode(r);
  3192.         $('HEX').innerHTML = Color.HEX_STRING(r.R << 16 | r.G << 8 | r.B);
  3193.         if (vars[vars.id] == 'solid') {
  3194.             vars[vars.id + 'CO'] = [ r.R, r.G, r.B, r.A ];
  3195.             vars.opacity_fill = r.A * 100;
  3196.             if($('opacity_fillCur') && vars.id == "fill") {
  3197.                 $('opacity_fillCur').style.left = parseInt(r.A * 110) + 'px';
  3198.                 $('opacity_fillCurV').innerHTML = parseInt(r.A * 100);         
  3199.             }
  3200.         } else if (vars[vars.id] == 'gradient') {
  3201.             var b = gui_gradient.o.id.substr(2);
  3202.             vars[vars.id + 'GD'][b][1] = [ r.R, r.G, r.B, r.A ];
  3203.             gui_gradient.run(b, 'move');
  3204.         }
  3205.     },
  3206.     // Data
  3207.     'mode': function (r, s) {
  3208.         return (s ? r : { R: r.R, G: r.G, B: r.B, A: r.A });
  3209.     },
  3210.     'RGB_': {
  3211.         'Red': 255,
  3212.         'Green': 255,
  3213.         'Blue': 255,
  3214.         'Alpha': 100
  3215.     },
  3216.     'HSV_': {
  3217.         'Hue': 360,
  3218.         'Saturation': 100,
  3219.         'Value': 100
  3220.     },
  3221.     'RGB': {
  3222.         'R': 255,
  3223.         'G': 0,
  3224.         'B': 0,
  3225.         'A': 1
  3226.     },
  3227.     'HSV': {
  3228.         'H': 0,
  3229.         'S': 100,
  3230.         'V': 100
  3231.     }
  3232. };
  3233.  
  3234. // EDIT GRADIENT
  3235.  
  3236. gui_gradient = {
  3237.     // Mouse
  3238.     'slide_x': function (a, b, m) {
  3239.         var g = vars[vars.id + 'GD'],
  3240.         r = g[gui_gradient.o.id.substr(2)];
  3241.         if (N.between(b.Y, 0, 40)) {
  3242.             if (gui_gradient.del) {
  3243.                 gui_gradient.o.style.display = 'block';
  3244.                 gui_gradient.del = '';
  3245.                 r[2] = 0;
  3246.             }
  3247.             r[0] = Math.round(Math.min(1, Math.max(0, b.X / 169)) * 1000) / 1000;
  3248.             $('gPos').innerHTML = Math.round(r[0] * 100) + '<span class="small">%</span>';
  3249.             gui_gradient.o.style.left = (Math.max(0, b.X) - 5) + 'px';
  3250.         } else if (g.length > 2) {
  3251.             gui_gradient.o.style.display = 'none';
  3252.             gui_gradient.del = gui_gradient.o;
  3253.             r[2] = 1;
  3254.         }
  3255.         if (m == 'up' && gui_gradient.del && g.length > 2) gui_gradient.remove();
  3256.         infc.info(m, 'cGD2', 'gPos');
  3257.         gui_gradient.fill(m);
  3258.     },
  3259.     'slide_y': function (a, b, m) {
  3260.         var g = vars[vars.id + 'GD'],
  3261.         op = Math.round((1 - (b.Y + 5) / 91) * 1000) / 1000;
  3262.         $S('gOpacity').top = b.Y + 'px';
  3263.         $('gPos').innerHTML = Math.round(op * 100) + '<span class="small">%</span>';
  3264.         vars.opacity_fill = op * 100;
  3265.         if($('opacity_fillCur') && vars.id == "fill") {
  3266.             $('opacity_fillCur').style.left = parseInt(op * 110) + 'px';
  3267.             $('opacity_fillCurV').innerHTML = parseInt(op * 100);          
  3268.         }
  3269.         for (var i in g) {
  3270.             g[i][1][3] = op;
  3271.         }
  3272.         infc.info(m, 'cGD2', 'gPos');
  3273.         gui_gradient.run('false', m);
  3274.         gui_gradient.cs();
  3275.     },
  3276.     'slide_o': function (o, m, a, x) {
  3277.         a.X += x.oX;
  3278.         a.Y += x.oY;
  3279.         var o = $S('gAngle'),
  3280.         W = 132,
  3281.         W2 = W / 2,
  3282.         R = Math.atan2(a.X - W2 - 3, W - a.Y - W2 - 6);
  3283.         gui_gradient.rotate = R;
  3284.         o.left = (Math.abs((Math.sin(R) * W2) + W2) + 30) + 'px';
  3285.         o.top = (Math.abs((Math.cos(R) * W2) - W2) + 40) + 'px';
  3286.         $('gPos').innerHTML = Math.round((gui_gradient.rotate + (Math.PI * 2.5)) * (180 / Math.PI) % 360) + '&deg;';
  3287.         infc.info(m, 'cGD2', 'gPos');
  3288.         gui_gradient.fill(m);
  3289.     },
  3290.     'cur': function (o) {
  3291.         if (gui_gradient.o) gui_gradient.o.className = '';
  3292.         o.className = 'cur';
  3293.         gui_gradient.o = o;
  3294.     },
  3295.     'add': function (e) {
  3296.         if (stop) {
  3297.             var g = vars[vars.id + 'GD'],
  3298.             n = g.length;
  3299.             g[n] = [0, deObject(vars[vars.id + 'GD'][gui_gradient.o.id.substr(2)][1])];
  3300.             gui_gradient.mk_x('gd' + n);
  3301.             core.fu('gd' + n, e, {
  3302.                 fu: core.X,
  3303.                 oX: 0,
  3304.                 oY: 15,
  3305.                 X1: 0,
  3306.                 X2: 169
  3307.             },
  3308.             gui_gradient.slide_x);
  3309.         }
  3310.     },
  3311.     'remove': function (o) {
  3312.         vars[vars.id + 'GD'].splice(gui_gradient.del.id.substr(2), 1);
  3313.         gui_gradient.mk_x();
  3314.     },
  3315.     // Create
  3316.     'mk': function () {
  3317.         var o = $C('MM', 'gradient')[0];
  3318.         o.innerHTML = '<div class="z" onmousedown="gui_swatch.toType(\'GD\')">' + ' <div onmousedown="core.fu(\'cGD1\',event, {fu:gui_gradient.slide_o, oX:-7, oY:-13}); return false;" id="gAngle" class="blue_dot" title="Angle"></div>' + ' <div onmousedown="core.fu(\'cGD1\',event, {fu:core.Y, oX:0, oY:-41, Y1:-5, Y2:86}, gui_gradient.slide_y); return false;" class="blue_slide"><div id="gOpacity" class="blue_dot" title="Opacity"></div></div>' + ' <div id="gPos"></div>' + ' <canvas id="cGD1" height="169" width="169"></canvas>' + ' <canvas id="cGD2" onmousedown="core.fu(\'cGD1\',event, {fu:gui_gradient.slide_o, oX:-7, oY:-13})" height="169" width="169"></canvas>' + ' <div class="slide_x" onmousedown="gui_gradient.add(event)"></div>' + '</div>';
  3319.         gui_gradient.mk_x();
  3320.         infc.info_draw('cGD2');
  3321.         if (vars[vars.id] == 'gradient') gui_gradient.cs();
  3322.     },
  3323.     'mk_x': function (o) {
  3324.         var g = vars[vars.id + 'GD'],
  3325.         z = '';
  3326.         for (var i in g) z += '<div onmousedown="gui_gradient.cur(this); gui_gradient.cs(); core.fu(\'gd' + i + '\',event,{fu:core.X, oX:0, oY:15, X1:0, X2:169}, gui_gradient.slide_x)" id="gd' + i + '" style="left: ' + ((g[i][0] * 169) - 5) + 'px"><canvas height="7" width="7"></canvas></div>';
  3327.         $C('slide_x', 'gradient')[0].innerHTML = z;
  3328.         gui_gradient.cur($(o ? o : 'gd' + i));
  3329.         gui_gradient.run('false', 'move');
  3330.     },
  3331.     // Visualizer
  3332.     'run': function (v, m) {
  3333.         var g = vars[vars.id + 'GD'];
  3334.         function z(i) {
  3335.             var c = $T('canvas', 'gd' + i)[0].getContext('2d');
  3336.             c.clearRect(0, 0, 7, 7);
  3337.             c.rect(0,0,7,7);
  3338.             co.style.fill(c, 'rgba(' + g[i][1].join(',') + ')');
  3339.         }
  3340.         if (isNaN(v)) {
  3341.             for (var i in g) {
  3342.                 z(i);
  3343.             }
  3344.         } else {
  3345.             z(v);
  3346.         }
  3347.         gui_gradient.fill(m);
  3348.     },
  3349.     'fill': function (m) {
  3350.         var c = $2D('cGD1'),
  3351.         g = vars[vars.id + 'GD'];
  3352.         co.gradient({
  3353.             'X': 0,
  3354.             'Y': 0
  3355.         },
  3356.         {
  3357.             'X': 169,
  3358.             'Y': 169
  3359.         },
  3360.         c, g, 'fill');
  3361.         c.clearRect(0, 0, 169, 169);
  3362.         c.fillRect(0, 0, 169, 169);
  3363.         if (m == 'up') gui_palette.create();
  3364.         else gui_palette.update('', m);
  3365.     },
  3366.     // Data
  3367.     'cs': function (v) {
  3368.         v = vars[vars.id + 'GD'][gui_gradient.o.id.substr(2)][1];
  3369.         gui_color.run('set', v);
  3370.     },
  3371.     'rotate': (Math.PI / 2) + Math.PI
  3372. };
  3373.  
  3374. // EDIT PATTERN
  3375.  
  3376. var gui_pattern = {
  3377.     // Mouse
  3378.     'slide_y': function (a, b, m) {
  3379.         var op = (gui_pattern.op[vars.id] = Math.round((1 - (b.Y + 5) / 91) * 1000) / 1000);
  3380.         $('pPos').innerHTML = Math.round(op * 100) + '<span class="small">%</span>';
  3381.         vars.opacity_fill = op * 100;
  3382.         if($('opacity_fillCur') && vars.id == "fill") {
  3383.             $('opacity_fillCur').style.left = parseInt(op * 110) + 'px';
  3384.             $('opacity_fillCurV').innerHTML = parseInt(op * 100);          
  3385.         }
  3386.         $S('pOpacity').top = b.Y + 'px';
  3387.         infc.info(m, 'cPT2', 'pPos');
  3388.         gui_pattern.create(op, m);
  3389.         if (m == 'up') gui_palette.create();
  3390.         else gui_palette.update('', m);
  3391.     },
  3392.     // Create
  3393.     'mk': function (s) {
  3394.         var j = 0,
  3395.         r = vars[vars.id + 'GD'],
  3396.         o = $C('MM', 'pattern')[0],
  3397.         z = '';
  3398.         o.innerHTML = '<div class="z" onmousedown="gui_swatch.toType(\'PT\')">' + ' <div onmousedown="core.fu(\'cPT1\',event, {fu:core.Y, oX:0, oY:-41, Y1:-5, Y2:86}, gui_pattern.slide_y); return false;" class="blue_slide"><div id="pOpacity" class="blue_dot" title="Opacity"></div></div>' + ' <div id="pPos"></div>' + ' <canvas id="cPT"></canvas>' + ' <canvas id="cPT1" height="169" width="169"></canvas>' + ' <canvas id="cPT2" height="169" width="169"></canvas>' + '</div>';
  3399.         gui_pattern.o[vars.id] = vars[vars.id + 'PT'];
  3400.         gui_pattern.fill();
  3401.         infc.info_draw('cPT2', 1);
  3402.         gui_palette.update();
  3403.         if (vars[vars.id] == 'pattern') {
  3404.             gui_gradient.cs();
  3405.         }
  3406.         gui_pattern.cache("fill");
  3407.         gui_pattern.cache("stroke");
  3408.     },
  3409.     // Visualizer
  3410.     'cache': function (type) { // cache image w/ createPattern()
  3411.         var pattern = vars[type+'PT'];
  3412.         dtx2D.width = pattern.width;
  3413.         dtx2D.height = pattern.height;
  3414.         ctx2D.save();
  3415.         ctx2D.globalAlpha = isNaN(pattern.opacity) ? 1 : pattern.opacity;
  3416.         ctx2D.drawImage(pattern, 0, 0);
  3417.         ctx2D.restore();
  3418.         vars[type+'PT~'] = ctx2D.createPattern(dtx2D, "repeat");
  3419.     },
  3420.     'create': function (opacity, m) {
  3421.         var image = vars[vars.id + 'PT'],
  3422.             b = { X: image.width, Y: image.height };
  3423.         if (!opacity) {
  3424.             opacity = gui_pattern.op[vars.id];
  3425.         }
  3426.         image.opacity = opacity;
  3427.         $('cPT').width = b.X;
  3428.         $('cPT').height = b.Y;
  3429.         gui_pattern.cache(vars.id);
  3430.         gui_pattern.o[vars.id] = $('cPT'); // GENERATE
  3431.         gui_pattern.fill(opacity, 0, m); // UPDATE
  3432.     },
  3433.     'fill': function (op, b, m, i) {
  3434.         if (!op) op = gui_pattern.op[vars.id];
  3435.         var a = {
  3436.             'X': 0,
  3437.             'Y': 0
  3438.         },
  3439.         b = b ? b : {
  3440.             'X': 169,
  3441.             'Y': 169
  3442.         },
  3443.         c = $2D(i ? i : 'cPT1');
  3444.         co.del(c);
  3445.         c.globalCompositeOperation = 'source-over';
  3446.         c.rect(a.X,a.Y,b.X,b.Y);
  3447.         co.style.fill(c, c.createPattern(vars[vars.id + 'PT'], 'repeat'));
  3448.         c.globalCompositeOperation = 'destination-in';
  3449.         c.rect(a.X,a.Y,b.X,b.Y);
  3450.         c.fillStyle = 'rgba(255,255,255,' + op + ')';
  3451.         c.fill();
  3452.         if (m == 'up') gui_palette.create();
  3453.         else gui_palette.update('', m);
  3454.     },
  3455.     // Data
  3456.     'o': {
  3457.         'stroke': new Image(),
  3458.         'fill': new Image()
  3459.     },
  3460.     'op': {
  3461.         'stroke': 1,
  3462.         'fill': 1
  3463.     },
  3464.     'dir': 'media/patterns/'
  3465. };
  3466.  
  3467. // EDIT SWATCH
  3468.  
  3469. gui_swatch = {
  3470.     // Mouse
  3471.     'click': function (o) {
  3472.         var n = parseInt(o.id.replace(/[a-zA-Z]*/, ''));
  3473.         if (gui_swatch.n[vars.id + gui_swatch.id] != n) {
  3474.             if (gui_swatch.id == 'PT') {
  3475.                 vars[vars.id + gui_swatch.id] = new Image();
  3476.                 vars[vars.id + gui_swatch.id].src = vars[gui_swatch.id][n - 1].src;
  3477.             } else {
  3478.                 vars[vars.id + gui_swatch.id] = deObject(vars[gui_swatch.id][n - 1]);
  3479.             }
  3480.             gui_swatch.cur_switch(n);
  3481.             co.glyph();
  3482.         }
  3483.     },
  3484.     'cur': function (type, s) {
  3485.         gui.Y.id = type = type || "CO";
  3486.         vars[vars.id] = gui_swatch.r[type][0];
  3487.         function z(a, b, c) {
  3488.             $C(a, 'swatch')[0].style[b] = c;
  3489.         }
  3490.         if(gui_swatch.id) {
  3491.             z(gui_swatch.id, 'display', 'none');
  3492.             z(gui_swatch.id + 'menu', 'cursor', 'pointer');
  3493.         }
  3494.         z(type, 'display', 'block');
  3495.         z(type + 'menu', 'cursor', 'default');
  3496.         gui_swatch.pos(gui_swatch.n[vars.id + (gui_swatch.id = type)]);
  3497.         gui_swatch.cur_switch(gui_swatch.n[vars.id + gui_swatch.id], s);
  3498.         co.glyph();
  3499.     },
  3500.     'cur_switch': function (n, s) {
  3501.         var b = gui_swatch.n[vars.id + gui_swatch.id];
  3502.         gui_swatch.n[vars.id + gui_swatch.id] = n;
  3503.         if (!s) {
  3504.             gui_swatch.run();
  3505.         }
  3506.         if ($(gui_swatch.o)) {
  3507.             $(gui_swatch.o).className = '';
  3508.             gui_swatch.update(b);
  3509.         }
  3510.         $(gui_swatch.o = vars.id + gui_swatch.id + n).className = 'cur';
  3511.         gui_swatch.update(n);
  3512.     },
  3513.     'pos': function (n) {
  3514.         var o = gui.Y,
  3515.         a = Math.ceil(n / 7) * 7,
  3516.         b = (a - 7) - (o.cur[gui_swatch.id] - 1);
  3517.         if (b > 21 || b < 0) o.cur[gui_swatch.id] = (a - (b < 0 ? 7 : 28));
  3518.         o.prev[gui_swatch.id] = 0;
  3519.         o.cord(0);
  3520.         o.sw(gui_swatch.n[vars.id + gui_swatch.id] = n);
  3521.     },
  3522.     'add': function () {
  3523.         var r = vars[gui_swatch.id],
  3524.         n = gui_swatch.n[vars.id + gui_swatch.id];
  3525.         var fu = {
  3526.             'CO': function (r) {
  3527.                 r = deObject(vars[vars.id + gui_swatch.id]);
  3528.                 return (r);
  3529.             },
  3530.             'GD': function (r) {
  3531.                 r = deObject(vars[vars.id + gui_swatch.id]);
  3532.                 return (r);
  3533.             },
  3534.             'PT': function (r) {
  3535.                 r = new Image();
  3536.                 r[r.length - 1].src = vars[vars.id + gui_swatch.id].src;
  3537.                 return (r);
  3538.             }
  3539.         };
  3540.         r.splice(n, 0, fu[gui_swatch.id](r));
  3541.         vars[vars.id + gui_swatch.id] = r[n];
  3542.         gui.Y.kontrol_update(gui_swatch.id);
  3543.         gui_swatch.pos(n + 1);
  3544.     },
  3545.     'remove': function () {
  3546.         if (vars[gui_swatch.id].length > 1) {
  3547.             var r = vars[gui_swatch.id],
  3548.             n = gui_swatch.n[vars.id + gui_swatch.id];
  3549.             r.splice(n - 1, 1);
  3550.             vars[vars.id + gui_swatch.id] = r[(n = Math.min(n, r.length)) - 1];
  3551.             gui_swatch.pos(n);
  3552.             gui_swatch.run();
  3553.             gui.Y.kontrol_update(gui_swatch.id);
  3554.         }
  3555.     },
  3556.     // Create
  3557.     author: function(id) {
  3558.         var id = id || gui_swatch.id,
  3559.             res = Resources[id][vars[id+'*']] || "";
  3560.         if(res) { // resource
  3561.             return '<i>by:&nbsp; <a href="'+res.url+'" target="_blank">'+res.name+'</a></i>';
  3562.         } else {
  3563.             return '';
  3564.         }
  3565.     },
  3566.     'mk': function () {
  3567.         var z = '';
  3568.         gui_swatch.set = {};
  3569.         for (var i in gui_swatch.r) {
  3570.             var k = 0;
  3571.             gui_swatch.set[i] = {};
  3572.             for (var j in Q[i]) gui_swatch.set[i][k++] = j;
  3573.         }
  3574.         for (var i in gui_swatch.r) {
  3575.             var res = '<div id="author_'+i+'" class="author">'+gui_swatch.author(i)+'</div>';
  3576.             z += '<div class="menu ' + i + 'menu" onmousedown="gui_swatch.cur(\'' + i + '\'); vars.cache(1);">' + ' <div>' + gui_swatch.r[i][0].toUpperCase() + 'S</div>' +
  3577.                  ' <span class="east">' +
  3578.                  ' <div style="padding: 2px 0 0; font-size: 12px" id="'+i+'_author"></div>' +
  3579. //               '  <img src="media/gui/sw_remove.png" onmousedown="if(this.parentNode.parentNode.style.cursor==\'default\') gui_swatch.remove(); return false;" alt="..." class="remove">' +
  3580. //               '  <img src="media/gui/sw_add.png" onmousedown="if(this.parentNode.parentNode.style.cursor==\'default\') gui_swatch.add(); return false;" alt="...">' +
  3581.                  ' </span>' +
  3582.                  '</div>' +
  3583.                  '<div class="' + i + '" style="display: none">' +
  3584.                  ' <div style="position: absolute; left: 19px; top: ' + (42 + gui_swatch.r[i][2]) + 'px;">' + gui.menu.build(i + '*', gui_swatch.set[i]) + '</div>' +
  3585.                  ' <div id="' + i + '" class="squares"></div>' + gui.Y.kontrol(i, gui_swatch.r[i][2] + 49) + '<br>' +res+
  3586.                  '</div>';
  3587.         }
  3588.         $C('MM', 'swatch')[0].innerHTML = '<div class="z">' + z + '</div>';
  3589.         gui_swatch.cur(gui_swatch.id = gui_swatch.L2S[vars[vars.id]]);
  3590.     },
  3591.     // Visualizer
  3592.     'run': function () {
  3593.         ({
  3594.             'CO': function () {
  3595.                 gui_color.run('set', vars[vars.id + gui_swatch.id]);
  3596.                 gui_palette.update();
  3597.             },
  3598.             'GD': function () {
  3599.                 gui_gradient.mk_x();
  3600.                 gui_gradient.cs();
  3601.                 $S('gOpacity').top = '-5px';
  3602.             },
  3603.             'PT': function () {
  3604.                 gui_pattern.o[vars.id] = vars[vars.id + 'PT'];
  3605.                 gui_pattern.create();
  3606.             }
  3607.         })[gui_swatch.id]();
  3608.     },
  3609.     'update': function (i, s) {
  3610.         var r = vars[gui_swatch.id];
  3611.         var fu = {
  3612.             'CO': function (r, c) {
  3613.                 c.fillStyle = 'rgba(' + r[i - 1].join(',') + ')';
  3614.                 c.fill();
  3615.             },
  3616.             'GD': function (r, c) {
  3617.                 co.gradient({
  3618.                     'X': 3,
  3619.                     'Y': 3
  3620.                 },
  3621.                 {
  3622.                     'X': 13,
  3623.                     'Y': 13
  3624.                 },
  3625.                 c, r[i - 1], 'fill', 1);
  3626.             },
  3627.             'PT': function (r, c) {
  3628.                 c.fillStyle = c.createPattern(r[i - 1], 'repeat');
  3629.                 c.fill();
  3630.             }
  3631.         };
  3632.         function z(i) {
  3633.             var d = $(vars.id + gui_swatch.id + i);
  3634.             if (d) {
  3635.                 var c = $2D(vars.id + gui_swatch.id + i);
  3636.                 c.clearRect(0, 0, 16, 16);
  3637.                 if (gui_swatch.n[vars.id + gui_swatch.id] == i && !s) {
  3638.                     var a = {
  3639.                         'X': 3,
  3640.                         'Y': 3
  3641.                     },
  3642.                     b = {
  3643.                         'X': 13,
  3644.                         'Y': 13
  3645.                     };
  3646.                     c.beginPath();
  3647.                     co.circle(a, b, c);
  3648.                     c.strokeStyle = 'rgba(255,255,255,1)';
  3649.                     c.lineWidth = 1.5;
  3650.                     c.stroke();
  3651.                     fu[gui_swatch.id](r, c);
  3652.                     c.beginPath();
  3653.                 } else {
  3654.                     c.rect(0, 0, 16,16);
  3655.                     fu[gui_swatch.id](r, c);
  3656.                 }
  3657.             }
  3658.         }
  3659.         if (isNaN(i)) for (var i = gui.Y.cur[gui_swatch.id], ii = 1; i <= r.length && ii <= 28; i++, ii++) z(i);
  3660.         else z(i);
  3661.     },
  3662.     toType: function (type) {
  3663.         if (gui_swatch.id != type) {
  3664.             gui_swatch.cur(type, 1);
  3665.             gui_palette.create();
  3666.         }
  3667.     },
  3668.     // Data
  3669.     'L2S': {
  3670.         'solid': 'CO',
  3671.         'gradient': 'GD',
  3672.         'pattern': 'PT'
  3673.     },
  3674.     'S2L': {
  3675.         'CO': 'solid',
  3676.         'GD': 'gradient',
  3677.         'PT': 'pattern'
  3678.     },
  3679.     'S2N': {
  3680.         'CO': 1,
  3681.         'GD': 2,
  3682.         'PT': 3
  3683.     },
  3684.     'r': {
  3685.         'CO': ['solid', -13, 6],
  3686.         'GD': ['gradient', 6, 25],
  3687.         'PT': ['pattern', 25, 44]
  3688.     },
  3689.     'n': {
  3690.         'fillCO': 1,
  3691.         'fillGD': 1,
  3692.         'fillPT': 1,
  3693.         'strokeCO': 2,
  3694.         'strokeGD': 2,
  3695.         'strokePT': 2
  3696.     },
  3697.     'o': ''
  3698. };
  3699.  
  3700. // INTERFACE
  3701.  
  3702. infc = {
  3703.     // INFORMATION
  3704.     'info': function (m, o, i) {
  3705.         if (m == 'down' || m == 'up') {
  3706.             var c = $2D(o),
  3707.             r = {
  3708.                 'down': ['source-over', 0.4, 0.2, 0],
  3709.                 'up': ['destination-out', 1, 1, 1]
  3710.             } [m];
  3711.             c.beginPath();
  3712.             c.globalCompositeOperation = r[0];
  3713.             co.circle({
  3714.                 'X': 35 + r[3],
  3715.                 'Y': 20 + r[3]
  3716.             },
  3717.             {
  3718.                 'X': -15 - r[3],
  3719.                 'Y': -30 - r[3]
  3720.             },
  3721.             c);
  3722.             c.lineWidth = 1;
  3723.             co.style.fill(c, 'rgba(0,0,0,' + r[1] + ')');
  3724.             co.style.stroke(c, 'rgba(0,0,0,' + r[2] + ')');
  3725.             $S(i).display = (m == 'down') ? 'block' : 'none';
  3726.         }
  3727.     },
  3728.     'info_draw': function (v, s) {
  3729.         var c = $2D(v),
  3730.         a = {
  3731.             'X': 37,
  3732.             'Y': 37
  3733.         },
  3734.         b = {
  3735.             'X': 131,
  3736.             'Y': 131
  3737.         }
  3738.         function ellip(a, b, r, w) {
  3739.             c.beginPath();
  3740.             c.lineWidth = w;
  3741.             co.circle(a, b, c);
  3742.             co.style.stroke(c, 'rgba(' + r + ')');
  3743.         }
  3744.         function line(a, b, r, w) {
  3745.             c.beginPath();
  3746.             c.lineWidth = w;
  3747.             c.moveTo(a.X, a.Y);
  3748.             c.lineTo(b.X, b.Y);
  3749.             co.style.stroke(c, 'rgba(' + r + ')');
  3750.         }
  3751.         if (!s) { // DRAW ROTATE
  3752.             ellip(a, b, [0, 0, 0, 1], 8);
  3753.             c.globalCompositeOperation = 'source-out';
  3754.             ellip({
  3755.                 'X': a.X + 3,
  3756.                 'Y': a.Y + 3
  3757.             },
  3758.             {
  3759.                 'X': b.X + 3,
  3760.                 'Y': b.Y + 3
  3761.             },
  3762.             [0, 0, 0, 0.3], 2);
  3763.             c.globalCompositeOperation = 'source-over';
  3764.             ellip(a, b, [128, 128, 128, 0.4], 8);
  3765.             ellip({
  3766.                 'X': a.X,
  3767.                 'Y': a.Y + 1
  3768.             },
  3769.             {
  3770.                 'X': b.X,
  3771.                 'Y': b.Y + 1
  3772.             },
  3773.             [255, 255, 255, 0.2], 1);
  3774.             ellip(a, b, [33, 33, 33, 1], 1);
  3775.             line({
  3776.                 X: 84,
  3777.                 Y: 14
  3778.             },
  3779.             {
  3780.                 X: 84,
  3781.                 Y: 7
  3782.             },
  3783.             [0, 0, 0, 0.4], 2);
  3784.             line({
  3785.                 X: 85,
  3786.                 Y: 14
  3787.             },
  3788.             {
  3789.                 X: 85,
  3790.                 Y: 7
  3791.             },
  3792.             [255, 255, 255, 0.4], 1); // N
  3793.             line({
  3794.                 X: 85,
  3795.                 Y: 154
  3796.             },
  3797.             {
  3798.                 X: 85,
  3799.                 Y: 161
  3800.             },
  3801.             [0, 0, 0, 0.4], 2);
  3802.             line({
  3803.                 X: 85,
  3804.                 Y: 154
  3805.             },
  3806.             {
  3807.                 X: 84,
  3808.                 Y: 161
  3809.             },
  3810.             [255, 255, 255, 0.4], 1); // S
  3811.             line({
  3812.                 X: 154,
  3813.                 Y: 85
  3814.             },
  3815.             {
  3816.                 X: 161,
  3817.                 Y: 85
  3818.             },
  3819.             [0, 0, 0, 0.4], 2);
  3820.             line({
  3821.                 X: 154,
  3822.                 Y: 86
  3823.             },
  3824.             {
  3825.                 X: 161,
  3826.                 Y: 86
  3827.             },
  3828.             [255, 255, 255, 0.4], 1); // E
  3829.             line({
  3830.                 X: 14,
  3831.                 Y: 86
  3832.             },
  3833.             {
  3834.                 X: 7,
  3835.                 Y: 86
  3836.             },
  3837.             [0, 0, 0, 0.4], 2);
  3838.             line({
  3839.                 X: 14,
  3840.                 Y: 85
  3841.             },
  3842.             {
  3843.                 X: 7,
  3844.                 Y: 85
  3845.             },
  3846.             [255, 255, 255, 0.4], 1); // W
  3847.         }
  3848.         line({
  3849.             X: 87,
  3850.             Y: 35
  3851.         },
  3852.         {
  3853.             X: 87,
  3854.             Y: 135
  3855.         },
  3856.         [0, 0, 0, 0.7], 1);
  3857.         line({
  3858.             X: 84,
  3859.             Y: 35
  3860.         },
  3861.         {
  3862.             X: 84,
  3863.             Y: 135
  3864.         },
  3865.         [128, 128, 128, 0.4], 8);
  3866.         line({
  3867.             X: 84,
  3868.             Y: 35
  3869.         },
  3870.         {
  3871.             X: 84,
  3872.             Y: 135
  3873.         },
  3874.         [0, 0, 0, 1], 1);
  3875.         line({
  3876.             X: 85,
  3877.             Y: 35
  3878.         },
  3879.         {
  3880.             X: 85,
  3881.             Y: 135
  3882.         },
  3883.         [255, 255, 255, 0.2], 1);
  3884.         c.closePath();
  3885.     },
  3886.     // GLOBAL OPACITY
  3887.     'opacity': function (o, v, n) {
  3888.         gui_palette.click("fill");
  3889.         var op = Math.round((vars[o] = Math.min(v[1], (Math.max(0, n) / 110) * 100)));
  3890.         if ($(o + 'CurV')) {
  3891.             $(o + 'CurV').innerHTML = Math.round(op);
  3892.         }
  3893.         switch(vars["fill"]) {
  3894.             case 'pattern':
  3895.                 gui_pattern.create(op / 100);
  3896.                 $S('pOpacity').top = ((1 - (op / 100)) * 91 - 5) + 'px'
  3897.                 gui_pattern.op["fill"] = Math.round((op / 100) * 1000) / 1000;
  3898.                 break;
  3899.             case 'gradient':
  3900.                 $S('gOpacity').top = Math.round((1 - (op / 100)) * 91 - 5) + 'px'
  3901.                 var g = vars["fill" + 'GD'];
  3902.                 for (var i in g) {
  3903.                     g[i][1][3] = op / 100;
  3904.                 }
  3905.                 gui_gradient.run('false', 'move');
  3906.                 break;
  3907.             case 'solid':
  3908.                 var c = vars["fill" + gui_swatch.id];
  3909.                 c[3] = op / 100;
  3910.                 gui_color.run('set', c);
  3911.                 gui_palette.update();
  3912.                 break;
  3913.         }
  3914.     }
  3915. };
  3916. /*
  3917.     KEYPRESS
  3918. */
  3919.  
  3920. (function() {
  3921.  
  3922. E = {
  3923.     'k': 0,
  3924.     'run': 0,
  3925.     'sh': 0,
  3926.     'sh_var': 0
  3927. };
  3928.  
  3929. key = {
  3930.     'k': function (e) {
  3931.         if(typeof(e) == 'undefined') var e = event;
  3932.         if(typeof(e.shiftKey) == 'undefined') e.shiftKey = 0;
  3933.         E.sh = E.sh_var = e.shiftKey ? 1 : 0;
  3934.         E.ctrl = e.ctrlKey ? 1 : 0;
  3935.         return (key.code(e));
  3936.     },
  3937.     'active': function () {
  3938.         if (vars.type == 'marquee') {
  3939.             marquee.core(oXY, cXY, 'move');
  3940.         } else if (vars.type == 'shape') {
  3941.             draw.shape(oXY, cXY, 'move');
  3942.         }
  3943.     },
  3944.     'block': function (e, k) {
  3945.         var o = {
  3946.             8: 'x',
  3947.             13: '\n',
  3948.             32: 'space',
  3949.             46: 'x',
  3950.             191: '/',
  3951.             222: "'",
  3952.             37: 'left',
  3953.             38: 'up',
  3954.             39: 'right',
  3955.             40: 'down'
  3956.         };
  3957.         if (k in o) {
  3958.             e.preventDefault();
  3959.             return false;
  3960.         }
  3961.     },
  3962.     'code': function (e) {
  3963.         return ! (agent('msie') || agent('opera')) ? e.keyCode : e.which;
  3964.     },
  3965.     'press': function (k, move, down, up) {
  3966.         function mv(x) {
  3967.             return function (n) {
  3968.                 move({
  3969.                     X: x.X * n,
  3970.                     Y: x.Y * n
  3971.                 });
  3972.             };
  3973.         };
  3974.         window.blur();
  3975.         setTimeout(window.focus, 0);
  3976.         E.k = k;
  3977.         key.up = up;
  3978.         key.down = down;
  3979.         key.move = {
  3980.             37: mv({
  3981.                 X: -1,
  3982.                 Y: 0
  3983.             }),
  3984.             38: mv({
  3985.                 X: 0,
  3986.                 Y: -1
  3987.             }),
  3988.             39: mv({
  3989.                 X: 1,
  3990.                 Y: 0
  3991.             }),
  3992.             40: mv({
  3993.                 X: 0,
  3994.                 Y: 1
  3995.             })
  3996.         } [k];
  3997.         setTimeout('key.run(' + (E.run = getTime()) + ')', 0);
  3998.     },
  3999.     'run': function (t) {
  4000.         if (E.k && E.run == t) {
  4001.             if (key.down) {
  4002.                 key.down();
  4003.                 key.down = '';
  4004.             };
  4005.             key.move(E.sh_var ? 10 : 1);
  4006.             setTimeout('key.run(' + t + ')', 100);
  4007.         } else if (!E.k && key.up) {
  4008.             key.up();
  4009.         }
  4010.     }
  4011. };
  4012.  
  4013. document.onkeydown = function (e) {
  4014.     if(typeof(e) == 'undefined') var e = event;
  4015.     var k = key.k(e),
  4016.         r = {};
  4017.     if (vars.type == 'marquee' && E.ctrl && k == 65) { // SELECT ALL
  4018.         marquee.core({
  4019.             'X': 1,
  4020.             'Y': 1
  4021.         },
  4022.         {
  4023.             'X': canvas.W - 1,
  4024.             'Y': canvas.H - 1
  4025.         },
  4026.         'up');
  4027.     }
  4028.     else if (e.ctrlKey && E.sh && k == 90 && (r = canvas.history_r) && r.r[r.n + 1] <= canvas.history_n && (r.n + 1) <= r.z) { // REDO
  4029.         canvas.history_set(r.n++);
  4030.     } else if (e.ctrlKey && !E.sh && k == 90 && (r = canvas.history_r) && r.r[r.n - 1] >= 0 && (r.n - 1) >= r.a) { // UNDO
  4031.         canvas.history_set(r.n--);
  4032.     } else if (mXY != 'up' && cXY && cXY.X) { // TOGGLE CONSTRAIN
  4033.         key.active();
  4034.     } else if (marquee.on || marquee.mv) { // MARQUEE
  4035.         if (k == 8 || k == 46) { // DELETE SELECTION
  4036.             marquee.del();
  4037.         } else if (k == 27) { // DESELECT
  4038.             marquee.reset();
  4039.         } else if (k >= 37 & k <= 40) { // MOVE
  4040.             marquee.on = 0;
  4041.             window.clearInterval(marqueeID);
  4042.             marquee.mv = 1;
  4043.             key.press(k, marquee.move, null, function () {
  4044.                 marquee.run();
  4045.                 marquee.mv = 0;
  4046.             });
  4047.         }
  4048.     } else if (vars.type == 'crop') { // CROP
  4049.         if (bXY.X && k == 13) { // CROP SELECTION
  4050.             crop.apply(aXY, bXY);
  4051.         } else if (E.ctrl && k == 65) { // SELECT ALL
  4052.             crop.core({
  4053.                 'X': 0,
  4054.                 'Y': 0
  4055.             },
  4056.             {
  4057.                 'X': canvas.W,
  4058.                 'Y': canvas.H
  4059.             },
  4060.             'up');
  4061.         } else if (k == 27) { // DESELECT
  4062.             crop.core({
  4063.                 'X': 0,
  4064.                 'Y': 0
  4065.             },
  4066.             {
  4067.                 'X': 0,
  4068.                 'Y': 0
  4069.             },
  4070.             'up');
  4071.         } else if (k >= 37 && k <= 40 && bXY.X) { // MOVE
  4072.             key.press(k, crop.move);
  4073.         }
  4074.     }
  4075.     if(vars.type != 'text')
  4076.         key.block(e, k);
  4077. };
  4078.  
  4079. document.onkeypress = function (e) {
  4080.     if(typeof(e) == 'undefined') var e = event;
  4081.     var k = key.k(e);
  4082.     if(vars.type != 'text')
  4083.         key.block(e, k);
  4084. };
  4085.  
  4086. document.onkeyup = function (e) {
  4087.     if(typeof(e) == 'undefined') var e = event;
  4088.     var k = key.k(e);
  4089.     if (k == E.k) E.k = 0;
  4090.     if (mXY != 'up' && oXY.X && cXY.X) key.active();
  4091. };
  4092.  
  4093. })();
  4094. /* MARQUEE */
  4095.  
  4096. marquee = {
  4097.  
  4098.     // Keypress
  4099.     'move': function (x) {
  4100.         var r = marquee.shapes;
  4101.         for (var i in r) {
  4102.             i = r[i];
  4103.             if (i.T == 'lasso') {
  4104.                 for (var j in i.R) {
  4105.                     i.R[j].X += x.X;
  4106.                     i.R[j].Y += x.Y;
  4107.                 }
  4108.             } else {
  4109.                 i.A.X += x.X;
  4110.                 i.A.Y += x.Y;
  4111.                 i.Z.X += x.X;
  4112.                 i.Z.Y += x.Y;
  4113.             }
  4114.         }
  4115.         marquee.dash(ants[ants_n]);
  4116.     },
  4117.     // Mouse
  4118.     'del': function (c) {
  4119.         c = $2D('ctx_temp');
  4120.         c.globalCompositeOperation = 'source-over';
  4121.         marquee.draw(c);
  4122.         co.style.fill(c, 'rgba(0,0,0,1)');
  4123.         c = $2D('ctx_box');
  4124.         c.globalCompositeOperation = 'destination-out';
  4125.         c.drawImage($('ctx_temp'), 0, 0, canvas.W, canvas.H);
  4126.         c.globalCompositeOperation = 'source-over';
  4127.         co.del('ctx_temp');
  4128.         canvas.history_set('delete selection');
  4129.     },
  4130.     'core': function (a, b, m, e) {
  4131.         var c = $2D('ctx_marquee');
  4132.         c.beginPath();
  4133.         c.globalCompositeOperation = 'source-over';
  4134.         if (!E.sh_var && mouse.id == 'move') {
  4135.             var r = marquee.shapes,
  4136.                 o = marquee.prev;
  4137.             if (!o) o = a;
  4138.             var v = {
  4139.                 X: o.X - b.X,
  4140.                 Y: o.Y - b.Y
  4141.             };
  4142.             if (m == 'down') {
  4143.                 marquee.on = 0;
  4144.                 window.clearInterval(marqueeID);
  4145.             }
  4146.             for (var i in r) {
  4147.                 i = r[i];
  4148.                 if (i.T == 'lasso') {
  4149.                     for (var j in i.R) {
  4150.                         i.R[j].X -= v.X;
  4151.                         i.R[j].Y -= v.Y;
  4152.                     }
  4153.                 } else {
  4154.                     i.A.X -= v.X;
  4155.                     i.A.Y -= v.Y;
  4156.                     i.Z.X -= v.X;
  4157.                     i.Z.Y -= v.Y;
  4158.                 }
  4159.             }
  4160.             marquee.dash(ants[ants_n]);
  4161.             marquee.prev = b;
  4162.             if (m == 'up') {
  4163.                 marquee.run();
  4164.                 marquee.prev = '';
  4165.                 marquee.cursor();
  4166.             }
  4167.         } else if (m != 'down' && (!e || mouse.id || mouse.moved == 1 || (getTime() - core.time) <= 1250)) {
  4168.             if (!mouse.down && e) {
  4169.                 marquee.reset(b);
  4170.                 mouse.down = 1;
  4171.                 if (marquee.shape > 0) {
  4172.                     E.sh = 0;
  4173.                 }
  4174.             } else {
  4175.                 moXY = a;
  4176.                 mcXY = b;
  4177.                 mouse.moved = 1;
  4178.             }
  4179.             if (Math.abs(a.X - b.X) > 1 && Math.abs(a.Y - b.Y) > 1) {
  4180.                 if (vars.marquee == 'lasso') {
  4181.                     marquee.r[marquee.i++] = b;
  4182.                 }
  4183.                 marquee.cache(marquee.shape);
  4184.                 if (m == 'up') {
  4185.                     mouse.reset();
  4186.                     if (mouse.moveCheck(a, b)) {
  4187.                         marquee.reset();
  4188.                     } else {
  4189.                         marquee.cache(marquee.shape++);
  4190.                         marquee.run();
  4191.                         marquee.cursor();
  4192.                     }
  4193.                 }
  4194.             }
  4195.             marquee.dash(ants[ants_n], c, 1);
  4196.         } else if(m == "down" && E.sh_var && marquee.shapes.length) {
  4197.             marquee.dash(ants[ants_n]);
  4198.         } else {
  4199.             marquee.reset();
  4200.         }
  4201.     },
  4202.     /* Visualize */
  4203.     'draw': function (c, s1, s2) {
  4204.         var r = marquee.shapes,
  4205.             o = {
  4206.                 sides: vars.sides_marquee,
  4207.                 slope: vars.slope_marquee
  4208.             },
  4209.             hasPath = false;
  4210.         for (var i in r) {
  4211.             var i = r[i];
  4212.             if (Math.abs(i.A.X - i.Z.X) > 1 && Math.abs(i.A.Y - i.Z.Y) > 1) { //... silly this has to be here
  4213.                 if (i.sides) {
  4214.                     vars.sides_marquee = i.sides;
  4215.                 }
  4216.                 if (i.slope) {
  4217.                     vars.slope_marquee = i.slope;
  4218.                 }
  4219.                 if (i.T == 'lasso') {
  4220.                     co.path(c, i.R);
  4221.                     if (!s1) c.closePath();
  4222.                 } else if (i.T == 'ellipses') {
  4223.                     co.ellipses(i.A, i.Z, c, i.sh);
  4224.                 } else if (i.T == 'polygon') {
  4225.                     co.polygon(i.A, i.Z, c, i.sh);
  4226.                 } else if (i.T == 'star') {
  4227.                     co.star(i.A, i.Z, c, i.sh);
  4228.                 } else if (i.T == 'burst') {
  4229.                     co.burst(i.A, i.Z, c, i.sh);
  4230.                 } else if (i.T == 'gear') {
  4231.                     co.gear(i.A, i.Z, c, i.sh);
  4232.                 }
  4233.                 hasPath = true;
  4234.             }
  4235.         }
  4236.         if (s2 && hasPath) {
  4237.             c.strokeStyle = s2.v;
  4238.             c.stroke();
  4239.         }
  4240.         vars.sides_marquee = o.sides;
  4241.         vars.slope_marquee = o.slope;
  4242.     },
  4243.     'cursor': function () {
  4244.         var c = $2D('ctx_mouse');
  4245.         co.del(c);
  4246.         c.beginPath();
  4247.         marquee.draw(c);
  4248.         c.lineWidth = 2;
  4249.         c.strokeStyle = 'rgba(0,0,0,1)';
  4250.         c.stroke();
  4251.         c.fillStyle = 'rgba(0,0,0,1)';
  4252.         c.fill();
  4253.         if (!mouse.area) mouse.area = {};
  4254.         mouse.area['000000FF'] = {
  4255.             'id': 'move',
  4256.             'cursor': 'move'
  4257.         };
  4258.         mouse.fu = function () {
  4259.             return (E.sh_var ? false : true);
  4260.         };
  4261.     },
  4262.     'cache': function (n) {
  4263.         var o = marquee.shapes,
  4264.             sh = E.sh ? 1 : 0,
  4265.             ctrl = E.ctrl ? 1 : 0;
  4266.         if (vars.marquee == 'lasso') {
  4267.             o[marquee.shape = 0] = {
  4268.                 'T': vars.marquee,
  4269.                 'R': marquee.r,
  4270.                 'sh': sh,
  4271.                 'ctrl': ctrl
  4272.             };
  4273.         } else {
  4274.             o[n] = {
  4275.                 'T': vars.marquee,
  4276.                 'A': moXY,
  4277.                 'Z': mcXY,
  4278.                 'sides': vars['sides_marquee'],
  4279.                 'slope': vars['slope_marquee'],
  4280.                 'sh': sh,
  4281.                 'ctrl': ctrl
  4282.             };
  4283.         }
  4284.     },
  4285.     'dash': function (p, c, s) {
  4286.         var c = c ? c : $2D('ctx_marquee'),
  4287.             p = p ? p : ants[ants_n = (ants_n + 1) % 4],
  4288.             lasso = (s && vars.marquee == 'lasso');
  4289.         c.globalCompositeOperation = 'source-over';
  4290.         c.clearRect(0, 0, canvas.W, canvas.H);
  4291.         c.lineWidth = lasso ? 0.5 : 1;
  4292.         marquee.draw(c, s, {
  4293.             'o': 'stroke',
  4294.             'v': p
  4295.         });
  4296.         if (!lasso) { //- replace this with actually combining the paths
  4297.             c.globalCompositeOperation = 'destination-out';
  4298.             co.style.fill(c, 'rgba(0,0,0,1)');
  4299.         }
  4300.     },
  4301.     'run': function (t, s) {
  4302.         if (!s) {
  4303.             E.run = (t = getTime());
  4304.             marquee.on = 1;
  4305.             marquee.ghost = 1;
  4306.         }
  4307.     //  marqueeID = setInterval(function() { marquee.dash(); }, 300);  
  4308.     },
  4309.     'reset': function (v, s) {
  4310.         v = v ? v : '';
  4311.         E.run = 0;
  4312.         marquee.r = '';
  4313.         moXY = v;
  4314.         mcXY = v;
  4315.         marquee.on = 0;
  4316.         window.clearInterval(marqueeID);
  4317.         marquee.ghost = 0;
  4318.         marquee.r = [];
  4319.         marquee.i = 0;
  4320.         if (!E.sh_var || !marquee.shapes || s) {
  4321.             marquee.shapes = [];
  4322.             marquee.shape = 0;
  4323.         }
  4324.         $2D('ctx_marquee').clearRect(0, 0, canvas.W, canvas.H);
  4325.         $2D('ctx_temp').clearRect(0, 0, canvas.W, canvas.H);
  4326.         marquee.cursor();
  4327.     },
  4328.     /* Data */
  4329.     'shapes': []
  4330. };
  4331.  
  4332. /* PICKER */
  4333.  
  4334. picker={
  4335.     'core':function (a, b, m) {
  4336.         var c = $2D('picker'),
  4337.             w = 129,
  4338.             h = 96,
  4339.             data = $2D('ctx_box').getImageData(Math.max(0, a.X - 1), Math.max(0, a.Y - 1), 1, 1),
  4340.             r = data.data,
  4341.             ctx = $2D('picker1x1');
  4342.         ctx.clearRect(0, 0, 1, 1);
  4343.         ctx.putImageData(data, 0, 0);
  4344.         r[3] = parseInt(r[3] / 255 * 100);
  4345.         $('picker_hex').innerHTML = r[0] + '<br>' + r[1] + '<br>' + r[2] + '<br>' + r[3];
  4346.         c.clearRect(0, 0, w + 20, h);
  4347.         c.globalCompositeOperation = 'source-over';
  4348.         var x = a.X - 7,
  4349.             y = a.Y - 3,
  4350.             xx = (x < 0 ? Math.abs(x + 1) : 0) * 10,
  4351.             yy = (y < 0 ? Math.abs(y + 1) : 0) * 10;
  4352.         //- should grab image data for area, then draw rectangles (pixels) manually... Then run the c.arc() to mask it out
  4353.         c.drawImage($('ctx_box'), Math.max(0, x), Math.max(0, y), w / 10, h / 10, 20 + xx, yy, w, h);
  4354.         c.globalCompositeOperation = 'destination-in';
  4355.         co.circle({
  4356.             'X': 45,
  4357.             'Y': -7
  4358.         },
  4359.         {
  4360.             'X': w,
  4361.             'Y': w - 58
  4362.         },
  4363.         c);
  4364.         c.fill();
  4365.         if (m == 'down') {
  4366.             r[3] = r[3] / 100;
  4367.             gui_color.run('set', r);
  4368.             gui_palette.update();
  4369.         }
  4370.     }
  4371. };
  4372.  
  4373.  
  4374. /* MOUSE */
  4375.  
  4376. mouse = {
  4377.    'cursor': function (e, o) {
  4378.        var r = mouse.area;
  4379.        if (r) {
  4380.            var a = XY(e);
  4381.            var d = win_size.LT();
  4382.            a.X -= abPos(o).X + d.L;
  4383.            a.Y -= abPos(o).Y + d.T;
  4384.            var getID = function () {
  4385.                var v = mouse.id.split('.'),
  4386.                n = parseInt(v[0]);
  4387.                return ({
  4388.                    'n': n,
  4389.                    'id': v[1],
  4390.                    'num': !isNaN(n)
  4391.                });
  4392.            }
  4393.            function z(v1, v2) {
  4394.                $S('cBound').cursor = v1;
  4395.                $('cZoom').innerHTML = mouse.id = v2;
  4396.                var d = $2D('ctx_active'),
  4397.                q = getID();
  4398.                co.del(d);
  4399.                if (q.id && q.id != 'A') {
  4400.                    var v = path.r[q.n + 1],
  4401.                    o = path.O2R,
  4402.                    n = o[v[0]][q.id];
  4403.                    if (n) {
  4404.                        d.beginPath();
  4405.                        d.drawImage(path[q.id == 'P' ? 'point_select' : 'node_select'], 0, 0, 7, 7, Math.round(v[n] - 4), Math.round(v[n + 1] - 4), 7, 7);
  4406.                        d.closePath();
  4407.                    }
  4408.                }
  4409.            };
  4410.            var o = $2D('ctx_mouse').getImageData(a.X,a.Y,1,1).data,
  4411.                 hex = (o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3]) >>> 0,
  4412.                 i = '';
  4413.             if (hex != '00000000' && mouse.fu()) {
  4414.                if ((i = r[hex]) && mouse.id != i.id) {
  4415.                    z(i.cursor, i.id);
  4416.                 }
  4417.             } else if (mouse.id) {
  4418.                 z('crosshair', '');
  4419.             }
  4420.         }
  4421.     },
  4422.     'draw': function (r) {
  4423.         var c = $2D('ctx_mouse'),
  4424.         fu = N.rand;
  4425.         co.del(c);
  4426.         mouse.area = {};
  4427.         for (var i in r) {
  4428.             var o = [fu(255), fu(255), fu(255), 255],
  4429.             k = r[i];
  4430.             c.beginPath();
  4431.             if (!k[2]) {
  4432.                 co.rectangle(k[0], k[1], c);
  4433.             } else if (k[2] == 'ellipses') {
  4434.                 co.ellipses(k[0], k[1], c);
  4435.             } else if (k[2] == 'star') {
  4436.                 co.star(k[0], k[1], c);
  4437.             } else if (k[2] == 'burst') {
  4438.                 co.burst(k[0], k[1], c);
  4439.             } else if (k[2] == 'gear') {
  4440.                 co.gear(k[0], k[1], c);
  4441.             } else if (k[2] == 'path') {
  4442.                 path.draw(c);
  4443.             }
  4444.             c.lineWidth = 2.5;
  4445.             c.strokeStyle = 'rgba(' + o + ')';
  4446.             c.stroke();
  4447.             c.fillStyle = 'rgba(' + o + ')';
  4448.             c.fill();
  4449.             mouse.area[(o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3]) >>> 0] = {
  4450.                 'id': i,
  4451.                 'cursor': k[3] ? r[i][3] : i
  4452.             };
  4453.         }
  4454.     },
  4455.     'moveCheck': function (a, b) {
  4456.         var t = getTime() - core.time;
  4457.         return (Math.abs(a.X - b.X) <= 5 || Math.abs(a.Y - b.Y) <= 5 || (mouse.area && !mouse.id && t <= 125));
  4458.    },
  4459.    'reset': function () {
  4460.        mouse.down = 0;
  4461.        mouse.moved = 0;
  4462.    }
  4463. };
  4464.  
  4465. /* CROP */
  4466.  
  4467. crop={
  4468.  
  4469.     /* Keypress */
  4470.    
  4471.     'move':function(x) { mouse.id='move';
  4472.    
  4473.         var value = function(a,v) { return({X:a.X+(!isNaN(v)?v:v.X), Y:a.Y+(!isNaN(v)?v:v.Y)}); };
  4474.    
  4475.         aXY=value(aXY,x); bXY=value(bXY,x);
  4476.        
  4477.         var x=Math.abs(aXY.X-bXY.X), y=Math.abs(aXY.Y-bXY.Y), w=canvas.W, h=canvas.H;
  4478.  
  4479.         if(aXY.X<0) { aXY.X=0; bXY.X=x; } else if(bXY.X>w) { aXY.X=w-x; bXY.X=w; }
  4480.         if(aXY.Y<0) { aXY.Y=0; bXY.Y=y; } else if(bXY.Y>h) { aXY.Y=h-y; bXY.Y=h; }
  4481.  
  4482.         crop.core(aXY,bXY,'up');
  4483.    
  4484.     },
  4485.    
  4486.     /* Mouse */
  4487.  
  4488.     'click':function() { if(vars.type=='crop') {
  4489.  
  4490.         var v=$T('div',$('constrain_check'))[0].className;
  4491.  
  4492.         if(crop.force(vars.crop) || !v) {
  4493.        
  4494.             var d=$C('cur','aspect_radio'); if(d.length>0) { d[0].className=''; }
  4495.            
  4496.             $S('aspect_radio').opacity=0.6;
  4497.            
  4498.             gui.menu.constrain=String(vars.aspect); vars.aspect='landscape';
  4499.            
  4500.         }
  4501.         else if(v) { var o=gui.menu;
  4502.        
  4503.             if(o.constrain) { vars.aspect=String(o.constrain); o.constrain=''; }
  4504.            
  4505.             $T('div',$('aspect_radio'))[vars.aspect=='portrait'?1:0].className='cur'; $S('aspect_radio').opacity=1;
  4506.  
  4507.         }
  4508.        
  4509.         if(!isNaN(aXY.X) && !isNaN(bXY.X)) {
  4510.  
  4511.             if(vars.constrain=='true') { crop.aspect(aXY,bXY); crop.transform(aXY,bXY); }
  4512.  
  4513.             crop.core(aXY,bXY,'up');
  4514.  
  4515.         }
  4516.     } },
  4517.     'core': function (a, b, m, e) {
  4518.         if (m != 'down' && (!e || mouse.id || mouse.moved == 1 || (getTime() - core.time) <= 1250)) {
  4519.             if (!mouse.down && e) {
  4520.                 if (!mouse.id) crop.reset();
  4521.                 mouse.down = 1;
  4522.             } else {
  4523.                 mouse.moved = 1;
  4524.             }
  4525.             var c = $2D('ctx_temp');
  4526.             x = { X: a.X, Y: a.Y };
  4527.             a = transform.xy(a);
  4528.             transform(a, b, m, e);
  4529.             var x1 = a.X + 0.5,
  4530.             x2 = b.X - 0.5,
  4531.             y1 = a.Y + 0.5,
  4532.             y2 = b.Y - 0.5;
  4533.             c.lineWidth = 1;
  4534.             c.beginPath();
  4535.             c.globalCompositeOperation = 'copy';
  4536.             c.rect(0,0,canvas.W,canvas.H);
  4537.             c.fillStyle = 'rgba(0,0,0,0.5)';
  4538.             c.fill(); // EVERYTHING
  4539.             c.beginPath();
  4540.             c.globalCompositeOperation = 'destination-out';
  4541.             c.rect(a.X, a.Y, b.X-a.X, b.Y-a.Y);
  4542.             c.fillStyle = 'rgba(0,0,0,1)';
  4543.             c.fill(); // AREA OUT
  4544.             c.beginPath();
  4545.             c.globalCompositeOperation = 'source-over';
  4546.             c.rect(x1 - 1, y1 - 1, x2 - x1 + 2, y2 - y1 + 2)
  4547.             c.strokeStyle = 'rgba(0,0,0,0.5)';
  4548.             c.stroke();
  4549.             c.beginPath();
  4550.             c.rect(x1, y1, x2 - x1, y2 - y1);
  4551.             if (m != 'up') { // DIVIDING LINES
  4552.                 c.moveTo(((x2 - x1) / 3) + x1, y1);
  4553.                 c.lineTo(((x2 - x1) / 3) + x1, y2); // Y1
  4554.                 c.moveTo(((x2 - x1) / 3 * 2) + x1, y1);
  4555.                 c.lineTo(((x2 - x1) / 3 * 2) + x1, y2); // Y2
  4556.                 c.moveTo(x1, ((y2 - y1) / 3) + y1);
  4557.                 c.lineTo(x2, ((y2 - y1) / 3) + y1); // X1
  4558.                 c.moveTo(x1, ((y2 - y1) / 3 * 2) + y1);
  4559.                 c.lineTo(x2, ((y2 - y1) / 3 * 2) + y1); // X2
  4560.             }
  4561.             c.strokeStyle = 'rgba(255,255,255,0.5)';
  4562.             c.stroke();
  4563.             c.beginPath();
  4564.             var NW = [{
  4565.                 X: x1,
  4566.                 Y: y1
  4567.             },
  4568.             {
  4569.                 X: x1 + 8,
  4570.                 Y: y1 + 8
  4571.             }],
  4572.             NE = [{
  4573.                 X: x2 - 8,
  4574.                 Y: y1
  4575.             },
  4576.             {
  4577.                 X: x2,
  4578.                 Y: y1 + 8
  4579.             }],
  4580.             SW = [{
  4581.                 X: x1,
  4582.                 Y: y2 - 8
  4583.             },
  4584.             {
  4585.                 X: x1 + 8,
  4586.                 Y: y2
  4587.             }],
  4588.             SE = [{
  4589.                 X: x2 - 8,
  4590.                 Y: y2 - 8
  4591.             },
  4592.             {
  4593.                 X: x2,
  4594.                 Y: y2
  4595.             }];
  4596.             if (Math.abs(x1 - x2) > 33 && Math.abs(y1 - y2) > 23) {
  4597.                 co.rectangle({
  4598.                     X: (x2 + x1) / 2 - 4,
  4599.                     Y: y1
  4600.                 },
  4601.                 {
  4602.                     X: (x2 + x1) / 2 + 4,
  4603.                     Y: y1 + 8
  4604.                 },
  4605.                 c);
  4606.                 co.rectangle({
  4607.                     X: (x2 + x1) / 2 - 4,
  4608.                     Y: y2 - 8
  4609.                 },
  4610.                 {
  4611.                     X: (x2 + x1) / 2 + 4,
  4612.                     Y: y2
  4613.                 },
  4614.                 c);
  4615.             }
  4616.             if (Math.abs(y1 - y2) > 33 && Math.abs(x1 - x2) > 23) {
  4617.                 co.rectangle({
  4618.                     X: x2 - 8,
  4619.                     Y: (y2 + y1) / 2 - 4
  4620.                 },
  4621.                 {
  4622.                     X: x2,
  4623.                     Y: (y2 + y1) / 2 + 4
  4624.                 },
  4625.                 c);
  4626.                 co.rectangle({
  4627.                     X: x1,
  4628.                     Y: (y2 + y1) / 2 - 4
  4629.                 },
  4630.                 {
  4631.                     X: x1 + 8,
  4632.                     Y: (y2 + y1) / 2 + 4
  4633.                 },
  4634.                 c);
  4635.             }
  4636.             if (Math.abs(x1 - x2) > 23 && Math.abs(y1 - y2) > 23) {
  4637.                 co.rectangle(NW[0], NW[1], c);
  4638.                 co.rectangle(NE[0], NE[1], c);
  4639.                 co.rectangle(SE[0], SE[1], c);
  4640.                 co.rectangle(SW[0], SW[1], c);
  4641.             }
  4642.             c.fillStyle = 'rgba(100,100,100,0.8)';
  4643.             c.fill();
  4644.             c.strokeStyle = 'rgba(255,255,255,0.5)';
  4645.             c.stroke();
  4646.             if (m == 'up') {
  4647.                 mouse.reset();
  4648.                 if (mouse.moveCheck(a, b)) {
  4649.                     crop.reset();
  4650.                 } else {
  4651.                     aXY = a;
  4652.                     bXY = b;
  4653.                     mouse.fu = function () {
  4654.                         return (true);
  4655.                     };
  4656.                     mouse.draw({
  4657.                         'move': [a, b],
  4658.                         'n-resize': [{
  4659.                             X: x1 + 8,
  4660.                             Y: y1
  4661.                         },
  4662.                         {
  4663.                             X: x2 - 8,
  4664.                             Y: y1 + 8
  4665.                         }],
  4666.                         's-resize': [{
  4667.                             X: x1 + 8,
  4668.                             Y: y2 - 8
  4669.                         },
  4670.                         {
  4671.                             X: x2 - 8,
  4672.                             Y: y2
  4673.                         }],
  4674.                         'e-resize': [{
  4675.                             X: x2 - 8,
  4676.                             Y: y1 + 8
  4677.                         },
  4678.                         {
  4679.                             X: x2,
  4680.                             Y: y2 - 8
  4681.                         }],
  4682.                         'w-resize': [{
  4683.                             X: x1,
  4684.                             Y: y1 + 8
  4685.                         },
  4686.                         {
  4687.                             X: x1 + 8,
  4688.                             Y: y2 - 8
  4689.                         }],
  4690.                         'nw-resize': [NW[0], NW[1]],
  4691.                         'ne-resize': [NE[0], NE[1]],
  4692.                         'se-resize': [SE[0], SE[1]],
  4693.                         'sw-resize': [SW[0], SW[1]]
  4694.                     });
  4695.                 }
  4696.             }
  4697.         }
  4698.     },
  4699.     /* Math */
  4700.    
  4701.     'aspect':function(a,b) {
  4702.    
  4703.         if((Math.abs(a.X-b.X)>Math.abs(a.Y-b.Y)?'landscape':'portrait')!=vars.aspect) {
  4704.  
  4705.             crop.XY(a,b, {X:Math.abs((b.Y-a.Y)*.5), Y:Math.abs((b.X-a.X)*.5)});
  4706.            
  4707.             crop.overflow(a,b);
  4708.  
  4709.         }
  4710.     },
  4711.     'constrain':function(a,b) { var r=crop.ratio[gui.menu.key.crop]; //- JUNK
  4712.    
  4713.         var n=(vars.aspect=='portrait')?{A:r[1]/r[0],B:r[0]/r[1]}:{A:r[0]/r[1],B:r[1]/r[0]};
  4714.  
  4715.         if(mouse.id=='n-resize' || mouse.id=='s-resize') {
  4716.        
  4717.             if((b.X-a.X>0 && b.Y-a.Y>0) || (b.X-a.X<0 && b.Y-a.Y<0)) b.X=a.X+(b.Y-a.Y)*n.B; else b.X=a.X-(b.Y-a.Y)*n.B;
  4718.            
  4719.             if(b.X>canvas.W) { b.X=canvas.W/b.X*b.X; if(b.Y<a.Y) { b.Y=a.Y-(b.X-a.X)*n.A; } else { b.Y=a.Y+(b.X-a.X)*n.A; } }
  4720.  
  4721.             else if(a.X<0) { a.X=0; if(b.Y>a.Y) { b.Y=a.Y+(b.X-a.X)*n.A; } else { b.Y=a.Y-(b.X-a.X)*n.A; } }
  4722.            
  4723.             b.X=Math.round(b.X); b.Y=Math.round(b.Y);
  4724.  
  4725.         }
  4726.         else {
  4727.        
  4728.             if((b.X-a.X>0 && b.Y-a.Y>0) || (b.X-a.X<0 && b.Y-a.Y<0)) b.Y=a.Y+(b.X-a.X)*n.A; else b.Y=a.Y-(b.X-a.X)*n.A;
  4729.            
  4730.             if(b.Y>canvas.H) { b.Y=canvas.H/b.Y*b.Y; if(b.X<a.X) { b.X=a.X-(b.Y-a.Y)*n.B; } else { b.X=a.X+(b.Y-a.Y)*n.B; } }
  4731.  
  4732.             else if(b.Y<0) { b.Y=0; if(b.X>a.X) { b.X=a.X-(b.Y-a.Y)*n.B; } else { b.X=a.X+(b.Y-a.Y)*n.B; } }
  4733.            
  4734.             b.X=Math.round(b.X); b.Y=Math.round(b.Y);
  4735.  
  4736.         }
  4737.     },
  4738.     'overflow':function(a,b) { var w=b.X-a.X, h=b.Y-a.Y, r=h/w;
  4739.  
  4740.         var N=a.Y<0, S=b.Y>canvas.H, E=b.X>canvas.W, W=a.X<0;
  4741.  
  4742.         if(N || S) { if(N) { h+=a.Y; a.Y=0; } if(S) { h+=canvas.H-b.Y-1; b.Y=canvas.H; } w=h/r; }
  4743.  
  4744.         if(E || W) { if(W) { w+=a.X; a.X=0; } if(E) { w+=canvas.W-b.X-1; b.X=canvas.W;} h=w*r; }
  4745.  
  4746.         crop.XY(a,b, {X:w/2, Y:h/2});
  4747.  
  4748.     },
  4749.     'transform':function(a,b) { var r=crop.ratio[gui.menu.key.crop], R2=r[0]/r[1];
  4750.  
  4751.         var w=Math.abs(b.X-a.X), h=Math.abs(b.Y-a.Y), R1=h/w;
  4752.  
  4753.         if((R1<1 && R2>1) || (R1>1 && R2<1)) R2=1/R2;
  4754.  
  4755.         w=Math.sqrt((1/R2)*(R1*w*w));
  4756.  
  4757.         crop.XY(a,b, {X:w/2, Y:(R2*w)/2});
  4758.        
  4759.         crop.overflow(a,b);
  4760.  
  4761.     },
  4762.     'XY':function(a,b,r) { var c={X:((b.X-a.X)*.5)+a.X, Y:((b.Y-a.Y)*.5)+a.Y};
  4763.  
  4764.         a.X=Math.round(c.X-r.X); a.Y=Math.round(c.Y-r.Y);
  4765.         b.X=Math.round(c.X+r.X); b.Y=Math.round(c.Y+r.Y);
  4766.  
  4767.     },
  4768.    
  4769.     /* Visualize */
  4770.    
  4771.     'apply':function(a,b) { var c=$2D('ctx_temp'), prev={W:canvas.W, H:canvas.H}; co.del(c);
  4772.  
  4773.         var m=[Math.max(a.X,b.X), Math.max(a.Y,b.Y), Math.min(a.X,b.X), Math.min(a.Y,b.Y)];
  4774.    
  4775.         c.drawImage($('ctx_box'), m[2],m[3], m[0]-m[2],m[1]-m[3], 0,0, m[0]-m[2],m[1]-m[3]);
  4776.  
  4777.         co.del('ctx_box'); co.del('ctx_marquee');
  4778.        
  4779.         canvas.W=m[0]-m[2]; canvas.H=m[1]-m[3];
  4780.    
  4781.         $('ctx_box').width=canvas.W; $('ctx_box').height=canvas.H;
  4782.        
  4783.         $2D('ctx_box').drawImage($('ctx_temp'),0,0,prev.W,prev.H);
  4784.  
  4785.         crop.resize(); canvas.history_set();
  4786.    
  4787.     },
  4788.     'resize':function() { co.del('ctx_temp');
  4789.    
  4790.         var w=canvas.W, h=canvas.H, o=$C('MM','canvas')[0].style;
  4791.        
  4792.         var l=(parseInt(o.width)-canvas.W)/2, t=(parseInt(o.height)-canvas.H)/2;
  4793.    
  4794.         function fu(o) { $(o).width=w; $(o).height=h; $S(o).left=l+'px'; $S(o).top=t+'px'; }
  4795.    
  4796.         $S('ctx_box').left=l+'px'; $S('ctx_box').top=t+'px';
  4797.    
  4798.         $S('cBound').cursor='crosshair'; mouse.id=''; aXY={}; bXY={}; mouse.area='';
  4799.  
  4800.         var r=['ctx_temp','ctx_marquee','ctx_active','ctx_mouse'];
  4801.        
  4802.         for(var i in r) { fu(r[i]); };
  4803.        
  4804.     },
  4805.  
  4806.     /* Data */
  4807.    
  4808.     'force':function(v) {
  4809.    
  4810.         eval("var r={'Display ("+screen.width+"x"+screen.height+")':1,'Original ("+canvas.W+"x"+canvas.H+")':1,'4x3 (DVD)':1,'16x9 (HD)':1}");
  4811.    
  4812.         return(r[v]);
  4813.    
  4814.     },
  4815.     'ratio_mk':function() {
  4816.    
  4817.         crop.ratio={'Display':[screen.height,screen.width], 'Original':[canvas.H,canvas.W], '2x3':[2,3], '3x5':[3,5], '4x3':[4,3], '4x6':[4,6], '5x7':[5,7], '8x10':[8,10], '16x9':[9,16], '16x20':[16,20], '20x30':[20,30], 'Square':[1,1]};
  4818.  
  4819.     },
  4820.     'reset':function() {
  4821.    
  4822.         $2D('ctx_temp').clearRect(0,0,canvas.W,canvas.H); $S('cBound').cursor='crosshair';
  4823.  
  4824.         mouse.id=''; aXY={}; bXY={}; mouse.area='';
  4825.  
  4826.     }
  4827. };
  4828.  
  4829.  
  4830. /* TRANSFORM */
  4831.  
  4832. transform={}; transXY={X:0,Y:0};
  4833.  
  4834. transform=function(a,b,m,e) {
  4835.  
  4836.     if(e) { var o=transXY;
  4837.  
  4838.         function zarea(v) { transXY={X:0,Y:0}; $S('cBound').cursor=mouse.id=v; co.core(e); }
  4839.    
  4840.         if(mouse.id=='n-resize') { a.X=aXY.X; a.Y=bXY.Y; b.X=bXY.X; b.Y=Math.max(0,aXY.Y+(b.Y-oXY.Y));
  4841.  
  4842.             if(a.Y<b.Y) { var v=bXY; bXY={X:bXY.X,Y:aXY.Y-o.Y}; aXY={X:aXY.X,Y:v.Y}; zarea('s-resize'); }
  4843.    
  4844.         }
  4845.         else if(mouse.id=='ne-resize') { a.X=aXY.X; a.Y=bXY.Y; b.X=Math.min(canvas.W,bXY.X+(b.X-oXY.X)); b.Y=Math.max(0,aXY.Y+(b.Y-oXY.Y));
  4846.        
  4847.             if(a.Y<b.Y) { var v=bXY; bXY={X:bXY.X-o.X,Y:aXY.Y-o.Y}; aXY={X:aXY.X,Y:v.Y}; zarea('se-resize'); }
  4848.            
  4849.             else if(a.X>b.X) { var v=bXY; bXY={X:aXY.X,Y:bXY.Y}; aXY={X:v.X-o.X,Y:aXY.Y-o.Y}; zarea('nw-resize'); }
  4850.    
  4851.         }
  4852.         else if(mouse.id=='e-resize') { a.X=aXY.X; a.Y=aXY.Y; b.X=Math.min(canvas.W,bXY.X+(b.X-oXY.X)); b.Y=bXY.Y;
  4853.        
  4854.             if(a.X>b.X) { var v=bXY; bXY={X:aXY.X,Y:bXY.Y}; aXY={X:v.X-o.X,Y:aXY.Y}; zarea('w-resize'); }
  4855.    
  4856.         }
  4857.         else if(mouse.id=='se-resize') { a.X=aXY.X; a.Y=aXY.Y; b.X=Math.min(canvas.W,bXY.X+(b.X-oXY.X)); b.Y=Math.min(canvas.H,bXY.Y+(b.Y-oXY.Y));
  4858.        
  4859.             if(a.Y>b.Y) { var v=bXY; bXY={X:bXY.X,Y:aXY.Y}; aXY={X:aXY.X,Y:v.Y-o.Y}; zarea('ne-resize'); }
  4860.            
  4861.             else if(a.X>b.X) { var v=bXY; bXY={X:aXY.X,Y:bXY.Y}; aXY={X:v.X-o.X,Y:aXY.Y}; zarea('sw-resize'); }
  4862.    
  4863.         }
  4864.         else if(mouse.id=='s-resize') { a.X=aXY.X; a.Y=aXY.Y; b.X=bXY.X; b.Y=Math.min(canvas.H,bXY.Y+(b.Y-oXY.Y));
  4865.    
  4866.             if(a.Y>b.Y) { var v=bXY; bXY={X:bXY.X,Y:aXY.Y}; aXY={X:aXY.X,Y:v.Y-o.Y}; zarea('n-resize'); }
  4867.    
  4868.         }
  4869.         else if(mouse.id=='sw-resize') { a.X=bXY.X; a.Y=aXY.Y; b.X=Math.max(0,aXY.X+(b.X-oXY.X)); b.Y=Math.min(canvas.H,bXY.Y+(b.Y-oXY.Y));
  4870.        
  4871.             if(a.Y>b.Y) { var v=bXY; bXY={X:bXY.X,Y:aXY.Y}; aXY={X:aXY.X-o.X,Y:v.Y-o.Y}; zarea('nw-resize'); }
  4872.            
  4873.             else if(a.X<b.X) { var v=bXY; bXY={X:aXY.X-o.X,Y:bXY.Y-o.Y}; aXY={X:v.X,Y:aXY.Y}; zarea('se-resize'); }
  4874.        
  4875.         }
  4876.         else if(mouse.id=='w-resize') { a.X=bXY.X; a.Y=aXY.Y; b.X=Math.max(0,aXY.X+(b.X-oXY.X)); b.Y=bXY.Y;
  4877.        
  4878.             if(a.X<b.X) { var v=bXY; bXY={X:aXY.X-o.X,Y:bXY.Y}; aXY={X:v.X,Y:aXY.Y}; zarea('e-resize'); }
  4879.        
  4880.         }
  4881.         else if(mouse.id=='nw-resize') { a.X=bXY.X; a.Y=bXY.Y; b.X=Math.max(0,aXY.X+(b.X-oXY.X)); b.Y=Math.max(0,aXY.Y+(b.Y-oXY.Y));
  4882.        
  4883.             if(a.Y<b.Y) { var v=bXY; bXY={X:bXY.X-o.X,Y:aXY.Y-o.Y}; aXY={X:aXY.X,Y:v.Y}; zarea('sw-resize'); }
  4884.            
  4885.             else if(a.X<b.X) { var v=bXY; bXY={X:aXY.X-o.X,Y:bXY.Y}; aXY={X:v.X,Y:aXY.Y}; zarea('ne-resize'); }
  4886.    
  4887.         }
  4888.         else if(mouse.id=='move') {
  4889.        
  4890.             var W=bXY.X-aXY.X, H=bXY.Y-aXY.Y;
  4891.    
  4892.             var aA=Math.max(0,aXY.X+(b.X-oXY.X)), bA=Math.max(0,aXY.Y+(b.Y-oXY.Y)); // MIN
  4893.            
  4894.             var aB=aA-Math.max(0,aA+W-canvas.W), bB=bA-Math.max(0,bA+H-canvas.H); // MAX
  4895.            
  4896.             a.X=aB; a.Y=bB; b.X=W+aB; b.Y=H+bB;
  4897.    
  4898.         }
  4899.         else {
  4900.    
  4901.             b.X=Math.min(canvas.W,Math.max(0,b.X)); b.Y=Math.min(canvas.H,Math.max(0,b.Y));
  4902.    
  4903.         }
  4904.     }
  4905.  
  4906.     if(vars.constrain=='true') { crop.constrain(a,b); }
  4907.        
  4908.     if(m=='down') { transXY={X:b.X-oXY.X,Y:b.Y-oXY.Y}; }
  4909.  
  4910.     if(a.X-b.X>0) { var t=parseInt(a.X); a.X=parseInt(b.X); b.X=parseInt(t); }
  4911.     if(a.Y-b.Y>0) { var t=parseInt(a.Y); a.Y=parseInt(b.Y); b.Y=parseInt(t); }
  4912.        
  4913. };
  4914.  
  4915. transform.xy=function(o,n) { n=n?n:0;
  4916.    
  4917.         return({X:Math.max(0+n,Math.min(canvas.W-n,o.X)), Y:Math.max(0+n,Math.min(canvas.H-n,o.Y))});
  4918.    
  4919. };// DRAW
  4920.  
  4921. style = function(c, style, type, a, b) {
  4922.     switch(vars[type]) {
  4923.         case "solid":
  4924.             c[style] = "rgba("+vars[type+'CO'].join(",")+")";
  4925.             break;
  4926.         case "gradient":
  4927.             var r = vars[type+'GD'],
  4928.                 gradient = c.createLinearGradient(a.X, a.Y, b.X, b.Y);
  4929.             for (var key in r) {
  4930.                 gradient.addColorStop(r[key][0], 'rgba(' + r[key][1].join(",") + ')');
  4931.             }
  4932.             c[style] = gradient;
  4933.             break;
  4934.         case "pattern":
  4935.             if(!vars[type+'PT~']) {
  4936.                 gui_pattern.cache(type);
  4937.             }
  4938.             c[style] = vars[type+'PT~'];
  4939.             break;
  4940.     }
  4941. };
  4942.  
  4943. (function() {
  4944.  
  4945. // helper functions
  4946.  
  4947. function createFlow(b, type, callback) {
  4948.     var oX = b.X - cXY.X,
  4949.         oY = b.Y - cXY.Y,
  4950.         flow = Math.max(1, 100 - vars['flow_' + type]);
  4951.     function run(a, b, n) {
  4952.         var i = n / flow;
  4953.         if (n > 0) {
  4954.             for (; i > 0; i--) {
  4955.                 callback(a * i, b * i);
  4956.             }
  4957.         } else {
  4958.             for (; i < 0; i++) {
  4959.                 callback(a * i, b * i);
  4960.             }
  4961.         }
  4962.     };
  4963.     if (Math.abs(oX) > Math.abs(oY)) {
  4964.         run(flow, flow * (oY / oX), oX);
  4965.     } else {
  4966.         run(flow * (oX / oY), flow, oY);
  4967.     }
  4968. };
  4969.  
  4970. function mask_active(m) {
  4971.     var c = $2D('ctx_temp'),
  4972.         type = vars.type == 'shape' ? vars.shape : vars.type;
  4973.     c.globalCompositeOperation = canvas.mode;
  4974.     if (vars['movement_' + type] == 'anchored') {
  4975.         c.clearRect(0, 0, canvas.W, canvas.H);
  4976.     }
  4977.     if (m == 'down' && marquee.on) {
  4978.         c.save();
  4979.         c.beginPath();
  4980.         marquee.draw(c);
  4981.         c.clip();
  4982.         marquee.on = 0;
  4983.         window.clearInterval(marqueeID);
  4984.     }
  4985.     return c;
  4986. };
  4987.  
  4988. function mask_up(c) {
  4989.     var ctx_temp = document.getElementById('ctx_temp').getContext('2d');
  4990.     co.copy('ctx_temp', 'ctx_box');
  4991.     ctx_temp.clearRect(0, 0, canvas.W, canvas.H);
  4992.     canvas.history_set();
  4993.     if (marquee.ghost) {
  4994.         marquee.run();
  4995.         c.restore();
  4996.     }
  4997.     moved = false;
  4998. };
  4999.  
  5000. var moved = false;
  5001.  
  5002. // tools
  5003.  
  5004. draw = {   
  5005.     shape: function (a, b, m) {
  5006.         var c = mask_active(m);
  5007.         if (vars['movement_' + vars.shape] == 'freedraw') {
  5008.             oXY = b;
  5009.         }
  5010.         if (Math.abs(a.X - b.X) > 0 && Math.abs(a.Y - b.Y) > 0) {
  5011.             moved = true;
  5012.             c.beginPath();
  5013.             co[vars.shape](a, b, c);
  5014.             c.lineJoin = vars.lineJoin;
  5015.             c.lineWidth = vars['stroke_' + vars.shape];
  5016.             style(c, "fillStyle", "fill", a, b);
  5017.             style(c, "strokeStyle", "stroke", a, b);
  5018.             c.fill();
  5019.             c.stroke();
  5020.         }
  5021.         if (m == 'up' && moved) {
  5022.             mask_up(c);
  5023.         }
  5024.     },
  5025.     text: function(a, b, m) {
  5026.         var c = mask_active(m);
  5027.         // NOTES: Check into scale.
  5028.         if(m == "down" || m == "move") {
  5029.             c.beginPath();
  5030.             if(c.setFont) c.setFont(vars.fontSize + "px Liberation Sans");
  5031.             c.font = vars.fontSize + "px Liberation Sans, sans-serif";
  5032.             c.lineWidth = vars.stroke_text;
  5033.             style(c, "strokeStyle", "stroke", a, b);
  5034.             style(c, "fillStyle", "fill", a, b);
  5035.             c.fillText(vars.textMessage, b.X, b.Y);
  5036.             c.strokeText(vars.textMessage, b.X, b.Y);
  5037.         }
  5038.         if(m == "up") {
  5039.             mask_up(c);
  5040.         }
  5041.     },
  5042.     pencil: function (a, b, m) {
  5043.         var c = mask_active(m),
  5044.             d = $('ctx_brush'),
  5045.             D = vars.diameter_pencil,
  5046.             D2 = D * 2;
  5047.         function z(x, y) {
  5048.             c.drawImage(d, 0, 0, D2, D2, b.X - D - x, b.Y - D - y, D2, D2);
  5049.         };
  5050.         if (m == 'down') {
  5051.             z(0, 0);
  5052.         } else if (m == 'move') {
  5053.             createFlow(b, 'pencil', z);
  5054.         }
  5055.         if(m == "up") {
  5056.             mask_up(c);
  5057.         }
  5058.     },
  5059.     brush: function (a, b, m) {
  5060.         var c = mask_active(m),
  5061.             d = $('ctx_brush'),
  5062.             D = vars.diameter_brush,
  5063.             D2 = D * 2;
  5064.         function z(x, y) {
  5065.             c.drawImage(d, 0, 0, D2, D2, b.X - D - x, b.Y - D - y, D2, D2);
  5066.         };
  5067.         if (m == 'down') {
  5068.             z(0, 0);
  5069.         } else if (m == 'move') {
  5070.             createFlow(b, 'brush', z);
  5071.         }
  5072.         if(m == "up") {
  5073.             mask_up(c);
  5074.         }
  5075.     },
  5076.     calligraphy: function (a, b, m) {
  5077.         var c = mask_active(m),
  5078.             d = $('ctx_stamp'),
  5079.             r = co.stamp.r,
  5080.             D = vars.diameter_calligraphy / 100,
  5081.             D2 = D * 2;
  5082.         function z(x, y) {
  5083.             c.drawImage(d, 0, 0, r.W, r.H, b.X - ((r.W * D) / 2) - x, b.Y - ((r.H * D) / 2) - y, r.W * D, r.H * D);
  5084.         };
  5085.         if (m == 'down') {
  5086.             z(0, 0);
  5087.         } else if (m == 'move') {
  5088.             createFlow(b, 'calligraphy', z);
  5089.         }
  5090.         if(m == "up") {
  5091.             mask_up(c);
  5092.         }
  5093.     },
  5094.     stamp: function (a, b, m) {
  5095.         var c = mask_active(m),
  5096.             d = $('ctx_stamp'),
  5097.             r = co.stamp.r,
  5098.             D = vars.diameter_stamp,
  5099.             D2 = D * 2;
  5100.         function z(x, y) {
  5101.             var n = Math.random(),
  5102.                 zoom = Math.max(vars.rand_max / 100, Math.min(vars.rand_min / 100, n));
  5103.             c.drawImage(d, 0, 0, r.W, r.H, b.X - ((r.W * zoom) / 2) - x, b.Y - ((r.H * zoom) / 2) - y, r.W * zoom, r.H * zoom);
  5104.         };
  5105.         if (m == 'down') {
  5106.             z(0, 0);
  5107.         } else if (m == 'move') {
  5108.             createFlow(b, 'stamp', z);
  5109.         }
  5110.         if(m == "up") {
  5111.             mask_up(c);
  5112.         }
  5113.     },
  5114.     eraser: function (a, b, m) {
  5115.         if(m == "down") {
  5116.             co.copy('ctx_box', 'ctx_temp');
  5117.             co.del('ctx_box');
  5118.         }
  5119.         var c = mask_active(m),
  5120.             D = vars.diameter_eraser,
  5121.             D2 = D * 2;
  5122.         function z(x, y) {
  5123.             c.drawImage($('ctx_brush'), 0, 0, D2, D2, b.X - D - x, b.Y - D - y, D2, D2);
  5124.         };
  5125.         if (m == 'down') {
  5126.             c.globalCompositeOperation = 'destination-out';
  5127.             z(0, 0);
  5128.         } else {
  5129.             c.globalCompositeOperation = 'destination-out';
  5130.             createFlow(b, 'eraser', z);
  5131.         }
  5132.         c.globalCompositeOperation = 'source-over';
  5133.         if(m == "up") {
  5134.             mask_up(c);
  5135.         }
  5136.     },
  5137.     fill: function (a, b, m) {
  5138.         var c = mask_active(m),
  5139.             type = vars.fill;
  5140.         if (type == 'gradient') {
  5141.             c.beginPath();
  5142.             c.lineWidth = 0.5;
  5143.             c.lineCap = 'round';
  5144.             c.moveTo(a.X, a.Y);
  5145.             c.lineTo(b.X, b.Y);
  5146.             c.strokeStyle = 'rgba(127,127,127,1)';
  5147.             c.stroke();
  5148.             c.drawImage(path['point'], 0, 0, 7, 7, a.X - 4, a.Y - 4, 7, 7);
  5149.             c.drawImage(path['node_select'], 0, 0, 7, 7, b.X - 4, b.Y - 4, 7, 7);
  5150.             if(m == "up") {
  5151.                 co.del('ctx_temp');
  5152.                 style(c, "fillStyle", "fill", a, b);
  5153.                 c.rect(0, 0, canvas.W, canvas.H);
  5154.                 c.fill();
  5155.                 mask_up(c);
  5156.             }
  5157.         } else if(m == "down") {
  5158.             style(c, "fillStyle", "fill", a, b);
  5159.             c.rect(0, 0, canvas.W, canvas.H);
  5160.             c.fill();
  5161.             mask_up(c);
  5162.         }
  5163.     }
  5164. };
  5165.  
  5166. // STAMP
  5167.  
  5168. stamp = { // Mouse Events
  5169.     current: function (o) {
  5170.         var b = stamp.fileNumber;
  5171.         stamp.fileNumber = o.id.substr(5);
  5172.         if ($('stamp' + b)) {
  5173.             stamp.preview(b);
  5174.             $('stamp' + b).className = '';
  5175.         }
  5176.         $('stamp' + stamp.fileNumber).className = 'cur';
  5177.         vars.cache(1);
  5178.     },
  5179.     uri: function (v) {
  5180.         return 'media/glyph/' + vars.stamp + '/' + (stamp.fileNumber - 1) + '-' + v + '.png';
  5181.     },
  5182.     preview: function (i, m) {
  5183.         if ($('stamp' + i) && stamp.src[i].src) {
  5184.             function O(n) {
  5185.                 return (n < 34 ? (34 - n) / 2 : 0);
  5186.             }
  5187.             function Z(n) {
  5188.                 o = {
  5189.                     W: (34 / n) * o.W,
  5190.                     H: (34 / n) * o.H
  5191.                 };
  5192.             }
  5193.             var c = $2D('stamp' + i),
  5194.                 d = stamp.src[i],
  5195.                 o = {
  5196.                     W: d.width,
  5197.                     H: d.height
  5198.                 };
  5199.             if (o.W >= o.H) Z(o.W);
  5200.             else if (o.H > o.W) Z(o.H);
  5201.             c.clearRect(0, 0, 34, 34);
  5202.             c.drawImage(d, O(o.W), O(o.H), o.W, o.H);
  5203.             if (i == stamp.fileNumber) {
  5204.                 c.globalCompositeOperation = 'source-in';
  5205.                 c.rect(0, 0, 34, 34);
  5206.                 co.style[vars[vars.id]]({
  5207.                     'X': 0,
  5208.                     'Y': 0
  5209.                 },
  5210.                 {
  5211.                     'X': 34,
  5212.                     'Y': 34
  5213.                 },
  5214.                 c, 'fill', vars.id);
  5215.                 c.globalCompositeOperation = 'source-over';
  5216.                 if (!m || m == 'up') {
  5217.                     co.glyph(stamp.uri('live'));
  5218.                 }
  5219.             }
  5220.         }
  5221.     },
  5222.     reset: function () {
  5223.         var o = gui.Y,
  5224.             r = o.r.stamp;
  5225.         if (!stamp.fileNumber) {
  5226.             stamp.fileNumber = 1;
  5227.         }
  5228.         var a = parseInt(stamp.fileNumber),
  5229.             b = stamp.r[vars.stamp],
  5230.             i = r.n() - r.display,
  5231.             n = (a / b <= 0.5) ? -2 : 2;
  5232.         o.prev.stamp = null;
  5233.         o.cur.stamp = Math.max(1, Math.min(i, Math.floor(((a + n) / b) * i)));
  5234.         o.id = 'stamp';
  5235.         o.stamp();
  5236.         o.kontrol_update(o.id);
  5237.         gui.X.range('rand');
  5238.     },
  5239.     r: {
  5240.         'Default': 1,
  5241.         'Butterflies': 27,
  5242.         'Doodles': 11,
  5243.         'Flowers': 28,
  5244.         'Footprints': 18,
  5245.         'Leafs': 50,
  5246.         'Light': 15,
  5247.         'Retro': 30,
  5248.         'Simple Smudges': 14,
  5249. //      'Splatter': 35,
  5250.         'Tizzape': 20,
  5251.         'Typogrunge': 24,
  5252.         'Water Colors': 17
  5253.     },
  5254.     src: []
  5255. };
  5256.  
  5257. // Spirograph
  5258.  
  5259. (function() {
  5260.  
  5261. var interval,
  5262.     o = { };
  5263.  
  5264. draw.spirograph = function (a, b, m) {
  5265.     var c = mask_active(m);
  5266.     if (m == 'move') {
  5267.         o = b;
  5268.     } else if (m == 'up') {
  5269.         clearTimeout(interval);
  5270.         mask_up(c);
  5271.     } else if (m == 'down') {
  5272.         o = b;
  5273.         var R = vars.inner_radius_spirograph, // Fixed circle
  5274.             r = vars.outer_radius_spirograph, // Moving circle
  5275.             d = vars.diameter_spirograph, // Distance
  5276.             speed = vars.speed_spirograph,
  5277.             resolution = vars.resolution_spirograph,
  5278.             stroke = 0.5,
  5279.             type = vars.type_spirograph,
  5280.             theta = 0,
  5281.             strokeStyle = vars["stroke" + gui_swatch.L2S[vars["stroke"]]];
  5282.         switch(vars["stroke"]) { // compile styles
  5283.             case "pattern":
  5284.                 c.strokeStyle = vars["stroke"+'PT~'];
  5285.                 break;
  5286.             case "gradient":
  5287.                 var Additive = function(A, B) {
  5288.                         var C = A + B;
  5289.                         return (C > 0xFF) ? 0xFF : C;
  5290.                     },
  5291.                     gradient = vars["stroke" + "GD"],
  5292.                     prev,
  5293.                     cur,
  5294.                     spectrum = [ ];
  5295.                 for (var key in gradient) {
  5296.                     cur = gradient[key][1];
  5297.                     if (prev) {
  5298.                         var len = 512 / (gradient.length - 1);
  5299.                         for (var j = 0; j <= len; j++) {
  5300.                             var n1 = (j / len),
  5301.                                 n2 = 1 - n1,
  5302.                                 color = [
  5303.                                     cur[0] + (Additive(cur[0], prev[0]) - cur[0]) * prev[3] / 0xFF,
  5304.                                     cur[1] + (Additive(cur[1], prev[1]) - cur[1]) * prev[3] / 0xFF,
  5305.                                     cur[2] + (Additive(cur[2], prev[2]) - cur[2]) * prev[3] / 0xFF,
  5306.                                     Math.min(cur[3] * 0xFF + prev[3] * 0xFF, 0xFF)
  5307.                                 ];
  5308.                             spectrum.push(cur.join(","));
  5309.                         }
  5310.                     }
  5311.                     prev = cur;
  5312.                 }
  5313.                 break;
  5314.             default: // color
  5315.                 c.strokeStyle = "rgba(" + strokeStyle.join(",") + ")";;
  5316.                 break;
  5317.         }
  5318.         interval = setInterval(function() {
  5319.             var _x, // previous line
  5320.                 _y,
  5321.                 _oX = o.X, // previous mouse position
  5322.                 _oY = o.Y;
  5323.             c.lineWidth = stroke;
  5324.             for (var n = 0; n < speed; n++) {
  5325.                 if (type == 'Hypotrochoid') {
  5326.                     x = (R - r) * Math.cos(theta) + d * Math.cos((R / r - 1) * theta) + (_oX + (o.X - _oX) * (n / speed)); // Hypotrochoid
  5327.                     y = (R - r) * Math.sin(theta) - d * Math.sin((R / r - 1) * theta) + (_oY + (o.Y - _oY) * (n / speed));
  5328.                 } else {
  5329.                     x = (R + r) * Math.cos(theta) - d * Math.cos((R / r + 1) * theta) + (_oX + (o.X - _oX) * (n / speed)); // Epitrochoid
  5330.                     y = (R + r) * Math.sin(theta) - d * Math.sin((R / r + 1) * theta) + (_oY + (o.Y - _oY) * (n / speed));
  5331.                 }
  5332.                 if (!isNaN(_x)) {
  5333.                     c.beginPath();
  5334.                     c.moveTo(_x, _y);
  5335.                     c.lineTo(x, y);
  5336.                     if (vars["stroke"] == 'gradient') {
  5337.                         var current = (((theta * Math.abs(1 - R / r) / Math.PI / 2) % 1) * 512) >> 0;
  5338.                         c.strokeStyle = 'rgba(' + spectrum[current] + ')';
  5339.                     }
  5340.                     c.stroke();
  5341.                 }
  5342.                 theta += resolution * Math.PI / 180 * 2;
  5343.                 _x = x;
  5344.                 _y = y;
  5345.             }
  5346.             _oX = o.X;
  5347.             _oY = o.Y;
  5348.         }, 5);
  5349.     }
  5350. };
  5351.  
  5352. })();
  5353.  
  5354. })();
  5355. /*
  5356.     Resources Database
  5357. */
  5358.  
  5359. /*
  5360.  
  5361. Canvas2D.vars = {
  5362.     marquee: {
  5363.         movement: 10
  5364.     },
  5365.     stroke: {
  5366.         pattern:
  5367.         gradient:
  5368.         color:
  5369.     },
  5370.     fill: {
  5371.         pattern:
  5372.         gradient:
  5373.         color:
  5374.     }
  5375. };
  5376.  
  5377. Resource = {
  5378.  
  5379.     // default databases
  5380.  
  5381.     brush: { // source:  /media/brush/name.png
  5382.         'Butterflies': { //ps7_butterfly_brushes_by_dead_brushes.abr
  5383.             author: 'Dead-Brushes',
  5384.             url: 'http://dead-brushes.deviantart.com/art/ps7-butterfly-brushes-61623697',
  5385.             email: 'bulletproof.cupidx@gmail.com',
  5386.             type: "Library", // set of elements organized by the creator
  5387.             data: [ // can be array, or integer (see below)
  5388.                 'green pea',
  5389.                 'yellow squash'
  5390.             ]
  5391.         },
  5392.         'Randomizer': { // modulate within a custom collection
  5393.             type: "Collection",  // set of elements organized by a user (contains parts of multiple libaries)
  5394.             data: [
  5395.                 'Butterflies.greenpea',
  5396.                 'Butterflies.yellow squash'
  5397.             ]
  5398.         }
  5399.     },
  5400.     pattern: { // source:  /media/pattern/name.filetype
  5401.         'Ava7': {
  5402.             author: 'Ava7',
  5403.             url: 'http://patterns.ava7.com/',
  5404.             email: 'domains.hr@gmail.com',
  5405.             type: "Library",
  5406.             data: 41 // there are 41 numbered patterns in /media/pattern/Ava7/
  5407.         }  
  5408.     },
  5409.     gradient: {  // source:  /media/gradient/name.ogr
  5410.         'Web v2.0': {
  5411.             author: 'Navdeep & Navin',
  5412.             url: 'http://gimp-tutorials.net/30-Ultimate-Web-20%20Layer-Styles-for%20-Gimp/',
  5413.             email: 'domains.hr@gmail.com',
  5414.             type: "Library",
  5415.             data: { // can be object or array
  5416.               'golden-yellow': [ 0, 0xFFFFD700, 0.5, 1, 0xFFFFFFFF ],
  5417.               'green': [ 0, 0xFF008000, 0.5, 1, 0xFFFFFF ],
  5418.               'indigo-orange': [ 0, 0xFF4B0082, 0.5, 1, 0xFFFFA500 ],
  5419.               'indigo': [ 0, 0xFF4B0082, 0.5, 1, 0xFFFFFF ]
  5420.             }
  5421.         }  
  5422.     },
  5423.     color: {  // source:  /media/color/name.opl
  5424.         'Oxygen': {
  5425.             author: 'KDE',
  5426.             url: 'http://techbase.kde.org/Development/Guidelines/CIG/Colors',
  5427.             email: 'domains.hr@gmail.com',
  5428.             type: "Library",
  5429.             data: { // can be object or array
  5430.                 'Almond': 0xEED9C4,
  5431.                 'Antique Brass': 0xC88A65,
  5432.                 'Apricot': 0xFDD5B1,
  5433.                 'Aquamarine': 0x71D9E2,
  5434.                 'Asparagus': 0x7BA05B
  5435.             }
  5436.         }
  5437.     },
  5438.  
  5439.     // keep multiple versions in RAM for quick switching (think randomizer on active mode)
  5440.  
  5441.     __brush: {
  5442.         'Butterflies': { // is an object, so it's easy to do:  delete Resource.__brush.Butterflies['green pea'];
  5443.             'green pea': createPattern(),
  5444.             'yellow squash': createPattern()
  5445.         },
  5446.         'Randomizer': { //
  5447.             'green pea': createPattern(),
  5448.             'yellow squash': createPattern()
  5449.         }
  5450.     },
  5451.     __pattern: {
  5452.         'Gaudi': { // would have at least two active (unless both stroke/fill were the same pattern)
  5453.             '0': createPattern(),
  5454.             '1': createPattern()
  5455.         }
  5456.     },
  5457.     __gradient: {
  5458.         'Nature': {
  5459.             '0': createLinearGradient() // or createRadialGradient() depending on what they have set
  5460.         }
  5461.     },
  5462.     __color: {
  5463.         'Fruity': {
  5464.             '0': 'rgba(123,45,67,1)'
  5465.         }
  5466.     }
  5467. };
  5468.  
  5469. */
  5470.  
  5471. Resources = {
  5472.     'Brushes': {
  5473.         'Butterflies': { //ps7_butterfly_brushes_by_dead_brushes.abr
  5474.             'email': 'bulletproof.cupidx@gmail.com',
  5475.             'url': 'http://dead-brushes.deviantart.com/art/ps7-butterfly-brushes-61623697',
  5476.             'name': 'dead-brushes'
  5477.         },
  5478.         'Doodles': { //punksafetypin_set21_boneydoodles.abr
  5479.             'email': 'punksafetypin@gmail.com',
  5480.             'url': 'http://punksafetypin.deviantart.com/art/Brush-Set-21-Boney-Doodles-57365483',
  5481.             'name': 'punksafetypin'
  5482.         },
  5483.         'Flowers': { //flowers1_brushes_by_hawksmont.abr
  5484.             'email': 'ir@hawksmont.com',
  5485.             'url': 'http://hawksmont.com/',
  5486.             'name': 'hawksmont'
  5487.         },
  5488.         'Footprints': { //Chain - Footprints.abr
  5489.             'email': 'jonas@rognemedia.no',
  5490.             'url': 'http://chain.deviantart.com/art/Footprint-brushes-60108797',
  5491.             'name': 'chain'
  5492.         },
  5493.         'Leafs': { //leaves_brushes_by hawksmont.abr
  5494.             'email': 'ir@hawksmont.com',
  5495.             'url': 'http://hawksmont.com/',
  5496.             'name': 'hawksmont'
  5497.         },
  5498.         'Retro': { //retro1.abr
  5499.             'email': 'vivekdhage@gmail.com',
  5500.             'url': 'http://vwake.deviantart.com/art/Retr0-Brushes-1689219',
  5501.             'name': 'vwake'
  5502.         },
  5503.         'Simple Smudges': { //SimpleSmudges__1__Brushes_Pack_by_env1ro.abr
  5504.             'email': 'p.szczepanski@gmail.com',
  5505.             'url': 'http://env1ro.deviantart.com/art/SimpleSmudges-1-Brushes-Pack-52089760',
  5506.             'name': 'env1ro'
  5507.         },
  5508. /*      'Splatter': { //SM_SplatterisM1_Low.abr
  5509.             'email': 'dan@fictionalhead.com',
  5510.             'url': 'http://smashmethod.deviantart.com/art/SM-splatterisM-1-ps7-repack-10351757',
  5511.             'name': 'smashmethod'
  5512.         },
  5513. */
  5514.         'Tizzape': { //tizzape_brushes.abr
  5515.             'email': 'services@dirt2.com',
  5516.             'url': 'http://keepwaiting.deviantart.com/art/Tizzape-Tape-Brushes-29459997',
  5517.             'name': 'keepwaiting'
  5518.         },
  5519.         'Typogrunge': { //JS_Scully7491_Typogrungebrushessm.abr
  5520.             'email': '',
  5521.             'url': 'http://scully7491.deviantart.com/art/Typographic-Grunge-Brushes-30565921',
  5522.             'name': 'scully7491'
  5523.         },
  5524.         'Water Colors': { //watercolors_env1ro.abr
  5525.             'email': 'p.szczepanski@gmail.com',
  5526.             'url': 'http://env1ro.deviantart.com/art/WaterColor-Reloaded-98294189',
  5527.             'name': 'env1ro'
  5528.         }
  5529.     },
  5530.     'PT': {
  5531.         'Ava7': {
  5532.             'email': 'domains.hr@gmail.com',
  5533.             'url': 'http://patterns.ava7.com/',
  5534.             'name': 'Ava7'
  5535.         },
  5536.         'DinPattern': {
  5537.             'email': 'http://www.dinpattern.com/pages/contact.php',
  5538.             'url': 'http://www.dinpattern.com/',
  5539.             'name': 'DinPattern'
  5540.         },
  5541.         'Gaudi': {
  5542.             'email': 'http://www.donbarnett.com/mail/index.php3',
  5543.             'url': 'http://www.donbarnett.com/tilesets/set3.htm',
  5544.             'name': 'Don Barnett'
  5545.         },
  5546.         'Headlock': {
  5547.             'email': 'dns@jpmax.net',
  5548.             'url': 'http://www.headlock.ws/patterns.html',
  5549.             'name': 'Headlock'
  5550.         },
  5551.         'HG - Patterns': {
  5552.             'email': 'hybridgenesis@gmail.com',
  5553.             'url': 'http://www.hybrid-genesis.com/freebies.html',
  5554.             'name': 'Hybrid Genesis'
  5555.         },
  5556.         'HGX - Patterns': {
  5557.             'email': 'hybridgenesis@gmail.com',
  5558.             'url': 'http://www.hybrid-genesis.com/hgx_intro.html',
  5559.             'name': 'Hybrid Genesis'
  5560.         },
  5561.         'Squidfingers': {
  5562.             'email': 'Travis@squidfingers.com',
  5563.             'url': 'http://www.squidfingers.com/patterns/',
  5564.             'name': 'Travis'
  5565.         }
  5566.     },
  5567.     'GD': {
  5568.         'Web v2.0': {
  5569.             'email': '',
  5570.             'url': 'http://gimp-tutorials.net/30-Ultimate-Web-20%20Layer-Styles-for%20-Gimp',
  5571.             'name': 'Navdeep & Navin'
  5572.         },
  5573.         'Web v2.1': {
  5574.             'email': '',
  5575.             'url': 'http://gimp-tutorials.net/130-UltimateWeb20-Gradients-for-Gimp',
  5576.             'name': 'Navdeep & Navin'
  5577.         }
  5578.     },
  5579.     'CO': {
  5580.         'Oxygen': {
  5581.             'email': '',
  5582.             'url': 'http://techbase.kde.org/Development/Guidelines/CIG/Colors',
  5583.             'name': 'KDE'
  5584.         },
  5585.         'Cranes': {
  5586.             'email': '',
  5587.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5588.             'name': 'Carol'
  5589.         },
  5590.         'Grays': {
  5591.             'email': '',
  5592.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5593.             'name': 'Carol'
  5594.         },
  5595.         'Named Colors': {
  5596.             'email': '',
  5597.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5598.             'name': 'Carol'
  5599.         },
  5600.         'Pastels': {
  5601.             'email': '',
  5602.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5603.             'name': 'Carol'
  5604.         },
  5605.         'Reds and Purples': {
  5606.             'email': '',
  5607.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5608.             'name': 'Carol'
  5609.         },
  5610.         'Web': {
  5611.             'email': '',
  5612.             'url': 'http://Carol.gimp.org/gimp2/resources/default/palettes.html',
  5613.             'name': 'Carol'
  5614.         },
  5615.         'Fruity': {
  5616.             'email': 'mud@visc.us',
  5617.             'url': 'http://mudcu.be/',
  5618.             'name': 'MUD'
  5619.         }
  5620.     }
  5621. };
  5622.  
  5623. /* GRADIENTS */
  5624.  
  5625. Q={}; Q.GD={};
  5626.  
  5627. Q.GD['Nature']=[
  5628.  
  5629.     [[0,[86,3,0,1]],[0.11,[153,0,0,1]],[0.36,[205,112,19,1]],[0.7,[219,181,82,1]],[1,[115,94,41,1]]],
  5630.     [[0,[0,0,0,1]],[1,[153,0,0,1]]],
  5631.     [[0,[41,68,99,1]],[0.57,[254,221,144,1]],[1,[41,68,99,1]]],
  5632.     [[0,[39,73,105,1]],[0.27,[98,122,155,1]],[0.61,[156,171,204,1]],[1,[215,220,254,1]]],
  5633.     [[0,[40,66,82,1]],[0.09,[206,213,254,1]],[0.28,[41,68,99,1]],[0.39,[65,79,92,1]],[0.57,[119,151,215,1]],[0.68,[70,103,145,1]],[0.81,[89,122,157,1]],[0.91,[41,68,99,1]],[1,[2,33,54,1]]],
  5634.     [[0,[87,42,0,1]],[0.2,[69,46,2,1]],[0.66,[190,160,88,1]],[1,[142,121,64,1]]],
  5635.     [[0,[177,128,152,1]],[0.36,[95,52,71,1]],[0.36,[99,58,75,1]],[1,[248,210,236,1]]],
  5636.     [[0,[139,9,3,1]],[1,[254,221,144,1]]],
  5637.     [[0,[139,9,3,1]],[1,[234,85,78,1]]],
  5638.     [[0,[16,40,65,1]],[1,[89,122,157,1]]],
  5639.     [[0,[168,183,240,1]],[0.32,[214,163,126,1]],[1,[120,124,148,1]]],
  5640.     [[0,[254,248,188,1]],[1,[254,228,170,1]]],
  5641.     [[0,[52,7,1,1]],[1,[177,128,152,1]]],
  5642.     [[0,[95,52,71,1]],[0.5,[254,246,185,1]],[1,[95,52,71,1]]],
  5643.     [[0,[136,113,86,1]],[1,[229,205,152,1]]],
  5644.     [[0,[205,135,85,1]],[1,[89,38,12,1]]],
  5645.     [[0,[83,58,7,1]],[1,[254,241,185,1]]],
  5646.     [[0,[33,43,52,1]],[1,[198,167,127,1]]],
  5647.     [[0,[2,33,54,1]],[0.11,[57,23,36,1]],[0.24,[95,52,71,1]],[0.6,[40,66,82,1]],[1,[2,33,54,1]]],
  5648.     [[0,[142,121,64,1]],[1,[41,68,99,1]]]]
  5649.  
  5650. Q.GD['Web v2.0']=[
  5651.    
  5652.     [[0,[16,16,16,1]],[1,[124,125,124,1]]],
  5653.     [[0,[43,43,43,1]],[0.51,[1,1,1,1]],[0.51,[61,61,61,1]],[1,[77,77,77,1]]],
  5654.     [[0,[128,224,248,1]],[1,[205,248,255,1]]],
  5655.     [[0,[65,151,238,1]],[1,[121,187,255,1]]],
  5656.     [[0,[66,145,219,1]],[0.13,[75,184,240,1]],[0.62,[58,134,197,1]],[0.62,[99,154,200,1]],[1,[205,219,232,1]]],
  5657.     [[0,[191,110,78,1]],[0.29,[118,34,1,1]],[0.54,[118,34,1,1]],[0.54,[141,53,18,1]],[1,[240,183,160,1]]],
  5658.     [[0,[109,0,25,1]],[1,[168,3,41,1]]],
  5659.     [[0,[255,116,0,1]],[1,[255,116,0,1]]],
  5660.     [[0,[254,191,5,1]],[1,[255,214,93,1]]],
  5661.     [[0,[202,38,0,1]],[0.18,[255,102,0,1]],[0.18,[255,101,0,1]],[0.59,[246,41,12,1]],[0.59,[233,116,96,1]],[1,[241,186,176,1]]],
  5662.     [[0,[225,233,160,1]],[1,[234,239,181,1]]],
  5663.     [[0,[171,220,40,1]],[1,[182,224,38,1]]],
  5664.     [[0,[63,76,107,1]],[1,[96,107,136,1]]],
  5665.     [[0,[98,145,192,1]],[1,[204,230,249,1]]],
  5666.     [[0,[128,171,203,1]],[1,[206,224,236,1]]],
  5667.     [[0,[215,236,251,1]],[0.29,[138,195,235,1]],[0.54,[138,195,235,1]],[0.54,[171,211,238,1]],[1,[234,241,246,1]]],
  5668.     [[0,[125,227,31,1]],[0.25,[160,240,38,1]],[1,[199,254,48,1]]],
  5669.     [[0,[125,227,31,1]],[1,[166,242,39,1]]],
  5670.     [[0,[255,123,215,1]],[0.18,[253,137,215,1]],[0.54,[253,137,215,1]],[0.54,[251,167,225,1]],[1,[251,231,251,1]]],
  5671.     [[0,[251,224,151,1]],[0.27,[248,182,3,1]],[0.56,[248,182,3,1]],[0.56,[252,205,79,1]],[1,[252,234,185,1]]],
  5672.     [[0,[255,126,2,1]],[0.51,[255,124,0,1]],[0.51,[255,167,61,1]],[1,[255,160,61,1]]],
  5673.     [[0,[169,73,164,1]],[1,[229,112,231,1]]],
  5674.     [[0,[216,49,162,1]],[0.51,[169,0,119,1]],[0.51,[193,70,161,1]],[1,[193,65,164,1]]],
  5675.     [[0,[198,232,250,1]],[1,[235,247,253,1]]],
  5676.     [[0,[209,20,20,1]],[1,[254,27,1,1]]],
  5677.     [[0,[234,58,42,1]],[0.18,[216,41,21,1]],[0.54,[246,41,12,1]],[0.54,[238,85,67,1]],[1,[254,88,55,1]]],
  5678.     [[0,[209,211,96,1]],[1,[229,230,149,1]]],
  5679.     [[0,[255,228,0,1]],[0.57,[255,136,0,1]],[1,[230,109,29,1]]],
  5680.     [[0,[241,244,246,1]],[0.51,[216,223,227,1]],[0.51,[229,235,238,1]],[1,[246,248,249,1]]],
  5681.     [[0,[252,181,54,1]],[1,[239,228,91,1]]]];
  5682.  
  5683. Q.GD['Web v2.1']=[
  5684.    
  5685.     [[0,[76,76,76,1]],[0.25,[102,102,102,1]],[0.5,[44,44,44,1]],[0.5,[0,0,0,1]],[0.76,[43,43,43,1]],[1,[19,19,19,1]]],
  5686.     [[0,[135,224,253,1]],[1,[5,171,224,1]]],
  5687.     [[0,[240,249,255,1]],[1,[161,219,255,1]]],
  5688.     [[0,[122,188,255,1]],[1,[64,150,238,1]]],
  5689.     [[0,[0,183,234,1]],[1,[0,158,195,1]]],
  5690.     [[0,[136,191,232,1]],[1,[112,176,224,1]]],
  5691.     [[0,[254,255,255,1]],[1,[160,216,239,1]]],
  5692.     [[0,[37,141,200,1]],[1,[37,141,200,1]]],
  5693.     [[0,[64,150,238,1]],[1,[64,150,238,1]]],
  5694.     [[0,[184,225,252,1]],[0.25,[144,186,228,1]],[0.5,[144,191,240,1]],[0.5,[107,168,229,1]],[1,[189,243,253,1]]],
  5695.     [[0,[59,103,158,1]],[0.5,[43,136,217,1]],[0.5,[32,124,202,1]],[1,[125,185,232,1]]],
  5696.     [[0,[109,179,242,1]],[0.5,[84,163,238,1]],[0.5,[54,144,240,1]],[1,[30,105,222,1]]],
  5697.     [[0,[235,241,246,1]],[0.5,[171,211,238,1]],[0.5,[137,195,235,1]],[1,[213,235,251,1]]],
  5698.     [[0,[228,245,252,1]],[0.5,[191,232,249,1]],[0.5,[159,216,239,1]],[1,[42,176,237,1]]],
  5699.     [[0,[206,219,233,1]],[0.5,[97,153,199,1]],[0.5,[58,132,195,1]],[0.71,[75,184,240,1]],[1,[38,85,139,1]]],
  5700.     [[0,[167,199,220,1]],[1,[133,178,211,1]]],
  5701.     [[0,[63,76,107,1]],[1,[63,76,107,1]]],
  5702.     [[0,[208,228,247,1]],[0.5,[10,119,213,1]],[1,[135,188,234,1]]],
  5703.     [[0,[225,255,255,1]],[0.12,[225,255,255,1]],[0.12,[253,255,255,1]],[0.54,[200,238,251,1]],[1,[177,216,245,1]]],
  5704.     [[0,[179,220,237,1]],[0.5,[41,184,229,1]],[1,[188,224,238,1]]],
  5705.     [[0,[213,206,166,1]],[1,[183,173,112,1]]],
  5706.     [[0,[240,183,161,1]],[0.5,[140,51,16,1]],[0.5,[117,34,1,1]],[1,[191,110,78,1]]],
  5707.     [[0,[169,3,41,1]],[1,[109,0,25,1]]],
  5708.     [[0,[254,252,234,1]],[1,[241,218,54,1]]],
  5709.     [[0,[180,221,180,1]],[0.33,[82,177,82,1]],[0.67,[0,138,0,1]],[1,[0,36,0,1]]],
  5710.     [[0,[205,235,142,1]],[1,[165,201,86,1]]],
  5711.     [[0,[201,222,150,1]],[1,[57,130,53,1]]],
  5712.     [[0,[248,255,232,1]],[1,[183,223,45,1]]],
  5713.     [[0,[169,219,128,1]],[1,[150,197,111,1]]],
  5714.     [[0,[180,227,145,1]],[0.5,[97,196,25,1]],[1,[180,227,145,1]]],
  5715.     [[0,[41,154,11,1]],[1,[41,154,11,1]]],
  5716.     [[0,[143,200,0,1]],[1,[143,200,0,1]]],
  5717.     [[0,[0,110,46,1]],[1,[0,110,46,1]]],
  5718.     [[0,[107,186,112,1]],[1,[107,186,112,1]]],
  5719.     [[0,[205,235,139,1]],[1,[205,235,139,1]]],
  5720.     [[0,[143,196,0,1]],[1,[143,196,0,1]]],
  5721.     [[0,[182,224,38,1]],[1,[171,220,40,1]]],
  5722.     [[0,[157,213,58,1]],[0.5,[161,213,79,1]],[0.5,[128,194,23,1]],[1,[124,188,10,1]]],
  5723.     [[0,[230,240,163,1]],[0.5,[210,230,56,1]],[0.5,[195,216,37,1]],[1,[219,240,67,1]]],
  5724.     [[0,[191,210,85,1]],[0.5,[142,185,42,1]],[0.5,[114,170,0,1]],[1,[158,203,45,1]]],
  5725.     [[0,[180,223,91,1]],[1,[180,223,91,1]]],
  5726.     [[0,[238,238,238,1]],[1,[204,204,204,1]]],
  5727.     [[0,[206,220,231,1]],[1,[89,106,114,1]]],
  5728.     [[0,[96,108,136,1]],[1,[63,76,107,1]]],
  5729.     [[0,[176,212,227,1]],[1,[136,186,207,1]]],
  5730.     [[0,[242,245,246,1]],[1,[200,215,220,1]]],
  5731.     [[0,[216,224,222,1]],[0.33,[153,175,171,1]],[0.67,[130,157,152,1]],[1,[14,14,14,1]]],
  5732.     [[0,[181,189,200,1]],[1,[40,52,59,1]]],
  5733.     [[0,[184,198,223,1]],[1,[109,136,183,1]]],
  5734.     [[0,[207,231,250,1]],[1,[99,147,193,1]]],
  5735.     [[0,[210,223,237,1]],[0.51,[190,208,234,1]],[0.51,[166,192,227,1]],[0.75,[186,208,239,1]],[1,[121,155,200,1]]],
  5736.     [[0,[238,238,238,1]],[1,[238,238,238,1]]],
  5737.     [[0,[226,226,226,1]],[0.5,[219,219,219,1]],[0.5,[209,209,209,1]],[1,[254,254,254,1]]],
  5738.     [[0,[242,246,248,1]],[0.5,[216,225,231,1]],[0.5,[181,198,208,1]],[1,[224,239,249,1]]],
  5739.     [[0,[212,228,239,1]],[1,[134,174,204,1]]],
  5740.     [[0,[245,246,246,1]],[0.49,[184,186,198,1]],[1,[245,246,246,1]]],
  5741.     [[0,[243,226,199,1]],[0.5,[193,158,103,1]],[0.5,[182,141,76,1]],[1,[233,212,179,1]]],
  5742.     [[0,[249,252,247,1]],[1,[245,249,240,1]]],
  5743.     [[0,[195,217,255,1]],[1,[152,176,217,1]]],
  5744.     [[0,[210,255,82,1]],[1,[145,232,66,1]]],
  5745.     [[0,[254,254,253,1]],[1,[174,191,118,1]]],
  5746.     [[0,[228,239,192,1]],[1,[171,189,115,1]]],
  5747.     [[0,[164,179,87,1]],[1,[117,137,12,1]]],
  5748.     [[0,[98,125,77,1]],[1,[31,59,8,1]]],
  5749.     [[0,[115,136,10,1]],[1,[115,136,10,1]]],
  5750.     [[0,[255,175,75,1]],[1,[255,146,10,1]]],
  5751.     [[0,[250,198,149,1]],[1,[239,141,49,1]]],
  5752.     [[0,[255,197,120,1]],[1,[251,157,35,1]]],
  5753.     [[0,[249,198,103,1]],[1,[247,150,33,1]]],
  5754.     [[0,[252,234,187,1]],[0.5,[252,205,77,1]],[0.5,[248,181,0,1]],[1,[251,223,147,1]]],
  5755.     [[0,[255,168,76,1]],[1,[255,123,13,1]]],
  5756.     [[0,[255,103,15,1]],[1,[255,103,15,1]]],
  5757.     [[0,[255,116,0,1]],[1,[255,116,0,1]]],
  5758.     [[0,[255,183,107,1]],[0.5,[255,167,61,1]],[0.5,[255,124,0,1]],[1,[255,127,4,1]]],
  5759.     [[0,[255,93,177,1]],[1,[239,1,124,1]]],
  5760.     [[0,[251,131,250,1]],[1,[233,60,236,1]]],
  5761.     [[0,[229,112,231,1]],[1,[168,73,163,1]]],
  5762.     [[0,[203,96,179,1]],[0.5,[173,18,131,1]],[1,[222,71,172,1]]],
  5763.     [[0,[255,0,132,1]],[1,[255,0,132,1]]],
  5764.     [[0,[252,236,252,1]],[0.5,[251,166,225,1]],[0.5,[253,137,215,1]],[1,[255,124,216,1]]],
  5765.     [[0,[203,96,179,1]],[0.5,[193,70,161,1]],[0.5,[168,0,119,1]],[1,[219,54,164,1]]],
  5766.     [[0,[235,233,249,1]],[0.5,[216,208,239,1]],[0.5,[206,199,236,1]],[1,[193,191,234,1]]],
  5767.     [[0,[137,137,186,1]],[1,[137,137,186,1]]],
  5768.     [[0,[254,187,187,1]],[1,[255,92,92,1]]],
  5769.     [[0,[242,130,91,1]],[0.5,[229,91,43,1]],[1,[240,113,70,1]]],
  5770.     [[0,[255,48,25,1]],[1,[207,4,4,1]]],
  5771.     [[0,[255,26,0,1]],[1,[255,26,0,1]]],
  5772.     [[0,[204,0,0,1]],[1,[204,0,0,1]]],
  5773.     [[0,[248,80,50,1]],[0.5,[241,111,92,1]],[0.5,[246,41,12,1]],[1,[231,56,39,1]]],
  5774.     [[0,[254,204,177,1]],[0.5,[241,116,50,1]],[0.5,[234,85,7,1]],[1,[251,149,94,1]]],
  5775.     [[0,[239,197,202,1]],[0.5,[210,75,90,1]],[0.5,[186,39,55,1]],[1,[241,142,153,1]]],
  5776.     [[0,[243,197,189,1]],[0.5,[232,108,87,1]],[0.5,[234,40,3,1]],[0.75,[255,102,0,1]],[1,[199,34,0,1]]],
  5777.     [[0,[183,222,237,1]],[0.5,[113,206,239,1]],[0.5,[33,180,226,1]],[1,[183,222,237,1]]],
  5778.     [[0,[224,243,250,1]],[0.5,[216,240,252,1]],[0.5,[184,226,246,1]],[1,[182,223,253,1]]],
  5779.     [[0,[254,255,232,1]],[1,[214,219,191,1]]],
  5780.     [[0,[252,255,244,1]],[1,[233,233,206,1]]],
  5781.     [[0,[252,255,244,1]],[1,[179,190,173,1]]],
  5782.     [[0,[229,230,150,1]],[1,[209,211,96,1]]],
  5783.     [[0,[234,239,181,1]],[1,[225,233,160,1]]],
  5784.     [[0,[69,72,77,1]],[1,[0,0,0,1]]],
  5785.     [[0,[125,126,125,1]],[1,[14,14,14,1]]],
  5786.     [[0,[149,149,149,1]],[0.5,[1,1,1,1]],[0.76,[78,78,78,1]],[1,[27,27,27,1]]],
  5787.     [[0,[174,188,191,1]],[0.5,[110,119,116,1]],[0.5,[10,14,10,1]],[1,[10,8,9,1]]],
  5788.     [[0,[197,222,234,1]],[1,[6,109,171,1]]],
  5789.     [[0,[247,251,252,1]],[1,[173,217,228,1]]],
  5790.     [[0,[214,249,255,1]],[1,[158,232,250,1]]],
  5791.     [[0,[233,246,253,1]],[1,[211,238,251,1]]],
  5792.     [[0,[99,182,219,1]],[1,[48,157,207,1]]],
  5793.     [[0,[44,83,158,1]],[1,[44,83,158,1]]],
  5794.     [[0,[169,228,247,1]],[1,[15,180,231,1]]],
  5795.     [[0,[178,225,255,1]],[1,[102,182,252,1]]],
  5796.     [[0,[79,133,187,1]],[1,[79,133,187,1]]],
  5797.     [[0,[147,206,222,1]],[1,[73,165,191,1]]],
  5798.     [[0,[222,239,255,1]],[1,[152,190,222,1]]],
  5799.     [[0,[73,192,240,1]],[1,[44,175,227,1]]],
  5800.     [[0,[254,255,255,1]],[1,[210,235,249,1]]],
  5801.     [[0,[167,207,223,1]],[1,[35,83,138,1]]],
  5802.     [[0,[73,155,234,1]],[1,[32,124,229,1]]],
  5803.     [[0,[53,106,160,1]],[1,[53,106,160,1]]],
  5804.     [[0,[255,255,255,1]],[1,[237,237,237,1]]],
  5805.     [[0,[242,249,254,1]],[1,[214,240,253,1]]],
  5806.     [[0,[255,255,255,1]],[1,[229,229,229,1]]],
  5807.     [[0,[255,255,255,1]],[0.5,[241,241,241,1]],[0.5,[225,225,225,1]],[1,[246,246,246,1]]],
  5808.     [[0,[255,255,255,1]],[0.5,[243,243,243,1]],[0.5,[237,237,237,1]],[1,[255,255,255,1]]],
  5809.     [[0,[246,248,249,1]],[0.5,[229,235,238,1]],[0.5,[215,222,227,1]],[1,[245,247,249,1]]],
  5810.     [[0,[246,230,180,1]],[1,[237,144,23,1]]],
  5811.     [[0,[234,185,45,1]],[1,[199,152,16,1]]],
  5812.     [[0,[255,214,94,1]],[1,[254,191,4,1]]],
  5813.     [[0,[241,231,103,1]],[1,[254,182,69,1]]],
  5814.     [[0,[255,255,136,1]],[1,[255,255,136,1]]],
  5815.     [[0,[254,191,1,1]],[1,[254,191,1,1]]]];
  5816.  
  5817.  
  5818. /* COLORS */
  5819.  
  5820. Q.CO={};
  5821.  
  5822. Q.CO['Fruity']=[
  5823.  
  5824.     [252,233,79,1],[237,212,0,1],[196,160,0,1],[138,226,52,1],[115,210,22,1],[78,154,6,1],[78,154,6,1],
  5825.     [252,175,62,1],[245,121,0,1],[206,92,0,1],[114,159,207,1],[52,101,164,1],[32,74,135,1],[32,74,135,1],
  5826.     [233,185,110,1],[193,125,17,1],[143,89,2,1],[173,127,168,1],[117,80,123,1],[92,53,102,1],[92,53,102,1],
  5827.     [164,0,0,1],[204,0,0,1],[239,41,41,1],[248,46,0,1],[255,142,3,1],[255,213,3,1],[189,248,0,1]];
  5828.    
  5829. Q.CO['Oxygen']=[[56,37,9,1],[87,64,30,1],[117,81,26,1],[143,107,50,1],[179,146,93,1],[222,188,133,1],[156,15,15,1],[191,3,3,1],[226,8,0,1],[232,87,82,1],[240,134,130,1],[249,204,202,1],[156,15,86,1],[191,3,97,1],[226,0,113,1],[232,82,144,1],[240,130,176,1],[249,202,222,1],[106,0,86,1],[133,2,108,1],[160,39,134,1],[177,79,154,1],[193,115,176,1],[232,183,215,1],[29,1,85,1],[52,23,110,1],[70,40,134,1],[100,74,155,1],[142,121,165,1],[195,180,218,1],[0,49,110,1],[0,67,138,1],[0,87,174,1],[44,114,199,1],[97,147,207,1],[164,192,228,1],[0,72,77,1],[0,96,102,1],[0,120,128,1],[0,167,179,1],[0,196,204,1],[168,221,224,1],[0,8,63,1],[0,115,77,1],[0,153,102,1],[0,179,119,1],[0,204,136,1],[153,220,198,1],[0,110,41,1],[0,137,44,1],[55,164,44,1],[119,183,83,1],[177,210,143,1],[216,232,194,1],[227,173,0,1],[243,195,0,1],[255,221,0,1],[255,235,85,1],[255,242,153,1],[255,246,200,1],[172,67,17,1],[207,73,19,1],[235,115,49,1],[242,155,104,1],[242,187,136,1],[255,217,176,1],[46,52,54,1],[85,87,83,1],[136,138,133,1],[186,189,182,1],[211,215,207,1],[238,238,236,1],[77,38,0,1],[128,63,0,1],[191,94,0,1],[255,126,0,1],[255,191,128,1],[255,223,191,1],[89,0,0,1],[140,0,0,1],[191,0,0,1],[255,0,0,1],[255,128,128,1],[255,191,191,1],[115,0,85,1],[163,0,123,1],[204,0,154,1],[255,0,191,1],[255,128,223,1],[255,191,240,1],[44,0,89,1],[64,0,128,1],[90,0,179,1],[128,0,255,1],[192,128,255,1],[223,191,255,1],[0,0,128,1],[0,0,191,1],[0,0,255,1],[0,102,255,1],[128,179,255,1],[191,217,255,1],[0,77,0,1],[0,140,0,1],[0,191,0,1],[0,255,0,1],[128,255,128,1],[191,255,191,1],[99,128,0,1],[139,179,0,1],[191,245,0,1],[229,255,0,1],[240,255,128,1],[248,255,191,1],[255,170,0,1],[255,191,0,1],[255,213,0,1],[255,255,0,1],[255,255,153,1],[255,255,191,1],[50,50,50,1],[85,85,85,1],[136,136,136,1],[187,187,187,1],[221,221,221,1],[238,238,238,1]];
  5830.  
  5831. Q.CO['Cranes']=[[8,8,8,1],[192,176,144,1],[192,164,128,1],[80,72,68,1],[112,140,88,1],[104,132,96,1],[92,104,84,1],[24,8,12,1],[96,108,92,1],[128,104,76,1],[44,28,24,1],[156,140,116,1],[156,148,116,1],[68,68,60,1],[212,196,148,1],[144,136,108,1],[160,148,128,1],[216,220,216,1],[44,28,40,1],[68,12,16,1],[12,8,32,1],[56,8,48,1],[48,8,40,1],[44,20,40,1],[104,104,92,1],[52,28,48,1],[156,176,124,1],[124,160,96,1],[44,40,24,1],[168,168,172,1],[196,188,168,1],[8,28,20,1],[160,60,60,1],[180,144,100,1],[192,144,112,1],[132,40,60,1],[48,8,24,1],[156,176,144,1],[80,84,64,1],[136,148,136,1],[120,160,116,1],[44,20,24,1],[128,84,80,1],[128,20,56,1],[168,68,76,1],[64,56,44,1],[56,40,40,1],[156,172,164,1],[100,92,72,1],[124,116,88,1],[32,8,28,1],[176,180,180,1],[156,44,68,1],[172,176,156,1],[176,168,144,1],[188,8,88,1],[148,8,52,1],[20,48,52,1],[68,60,68,1],[216,204,160,1],[140,160,112,1],[112,116,88,1],[152,160,164,1],[116,156,104,1],[192,192,184,1],[80,84,72,1],[56,24,24,1],[24,36,40,1],[48,56,52,1],[92,84,64,1],[180,160,120,1],[112,100,76,1],[156,120,88,1],[96,96,84,1],[148,160,152,1],[192,200,144,1],[68,56,56,1],[100,48,96,1],[108,144,100,1],[188,180,160,1],[60,48,68,1],[80,48,52,1],[188,56,72,1],[196,176,128,1],[220,180,164,1],[132,116,100,1],[68,36,52,1],[168,132,100,1],[180,168,132,1],[148,156,140,1],[120,128,108,1],[108,12,48,1],[108,80,68,1],[44,40,56,1],[140,124,104,1],[24,28,20,1],[204,172,120,1],[164,156,132,1],[116,104,96,1],[144,152,148,1],[84,92,72,1],[120,148,100,1],[120,112,108,1],[60,64,56,1],[204,176,140,1],[212,140,128,1],[80,56,64,1],[152,140,108,1],[72,72,76,1],[20,12,48,1],[140,152,128,1],[208,100,88,1],[8,36,48,1],[80,104,68,1],[44,40,8,1],[76,60,84,1],[56,40,24,1],[112,52,64,1],[212,124,112,1],[152,72,76,1],[212,124,128,1],[88,88,96,1],[16,68,8,1],[36,8,40,1],[128,168,112,1],[208,212,196,1],[216,208,176,1],[76,68,56,1],[40,44,28,1],[32,20,80,1],[136,64,68,1],[60,76,64,1],[200,104,96,1],[92,84,80,1],[164,148,116,1],[116,108,84,1],[148,128,100,1],[80,80,84,1],[136,140,128,1],[88,16,76,1],[124,12,8,1],[100,96,104,1],[132,52,36,1],[56,28,40,1],[196,96,88,1],[64,84,44,1],[164,188,132,1],[204,196,168,1],[216,220,208,1],[136,172,100,1],[148,188,124,1],[52,72,32,1],[108,108,116,1],[136,172,132,1],[60,60,64,1],[108,92,92,1],[216,156,144,1],[104,96,84,1],[172,180,172,1],[140,108,88,1],[160,164,156,1],[148,132,108,1],[128,140,120,1],[40,84,56,1],[132,56,108,1],[96,32,56,1],[164,88,84,1],[96,104,72,1],[172,192,152,1],[192,196,172,1],[208,108,100,1],[68,84,72,1],[140,128,96,1],[224,228,224,1],[128,128,132,1],[76,96,56,1],[88,76,100,1],[72,12,52,1],[56,44,56,1],[68,48,68,1],[60,20,64,1],[44,12,56,1],[84,68,76,1],[44,8,8,1],[148,136,100,1],[148,180,108,1],[184,52,20,1],[0,0,0,1],[40,0,0,1],[0,56,92,1],[0,0,4,1],[0,0,0,1],[60,56,56,1],[56,20,40,1],[192,28,36,1],[72,80,60,1],[72,92,68,1],[88,100,76,1],[88,116,72,1],[0,0,0,1],[56,40,56,1],[72,76,68,1],[128,48,52,1],[168,36,60,1],[76,96,76,1],[80,108,80,1],[128,120,108,1],[184,72,80,1],[104,128,84,1],[136,132,108,1],[148,140,116,1],[112,152,92,1],[208,184,132,1],[104,116,100,1],[132,128,116,1],[136,120,88,1],[0,0,0,1],[116,124,120,1],[136,152,152,1],[144,156,160,1],[156,168,176,1],[184,184,176,1],[152,172,184,1],[184,188,188,1],[196,200,196,1],[212,212,208,1],[148,164,172,1],[84,96,84,1],[96,8,20,1],[100,116,80,1],[96,120,92,1],[164,176,184,1],[204,188,152,1],[128,128,100,1],[44,40,40,1],[204,204,188,1],[92,128,80,1],[100,140,88,1],[56,48,44,1],[128,148,112,1],[36,28,40,1],[196,160,112,1],[124,116,96,1],[104,104,84,1],[132,140,140,1],[140,132,116,1],[204,208,200,1],[196,80,84,1],[116,112,96,1],[88,116,84,1],[64,44,56,1],[44,24,8,1],[196,116,116,1],[180,148,116,1],[136,176,116,1],[148,140,124,1]];
  5832.  
  5833. Q.CO['Grays']=[[0,0,0,1],[7,7,7,1],[15,15,15,1],[23,23,23,1],[31,31,31,1],[39,39,39,1],[47,47,47,1],[55,55,55,1],[63,63,63,1],[71,71,71,1],[79,79,79,1],[87,87,87,1],[95,95,95,1],[103,103,103,1],[111,111,111,1],[119,119,119,1],[127,127,127,1],[135,135,135,1],[143,143,143,1],[151,151,151,1],[159,159,159,1],[167,167,167,1],[175,175,175,1],[183,183,183,1],[191,191,191,1],[199,199,199,1],[207,207,207,1],[215,215,215,1],[223,223,223,1],[231,231,231,1],[239,239,239,1],[247,247,247,1]];
  5834.  
  5835. Q.CO['Named Colors']=[[255,250,250,1],[248,248,255,1],[245,245,245,1],[220,220,220,1],[255,250,240,1],[253,245,230,1],[250,240,230,1],[250,235,215,1],[255,239,213,1],[255,235,205,1],[255,228,196,1],[255,218,185,1],[255,222,173,1],[255,228,181,1],[255,248,220,1],[255,255,240,1],[255,250,205,1],[255,245,238,1],[240,255,240,1],[245,255,250,1],[240,255,255,1],[240,248,255,1],[230,230,250,1],[255,240,245,1],[255,228,225,1],[255,255,255,1],[0,0,0,1],[47,79,79,1],[105,105,105,1],[112,128,144,1],[119,136,153,1],[190,190,190,1],[211,211,211,1],[25,25,112,1],[0,0,128,1],[100,149,237,1],[72,61,139,1],[106,90,205,1],[123,104,238,1],[132,112,255,1],[0,0,205,1],[65,105,225,1],[0,0,255,1],[30,144,255,1],[0,191,255,1],[135,206,235,1],[135,206,250,1],[70,130,180,1],[176,196,222,1],[173,216,230,1],[176,224,230,1],[175,238,238,1],[0,206,209,1],[72,209,204,1],[64,224,208,1],[0,255,255,1],[224,255,255,1],[95,158,160,1],[102,205,170,1],[127,255,212,1],[0,100,0,1],[85,107,47,1],[143,188,143,1],[46,139,87,1],[60,179,113,1],[32,178,170,1],[152,251,152,1],[0,255,127,1],[124,252,0,1],[0,255,0,1],[127,255,0,1],[0,250,154,1],[173,255,47,1],[50,205,50,1],[154,205,50,1],[34,139,34,1],[107,142,35,1],[189,183,107,1],[240,230,140,1],[238,232,170,1],[250,250,210,1],[255,255,224,1],[255,255,0,1],[255,215,0,1],[238,221,130,1],[218,165,32,1],[184,134,11,1],[188,143,143,1],[205,92,92,1],[139,69,19,1],[160,82,45,1],[205,133,63,1],[222,184,135,1],[245,245,220,1],[245,222,179,1],[244,164,96,1],[210,180,140,1],[210,105,30,1],[178,34,34,1],[165,42,42,1],[233,150,122,1],[250,128,114,1],[255,160,122,1],[255,165,0,1],[255,140,0,1],[255,127,80,1],[240,128,128,1],[255,99,71,1],[255,69,0,1],[255,0,0,1],[255,105,180,1],[255,20,147,1],[255,192,203,1],[255,182,193,1],[219,112,147,1],[176,48,96,1],[199,21,133,1],[208,32,144,1],[255,0,255,1],[238,130,238,1],[221,160,221,1],[218,112,214,1],[186,85,211,1],[153,50,204,1],[148,0,211,1],[138,43,226,1],[160,32,240,1],[147,112,219,1],[216,191,216,1],[255,250,250,1],[238,233,233,1],[205,201,201,1],[139,137,137,1],[255,245,238,1],[238,229,222,1],[205,197,191,1],[139,134,130,1],[255,239,219,1],[238,223,204,1],[205,192,176,1],[139,131,120,1],[255,228,196,1],[238,213,183,1],[205,183,158,1],[139,125,107,1],[255,218,185,1],[238,203,173,1],[205,175,149,1],[139,119,101,1],[255,222,173,1],[238,207,161,1],[205,179,139,1],[139,121,94,1],[255,250,205,1],[238,233,191,1],[205,201,165,1],[139,137,112,1],[255,248,220,1],[238,232,205,1],[205,200,177,1],[139,136,120,1],[255,255,240,1],[238,238,224,1],[205,205,193,1],[139,139,131,1],[240,255,240,1],[224,238,224,1],[193,205,193,1],[131,139,131,1],[255,240,245,1],[238,224,229,1],[205,193,197,1],[139,131,134,1],[255,228,225,1],[238,213,210,1],[205,183,181,1],[139,125,123,1],[240,255,255,1],[224,238,238,1],[193,205,205,1],[131,139,139,1],[131,111,255,1],[122,103,238,1],[105,89,205,1],[71,60,139,1],[72,118,255,1],[67,110,238,1],[58,95,205,1],[39,64,139,1],[0,0,255,1],[0,0,238,1],[0,0,205,1],[0,0,139,1],[30,144,255,1],[28,134,238,1],[24,116,205,1],[16,78,139,1],[99,184,255,1],[92,172,238,1],[79,148,205,1],[54,100,139,1],[0,191,255,1],[0,178,238,1],[0,154,205,1],[0,104,139,1],[135,206,255,1],[126,192,238,1],[108,166,205,1],[74,112,139,1],[176,226,255,1],[164,211,238,1],[141,182,205,1],[96,123,139,1],[198,226,255,1],[185,211,238,1],[159,182,205,1],[108,123,139,1],[202,225,255,1],[188,210,238,1],[162,181,205,1],[110,123,139,1],[191,239,255,1],[178,223,238,1],[154,192,205,1],[104,131,139,1],[224,255,255,1],[209,238,238,1],[180,205,205,1],[122,139,139,1],[187,255,255,1],[174,238,238,1],[150,205,205,1],[102,139,139,1],[152,245,255,1],[142,229,238,1],[122,197,205,1],[83,134,139,1],[0,245,255,1],[0,229,238,1],[0,197,205,1],[0,134,139,1],[0,255,255,1],[0,238,238,1],[0,205,205,1],[0,139,139,1],[151,255,255,1],[141,238,238,1],[121,205,205,1],[82,139,139,1],[127,255,212,1],[118,238,198,1],[102,205,170,1],[69,139,116,1],[193,255,193,1],[180,238,180,1],[155,205,155,1],[105,139,105,1],[84,255,159,1],[78,238,148,1],[67,205,128,1],[46,139,87,1],[154,255,154,1],[144,238,144,1],[124,205,124,1],[84,139,84,1],[0,255,127,1],[0,238,118,1],[0,205,102,1],[0,139,69,1],[0,255,0,1],[0,238,0,1],[0,205,0,1],[0,139,0,1],[127,255,0,1],[118,238,0,1],[102,205,0,1],[69,139,0,1],[192,255,62,1],[179,238,58,1],[154,205,50,1],[105,139,34,1],[202,255,112,1],[188,238,104,1],[162,205,90,1],[110,139,61,1],[255,246,143,1],[238,230,133,1],[205,198,115,1],[139,134,78,1],[255,236,139,1],[238,220,130,1],[205,190,112,1],[139,129,76,1],[255,255,224,1],[238,238,209,1],[205,205,180,1],[139,139,122,1],[255,255,0,1],[238,238,0,1],[205,205,0,1],[139,139,0,1],[255,215,0,1],[238,201,0,1],[205,173,0,1],[139,117,0,1],[255,193,37,1],[238,180,34,1],[205,155,29,1],[139,105,20,1],[255,185,15,1],[238,173,14,1],[205,149,12,1],[139,101,8,1],[255,193,193,1],[238,180,180,1],[205,155,155,1],[139,105,105,1],[255,106,106,1],[238,99,99,1],[205,85,85,1],[139,58,58,1],[255,130,71,1],[238,121,66,1],[205,104,57,1],[139,71,38,1],[255,211,155,1],[238,197,145,1],[205,170,125,1],[139,115,85,1],[255,231,186,1],[238,216,174,1],[205,186,150,1],[139,126,102,1],[255,165,79,1],[238,154,73,1],[205,133,63,1],[139,90,43,1],[255,127,36,1],[238,118,33,1],[205,102,29,1],[139,69,19,1],[255,48,48,1],[238,44,44,1],[205,38,38,1],[139,26,26,1],[255,64,64,1],[238,59,59,1],[205,51,51,1],[139,35,35,1],[255,140,105,1],[238,130,98,1],[205,112,84,1],[139,76,57,1],[255,160,122,1],[238,149,114,1],[205,129,98,1],[139,87,66,1],[255,165,0,1],[238,154,0,1],[205,133,0,1],[139,90,0,1],[255,127,0,1],[238,118,0,1],[205,102,0,1],[139,69,0,1],[255,114,86,1],[238,106,80,1],[205,91,69,1],[139,62,47,1],[255,99,71,1],[238,92,66,1],[205,79,57,1],[139,54,38,1],[255,69,0,1],[238,64,0,1],[205,55,0,1],[139,37,0,1],[255,0,0,1],[238,0,0,1],[205,0,0,1],[139,0,0,1],[255,20,147,1],[238,18,137,1],[205,16,118,1],[139,10,80,1],[255,110,180,1],[238,106,167,1],[205,96,144,1],[139,58,98,1],[255,181,197,1],[238,169,184,1],[205,145,158,1],[139,99,108,1],[255,174,185,1],[238,162,173,1],[205,140,149,1],[139,95,101,1],[255,130,171,1],[238,121,159,1],[205,104,137,1],[139,71,93,1],[255,52,179,1],[238,48,167,1],[205,41,144,1],[139,28,98,1],[255,62,150,1],[238,58,140,1],[205,50,120,1],[139,34,82,1],[255,0,255,1],[238,0,238,1],[205,0,205,1],[139,0,139,1],[255,131,250,1],[238,122,233,1],[205,105,201,1],[139,71,137,1],[255,187,255,1],[238,174,238,1],[205,150,205,1],[139,102,139,1],[224,102,255,1],[209,95,238,1],[180,82,205,1],[122,55,139,1],[191,62,255,1],[178,58,238,1],[154,50,205,1],[104,34,139,1],[155,48,255,1],[145,44,238,1],[125,38,205,1],[85,26,139,1],[171,130,255,1],[159,121,238,1],[137,104,205,1],[93,71,139,1],[255,225,255,1],[238,210,238,1],[205,181,205,1],[139,123,139,1],[169,169,169,1],[169,169,169,1],[0,0,139,1],[0,139,139,1],[139,0,139,1],[139,0,0,1],[144,238,144,1]];
  5836.  
  5837. Q.CO['Pastels']=[[226,145,145,1],[153,221,146,1],[147,216,185,1],[148,196,211,1],[148,154,206,1],[179,148,204,1],[204,150,177,1],[204,164,153,1],[223,229,146,1],[255,165,96,1],[107,255,99,1],[101,255,204,1],[101,196,255,1],[101,107,255,1],[173,101,255,1],[255,101,244,1],[255,101,132,1],[255,101,101,1]];
  5838.  
  5839. Q.CO['Reds And Purples']=[[205,92,92,1],[178,34,34,1],[165,42,42,1],[233,150,122,1],[250,128,114,1],[255,160,122,1],[255,127,80,1],[240,128,128,1],[255,99,71,1],[255,69,0,1],[255,0,0,1],[255,105,180,1],[255,20,147,1],[255,192,203,1],[255,182,193,1],[219,112,147,1],[176,48,96,1],[199,21,133,1],[208,32,144,1],[255,0,255,1],[238,130,238,1],[221,160,221,1],[218,112,214,1],[186,85,211,1],[153,50,204,1],[148,0,211,1],[138,43,226,1],[160,32,240,1],[147,112,219,1],[216,191,216,1]];
  5840.  
  5841. Q.CO['Web']=[[255,255,255,1],[255,255,204,1],[255,255,153,1],[255,255,102,1],[255,255,51,1],[255,255,0,1],[255,204,255,1],[255,204,204,1],[255,204,153,1],[255,204,102,1],[255,204,51,1],[255,204,0,1],[255,153,255,1],[255,153,204,1],[255,153,153,1],[255,153,102,1],[255,153,51,1],[255,153,0,1],[255,102,255,1],[255,102,204,1],[255,102,153,1],[255,102,102,1],[255,102,51,1],[255,102,0,1],[255,51,255,1],[255,51,204,1],[255,51,153,1],[255,51,102,1],[255,51,51,1],[255,51,0,1],[255,0,255,1],[255,0,204,1],[255,0,153,1],[255,0,102,1],[255,0,51,1],[255,0,0,1],[204,255,255,1],[204,255,204,1],[204,255,153,1],[204,255,102,1],[204,255,51,1],[204,255,0,1],[204,204,255,1],[204,204,204,1],[204,204,153,1],[204,204,102,1],[204,204,51,1],[204,204,0,1],[204,153,255,1],[204,153,204,1],[204,153,153,1],[204,153,102,1],[204,153,51,1],[204,153,0,1],[204,102,255,1],[204,102,204,1],[204,102,153,1],[204,102,102,1],[204,102,51,1],[204,102,0,1],[204,51,255,1],[204,51,204,1],[204,51,153,1],[204,51,102,1],[204,51,51,1],[204,51,0,1],[204,0,255,1],[204,0,204,1],[204,0,153,1],[204,0,102,1],[204,0,51,1],[204,0,0,1],[153,255,255,1],[153,255,204,1],[153,255,153,1],[153,255,102,1],[153,255,51,1],[153,255,0,1],[153,204,255,1],[153,204,204,1],[153,204,153,1],[153,204,102,1],[153,204,51,1],[153,204,0,1],[153,153,255,1],[153,153,204,1],[153,153,153,1],[153,153,102,1],[153,153,51,1],[153,153,0,1],[153,102,255,1],[153,102,204,1],[153,102,153,1],[153,102,102,1],[153,102,51,1],[153,102,0,1],[153,51,255,1],[153,51,204,1],[153,51,153,1],[153,51,102,1],[153,51,51,1],[153,51,0,1],[153,0,255,1],[153,0,204,1],[153,0,153,1],[153,0,102,1],[153,0,51,1],[153,0,0,1],[102,255,255,1],[102,255,204,1],[102,255,153,1],[102,255,102,1],[102,255,51,1],[102,255,0,1],[102,204,255,1],[102,204,204,1],[102,204,153,1],[102,204,102,1],[102,204,51,1],[102,204,0,1],[102,153,255,1],[102,153,204,1],[102,153,153,1],[102,153,102,1],[102,153,51,1],[102,153,0,1],[102,102,255,1],[102,102,204,1],[102,102,153,1],[102,102,102,1],[102,102,51,1],[102,102,0,1],[102,51,255,1],[102,51,204,1],[102,51,153,1],[102,51,102,1],[102,51,51,1],[102,51,0,1],[102,0,255,1],[102,0,204,1],[102,0,153,1],[102,0,102,1],[102,0,51,1],[102,0,0,1],[51,255,255,1],[51,255,204,1],[51,255,153,1],[51,255,102,1],[51,255,51,1],[51,255,0,1],[51,204,255,1],[51,204,204,1],[51,204,153,1],[51,204,102,1],[51,204,51,1],[51,204,0,1],[51,153,255,1],[51,153,204,1],[51,153,153,1],[51,153,102,1],[51,153,51,1],[51,153,0,1],[51,102,255,1],[51,102,204,1],[51,102,153,1],[51,102,102,1],[51,102,51,1],[51,102,0,1],[51,51,255,1],[51,51,204,1],[51,51,153,1],[51,51,102,1],[51,51,51,1],[51,51,0,1],[51,0,255,1],[51,0,204,1],[51,0,153,1],[51,0,102,1],[51,0,51,1],[51,0,0,1],[0,255,255,1],[0,255,204,1],[0,255,153,1],[0,255,102,1],[0,255,51,1],[0,255,0,1],[0,204,255,1],[0,204,204,1],[0,204,153,1],[0,204,102,1],[0,204,51,1],[0,204,0,1],[0,153,255,1],[0,153,204,1],[0,153,153,1],[0,153,102,1],[0,153,51,1],[0,153,0,1],[0,102,255,1],[0,102,204,1],[0,102,153,1],[0,102,102,1],[0,102,51,1],[0,102,0,1],[0,51,255,1],[0,51,204,1],[0,51,153,1],[0,51,102,1],[0,51,51,1],[0,51,0,1],[0,0,255,1],[0,0,204,1],[0,0,153,1],[0,0,102,1],[0,0,51,1],[0,0,0,1]];
  5842.  
  5843.  
  5844. /* PATTERNS */
  5845.  
  5846. Q.PT={};
  5847.  
  5848. Q.PT['DinPattern']=new Array(38);
  5849.  
  5850. Q.PT['Gaudi']=new Array(31);
  5851.  
  5852. Q.PT['Headlock']=new Array(141);
  5853.  
  5854. Q.PT['Squidfingers']=new Array(158);
  5855.  
  5856.  
  5857. /* CURRENT */
  5858.  
  5859. vars.CO=Q.CO['Oxygen'];
  5860. vars.GD=Q.GD['Web v2.0'];
  5861. vars.PT=Q.PT['Squidfingers'];
  5862. canvas = {
  5863.     'history_n': 25,
  5864.     'history_mk': function () {
  5865.         var z = '';
  5866.         canvas.history_r = {
  5867.             'n': 0,
  5868.             'r': {
  5869.                 0: 0
  5870.             },
  5871.             'data': {
  5872.                 0: [canvas.W, canvas.H]
  5873.             },
  5874.             'a': 0,
  5875.             'z': 0
  5876.         };
  5877.         for (var i = 0; i <= canvas.history_n; i++) {
  5878.             z += '<canvas id="history_' + i + '" width="' + canvas.W + '" height="' + canvas.H + '">' + "<\/canvas>";
  5879.         }
  5880.         $('cHistory').innerHTML = z;
  5881.         $2D('history_0').drawImage($('ctx_box'), 0, 0, canvas.W, canvas.H);
  5882.         var o = gui.Y;
  5883.         $C('MM', 'history')[0].innerHTML = '<div class="z"></div>' + o.kontrol('hi');
  5884.         $S('hiKontrol').display = 'none';
  5885.         o.cur[o.id] = 0;
  5886.         o.hi(1);
  5887.     },
  5888.     'history_set': function (v, s) {
  5889.         if ($('history_0')) {
  5890.             var o = gui.Y,
  5891.             r = canvas.history_r;
  5892.             if (isNaN(v)) { // SAVE
  5893.                 var z = r.z;
  5894.                 r.r[r.n + 1] = (r.n % canvas.history_n) + 1;
  5895.                 r.z = ++r.n;
  5896.                 r.r[r.a = Math.max(0, r.n - canvas.history_n)] = 0;
  5897.                 r.data[r.n] = [canvas.W, canvas.H, vars.type, vars.typeImg, v];
  5898.                 if (r.r[r.n + 1]) {
  5899.                     for (var i = r.n + 1; i <= z; i++) {
  5900.                         r.data[i] = [];
  5901.                     }
  5902.                 }
  5903.                 var a = 'history_' + r.r[r.n],
  5904.                 b = 'ctx_box';
  5905.                 $(a).width = canvas.W;
  5906.                 $(a).height = canvas.H;
  5907.             } else { // UNDO + REDO
  5908.                 var a = 'ctx_box',
  5909.                 b = 'history_' + r.r[r.n];
  5910.                 canvas.W = r.data[r.n][0];
  5911.                 canvas.H = r.data[r.n][1];
  5912.                 $('ctx_box').width = canvas.W;
  5913.                 $('ctx_box').height = canvas.H;
  5914.                 crop.resize();
  5915.             }
  5916.             var c = $2D(a);
  5917.             co.del(c);
  5918.             c.drawImage($(b), 0, 0, canvas.W, canvas.H);
  5919.             if (b == 'ctx_box') {
  5920.                 c.drawImage($('ctx_temp'), 0, 0, canvas.W, canvas.H);
  5921.             }
  5922.             if (!s) {
  5923.                 o.cur[o.id] = r.z - 5;
  5924.             }
  5925.             o.hi(1);
  5926.             gui.Y.kontrol_update('hi');
  5927.         }
  5928.     },
  5929.     'close': function () {
  5930.         $S('canvas').display = 'none';
  5931.         $('history').innerHTML = '';
  5932.     },
  5933.     'load': function (u, w, h) {
  5934.         gui_swatch.id = 'CO';
  5935.         $('ctx_box').width = canvas.W = w;
  5936.         $('ctx_box').height = canvas.H = h;
  5937.         crop.apply({ X: 0, Y: 0 }, { X: w, Y: h });
  5938.         if (u) {
  5939.             jelly.src = u;
  5940.             jelly.onload = function () {
  5941.                 var c = $2D('ctx_box');
  5942.                 co.del(c);
  5943.                 c.drawImage(jelly, 0, 0, canvas.W, canvas.H);
  5944.             }
  5945.         } else {
  5946.             var a = {
  5947.                     X: 0,
  5948.                     Y: 0
  5949.                 },
  5950.                 b = {
  5951.                     X: w,
  5952.                     Y: h
  5953.                 },
  5954.                 c = $2D('ctx_box');
  5955.             c.rect(a.X, a.Y, b.X, b.Y);
  5956.             co.style[vars[vars.id]](a, b, c, 'fill', 1);
  5957.         }
  5958.     },
  5959.     'resize': function (w, h) {
  5960.         $C('TM', 'canvas')[0].style.width = w + 'px';
  5961.         $C('MM', 'canvas')[0].style.width = w + 'px';
  5962.         $C('BM', 'canvas')[0].style.width = w + 'px';
  5963.         $C('ML', 'canvas')[0].style.height = h + 'px';
  5964.         $C('MM', 'canvas')[0].style.height = h + 'px';
  5965.         $C('MR', 'canvas')[0].style.height = h + 'px';
  5966.         $S('cBound').width = w + 'px';
  5967.         $S('cBound').height = h + 'px';
  5968.     },
  5969.     'mode_sw': function (o) {
  5970.         var r = {
  5971.                 'paint': 'source-over',
  5972.                 'light': 'lighter'
  5973.             },
  5974.             d = $C('cur', $(o).parentNode);
  5975.         if (d[0]) d[0].className = '';
  5976.         $(o).className = 'cur';
  5977.         vars.mode = $(o).innerHTML;
  5978.         vars.cache(1);
  5979.         $2D('ctx_temp').globalCompositeOperation = canvas.mode = r[$(o).innerHTML];
  5980.     },
  5981.     'mode': 'source-over'
  5982.  
  5983. };
  5984. </script>
  5985. </head>
  5986. <body onmousedown="if(false && preventDefault) event.preventDefault(); preventDefault = true;">
  5987.  
  5988. <div id="top">
  5989.  <div class="center">
  5990.   <div class="west" style="font-variant: small-caps">
  5991.    <div style="left: 12px; top: 10px" onmousedown="canvas.mode_sw('paint');" id="paint" class="cur">paint</div>
  5992.    <div style="left: 24px; top: 10px" onmousedown="canvas.mode_sw('light');" id="light">light</div>
  5993.   </div>
  5994.   <div class="east">
  5995.    <div style="background: none; border-left: none; border-right:1px solid #161616; height: 22px; padding: 0; cursor: default"></div>
  5996.    <div id="isolid" onmousedown="win.tab(this,'solid','solid'); if(this.className != 'cur') gui_swatch.toType('CO');">color</div>
  5997.    <div id="igradient" onmousedown="win.tab(this,'gradient','gradient'); if(this.className != 'cur') gui_swatch.toType('GD');">gradient</div>
  5998.    <div id="ipattern" onmousedown="win.tab(this,'pattern','pattern'); if(this.className != 'cur') gui_swatch.toType('PT');">pattern</div>
  5999.    <div id="iswatch" onmousedown="win.tab(this,'swatch',vars[vars.id])">swatch</div>
  6000.    <div id="ihistory" onmousedown="win.tab(this,'history',vars[vars.id])">history</div>
  6001.    <div id="ioptions" onmousedown="win.tab(this,'options',vars[vars.id])">options</div>
  6002.    <div onmousedown="canvas.open();" class="cur open" style="display:none"><span></span></div>
  6003.    <a href="#" onclick="window.saveDrawing(); return false;" target="_blank"><div class="cur save"><span></span></div></a>
  6004.    <div style="background: none; border-left: none; border: none; border-left:1px solid #3e3e3e; height: 22px; padding: 0; cursor: default"></div>
  6005.   </div>
  6006.  </div>
  6007. </div>
  6008.  
  6009. <div id="tools" class="gui">
  6010.  <div class="bounds">
  6011.   <div class="TL"></div>
  6012.   <div class="TM"><div class="TMM">tools</div></div>
  6013.   <div class="TR"></div><br />
  6014.   <div class="ML"></div>
  6015.   <div class="MM" onmousedown="noMove();">
  6016.    <div class="z">
  6017.     <div class="tools">
  6018.      <div onclick="gui_tools.imageCurrent('Marquee_'+vars.marquee)"><img src="http://mudcu.be/sketchpad/media/gui/sw_add.png" class="plus" alt="Marquee" /><img src="" class="Marquee_lasso Marquee_ellipses Marquee_polygon Marquee_star Marquee_burst Marquee_gear" alt="Marquee" /></div>
  6019.      <div onclick="gui_tools.imageCurrent('Crop')"><img src="" class="Crop" alt="Crop" /></div><br />
  6020.      <div class="hr"></div>
  6021.      <div onclick="gui_tools.imageCurrent('Text')"><img src="" class="Text" alt="Text" /></div>
  6022.      <div onclick="gui_tools.imageCurrent('Shape_'+vars.shape)"><img src="http://mudcu.be/sketchpad/media/gui/sw_add.png" class="plus" alt="Shape" /><img src="" class="Shape_ellipses Shape_polygon Shape_star Shape_burst Shape_gear" alt="Shape" /></div>
  6023.      <div onclick="gui_tools.imageCurrent('Spirograph')"><img src="" class="Spirograph" alt="Spirograph" /></div>
  6024.      <div onclick="gui_tools.imageCurrent(vars.draw)"><img src="http://mudcu.be/sketchpad/media/gui/sw_add.png" class="plus" alt="Draw" /><img src="" class="Brush Calligraphy Pencil" alt="Draw" /></div>
  6025.      <div onclick="gui_tools.imageCurrent('Fill')"><img src="" class="Fill" alt="Fill" /></div>
  6026.      <div onclick="gui_tools.imageCurrent('Stamp')"><img src="" class="Stamp" alt="Stamp" /></div>
  6027.      <div onclick="gui_tools.imageCurrent('Eraser')"><img src="" class="Eraser" alt="Eraser" /></div>
  6028.      <div onclick="gui_tools.imageCurrent('Picker')"><img src="" class="Picker" alt="Picker" /></div>
  6029.      <br />
  6030.      <div class="hr"></div>
  6031.     </div>
  6032.     <div class="ss">
  6033.      <div id="swap">F</div>
  6034.      <div class="fill">
  6035.       <canvas onmousedown="gui_palette.click('fill')" id="fill" title="Fill"></canvas>
  6036.      </div>
  6037.      <div class="stroke">
  6038.       <canvas onmousedown="gui_palette.click('stroke')" id="stroke" title="Stroke"></canvas>
  6039.       <div onmousedown="gui_palette.click('stroke')"><div></div></div>
  6040.       <img src="http://mudcu.be/sketchpad/media/gui/sw_switch.png"  style="display: block" onmousedown="gui_palette.current(); return false" alt="Switch Stroke with Fill" />
  6041.      </div>
  6042.     </div>
  6043.    </div>
  6044.   </div>
  6045.   <div class="MR"></div><br />
  6046.   <div class="BL"></div>
  6047.   <div class="BM"></div>
  6048.   <div class="BR"></div>
  6049.  </div>
  6050. </div>
  6051.  
  6052. <div id="options" class="gui">
  6053.  <div class="bounds">
  6054.   <div class="TL"></div>
  6055.   <div class="TM">
  6056.    <span class="TML"></span>
  6057.    <div class="TRx"><img onclick="win.close('options',1)" onmousedown="return(noMove())" src="media/gui/win_close.png" title="Close" /></div>
  6058.   </div>
  6059.   <div class="TR"></div><br />
  6060.   <div class="ML"></div>
  6061.   <div class="MM" onmousedown="noMove()"></div>
  6062.   <div class="MR"></div><br />
  6063.   <div class="BL"></div>
  6064.   <div class="BM"></div>
  6065.   <div class="BR"></div>
  6066.  </div>
  6067. </div>
  6068.  
  6069. <div id="history" class="gui">
  6070.  <div class="bounds">
  6071.   <div class="TL"></div>
  6072.   <div class="TM">
  6073.    <span class="TML">history</span>
  6074.    <div class="TRx"><img onclick="win.close('history',1)" onmousedown="return(noMove())" src="http://mudcu.be/sketchpad/media/gui/win_close.png" title="Close" /></div>
  6075.   </div>
  6076.   <div class="TR"></div><br />
  6077.   <div class="ML"></div>
  6078.   <div class="MM" onmousedown="noMove()"></div>
  6079.   <div class="MR"></div><br />
  6080.   <div class="BL"></div>
  6081.   <div class="BM"></div>
  6082.   <div class="BR"></div>
  6083.  </div>
  6084. </div>
  6085.  
  6086. <div id="swatch" class="gui">
  6087.  <div class="bounds">
  6088.   <div class="TL"></div>
  6089.   <div class="TM">
  6090.    <span class="TML">swatch</span>
  6091.    <div class="TRx"><img onclick="win.close('swatch',1)" onmousedown="return(noMove())" src="http://mudcu.be/sketchpad/media/gui/win_close.png" title="Close" /></div>
  6092.   </div>
  6093.   <div class="TR"></div><br />
  6094.   <div class="ML"></div>
  6095.   <div class="MM" onmousedown="noMove()"></div>
  6096.   <div class="MR"></div><br />
  6097.   <div class="BL"></div>
  6098.   <div class="BM"></div>
  6099.   <div class="BR"></div>
  6100.  </div>
  6101. </div>
  6102.  
  6103. <div id="pattern" class="gui">
  6104.  <div class="bounds">
  6105.   <div class="TL"></div>
  6106.   <div class="TM">
  6107.    <span class="TML">pattern</span>
  6108.    <div class="TRx"><img onclick="win.close('pattern',1)" onmousedown="return(noMove())" src="http://mudcu.be/sketchpad/media/gui/win_close.png" title="Close" /></div>
  6109.   </div>
  6110.   <div class="TR"></div><br />
  6111.   <div class="ML"></div>
  6112.   <div class="MM" onmousedown="noMove()"><div class="z"></div></div>
  6113.   <div class="MR"></div><br />
  6114.   <div class="BL"></div>
  6115.   <div class="BM"></div>
  6116.   <div class="BR"></div>
  6117.  </div>
  6118. </div>
  6119.  
  6120. <div id="gradient" class="gui">
  6121.  <div class="bounds">
  6122.   <div class="TL"></div>
  6123.   <div class="TM">
  6124.    <span class="TML">gradient</span>
  6125.    <div class="TRx"><img onclick="win.close('gradient',1)" onmousedown="return(noMove())" src="media/gui/win_close.png" title="Close" /></div>
  6126.   </div>
  6127.   <div class="TR"></div><br />
  6128.   <div class="ML"></div>
  6129.   <div class="MM" onmousedown="noMove()"></div>
  6130.   <div class="MR"></div><br />
  6131.   <div class="BL"></div>
  6132.   <div class="BM"></div>
  6133.   <div class="BR"></div>
  6134.  </div>
  6135. </div>
  6136.  
  6137. <div id="solid" class="gui">
  6138.  <div class="bounds">
  6139.   <div class="TL"></div>
  6140.   <div class="TM">
  6141.    <span id="HEX" class="TML" title="HEX" onmousedown="preventDefault = false;" style="cursor: text; text-transform:uppercase">FFFFFF</span>
  6142.    <div class="TRx"><img onclick="win.close('solid',1)" onmousedown="return(noMove())" src="http://mudcu.be/sketchpad/media/gui/win_close.png" title="Close" /></div>
  6143.   </div>
  6144.   <div class="TR"></div><br />
  6145.   <div class="ML"></div>
  6146.   <div class="MM" onmousedown="noMove()"></div>
  6147.   <div class="MR"></div><br />
  6148.   <div class="BL"></div>
  6149.   <div class="BM"></div>
  6150.   <div class="BR"></div>
  6151.  </div>
  6152. </div>
  6153.  
  6154. <div id="canvas" onmousedown="core.fu('canvas',event,{fu:core.win,Y1:19})" class="gui" style="width: 732px; height: 615px;">
  6155.  <div class="TL"></div>
  6156.  <div class="TM" ondblclick="win_size.tog(vars.winMax?'min':'max')">
  6157.   <div class="center">
  6158.    <span id="cTitle">DRAWING.PNG</span>
  6159.   </div>
  6160.   <div class="east" id="cZoom"></div>
  6161.  </div>
  6162.  <div class="TR"></div><br />
  6163.  <div class="ML"></div>
  6164.  <div class="MM">
  6165.   <div class="z">
  6166.    <div id="cBound" onmousedown="return(noMove())">
  6167.     <canvas id="ctx_box" style="z-index: 1"></canvas>
  6168.     <canvas id="ctx_temp" style="z-index: 2"></canvas>
  6169.     <canvas id="ctx_active" style="z-index: 5"></canvas>
  6170.     <canvas id="ctx_marquee" style="z-index: 6"></canvas>
  6171.     <canvas id="ctx_mouse" style="z-index: 7"></canvas>
  6172.    </div>
  6173.    <canvas id="ctx_brush" width="200" height="200"></canvas>
  6174.    <canvas id="ctx_stamp" width="200" height="200"></canvas>
  6175.    <canvas id="ctx_eraser" width="200" height="200"></canvas>
  6176.    <canvas id="ctx_picker" height="1" width="1"></canvas>
  6177.    <div id="cHistory"></div>
  6178.   </div>
  6179.  </div>
  6180.  <div class="MR"></div><br />
  6181.  <div class="BL"></div>
  6182.  <div class="BM"></div>
  6183.  <div class="BR" onmousedown="vars.winMax='min'; win_size.core(event)"></div>
  6184. </div>
  6185.  
  6186. <div style="display: none" id="canvas_open">
  6187.  <div style="padding: 15px 0;">
  6188.   My Computer&hellip;<br><input type="file" id="local" size="17"><br><br>The Internet&hellip;<br><input type="datafile_url" id="server" size="27"><br><br><input onclick="canvas.open_event()" type="submit" value="open">
  6189.   <div id="canvas_open_error" style="padding: 4px 0 0 0; color: #ef3333"></div>
  6190.  </div>
  6191. </div>
  6192. <div class="ads">
  6193.   <a href="https://sketch.io/sketchpad" target="_blank">Sketchpad 3.4 is out!</a>
  6194. </div>
  6195. <div id="TEST" style="color: #fff; position: absolute; top: 40px; z-index: 100000"></div>
  6196.  
  6197. <script type="text/javascript">
  6198.  
  6199. var preventDefault = true;
  6200.  
  6201. var init = {
  6202.     'canvas': function (w, h, u) {
  6203.         gui_swatch.id = 'CO';
  6204.         function z(n) {
  6205.             return (Math.floor(Math.random() * n));
  6206.         }
  6207.         $('ctx_box').width = canvas.W = w;
  6208.         $('ctx_box').height = canvas.H = h;
  6209.         crop.apply({
  6210.             X: 0,
  6211.             Y: 0
  6212.         },
  6213.         {
  6214.             X: w,
  6215.             Y: h
  6216.         });
  6217.         if (isNaN(vars.winW) || isNaN(vars.winH)) {
  6218.             vars.winW = parseInt(canvas.W);
  6219.             vars.winH = parseInt(canvas.H);
  6220.         }
  6221.         if (u) {
  6222.             var img = new Image();
  6223.             img.src = u;
  6224.             img.onload = function () {
  6225.                 var c = $2D('ctx_box');
  6226.                 co.del(c);
  6227.                 c.drawImage(img, 0, 0, canvas.W, canvas.H);
  6228.             }
  6229.         } else {
  6230.             var a = {
  6231.                 X: 0,
  6232.                 Y: 0
  6233.             },
  6234.             b = {
  6235.                 X: w,
  6236.                 Y: h
  6237.             },
  6238.             c = $2D('ctx_box');
  6239.             c.rect(0, 0, w, h);
  6240.             co.gradient(a, b, c, vars.GD[z(vars.GD.length)], 'fill', 1);
  6241.         }
  6242.     },
  6243.     'content': function () {
  6244.         //Windows
  6245.         if (vars.winMax == 1) {
  6246.             win_size.max();
  6247.         } else if (!isNaN(vars.winW)) {
  6248.             win_size.fu({
  6249.                 W: zero(vars.winW),
  6250.                 H: zero(vars.winH)
  6251.             },
  6252.             win_size.construct({}));
  6253.         } else {
  6254.             canvas.resize(700, 575);
  6255.         }
  6256.         init.canvas(700, 575);
  6257.         gui.options();
  6258.         gui_tools.imageMap();
  6259.         //Interface
  6260.         gui_palette.update('stroke');
  6261.         gui_palette.update('fill');
  6262.         gui_palette.zindex(vars.id);
  6263.         crop.ratio_mk();
  6264.         gui_color.mk();
  6265.         gui_gradient.mk();
  6266.         gui_pattern.mk();
  6267.         gui_swatch.mk();
  6268.         win.feed();
  6269.         gui_tools.imageCurrent(vars.tool);
  6270.         canvas.mode_sw(vars.mode = vars.mode ? vars.mode : 'paint');
  6271.         canvas.history_mk();
  6272.         init.events();
  6273.     },
  6274.     'events': function () {
  6275.         //Canvas
  6276.         var o = $('cBound');
  6277.         o.oncontextmenu = function (e) {
  6278.             if ({
  6279.                 'zoom': 1,
  6280.                 'path': 1,
  6281.                 'shape': 1,
  6282.                 'marquee': 1
  6283.             } [vars.type]) return false;
  6284.         };
  6285.         o.ondblclick = function (e) {
  6286.             if (vars.type == 'text') {
  6287.                 noMove()
  6288. //                co.core(e, text.core);
  6289.             }
  6290.         };
  6291.         o.onmousemove = function (e) {
  6292.             if (stop) {
  6293.                 if ({
  6294.                     'marquee': 1,
  6295.                     'text': 1,
  6296.                     'crop': 1
  6297.                 } [vars.type]) {
  6298.                     mouse.cursor(e, this);
  6299.                 }
  6300.                 if (vars.type == 'picker') {
  6301.                     var a = XY(e);
  6302.                     a.X -= abPos(this).X;
  6303.                     a.Y -= abPos(this).Y;
  6304.                     a.X = Math.max(0, Math.min(canvas.W - 1, a.X));
  6305.                     a.Y = Math.max(0, Math.min(canvas.H - 1, a.Y));
  6306.                     picker.core(a, '', 'move');
  6307.                 }
  6308.             }
  6309.         };
  6310.         o.onmousedown = function (e) {
  6311.             if (vars.type == 'crop') {
  6312.                 co.core(e, crop.core);
  6313.             } else if (vars.type == 'fill') {
  6314.                 co.core(e, draw.fill);
  6315.             } else if (vars.type == 'marquee') {
  6316.                 co.core(e, marquee.core);
  6317.             } else if (vars.type == 'picker') {
  6318.                 var a = XY(e); 
  6319.                 a.X -= abPos(this).X;
  6320.                 a.Y -= abPos(this).Y;
  6321.                 a.X = Math.max(0, Math.min(canvas.W - 1, a.X));
  6322.                 a.Y = Math.max(0, Math.min(canvas.H - 1, a.Y));
  6323.                 picker.core(a, a, 'down', e);
  6324.             } else if (vars.type == 'shape') {
  6325.                 co.core(e, draw.shape);
  6326.             } else if (vars.type == 'text') {
  6327.                 co.core(e, draw.text);
  6328.             } else if ({
  6329.                 'calligraphy': 1,
  6330.                 'stamp': 1
  6331.             } [vars.type]) {
  6332.                 if (stamp.loaded) {
  6333.                     co.core(e, draw[vars.type]);
  6334.                 } else {
  6335.                     noMove();
  6336.                 }
  6337.             } else if(vars.type == 'spirograph') {
  6338.                 co.core(e, draw.spirograph);
  6339.             } else if ({
  6340.                 'brush': 1,
  6341.                 'pencil': 1,
  6342.                 'eraser': 1
  6343.             } [vars.type]) {
  6344.                 co.core(e, draw[vars.type]);
  6345.             } else {
  6346.                 return noMove();
  6347.             }
  6348.             return false;
  6349.         };
  6350.         o.onmouseout = function (e) {
  6351.             if (stop) {
  6352.                 if (vars.type == 'picker') {
  6353.                     var a = XY(e); 
  6354.                     a.X -= abPos(this).X;
  6355.                     a.Y -= abPos(this).Y;
  6356.                     a.X = Math.max(0, Math.min(canvas.W - 1, a.X));
  6357.                     a.Y = Math.max(0, Math.min(canvas.H - 1, a.Y));
  6358.                     picker.core(a);
  6359.                 }
  6360.             }
  6361.         };
  6362.         //Mouse Wheel
  6363.         var o = {
  6364.             'stamp': $C('MM', 'options'),
  6365.             'hi': $C('MM', 'history'),
  6366.             'CO': $C('CO', 'swatch'),
  6367.             'GD': $C('GD', 'swatch'),
  6368.             'PT': $C('PT', 'swatch')
  6369.         };
  6370.         function addWheel(id) {
  6371.             Event.add(o[id][0], {
  6372.                 el: 'DOMMouseScroll',
  6373.                 e: 'onmousewheel'
  6374.             },
  6375.             function (event) {
  6376.                 gui.Y.id = id;
  6377.                 gui.Y.wheel(event);
  6378.                 event.preventDefault();
  6379.             });
  6380.         };
  6381.         for (var i in o) addWheel(i);
  6382.         //Window CoreXY
  6383.         var o = $C('gui', document.body);
  6384.         for (var i = 0; i < o.length; i++) {
  6385.            if (o[i].onmousedown) continue;
  6386.            Event.add(o[i], {
  6387.                el: 'mousedown',
  6388.                e: 'onmousedown'
  6389.            },
  6390.            function (event) {
  6391.                core.fu(this.id, event, {
  6392.                    fu: core.win,
  6393.                    Y1: 19,
  6394.                    z: true
  6395.                });
  6396.            });
  6397.        }
  6398.    },
  6399.    'images': function () {
  6400.        var dir = 'media/gui/';
  6401.        op_8x8 = new Image();
  6402.        op_8x8.src = dir + 'op_8x8.gif';
  6403.        path = {
  6404.            point: new Image(),
  6405.            node_select: new Image()
  6406.         }
  6407.         path.point.src = dir + 'point.png';
  6408.         path.node_select.src = dir + 'node_select.png';
  6409.    },
  6410.    'swatch': function () {
  6411.        var rand = N.rand;
  6412.        init.images();
  6413.        if(typeof ScreenMetrics == 'function') {
  6414.             $.metrics = ScreenMetrics();
  6415.        }
  6416.        function PT(v, n) {
  6417.            var n = vars.PT.length;
  6418.         var random;
  6419.         if(vars['PT*'] == 'Squidfingers')
  6420.          random = Math.random() > .5 ? '82' : '105';
  6421.         else random = rand(n);
  6422.             src = gui_pattern.dir + vars['PT*'] + '/' + (gui_swatch.n[v + 'PT'] = random) + '-live.jpg';
  6423.             gui_pattern.o[v].src = src;
  6424.             vars[v + 'PT'].src = src;
  6425.             gui_swatch.n[v + 'PT'] = n - gui_swatch.n[v + 'PT'];
  6426.         }
  6427.         function CO(v) {
  6428.             var n = vars[v].length,
  6429.             a = rand(n),
  6430.             z = rand(n);
  6431.             vars['fill' + v] = vars[v][a];
  6432.             gui_swatch.n['fill' + v] = a + 1;
  6433.             vars['stroke' + v] = vars[v][z];
  6434.             gui_swatch.n['stroke' + v] = z + 1;
  6435.         }
  6436.         vars.CO = Q.CO[vars['CO*']];
  6437.         vars.GD = Q.GD[vars['GD*']];
  6438.         vars.PT = Q.PT[vars['PT*']];
  6439.         CO('CO');
  6440.         CO('GD');
  6441.         PT('fill');
  6442.         PT('stroke');
  6443.     // setTimeout( init.content, 1000);
  6444.        
  6445.         gui_pattern.o.fill.onload = function () {
  6446.             if (gui_pattern.o.stroke.loaded) init.content();
  6447.             gui_pattern.o.fill.loaded = 1;
  6448.         };
  6449.         gui_pattern.o.stroke.onload = function () {
  6450.             if (gui_pattern.o.fill.loaded) init.content();
  6451.             gui_pattern.o.stroke.loaded = 1;
  6452.         };
  6453.     }
  6454. };
  6455.  
  6456. var ants = [ ];
  6457.     var ants_n = 0;
  6458.  
  6459. window.onresize = win.feed;
  6460. window.currentBlob = null;
  6461. window.currentPort = null;
  6462. window.saveDrawing = function() {
  6463.     window.location.href=$('ctx_box').toDataURL();
  6464. };
  6465. window.onload = function () {
  6466.     if (document.location.hash == '#snapshot') {
  6467.         document.body.style.background = 'transparent';
  6468.         // FIXME: Waiting on toBlob for Canvas
  6469.         window.saveDrawing = function (e) {
  6470.             if (!window.currentPort) {
  6471.                 window.href = $('ctx_box').toDataURL();
  6472.             }
  6473.             var n = $('ctx_box').toDataURL();
  6474.             window.currentPort.postMessage("send", '*');
  6475.             window.currentPort.postMessage(n, '*');
  6476.             return false;
  6477.         };
  6478.         window.onmessage = function (event) {
  6479.             if (event.origin.indexOf('chrome-extension:') == -1) if (event.origin != 'http://mugtug.com') if (event.origin != 'https://mugtugdarkroom.appspot.com') if (event.origin != 'https://mugtugsketchpad.appspot.com') return;
  6480.             if (event.source != window.self) event.source.postMessage("recv", '*');
  6481.             var data = event.data;
  6482.             if (typeof (data) == 'object' && data.type) {
  6483.                 if (window.currentBlob) webkitURL.revokeObjectURL(window.currentBlob);
  6484.                 window.currentBlob = webkitURL.createObjectURL(data);
  6485.                 data = window.currentBlob;
  6486.                 window.currentPort = event.source;
  6487.             }
  6488.             if (data.indexOf(':') > -1) {
  6489.                 var a = document.createElement('img');
  6490.                 a.onload = function () {
  6491.                     var width = a.naturalWidth;
  6492.                     var height = a.naturalHeight;
  6493.                     win_size.fu({
  6494.                         W: width,
  6495.                         H: height
  6496.                     }, win_size.construct({}));
  6497.                     canvas.resize(width, height);
  6498.                     init.canvas(width, height, data);
  6499.                 }
  6500.                 a.src = data;
  6501.             }
  6502.         }
  6503.         if (window.parent && window.parent != window.self) {
  6504.             // FIXME: Don't ack until load, otherwise we'll overwrite the image.
  6505.             setTimeout(function () {
  6506.                 if (window.parent.postMessage) window.parent.postMessage('ack', '*');
  6507.             }, 300);
  6508.         }
  6509.     }
  6510.     setTimeout(function () {
  6511.         dtx2D = document.createElement("canvas");
  6512.         ctx2D = dtx2D.getContext('2d');
  6513.     }, 100);
  6514.     setTimeout(init.swatch, 250);
  6515.     setTimeout(function () {
  6516.         data2pattern(ants, ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAMklEQVQYlYXOtw0AMAzEQO6/NN04QAlW+cdCAALmOzsftGjAHGRUX9DhDSbcNmMJuocXA4afYTYwTaEAAAAASUVORK5CYII=", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAMklEQVQYlYXPsQ0AMAjEQO+/tFOkIALxQaI6FwDgu334YAUL3iCgQ/tNJFQr2L4hoeoBA4afYdiStBMAAAAASUVORK5CYII=", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAMklEQVQYlWP4DwUMDAwoGC6OTxIqh1sSQwEWSYQCHJIQBXgk/2PIoruJAZ/k/////wMAA4afYVpnmEkAAAAASUVORK5CYII=", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALUlEQVQYlWP4jwYYGBhQMT7J////IxRgk4QrwCUJlcMtiaEAh4PxSkIU4PMqAAOGn2Gql3FAAAAAAElFTkSuQmCC"]);
  6517.     }, 200);
  6518. };
  6519.  
  6520. ///------  PARTS OF LIBRARIES
  6521.  
  6522. Color = { };
  6523. Color.HEX_STRING = function(o) {
  6524.  
  6525.     var z = o.toString(16), n = z.length;
  6526.  
  6527.     while(n < 6) { z = '0' + z; n++; }
  6528.  
  6529.     return z;
  6530.  
  6531. };
  6532.  
  6533. Color.RGB_HSV = function(o) { //- RGB from 0 to 255
  6534.  
  6535.     var _R = o.R / 255, _G = o.G / 255, _B = o.B / 255, H, S, V;
  6536.    
  6537.     var min = Math.min(_R, _G, _B), max = Math.max(_R, _G, _B), D = max - min;
  6538.    
  6539.     V = max;
  6540.    
  6541.     if(D == 0) { H = 0; S = 0; } // No chroma
  6542.  
  6543.     else { // Chromatic data
  6544.  
  6545.     S = D / max;
  6546.  
  6547.         var DR = ( ((max - _R) / 6) + (D / 2) ) / D;
  6548.         var DG = ( ((max - _G) / 6) + (D / 2) ) / D;
  6549.         var DB = ( ((max - _B) / 6) + (D / 2) ) / D;
  6550.  
  6551.         if(_R == max) H = DB - DG;
  6552.         else if(_G == max) H = (1 / 3) + DR - DB;
  6553.         else if(_B == max) H = (2 / 3) + DG - DR;
  6554.  
  6555.         if(H < 0) H += 1;
  6556.         if(H > 1) H -= 1;
  6557.  
  6558.     }
  6559.    
  6560.     return { H: H * 360, S: S * 100, V: V * 100 };
  6561.  
  6562. };
  6563.  
  6564. Color.HSV_RGB = function(o) {
  6565.  
  6566.     var H = o.H / 360, S = o.S / 100, V = o.V / 100, R, G, B;
  6567.    
  6568.     if(S == 0) { R = G = B = Math.round(V * 255); }
  6569.  
  6570.     else { if(H >= 1) H = 0;
  6571.  
  6572.         H = 6 * H;
  6573.         D = H - Math.floor(H);
  6574.         A = Math.round(255 * V * (1 - S));
  6575.         B = Math.round(255 * V * (1 - (S * D)));
  6576.         C = Math.round(255 * V * (1 - (S * (1 - D))));
  6577.         V = Math.round(255 * V);
  6578.  
  6579.         switch(Math.floor(H)) {
  6580.  
  6581.             case 0: R = V; G = C; B = A; break;
  6582.             case 1: R = B; G = V; B = A; break;
  6583.             case 2: R = A; G = V; B = C; break;
  6584.             case 3: R = A; G = B; B = V; break;
  6585.             case 4: R = C; G = A; B = V; break;
  6586.             case 5: R = V; G = A; B = B; break;
  6587.  
  6588.         }
  6589.     }
  6590.  
  6591.     return { R: R, G: G, B: B };
  6592.  
  6593. };
  6594.  
  6595. </script>
  6596. <script type="text/javascript">
  6597. var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  6598. document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
  6599.  
  6600. </script>
  6601. <script type="text/javascript">
  6602. try {
  6603. var pageTracker = _gat._getTracker("UA-400768-12");
  6604. pageTracker._trackPageview();
  6605. } catch(err) {}
  6606. </script>
  6607. </body>
  6608. </html>
Add Comment
Please, Sign In to add comment