[
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>LayerStyles</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t</buildSpec>\n\t<natures>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "README.markdown",
    "content": "Layer Styles\n============\n\nA HTML5 app for creating CSS3 in a intuitive way.\n\nHighlights\n----------\n\n- Colorpicker can pick any color of the element your working on\n- Drag and Drop images onto the page to use them as a background or to pick their colors\n- Color Swatches, Gradients and Styles are locally stored"
  },
  {
    "path": "builder.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Layer Styles</title>\n    <link rel=\"icon\" type=\"image/png\" href=\"favicon.png\" />\n    <script type=\"text/javascript\" src=\"js/modernizr-1.7.min.js\"></script>\n    <link rel=\"stylesheet\" href=\"css/style.css\" type=\"text/css\" />\n</head>\n<body>\n    <div id=\"main\" class=\"box vertical flex\">\n        <span id=\"codeBoxToggle\">CSS Code</span>\n        <div id=\"workspace\" class=\"box vertical flex\">\n            <div id=\"overlay\"></div>\n            <canvas id=\"innerShadow_universe\"></canvas>\n            <canvas id=\"parallel_universe\"></canvas>\n            <div id=\"background_layer\" class=\"flex\"></div>\n            <div id=\"layer\"><div id=\"resize\" class=\"resize\"></div></div>\n        </div> <!-- /workspace -->\n        <div id=\"codeBox\" class=\"paper\">\n            <div class=\"dragger y\"><div class=\"dragBox\"></div></div>\n            <div class=\"body\">\n                <div class=\"scroll paper\">\n                    <div id=\"copyCode\">copy</div>\n                    <div id=\"colorSwitch\" class=\"toggle\">\n                        <div class=\"slidePanel\">\n                            <span class=\"left\">rgb</span><span class=\"button\"></span><span class=\"right\">hex</span>\n                        </div>\n                    </div>\n                    <code></code>\n                </div>\n            </div>\n        </div> <!-- /codeBox -->\n    </div> <!-- /main -->\n    <div id=\"layerstyle\">\n\t\t<div id=\"headerBg\"></div>\n\t\t<div id=\"dialog\" class=\"window\">\n\t\t\t<div class=\"head moveable\">\n\t\t\t\t<h2>Layer Style</h2>\n\t\t\t</div>\n\t\t\t<div class=\"body\">\n\t       \t\t<div class=\"main\">\n\t                <div id=\"nav\">\n\t                    <ul>\n\t                        <li>Styles</li>\n\t                        <li class=\"nav-dropShadow active\"><input type=\"checkbox\" checked=\"checked\">Drop Shadow</li>\n\t                        <li class=\"nav-innerShadow\"><input type=\"checkbox\">Inner Shadow</li>\n\t                        <li class=\"nav-background\"><input type=\"checkbox\" checked=\"checked\">Background</li>\n\t                        <li class=\"nav-border\"><input type=\"checkbox\" checked=\"checked\">Border</li>\n\t                        <li class=\"nav-borderRadius\"><input type=\"checkbox\">Border Radius</li>\n\t                    </ul>\n\t                </div>\n\t                <div class=\"styles\">\n\t                    <div id=\"holder\" class=\"holder\">\n\t                        <div>\n\t                            <h3>Styles</h3>\n\t\t\t\t\t\t\t\t<div id=\"stylePresets\" class=\"border_box\">\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t</div>\n\t                        </div>\n\t                        <div id=\"dropShadow\">\n\t                            <h3>Drop Shadow</h3>\n\t                            <label>Color:</label>\n\t                            <div>\n\t                                <div class=\"color_field\"></div>\n\t                            </div>\n\t                            <label for=\"ds-opacity\">Opacity:</label>\n\t                            <div>\n\t                                <div class=\"slider\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"opacity\" id=\"ds-opacity\" type=\"text\" data-min=\"0\" data-max=\"100\" data-restrict=\"digits\" value=\"75\">\n\t                                %\n\t                            </div>\n\t                            <label class=\"angle_holder\" for=\"ds-angle\">Angle:</label>\n\t                            <div>\n\t                                <div class=\"pot\"><div class=\"pointer\"><div class=\"dot\"></div><div class=\"line\"></div></div></div>\n\t                                <div class=\"angle_holder\">\n\t                                    <input class=\"angle\" id=\"ds-angle\" type=\"text\" data-min=\"0\" data-max=\"360\" data-restrict=\"digits\" value=\"90\">\n\t                                    &deg;\n\t                                    <input type=\"checkbox\" class=\"globalLight\" id=\"ds-globalLight\"><label for=\"ds-globalLight\">Use Global Light</label>\n\t                                </div>\n\t                            </div>\n\t                            <label for=\"ds-distance\">Distance:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"distance\" id=\"ds-distance\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"1\">\n\t                                px\n\t                            </div>\n\t                            <label for=\"ds-blur\">Blur:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"blur\" id=\"ds-blur\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"5\">\n\t                                px\n\t                            </div>\n\t                            <label for=\"ds-size\">Size:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"size\" id=\"ds-size\" type=\"text\" data-min=\"0\" data-max=\"255\" value=\"0\">\n\t                                px\n\t                            </div>\n\t                            <div class=\"clear\"></div>\n\t                        </div>\n\t\t\t\t\t\t\t<div id=\"innerShadow\">\n\t                            <h3>Inner Shadow</h3>\n\t                            <label>Color:</label>\n\t                            <div>\n\t                                <div class=\"color_field\"></div>\n\t                            </div>\n\t                            <label for=\"is-opacity\">Opacity:</label>\n\t                            <div>\n\t                                <div class=\"slider\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"opacity\" id=\"is-opacity\" type=\"text\" data-min=\"0\" data-max=\"100\" data-restrict=\"digits\" value=\"90\">\n\t                                %\n\t                            </div>\n\t                            <label class=\"angle_holder\" for=\"is-angle\">Angle:</label>\n\t                            <div>\n\t                                <div class=\"pot\"><div class=\"pointer\"><div class=\"dot\"></div><div class=\"line\"></div></div></div>\n\t                                <div class=\"angle_holder\">\n\t                                    <input class=\"angle\" id=\"is-angle\" type=\"text\" data-min=\"0\" data-max=\"360\" data-restrict=\"digits\" value=\"90\">\n\t                                    &deg;\n\t                                    <input type=\"checkbox\" class=\"globalLight\" id=\"is-globalLight\"><label for=\"is-globalLight\">Use Global Light</label>\n\t                                </div>\n\t                            </div>\n\t                            <label for=\"is-distance\">Distance:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"distance\" id=\"is-distance\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"1\">\n\t                                px\n\t                            </div>\n\t                            <label for=\"is-blur\">Blur:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"blur\" id=\"is-blur\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"0\">\n\t                                px\n\t                            </div>\n\t                            <label for=\"is-size\">Size:</label>\n\t                            <div>\n\t                                <div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"size\" id=\"is-size\" type=\"text\" data-min=\"0\" data-max=\"255\" value=\"0\">\n\t                                px\n\t                            </div>\n\t                            <div class=\"clear\"></div>\n\t                        </div>\n\t                        <div id=\"background\">\n\t                            <h3>Background</h3>\n\t\t\t\t\t\t\t\t<label for=\"bg-opacity\">Opacity:</label>\n\t                            <div>\n\t                                <div class=\"slider\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"opacity\" id=\"bg-opacity\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"100\">\n\t                                %\n\t                            </div>\n\t\t\t\t\t\t\t\t<label>Gradient</label>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<div class=\"gradientField\"></div>\n\t\t\t\t\t\t\t\t\t<input type=\"checkbox\" class=\"reverse\" id=\"bg-reverse\"><label for=\"bg-reverse\">Reverse</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<label>Style</label>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<select id=\"background_style\">\n\t\t\t\t\t\t\t\t\t\t<option value=\"linear\">Linear</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"reflected\">Reflected</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"contain\">Radial - contain</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"cover\">Radial - cover</option>\n\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t</div>\n\t                            <label class=\"angle_holder\" for=\"bg-angle\">Angle:</label>\n\t                            <div>\n\t                                <div class=\"pot\"><div class=\"pointer\"><div class=\"dot\"></div><div class=\"line\"></div></div></div>\n\t                                <div class=\"angle_holder\">\n\t                                    <input class=\"angle\" id=\"bg-angle\" type=\"text\" data-min=\"0\" data-max=\"360\" value=\"90\">\n\t                                    &deg;\n\t                                    <input type=\"checkbox\" class=\"globalLight\" id=\"bg-globalLight\"><label for=\"bg-globalLight\">Use Global Light</label>\n\t                                </div>\n\t                            </div>\n\t\t                       \t<div class=\"clear\"></div>\n\t                        </div>\n\t\t\t\t\t\t\t<div id=\"border\">\n\t                            <h3>Border</h3>\n\t\t\t\t\t\t\t\t<label>Color:</label>\n\t                            <div>\n\t                                <div class=\"color_field\"></div>\n\t                            </div>\n\t                            <label for=\"bd-opacity\">Opacity:</label>\n\t                            <div>\n\t                                <div class=\"slider\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"opacity\" id=\"bd-opacity\" type=\"text\" data-min=\"0\" data-max=\"100\" value=\"100\">\n\t                                %\n\t                            </div>\n\t                            <label for=\"bd-size\">Size:</label>\n\t                            <div>\n\t                                <div class=\"slider\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t                                <input class=\"size\" id=\"bd-size\" type=\"text\" data-min=\"0\" data-max=\"10\" value=\"1\">\n\t                                px\n\t                            </div>\n\t                            <label>Style:</label>\n\t                            <div id=\"border_styles\" class=\"previews\">\n\t\t\t\t\t\t\t\t\t<div id=\"border_style_solid\" title=\"solid\" data-style=\"solid\" class=\"active\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"border_style_dashed\" title=\"dashed\" data-style=\"dashed\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"border_style_dotted\" title=\"dotted\" data-style=\"dotted\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"border_style_double\" title=\"double\" data-style=\"double\"></div>\n\t                            </div>\n\t                            <div class=\"clear\"></div>\n\t                        </div><!-- /border -->\n\t\t\t\t\t\t\t<div id=\"borderRadius\">\n\t                            <h3>Border Radius</h3>\n\t\t\t\t\t\t\t\t<label for=\"br-radius\">Radius:</label>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<div class=\"slider\" data-easing=\"true\"><div class=\"bar\"></div><div class=\"arrow\"><div class=\"spike\"></div><div class=\"rear\"></div></div></div>\n\t\t\t\t\t\t\t\t\t<input class=\"radius\" id=\"br-radius\" type=\"text\" data-min=\"0\" data-max=\"200\" value=\"0\">\n\t                                <span class=\"options\" id=\"border_radius_unit\"><span id=\"border_radius_pixel\" data-unit=\"px\" class=\"active\">px</span><span id=\"border_radius_percent\" data-unit=\"%\">%</span></span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<label>Corners:</label>\n\t\t\t\t\t\t\t\t<div id=\"border_radius_preview\">\n\t\t\t\t\t\t\t\t\t<div id=\"topLeft\" class=\"active\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"topRight\" class=\"active\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"bottomRight\" class=\"active\"></div>\n\t\t\t\t\t\t\t\t\t<div id=\"bottomLeft\" class=\"active\"></div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"clear\"></div>\n\t\t\t\t\t\t\t</div>\n\t                    </div>\n\t                </div>\n\t                <div class=\"clear\"></div>\n\t            </div>\n\t            <div class=\"controls\">\n\t                <button id=\"ok\">OK</button>\n\t                <button id=\"cancel\">Cancel</button>\n\t                <button id=\"new_style\">New Style...</button>\n\t            </div>\n\t\t\t</div>\n        </div>\n\t\t<div id=\"gradient_editor\" class=\"window\">\n\t\t\t<div class=\"head moveable\">\n\t\t\t\t<h2>Gradient Editor</h2>\n\t\t\t</div>\n\t\t\t<div class=\"body\">\n\t           <div class=\"static_right\">\n\t                <div class=\"main\">\n\t                    <div class=\"holder\">\n\t                        <h3>Presets</h3>\n\t                        <div id=\"gradient_presets_holder\" class=\"border_box\">\n\t                            <div id=\"gradient_presets\">\n\t                            </div>\n\t                        </div>\n\t                    </div>\n\t                </div>\n\t                <div class=\"controls sidebar\">\n\t                    <button id=\"gradient_ok\">OK</button>\n\t                    <button id=\"gradient_cancel\">Cancel</button>\n\t                </div>\n\t                <div class=\"clear\"></div>\n\t            </div>\n\t            <div class=\"static_right\">\n\t                <div class=\"main\">\n\t                    <div class=\"static_left\">\n\t                        <span>Name:</span><input id=\"gradient_name\" type=\"text\">\n\t                    </div>\n\t                </div>\n\t                <div class=\"controls sidebar\">\n\t                    <button id=\"gradient_new\">New</button>\n\t                </div>\n\t                <div class=\"clear\"></div>\n\t            </div>\n\t            <div class=\"holder\">\n\t                <h3>Gradient</h3>\n\t                <div id=\"gradient_holder\">\n\t                    <div class=\"frame\">\n\t                        <div id=\"gradient\">\n\t                        </div>\n\t                    </div>\n\t                </div>\n\t                <div id=\"stops\" class=\"holder\">\n\t                    <h3>Stops</h3>\n\t                    <div id=\"color_stops\">\n\t                        <div class=\"disabled\">\n\t                            <span>Color:</span><div id=\"stop_color\" class=\"color_field\"></div>\n\t                        </div>\n\t                        <div class=\"disabled\">\n\t                            <label for=\"stop_location\">Location:</label>\n\t\t\t\t\t\t\t\t\t<input type=\"text\" id=\"stop_location\" data-min=\"0\" data-max=\"100\" data-restrict=\"digits\" disabled=\"disabled\">%\n\t                        </div>\n\t                        <button id=\"remove_stop\" disabled=\"disabled\">Delete</button>\n\t                    </div>\n\t                </div>\n\t            </div>\n\t        </div>\n\t\t</div>\n\t\t<div id=\"colorpicker\" class=\"window\">\n\t\t\t<div class=\"head moveable\">\n\t\t\t\t<h2>Colorpicker</h2>\n\t\t\t</div>\n\t\t\t<div class=\"body\">\n            \t<div class=\"main\">\n\t                <div id=\"color_field\" class=\"border_box\">\n\t                    <canvas id=\"field\" width=\"256\" height=\"256\"></canvas>\n\t                    <canvas id=\"circle\" class=\"colorcircle\" width=\"256\" height=\"256\"></canvas>\n\t                </div> \n\t                <div id=\"color_slider\">\n\t                    <canvas class=\"border_box\" width=\"19\" height=\"256\"></canvas>\n\t                    <div>\n\t                        <div class=\"arrow left\"><div class=\"spike\"></div><div class=\"rear\"></div></div>\n\t                        <div class=\"arrow right\"><div class=\"spike\"></div><div class=\"rear\"></div></div>\n\t                    </div>\n\t                </div>\n\t                <div class=\"color_preview lightbox\">\n\t                    <label>new</label>\n\t                    <div id=\"new_color\"></div>\n\t                    <label>current</label>\n\t                    <div id=\"current_color\"></div>\n\t                </div>\n\t                <div class=\"color_inputs\">\n\t                    <ul>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"hsb_h-radio\" name=\"color\" value=\"hsb_h\">\n\t\t\t\t\t\t\t\t<label for=\"hsb_h-radio\">H:</label>\n\t\t\t\t\t\t\t\t<input id=\"hsb_h\" type=\"text\" data-min=\"0\" data-max=\"360\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t\t&deg;\n\t\t\t\t\t\t\t</li>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"hsb_s-radio\" name=\"color\" value=\"hsb_s\">\n\t\t\t\t\t\t\t\t<label for=\"hsb_s-radio\">S:</label>\n\t\t\t\t\t\t\t\t<input id=\"hsb_s\" type=\"text\" data-min=\"0\" data-max=\"100\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t\t%\n\t\t\t\t\t\t\t</li>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"hsb_b-radio\" name=\"color\" value=\"hsb_b\" checked=\"checked\">\n\t\t\t\t\t\t\t\t<label for=\"hsb_b-radio\">B:</label>\n\t\t\t\t\t\t\t\t<input id=\"hsb_b\" type=\"text\" data-min=\"0\" data-max=\"100\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t\t%\n\t\t\t\t\t\t\t</li>\n\t                    </ul>\n\t                    <ul>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"rgb_r-radio\" name=\"color\" value=\"rgb_r\">\n\t\t\t\t\t\t\t\t<label for=\"rgb_r-radio\">R:</label>\n\t\t\t\t\t\t\t\t<input id=\"rgb_r\" type=\"text\" data-min=\"0\" data-max=\"255\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t</li>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"rgb_g-radio\" name=\"color\" value=\"rgb_g\">\n\t\t\t\t\t\t\t\t<label for=\"rgb_g-radio\">G:</label>\n\t\t\t\t\t\t\t\t<input id=\"rgb_g\" type=\"text\" data-min=\"0\" data-max=\"255\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t</li>\n\t                        <li>\n\t\t\t\t\t\t\t\t<input type=\"radio\" id=\"rgb_b-radio\" name=\"color\" value=\"rgb_b\">\n\t\t\t\t\t\t\t\t<label for=\"rgb_b-radio\">B:</label>\n\t\t\t\t\t\t\t\t<input id=\"rgb_b\" type=\"text\" data-min=\"0\" data-max=\"255\" data-restrict=\"digits\" value=\"0\">\n\t\t\t\t\t\t\t</li>\n\t                    </ul>\n\t                    <div id=\"hex_holder\">\n\t\t\t\t\t\t\t<label for=\"hex\">#</label>\n\t\t\t\t\t\t\t<input type=\"text\" id=\"hex\" size=\"10\" maxlength=\"6\" data-restrict=\"hexcode\">\n\t\t\t\t\t\t</div>\n\t                </div>\n\t            </div>\n\t            <div class=\"controls\">\n\t                <button id=\"color_ok\">OK</button>\n\t                <button id=\"color_cancel\">Cancel</button>\n\t                <button id=\"color_add\">Add to Swatches</button>\n\t                <div id=\"swatches_holder\">\n\t                    <div id=\"swatches\" class=\"paint_bucket\">\n\t                    </div>\n\t                </div>\n\t            </div>\n\t        </div>\n\t\t</div><!-- /ColorPicker -->\n\t</div> <!-- /LayerStyle -->\n<script type=\"text/javascript\" src=\"js/jquery-1.6.min.js\"></script>\n<script type=\"text/javascript\" src=\"js/ui.js\"></script>\n<script type=\"text/javascript\" src=\"js/zeroclipboard/ZeroClipboard.js\"></script>\n<script type=\"text/javascript\" src=\"js/localization.js\"></script>\n<script type=\"text/javascript\" src=\"js/color.js\"></script>\n<script type=\"text/javascript\" src=\"js/numbers.js\"></script>\n<script type=\"text/javascript\" src=\"js/tools.js\"></script>\n<script type=\"text/javascript\" src=\"js/css.js\"></script>\n<script type=\"text/javascript\" src=\"js/style.js\"></script>\n<script type=\"text/javascript\" src=\"js/colorpicker.js\"></script>\n<script type=\"text/javascript\" src=\"js/gradienteditor.js\"></script>\n<script type=\"text/javascript\" src=\"js/codebox.js\"></script>\n<script type=\"text/javascript\" src=\"js/universe.js\"></script>\n<script type=\"text/javascript\" src=\"js/styleStore.js\"></script>\n<script type=\"text/javascript\" src=\"js/application.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "css/index.css",
    "content": "* { margin: 0; padding: 0; }\nhtml { height: 100%; }\nbody {\n\tfont: 12px/1.4 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\tbackground-color: #fcfcfc;\n\tbackground-image: -moz-linear-gradient(top, rgba(52,154,227,0.21), rgba(52,154,227,0) 13px);\n\tbackground-image: -webkit-linear-gradient(top, rgba(52,154,227,0.21), rgba(52,154,227,0) 13px);\n\tbackground-image: -o-linear-gradient(top, rgba(52,154,227,0.21), rgba(52,154,227,0) 13px);\n\tbackground-image: -ms-linear-gradient(top, rgba(52,154,227,0.21), rgba(52,154,227,0) 13px);\n}\n#arche {\n\tpadding-top: 55px;\n\twidth: 556px;\n\tmargin: 0 auto;\n\ttext-transform: uppercase;\n\ttext-shadow: 0 1px white;\n\tz-index: 200;\n\tposition: relative;\n\t-moz-transition: 320ms;\n\t-webkit-transition: 320ms;\n\ttransition: 320ms;\n}\nh1 span { color: #349ae3; text-transform: none; font-size: 16px; }\nh3 { color: #666; font-weight: normal; }\na { text-decoration: none; color: #349ae3; }\nem { font-weight: bold; font-style: normal; }\nimg { border: none; }\n#header {\n\tmargin-top: 14px;\n\tpadding-left: 100px;\n\tposition: relative;\n\tbackground: url(../img/logo.png) no-repeat 24px 5px;\n}\n.hero {\n\ttop: 0;\n    -webkit-border-top-left-radius: 4px;\n    -webkit-border-top-right-radius: 4px;\n    -moz-border-radius-topleft: 4px;\n    -moz-border-radius-topright: 4px;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    -moz-box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n    -webkit-box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n    box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n\tposition: relative;\n}\n#ready {\n\tmargin: 17px 0 21px;\n\tdisplay: none;\n}\n\t#ready .hero {\n\t\t-moz-transition: 240ms ease;\n\t\t-webkit-transition: 240ms ease;\n\t\ttransition: 240ms ease;\n\t}\n\t#ready:hover .hero { \n\t\ttop: 3px;\n\t    -moz-box-shadow: 0 12px 40px 8px rgba(0,0,0,.20), 0 0 0 1px rgba(0,0,0,.16);\n\t    -webkit-box-shadow: 0 12px 40px 8px rgba(0,0,0,.20), 0 0 0 1px rgba(0,0,0,.16);\n\t    box-shadow: 0 12px 40px 8px rgba(0,0,0,.20), 0 0 0 1px rgba(0,0,0,.16);\n\t}\n#not-ready { \n\tmargin: 17px 0 21px;\n\tdisplay: none;\n\tposition: relative;\n}\n\t#not-ready .holder { \n\t\tleft: 153px;\n\t\ttop: 76px;\n\t\twidth: 276px;\n\t\t-moz-border-radius: 4px;\n\t\t-webkit-border-radius: 4px;\n\t\tborder-radius: 4px;\n\t    -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.21), 0 15px 40px 10px rgba(0, 0, 0, 0.34);\n\t    -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.21), 0 15px 40px 10px rgba(0, 0, 0, 0.34);\n\t    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.21), 0 15px 40px 10px rgba(0, 0, 0, 0.34);\n\t\tposition: absolute;\n\t\ttext-shadow: none;\n\t\ttext-transform: none;\n\t}\n\t#not-ready .upper {\n\t\tpadding: 13px;\n\t\tborder: 1px solid #A6281C;\n    \tbackground: #F03432;\n    \t-webkit-border-top-left-radius: 4px;\n\t    -webkit-border-top-right-radius: 4px;\n\t    -moz-border-radius-topleft: 4px;\n\t    -moz-border-radius-topright: 4px;\n\t    border-top-left-radius: 4px;\n\t    border-top-right-radius: 4px;\n\t\t-moz-box-shadow: 0 0 0 1px #F25146 inset;\n\t\t-webkit-box-shadow: 0 0 0 1px #F25146 inset;\n\t\tbox-shadow: 0 0 0 1px #F25146 inset;\n\t}\n\t#not-ready h2 { padding-bottom: 13px; font-size: 14px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.21); border-bottom: 1px solid rgba(0, 0, 0, 0.34); } \n\t.features { border-top: 1px solid rgba(255,255,255,.13); padding-top: 8px;  line-height: 2; }\n\t.features span { \n\t\tdisplay: none;\n\t\tpadding: 1px 8px;\n\t\tcolor: white;\n\t\twhite-space: nowrap;\n\t\tbackground: #F25146;\n\t\ttext-shadow: 0 1px 0 rgba(255,255,255,0.21);\n\t\t-moz-border-radius: 7px;\n\t\t-webkit-border-radius: 7px;\n\t\tborder-radius: 7px;\n\t}\n\t#not-ready .bottom {\n\t\tpadding: 13px;\n\t\tcolor: white;\n\t\ttext-shadow: 0 2px black;\n\t\tbackground: black;\n\t\tbackground: rgba(0,0,0,.8);\n\t\t-webkit-border-bottom-left-radius: 4px;\n\t    -webkit-border-bottom-right-radius: 4px;\n\t    -moz-border-radius-bottomleft: 4px;\n\t    -moz-border-radius-bottomright: 4px;\n\t    border-bottom-left-radius: 4px;\n\t    border-bottom-right-radius: 4px;\n\t}\n.js.nativejson.flexbox.canvas.rgba.borderradius.boxshadow.cssgradients #ready { display: block; }\n.no-js #not-ready,\n.no-flexbox #not-ready,\n.no-canvas #not-ready,\n.no-rgba #not-ready,\n.no-borderradius #not-ready,\n.no-boxshadow #not-ready,\n.no-cssgradients #not-ready { display: block; }\n.no-js .feature-js { display: inline; }\n.no-nativejson .feature-json { display: inline; }\n.no-flexbox .feature-flexbox { display: inline; }\n.no-canvas .feature-canvas { display: inline; }\n.no-rgba .feature-rgba { display: inline; }\n.no-borderradius .feature-borderradius { display: inline; }\n.no-boxshadow .feature-boxshadow { display: inline; }\n.no-cssgradients .feature-cssgradients { display: inline; }\nfooter {\n\tpadding: 0 21px;\n\tcolor: rgba(0,0,0,.34);\n}"
  },
  {
    "path": "css/style.css",
    "content": "* { margin: 0; padding: 0; }\nbody, html { height: 100%; overflow: hidden; }\nbody {\n    width: 100%;\n    font: 12px/14px \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    background: url(../img/transparent.gif);\n}\n.box {\n    display: -moz-box;\n    display: -webkit-box;\n    display: box;\n}\n.box.vertical {\n    -moz-box-orient: vertical;\n    -webkit-box-orient: vertical;\n    box-orient: vertical;\n}\n.flex {\n    -webkit-box-flex: 1;\n    -moz-box-flex: 1;\n    box-flex: 1;\n}\nul { list-style: none; }\n#helper { top: 5px; right: 5px; padding: 8px 13px; position: absolute; z-index: 9999; background: rgba(0,0,0,.5); \n    -moz-border-radius: 13px;\n    -webkit-border-radius: 13px;\n    border-radius: 13px;\n}\n#layer { \n    top: 50%;\n    left: 50%;\n    margin: -150px 0 0 -150px;\n    width: 300px;\n    height: 300px;\n    position: absolute;\n    z-index: 99;\n    -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;\n    opacity: 1;\n}\n    #resize { bottom: -15px; right: -15px; width: 30px; height: 30px; position: absolute; }\n    #layer.borderRadius:hover #resize { border-right: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1); }\n#main { position: relative; height: 100%; width: 100%; }\n#workspace { position: relative; }\n    #parallel_universe { position: absolute; z-index: -1; }\n    #innerShadow_universe { position: absolute; z-index: -1; }\n    #background_layer {\n        background: -moz-linear-gradient(top, #e2e2e2, #ababab);\n        background: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#ababab));\n        background: -o-linear-gradient(top, #e2e2e2, #ababab);\n        display: block;\n    }\n    #codeBoxToggle {\n        bottom: 0; \n        left: 0; \n        padding: 5px 13px 4px; \n        line-height: 18px; \n        color: rgba(0, 0, 0, 0.75);\n        background: rgba(0,0,0,.08); \n        border-radius: 2px 2px 0 0; \n        position: absolute; \n        cursor: pointer;\n        display: inline-block;\n        z-index: 101;\n        -moz-transition: background-color 240ms ease;\n        -webkit-transition: background-color 240ms ease;\n        transition: background-color 240ms ease;\n    }\n        #codeBoxToggle:hover {\n            background: rgba(0,0,0,.13);\n        }\n#overlay { width: 100%; height: 100%; position: absolute; top: 0; background-color: transparent;\n    -moz-transition: background-color 240ms ease;\n    -webkit-transition: background-color 240ms ease;\n    transition: background-color 240ms ease;\n}\n    .dragging #overlay { z-index: 101; background-color: rgba(0,0,0,.21); }\n    .pick #overlay { z-index: 100; cursor: url(../img/eyedropper.gif) 0 15, auto; }\n#infoButton { \n    position: absolute; \n    left: 0; \n    padding: 13px; \n    color: black; \n    text-decoration: none; \n    text-transform: uppercase; \n    opacity: 0.21; \n    z-index: 99; \n    display: block;\n    -moz-transition: 240ms;\n    -webkit-transition: 240ms;\n    transition: 240ms;\n}\n    #infoButton:hover { opacity: 0.55; }\n#codeBox {\n    height: 0;\n    position: relative;\n    overflow: hidden;\n    background-position: 0 2px;\n    -webkit-transition: 300ms ease-out;\n    -moz-transition: 300ms ease-out;\n    transition: 300ms ease-out;\n}\n    #codeBox.resizing {\n        -webkit-transition: none;\n        -moz-transition: none;\n        transition: none;\n    }\n    #codeBox .dragger.y {\n        top: 0;\n        height: 21px;\n        background: -moz-linear-gradient(#9E9E9E, #999);\n        background: -webkit-gradient(linear, center top, center bottom, from(#9E9E9E), to(#999));\n        background: -webkit-linear-gradient(#9E9E9E, #99);\n        border-bottom: 1px solid #666;\n        -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;\n        display: block;\n        position: relative;\n        z-index: 1;\n    }\n    #copyCode { \n        top: 21px;\n        left: 1px;\n        width: 78px;\n        height: 15px;\n        color: #444;\n        font-family: \"Consolas\", \"Monaco\", monospace;\n        line-height: 15px; \n        font-size: 10px;\n        text-align: center;\n        border: 1px solid #edc59c;\n        border-radius: 4px;\n        background-image: -moz-repeating-linear-gradient(-45deg, transparent, transparent 2px, #edc59c 2px, #edc59c 3px);\n        background-image: -webkit-repeating-linear-gradient(-45deg, transparent, transparent 2px, #edc59c 2px, #edc59c 3px);\n        background-size: 4px 4px;\n        position: absolute;\n        cursor: pointer;\n    }\n        #copyCode:active { color: black; }\n        #copyCode embed { left: 0; position: absolute; outline: none; }\n        #colorSwitch {\n            top: 41px;\n            left: 1px;\n            width: 78px;\n            height: 15px;\n            color: #444;\n            border: 1px solid #edc59c;\n            border-radius: 4px;\n            overflow: hidden;\n            position: absolute;\n        }\n            .toggle { cursor: pointer; }\n            #colorSwitch .slidePanel {\n                width: 150%;\n                height: 100%;\n                left: -50%;\n                margin: 1px;\n                position: absolute;\n                -moz-transition: 320ms ease;\n                -webkit-transition: 320ms ease;\n            }\n            #colorSwitch.moving .slidePanel {\n                -moz-transition: none;\n                -webkit-transition: none;\n            }\n            #colorSwitch .button {\n                top: 0;\n                left: 33.33%;\n                width: 35px;\n                height: 11px;\n                position: absolute;\n                border: 1px solid #edc59c;\n                border-radius: 3px;\n                background-image: -moz-repeating-linear-gradient(-45deg, transparent, transparent 2px, #edc59c 2px, #edc59c 3px);\n                background-image: -webkit-repeating-linear-gradient(-45deg, transparent, transparent 2px, #edc59c 2px, #edc59c 3px);\n                background-size: 4px 4px;\n            }\n            #colorSwitch .left,\n            #colorSwitch .right { right: 0; width: 33.33%; height: 100%; line-height: 13px; font-size: 10px; text-align: center; position: absolute; }\n            #colorSwitch .left { left: 0; right: auto; }\n    #codeBox .body {\n        color: #444;\n        height: 100%;\n        border-top: 1px solid rgba(0,0,0,.13);\n        overflow: auto;\n        position: relative;\n    }\n    .paper {\n        background-color: #ffe4b5;\n        /* lines */\n        background-image:\n            -moz-linear-gradient(left, transparent 82px, rgba(128,0,0,.08) 82px, rgba(128,0,0,.08) 82px, transparent 83px),\n            -moz-repeating-linear-gradient(transparent, transparent 19px, rgba(128, 0, 0, 0.08) 19px, rgba(128, 0, 0, 0.08) 20px);\n        background-image: \n            -webkit-linear-gradient(left, transparent 82px, rgba(128,0,0,.08) 82px, rgba(128,0,0,.08) 82px, transparent 83px),\n            -webkit-repeating-linear-gradient(transparent, transparent 19px, rgba(128, 0, 0, 0.08) 19px, rgba(128, 0, 0, 0.08) 20px);\n    }\n        #codeBox .scroll {\n            padding: 20px 0 0 108px;\n        }\n        #codeBox code { \n            padding-bottom: 20px;\n            border: none;\n            font-family: \"Consolas\", monospace;\n            line-height: 20px;\n            display: block;\n        }\n.dragger { position: absolute; z-index: 100; }\n    .dragger.x { width: 10px; left: -5px; top: 0; height: 100%; cursor: w-resize; }\n    .dragger.y { width: 100%; top: -5px; left: 0; height: 10px; cursor: n-resize; }\n    .dragBox { bottom: 0; left: 5px; height: 20px; width: 20px; border: 1px solid rgba(0,0,0,.13); background: url(../img/dragger.png) no-repeat 6px 6px; position: absolute; }\n    .dragger.y .dragBox {\n        bottom: -1px;\n        border: none;\n        -moz-transform: rotate(90deg);\n        -webkit-transform: rotate(90deg);\n        transform: rotate(90deg);\n        -moz-transform-origin: center center;\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n    }\n.moveable { cursor: move; }\n#layerstyle {\n    top: 11px;\n    left: 51px;\n    width: 556px;\n    height: 393px;\n    color: black;\n    background: #EDEDED;\n    -webkit-border-top-left-radius: 4px;\n    -webkit-border-top-right-radius: 4px;\n    -moz-border-radius-topleft: 4px;\n    -moz-border-radius-topright: 4px;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    -moz-box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n    -webkit-box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n    box-shadow: 0 15px 40px 10px rgba(0,0,0,.25), 0 0 0 1px rgba(0,0,0,.16);\n    position: absolute;\n    z-index: 100;\n    display: block;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -o-user-select: none;\n    user-select: none;\n}\n#headerBg {\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 24px;\n    border-top: 1px solid #E2E2E2;\n    border-bottom: 1px solid #515151;\n    background: -moz-linear-gradient(#CFCFCF, #A8A8A8);\n    background: -webkit-gradient(linear, center top, center bottom, from(#CFCFCF), to(#A8A8A8));\n    -webkit-border-top-left-radius: 4px;\n    -webkit-border-top-right-radius: 4px;\n    -moz-border-radius-topleft: 4px;\n    -moz-border-radius-topright: 4px;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    position: absolute;\n}\n.window { top: 0; width: 100%; position: absolute; }\n    .window .head {\n        padding: 6px;\n        position: relative;\n    }\n    .window .head h2 {\n        font-size: 13px;\n        font-weight: normal;\n        text-align: center;\n        color: black;\n        text-shadow: 0 1px 0 #cfcfcf;\n    }\n        .window .head > button {\n            position: absolute;\n            left: 3px;\n            top: 3px;\n            width: auto;\n            padding: 1px 9px;\n            text-shadow: 0 1px 0 white;\n            background: -moz-linear-gradient(top, #ebebeb, #d7d7d7);\n            background: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#d7d7d7));\n            border: 1px solid #999999;\n            -moz-border-radius: 3px;\n            -webkit-border-radius: 3px;\n            border-radius: 3px;\n            -moz-box-shadow: 0 1px 0 rgba(255,255,255,0.5), 0 1px 0 white inset;\n            -webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.5), 0 1px 0 white inset;\n            box-shadow: 0 1px 0 rgba(255,255,255,0.5), 0 1px 0 white inset;\n            cursor: pointer;\n        }\n.window .body { padding: 15px 10px; position: relative; }\n.inactive {\n    color: gray;\n}\n#dialog { visibility: hidden; }\n.main { width: 82%; float: left; font-size: 10px; }\n    .main > .styles { width: 72%; float: left; }\n        #holder { margin: 0 16px; }\n        #holder > div { width: 100%; visibility: hidden; position: absolute; top: 0; padding: 12px 0; border: 1px solid #909090; }\n        #holder > div.active { visibility: visible; }\n        .holder { position: relative; }\n        .holder h3 { left: 9px; top: -8px; padding: 0 3px 0 2px; font-size: 10px; position: absolute; background: #ededed; }\n        .styles > div > div > label { width: 22%; padding-top: 1px; margin-right: 2%; text-align: right; float: left; clear: right; }\n        .styles label + div { width: 75%; float: right; }\n        .styles label, .styles label + div { margin-top: 2px; }\n        .styles .color_field { height: 13px; width: 33px; border: 1px solid #909090; background: white; cursor: pointer; }\n        .styles input[type=checkbox] { margin: 0 6px; vertical-align: middle; width: auto; }\n        .styles input[type=checkbox] + label { vertical-align: middle; }\n        .styles .angle_holder { top: 13px; position: relative; display: inline-block; vertical-align: top; }\n        input[type=text] { \n            width: 40px;\n            padding: 1px;\n            font-size: 10px;\n            border: 1px solid #909090;\n            border-bottom-width: 0;\n            -moz-box-shadow: inset 0 0 0 1px #bababa, 0 1px 0 rgba(0,0,0,.04);\n            -webkit-box-shadow: inset 0 0 0 1px #bababa, 0 1px 0 rgba(0,0,0,.04);\n            box-shadow: inset 0 0 0 1px #bababa, 0 1px 0 rgba(0,0,0,.04);\n        }\n        .styles .slider { width: 100px; margin: 0 5px 0 3px; }\n    #stylePresets { margin: -2px 9px 0; height: 230px; overflow: auto; }\n    #stylePresets .swatch { width: 31px; height: 31px; border-right: 1px solid #909090; border-bottom: 1px solid #909090; float: left;\n            -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;\n        }\n    #stylePresets .swatch.active { border: 2px solid black; }\n            #stylePresets .swatch > div { width: 17px; height: 17px; margin: 7px 0 0 7px; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }\n            #stylePresets .swatch.active > div { margin: 5px 0 0 5px; }\n    #holder #background { }\n        .gradientField {\n            margin: 2px 0;\n            width: 109px;\n            height: 15px;\n            vertical-align: middle;\n            border: 1px solid black;\n            display: inline-block;\n            cursor: pointer;\n        }\n        .previews > div { margin: 2px 2px 2px 0; width: 24px; height: 24px; border: 1px solid black; display: inline-block; opacity: 0.3; }\n        .previews > .active { opacity: 1; background-color: #A7D4F6; }\n        .inactive .previews > .active { background-color: rgba(0,0,0,.08); border-color: gray; }\n        #border .previews > div { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }\n        #border_style_dotted { border-style: dotted; }    \n        #border_style_dashed { border-style: dashed; }\n        #border_style_double { border: 3px double black; }\n        #border_radius_preview {\n            width: 104px;\n            height: 104px;\n            margin: 4px 3px;\n            float: left;\n            border-color: rgba(0,0,0,.25);\n            position: relative;\n            -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;\n            overflow: hidden;\n        }\n            #border_radius_preview > div {\n                width: 50%;\n                height: 50%;\n                float: left;\n                -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;\n            }\n            #border_radius_preview #bottomRight { float: right; border-bottom: 1px solid rgba(0,0,0,.25); border-right: 1px solid rgba(0,0,0,.25); }\n            #border_radius_preview #topLeft { border-top: 1px solid rgba(0,0,0,.25); border-left: 1px solid rgba(0,0,0,.25); border-bottom: 1px dotted rgba(0,0,0,.25); border-right: 1px dotted rgba(0,0,0,.25); }\n            #border_radius_preview #topRight { border-top: 1px solid rgba(0,0,0,.25); border-right: 1px solid rgba(0,0,0,.25); border-bottom: 1px dotted rgba(0,0,0,.25); }\n            #border_radius_preview #bottomLeft { border-bottom: 1px solid rgba(0,0,0,.25); border-left: 1px solid rgba(0,0,0,.25); border-right: 1px dotted rgba(0,0,0,.25); }\n            #border_radius_preview > div.active { background: #A7D4F6; }\n            .inactive #border_radius_preview > div.active { background: rgba(0,0,0,.08); }\n            .options { \n                -moz-box-shadow: 0 2px white;\n                -webkit-box-shadow: 0 2px white;\n                box-shadow: 0 2px white;\n                cursor: pointer;\n            }\n                .options span:first-child { border-right: none; }\n                .options span:last-child { border-left: none; }\n                .options span {\n                    padding: 0 4px;\n                    border: 1px solid rgba(0,0,0,.5);\n                    background: -moz-linear-gradient(#C1C1C1, #D4D4D4);\n                    background: -webkit-linear-gradient(#C1C1C1, #D4D4D4);\n                    background: linear-gradient(#C1C1C1, #D4D4D4);\n                    -moz-box-shadow: 0 1px white inset;\n                    -webkit-box-shadow: 0 1px white inset;\n                    box-shadow: 0 1px white inset;\n                }\n                .options span.active {\n                    border: 1px solid rgba(0,0,0,.5);\n                    background: -moz-linear-gradient(#999999, #BBBBBB);\n                    background: -webkit-linear-gradient(#999999, #BBBBBB);\n                    background: linear-gradient(#999999, #BBBBBB);\n                    -moz-box-shadow: none;\n                    -webkit-box-shadow: none;\n                    box-shadow: none;\n                }\n                .inactive .options span { opacity: 0.5; }\n    #nav { width: 28%; height: 100%; float: left; cursor: default; }\n        #nav ul {\n            border: 1px solid #909090;\n            -moz-box-shadow: inset 1px 1px 0 rgba(0,0,0,.3);\n            -webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.3);\n            box-shadow: inset 1px 1px 0 rgba(0,0,0,.3);\n        }\n        #nav li { margin: 0 0 0 1px; padding: 4px 6px; border-bottom: 1px solid white; cursor: pointer; }\n        #nav li input { margin-right: 5px; vertical-align: bottom; cursor: pointer; }\n        #nav li.active { background: #b5d5ff; font-weight: bold; }\n        #nav li:first-child { padding-bottom: 6px; \n            -moz-box-shadow: inset 0 -1px 0 black;\n            -webkit-box-shadow: inset 0 -1px 0 black;\n            box-shadow: inset 0 -1px 0 black;\n        }\n        #nav li:first-child + li { padding-top: 5px; border-top: 1px solid #909090;\n            -moz-box-shadow: inset 0 1px 0 black;\n            -webkit-box-shadow: inset 0 1px 0 black;\n            box-shadow: inset 0 1px 0 black;\n        }\n    .controls { width: 18%; float: right; }\n        .controls > div { text-align: center; }\n        .controls > div input { margin-right: 2px; }\n#colorpicker { visibility: hidden; }\n    #colorpicker .body { padding-top: 9px; }\n    #colorpicker .main { width: 75%; height: 294px; margin-top: 21px; position: relative; }\n    #color_field { height: 256px; width: 256px; position: absolute; }\n        #field, #circle { position: absolute; }\n        #circle { z-index: 999; }\n    #color_slider { left: 259px; top: 2px; width: 44px; height: 256px; position: absolute; }\n    #color_slider canvas {\n        top: -2px;\n        left: 11px;\n        height: 256px;\n        width: 19px;\n        position: absolute;\n    }\n    .border_box { border-color: #909090 #909090 #e4e4e4 #909090; border-width: 2px 1px 1px 2px; border-style: solid; }\n    .lightbox { border: 1px solid #909090; border-bottom-color: #e4e4e4; }\n    #color_slider > div { left: 11px; top: 256px; width: 21px; position: absolute; }\n        #color_slider > div > .arrow.right { right: -3px;  }\n        #color_slider > div > .arrow.left { left: -9px; }\n        #color_slider .arrow { top: -4px; position: absolute; }\n        #color_slider .arrow div { border: 1px solid #747474; background: white; position: absolute; }\n        #color_slider .arrow .rear { width: 4px; height: 6px;\n            -moz-border-radius: 2px;\n            -webkit-border-radius: 2px;\n            border-radius: 2px;\n        }\n        #color_slider .arrow .spike { top: 1px; width: 4px; height: 4px; \n            -moz-transform: rotate(45deg);\n            -webkit-transform: rotate(45deg);\n            transform: rotate(45deg);\n        }\n        #color_slider .arrow.left .rear { border-right-width: 0; }\n        #color_slider .arrow.left .spike { left: 1px; }\n        #color_slider .arrow.right .rear { border-left-width: 0; left: 2px; }\n    .color_preview { top: 4px; left: 304px; width: 60px; position: absolute; }\n        .color_preview > div { height: 34px; background: black; border: 1px solid black; }\n        #new_color { border-bottom: none; }\n        #current_color { background: white; border-top: none; }\n        .color_preview > label { bottom: -14px; width: 100%; text-align: center; position: absolute; }\n        .color_preview > label:first-child { top: -20px; height: 20px; }\n    .color_inputs { top: 111px; left: 305px; width: 100px; position: absolute; font-size: 13px; }\n        .color_inputs ul { padding-bottom: 4px; }\n        .color_inputs li { margin: 2px 0 3px; display: inline-block; }\n        .color_inputs input[type=radio] { margin-right: 4px; }\n        .color_inputs span { width: 20px; display: inline-block; }\n        .color_inputs ul input[type=text] { width: 33px; height: 18px; margin-right: 2px; font-size: 13px; }\n        .color_inputs #hex_holder { margin: 2px 3px; }\n            .color_inputs #hex { height: 18px; margin-left: 4px; font-size: 13px; width: 68px; }\n#colorpicker .controls { width: 25%; }\n    #swatches_holder { margin: 5px; background: #d6d6d6; border-top: 1px solid #909090; overflow: hidden; }\n    #swatches { padding-bottom: 12px; overflow: hidden; }\n    #swatches span { \n        width: 10px; \n        height: 11px;\n        border-right: 1px solid black;\n        border-bottom: 1px solid black;\n        float: left;\n        cursor: url(../img/eyedropper.gif) 0 15, auto;\n    }\n    .alt .swatch { cursor: url(../img/scissor.gif) 6 6, auto; }\n#gradient_editor { visibility: hidden; }\n    /* overwritings */\n    #gradient_editor .holder { padding: 13px 9px 9px; border: 1px solid #909090; }\n    #gradient_editor .holder h3 { left: 16px; font-size: 13px; font-weight: normal; }\n    #gradient_editor input[type=text] { padding: 2px; font-size: 13px; }\n    #gradient_editor .static_right { margin-right: 105px; }\n    #gradient_editor .main { width: 100%; font-size: 13px; }\n        #gradient_editor .static_left { margin: 16px 4px 22px 56px; }\n            #gradient_editor .static_left > span { margin-left: -55px; line-height: 22px; float: left; } \n            #gradient_name { width: 100%; }\n            #gradient_new { margin-top: 17px; }\n        #gradient_presets_holder { height: 115px; overflow: auto; }\n            #gradient_presets div { width: 31px; height: 31px; border-right: 1px solid #909090; border-bottom: 1px solid #909090; float: left; }\n    #gradient_editor .sidebar { width: 89px; margin-right: -105px; }\n    #gradient_holder { padding: 12px 6px 34px; }\n        .frame { border: 1px solid #909090; }\n        #gradient { height: 25px; position: relative; }\n        #gradient div { cursor: default; }\n        #gradient .picker { position: absolute; }\n        #gradient .picker.top { top: -19px; }\n        #gradient .picker.bottom { top: 33px; }\n        #gradient .picker > div { position: absolute; }\n        #gradient .picker .arrow { left: -3px; top: 6px; height: 6px; width: 6px; border: 1px solid black;\n            -moz-box-shadow: -1px 0 #909090 inset;\n            -webkit-box-shadow: -1px 0 #909090 inset;\n            box-shadow: -1px 0 #909090 inset;\n            -moz-transform: rotate(45deg);\n            -webkit-transform: rotate(45deg);\n            transform: rotate(45deg);\n            -moz-transform-origin: 2px 3px;\n            -webkit-transform-origin: 2px 3px;\n            transform-origin: 2px 3px;\n        }\n        #gradient .picker.bottom .arrow { top: -5px; \n            -moz-box-shadow: 0 1px #909090 inset;\n            -webkit-box-shadow: 0 1px #909090 inset;\n            box-shadow: 0 1px #909090 inset;\n        }\n        #gradient .picker.selected .arrow { background: black;\n            -moz-box-shadow: none;\n            -webkit-box-shadow: none;\n            box-shadow: none;\n        }\n        #gradient .picker .box { left: -6px; height: 10px; width: 9px; background: #E4E4E4; border: 1px solid black; border-bottom: none;\n            -moz-box-shadow: -1px 0 #909090 inset;\n            -webkit-box-shadow: -1px 0 #909090 inset;\n            box-shadow: -1px 0 #909090 inset;\n        }\n        #gradient .picker.bottom .box { height: 9px; padding-top: 1px; border-bottom: 1px solid black; border-top: none;\n            -moz-box-shadow: 0 1px #909090 inset;\n            -webkit-box-shadow: 0 1px #909090 inset;\n            box-shadow: 0 1px #909090 inset;\n        }\n        #gradient .picker .color_field { height: 7px; width: 7px; border-width: 1px; border-style: solid; border-color: #E4E4E4 #909090 #909090 #E4E4E4; background: black; }\n        #gradient .middlepoint { top: -9px; position: absolute; display: none; cursor: default; }\n        #gradient .middlepoint.visible { display: block; }\n        #gradient .middlepoint.bottom { top: 27px; }\n        #gradient .middlepoint span { margin-left: -4px; width: 7px; height: 7px; background: url(../img/middlepoint.gif); display: block; }\n        #gradient .middlepoint.selected span { background-position: 0 -7px; }\n    #gradient_editor #stops { padding: 9px 9px 2px; font-size: 13px; }\n    #stops .disabled { color: #7f7f7f; }\n    #stops button { width: 89px; display: inline; }\n    #stops > div > div { width: 140px; display: inline-block; }\n        #stops span { width: 54px; margin-right: 4px; text-align: right; display: inline-block; }\n        #stops input[type=\"text\"] { margin-right: 2px; }\n        #stop_color { width: 45px; height: 18px; margin-bottom: -5px; border: 1px solid #909090; display: inline-block; cursor: pointer; }\n        .disabled #stop_color { cursor: auto; }\n.eyedropper { cursor: url(../img/eyedropper.gif) 0 15, auto; }\n.colorcircle { cursor: url(../img/colorcircle.gif) 8 8, auto; }\n.paint_bucket { cursor: url(../img/paint_bucket.gif) 13 14, auto; }\n.resize { cursor: url(../img/resize.gif) 8 8, se-resize; }\n.pot {\n    margin: 0 3px;\n    width: 40px;\n    height: 40px;\n    background: -moz-linear-gradient(top, #dbdbdb, #e1e1de 20%, #f8f8f3);\n    background: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), color-stop(50%, #e1e1de), to(#f8f8f3));\n    border: 2px solid #727272;\n    -moz-box-shadow: inset 0 2px 3px white, inset 0 -1px 2px #fffef8;\n    -webkit-box-shadow: inset 0 2px 3px white, inset 0 -1px 2px #fffef8;\n    box-shadow: inset 0 2px 3px white, inset 0 -1px 2px #fffef8;\n    -moz-border-radius: 40px;\n    -webkit-border-radius: 40px;\n    border-radius: 40px;\n    position: relative;\n    display: inline-block;\n}\n    .pointer {\n        top: 50%;\n        left: 50%;\n        margin: -1.5px 0 0 -1.5px;\n        width: 50%;\n        -moz-transform: rotate(-90deg);\n        -webkit-transform: rotate(-90deg);\n        transform: rotate(-90deg);\n        -moz-transform-origin: 1.5px 1.5px;\n        -webkit-transform-origin: 1.5px 1.5px;\n        transform-origin: 1.5px 1.5px;\n        position: absolute;\n    }\n        .dot {\n            height: 3px;\n            width: 3px;\n            background: #909090;\n            position: absolute;\n        }\n        .line {\n            margin-top: 1px;\n            height: 1px;\n            background: #909090;\n        }\n.slider {\n    padding: 4px 0 2px 1px;\n    position: relative;\n    display: inline-block;\n}\n    .slider .bar {\n        margin-top: 3px;\n        height: 3px;\n        background: -moz-linear-gradient(top, #adadad, #b2b2b2);\n        background: -webkit-gradient(linear, left top, left bottom, from(#adadad), to(#b2b2b2));\n        -moz-box-shadow: inset 0 1px 0 #929292;\n        -webkit-box-shadow: inset 0 1px 0 #929292;\n        box-shadow: inset 0 1px 0 #929292;\n        border: 1px solid #686868;\n        border-bottom-color: #aaa;\n        -moz-border-radius: 3px;\n        -webkit-border-radius: 3px;\n        border-radius: 3px;\n    }\n    .inactive .slider .bar {\n        background: -moz-linear-gradient(top, #bfbfbf, #d0d0d0);\n        background: -webkit-linear-gradient(top, #bfbfbf, #d0d0d0);\n        background: linear-gradient(top, #bfbfbf, #d0d0d0);\n        -moz-box-shadow: inset 0 1px 0 #bfbfbf;\n        -webkit-box-shadow: inset 0 1px 0 #bfbfbf;\n        box-shadow: inset 0 1px 0 #bfbfbf;\n        border-color: #aaa #aaa #cacaca;\n    }\n    .slider .arrow {\n        left: 0;\n        top: 3px;\n        position: absolute;\n    }\n        .slider .rear {\n            left: -3px;\n            top: 4px;\n            height: 5px;\n            width: 7px;\n            background: -moz-linear-gradient(top, #a7d4f6, #73bbf2, #b0e9fd);\n            background: -webkit-gradient(linear, left top, left bottom, from(#a7d4f6), color-stop(50%,#73bbf2), to(#b0e9fd));\n            border: 1px solid #787a96;\n            border-top-width: 0;\n            -moz-border-radius: 0 0 2px 2px;\n            -webkit-border-radius: 2px;\n            border-radius: 2px;\n            -moz-box-shadow: 0 1px 0 rgba(0,0,0,.05);\n            position: relative;\n        }\n        .slider .spike {\n            left: -4px;\n            height: 4px;\n            width: 4px;\n            background: -moz-linear-gradient(-45deg, #e4f1fc, #88c4f2);\n            background: -webkit-gradient(linear, left top, right bottom, from(#e4f1fc), to(#88c4f2));\n            border: 1px solid #8d84ae;\n            -moz-transform-origin: 3px 7px;\n            -webkit-transform-origin: 3px 7px;\n            transform-origin: 3px 7px;\n            -moz-transform: rotate(45deg);\n            -webkit-transform: rotate(45deg);\n            transform: rotate(45deg);\n            position: absolute;\n        }\n        .inactive .slider .rear {\n            background: -moz-linear-gradient(#ECEDED, #DBDBDB, #EBEBEB);\n            background: -webkit-linear-gradient(#ECEDED, #DBDBDB, #EBEBEB);\n            background: linear-gradient(#ECEDED, #DBDBDB, #EBEBEB);\n            border-color: #7F7D7D;\n        }\n        .inactive .slider .spike {\n            background: -moz-linear-gradient(-45deg, #E1E1E1, white);\n            background: -webkit-linear-gradient(-45deg, #E1E1E1, white);\n            background: linear-gradient(-45deg, #E1E1E1, white);\n            border-color: #9E9E9E;\n        }\nbutton {\n    width: 100%;\n    margin: 8px 0;\n    padding: 1px 0;\n    background: -moz-linear-gradient(top, #fcfcfc, #f4f4f4 40%, #e6e6e5 42%, #f5f5f5 75%, #fff);\n    background: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), color-stop(40%,#f4f4f4), color-stop(42%,#e6e6e5), color-stop(75%,#f5f5f5), to(#fff));\n    font-size: 12px;\n    border: 1px solid #7d7d7d;\n    -moz-border-radius: 17px;\n    -webkit-border-radius: 17px;\n    border-radius: 17px;\n    -moz-box-shadow: 0 1px 0 rgba(0,0,0,.2);\n    -webkit-box-shadow: 0 1px 0 rgba(0,0,0,.2);\n    box-shadow: 0 1px 0 rgba(0,0,0,.2);\n    display: block;\n    outline: none;\n    cursor: pointer;\n}\nbutton::-moz-focus-inner { border: 0; } /* firefox outline removed */\nbutton:first-child { margin-top: 0; }\nlabel[for] { cursor: pointer; }\n#puff { width: 22px; height: 22px; background: url(../img/puff.png); position: absolute; display: block; z-index: 110; }\n.clear { clear: both; }"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<title>Layer Styles</title>\n\t<link rel=\"icon\" type=\"image/png\" href=\"favicon.png\" />\n\t<script type=\"text/javascript\" src=\"js/modernizr-1.7.min.js\"></script>\n\t<link rel=\"stylesheet\" href=\"css/index.css\" type=\"text/css\" />\n</head>\n<body>\n<div id=\"arche\">\n\t<header>\n\t\t<div id=\"logo\">LS</div>\n\t\t<div id=\"headline\">\n\t\t\t<h1>LayerStyles</h1>\n\t\t\t<h3 class=\"tagline\">just like your favorite graphics editor</h3>\n\t\t\t<h3 class=\"tagline\">but in your browser. And it creates CSS.</h3>\n\t\t</div>\n\t</header>\n\t\n\t<section id=\"ready\">\n\t\t<a href=\"builder.html\"><img class=\"hero\" src=\"img/hero.png\" width=\"556\" height=\"393\" alt=\"Layerstyles main interface\" /></a>\n\t</section>\n\t<section id=\"not-ready\">\n\t\t<img class=\"hero\" src=\"img/hero.png\" width=\"556\" height=\"393\" alt=\"Layerstyles main interface\" />\n\t\t<div class=\"holder\">\n\t\t\t<div class=\"upper\">\n\t\t\t\t<h2>Unfortunately your browser doesn't support the following requirements:</h2>\n\t\t\t\t<div class=\"features\">\n\t\t\t\t\t<span class=\"feature-js\">Javascript enabled</span>\n\t\t\t\t\t<span class=\"feature-json\">Native JSON</span>\n\t\t\t\t\t<span class=\"feature-cssgradients\">CSS Background Gradients</span>\n\t\t\t\t\t<span class=\"feature-borderradius\">Border Radius</span>\n\t\t\t\t\t<span class=\"feature-canvas\">HTML5 Canvas</span>\n\t\t\t\t\t<span class=\"feature-flexbox\">HTML5 Flexbox</span>\n\t\t\t\t\t<span class=\"feature-rgba\">RGB Alpha-Channel</span>\n\t\t\t\t\t<span class=\"feature-boxshadow\">Box Shadows</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"bottom\">\n\t\t\t\t<p>\n\t\t\t\t\tPlease update your browser.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n\t<footer>\n\t\t<p>LayerStyles is <em>Open Source</em> and on <a href=\"https://github.com/mrflix/LayerStyles\">Github</a></p>\n\t\t<p>made by <a href=\"http://www.felixniklas.de\">Felix Niklas</a> &copy 2011 <em>follow me on mastodon:</em> <a href=\"https://mastodon.social/@mrflix\">@mrflix</a>.</p>\n\t</footer>\n</div><!-- /arche -->\n<script type=\"text/javascript\" src=\"js/jquery-1.6.min.js\"></script>\n<script type=\"text/javascript\" src=\"js/ui.js\"></script>\n<script type=\"text/javascript\" src=\"js/zeroclipboard/ZeroClipboard.js\"></script>\n<script type=\"text/javascript\" src=\"js/localization.js\"></script>\n<script type=\"text/javascript\" src=\"js/color.js\"></script>\n<script type=\"text/javascript\" src=\"js/numbers.js\"></script>\n<script type=\"text/javascript\" src=\"js/tools.js\"></script>\n<script type=\"text/javascript\" src=\"js/css.js\"></script>\n<script type=\"text/javascript\" src=\"js/style.js\"></script>\n<script type=\"text/javascript\" src=\"js/colorpicker.js\"></script>\n<script type=\"text/javascript\" src=\"js/gradienteditor.js\"></script>\n<script type=\"text/javascript\" src=\"js/codebox.js\"></script>\n<script type=\"text/javascript\" src=\"js/universe.js\"></script>\n<script type=\"text/javascript\" src=\"js/styleStore.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "js/application.js",
    "content": "/*!\n *     _                                       ________                  _\n *    | |                                     |  ______|                | |\n *    | |                                     | |          _            | |\n *    | |       _____ ___  ___ _____  _____   | |______  _| |_ ___  ___ | |     _____  _____\n *    | |      |  _  |\\  \\/  /|  _  ||   __|  |______  ||_   _|\\  \\/  / | |    |  _  ||  ___|\n *    | |_____ | |_| | /   /  |  ___||  |      ______| |  | |   /   /   | |___ |  ___||___  |\n *    |_______||___,\\|/___/   |_____||__|     |________|  |_|  /___/    |_____||_____||_____|\n *    \n *       http://www.layerstyles.org\n *    \n *    Copyright (c) 2011 Felix Niklas\n *    This script is freely distributable under the terms of the MIT license.\n */\n\nlocalStorage['version'] = \"0.1\";\n\nvar movePos = { x: 0, y: 0 }, bytes, reader;\nvar $body = $('body');\nvar $overlay = $('#overlay');\nvar $workspace = $('#workspace');\nvar dimensions = { width: $workspace.width(), height: $workspace.height() };\nvar $dialog = $('#dialog');\nvar $layerstyle = $('#layerstyle');\nvar $navElements = $('#nav ul li');\nvar $holderElements = $('#holder > div');\nvar $pots = $('.pot');\nvar potDimensions = {'height': 40, 'width': 40};\nvar $sliders = $('.slider'), shouldEase = false;\nvar $numericalInputs = $('input[type=text]', $dialog);\nvar $buttons = { 'ok': $('#ok'), 'cancel': $('#cancel'), 'newStyle': $('#new_style')  };\nvar $layer = $('#layer');\nvar resizeArea = $('#resize');\nvar $backgroundLayer = $('#background_layer');//.css(\"height\", dimensions.height);\nvar $parallelUniverse = $('#parallel_universe').attr({height: dimensions.height, width: dimensions.width});\nvar pu = $parallelUniverse.get(0).getContext('2d');\nvar $innerShadowUniverse = $('#innerShadow_universe').attr({height: dimensions.height, width: dimensions.width});\nvar iu = $innerShadowUniverse.get(0).getContext('2d');\nvar moveAreas = $('.moveable'), movingWindow;\nvar offset = { x: 0, y: 0 };\nvar $colorfields = $('.color_field');\nvar currentStyle, lang;\nvar background = {\n        background: [{\n                stops: [[255,255,255,1], [255,255,255,0]],\n                style: 'radial',\n                position: 'center',\n                angle: 90\n            },\n            {\n                stops: [[226, 226, 226], [171, 171, 171]],\n                style: 'linear',\n                angle: 90\n            }\n        ]\n};\n\n// array compare function - thanks to David and Anentropic\n// http://stackoverflow.com/questions/1773069/using-jquery-to-compare-two-arrays\n// (sort removed and extended to deep comparison)\n// syntax: $.compare(a, b);\n\njQuery.extend({\n    compare: function (b, a) {\n        if (a.length != b.length) { return false; }\n        for (var i = 0, l = a.length; i < l; i++) {\n            if (a[i] !== b[i]) { \n                if(typeof a[i] === 'object'){\n                    return jQuery.compare(a[i],b[i]);\n                } else {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n});\n\n// Object.create implementation for older browsers\n// by Ben Newman\n\nif(Object.create === undefined){\n    Object.create = function( proto, props ) {\n      var ctor = function( ps ) {\n        if ( ps )\n          Object.defineProperties( this, ps );\n      };\n      ctor.prototype = proto;\n      return new ctor( props );\n    };\n}\n\n/*\n\nthings to store:\n    - styles, gradients and colors\n    - layerstyles version\n    - currentStyle\n\n*/\nvar defaults = {\n        height: 300,\n        width: 300,\n        ratio: 1,\n        globalAngle: 90,\n        dropShadow: {\n            isActive: true,\n            color: [0,0,0],\n            opacity: 75,\n            angle: 90,\n            hasGlobalLight: false,\n            distance: 1,\n            blur: 5,\n            size: 0\n        },\n        innerShadow: {\n            isActive: false,\n            color: [255,255,255],\n            opacity: 100,\n            angle: 90,\n            hasGlobalLight: false,\n            distance: 1,\n            blur: 0,\n            size: 0,\n            isInset: true\n        },\n        background: {\n            isActive: true,\n            opacity: 100,\n            stops: [[252, 252, 252], 23, [[242, 242, 242], 12], 89, [191, 191, 191]],\n            isReverse: false,\n            style: 'linear',\n            angle: 90,\n            hasGlobalLight: false\n        },\n        border: {\n            isActive: true,\n            color: [0,0,0],\n            opacity: 100,\n            size: 1,\n            style: 'solid'\n        },\n        borderRadius: {\n            isActive: false,\n            radii: [[0, \"px\"],[0, \"px\"],[0, \"px\"],[0, \"px\"]],\n            isSelected: [true,true,true,true],\n            hasPercentage: [false, false, false, false]\n        }\n};\n\nvar nav = {\n    $el: $layerstyle,\n    $pages: null,\n    width: null,\n    page: null,\n    prev: null,\n    speed: 0,\n    goTo: function(pageNr){\n        // parse Int\n        pageNr = pageNr*1;\n        localStorage[\"pageNr\"] = pageNr;\n        if(pageNr === -1){\n            pageNr = this.prev; // go back\n        }\n        else {\n            pageNr--; // pages area 1,2,3 - but in the array they are 0,1,2\n        }\n        var goPage = this.$pages.eq(pageNr);\n        var currentPage = this.$pages.eq(this.page);\n        var direction = pageNr > this.page ? 1 : -1; // 1 = right, -1 = left\n        var offset = this.width;\n        this.$el.css('overflow', 'hidden');\n        currentPage\n            .animate({\n                'margin-left': -direction*offset+'px',\n                'opacity': 0\n            }, this.speed, function(){ nav.$pages.eq(nav.page).css('visibility', 'hidden'); });\n        goPage\n            .css({\n                'margin-left': direction*offset+'px',\n                'visibility': 'visible',\n                'opacity': 0\n            })\n            .animate({\n                'margin-left': 0,\n                'opacity': 1\n            }, this.speed, function(){ nav.$el.css('overflow', 'visible'); });\n        this.prev = this.page;\n        this.page = pageNr;\n    },\n    show: function(pageNr){\n        pageNr--;\n        $(this.$pages[pageNr]).css('visibility', 'visible');\n        this.page = pageNr;\n    },\n    init: function(){\n        this.width = this.$el.width();\n        this.$pages = $('> .window', this.$el);\n        this.show(1);\n    }\n}\n\nfunction moveWindow(event){\n    movingWindow.css({ top: event.pageY - movePos.y, left: event.pageX - movePos.x });\n}\n\nfunction resizeLayer(event, x, y){\n    var halfWidth, halfHeight, maxWidth, maxHeight;\n     halfWidth = parseInt(( x != null ? x/2 : event.pageX - dimensions.width/2 + offset.x), 10);\n    halfHeight = event != null && event.shiftKey ? halfWidth / currentStyle.ratio : parseInt(( y != null ? y/2 : event.pageY - dimensions.height/2 + offset.y), 10);\n    maxWidth = dimensions.width/2;\n    maxHeight = dimensions.height/2;\n    halfWidth =  halfWidth < 8 ? 8 : halfWidth > maxWidth ? maxWidth : halfWidth;\n    halfHeight = halfHeight < 8 ? 8 : halfHeight > maxHeight ? maxHeight : halfHeight;\n    currentStyle.width = halfWidth*2;\n    currentStyle.height = halfHeight*2;\n    $layer.css({\n        'width': currentStyle.width,\n        'height': currentStyle.height,\n        'margin-top': -halfHeight,\n        'margin-left': -halfWidth\n    });\n}\n\nfunction showSlide(pos){\n    $navElements.removeClass('active');\n    $navElements.eq(pos).addClass('active');\n    $holderElements.removeClass('active').eq(pos).addClass('active');\n}\n\nfunction dragenter(e) {\n      e.stopPropagation();\n      e.preventDefault();\n    $body.addClass(\"dragging\");\n}\n\nfunction dragleave(e) {\n      e.stopPropagation();\n      e.preventDefault();\n    $body.removeClass(\"dragging\");\n}\n\nfunction dragover(e) {\n      e.stopPropagation();\n      e.preventDefault();\n}\n\nfunction drop(e) {\n      e.stopPropagation();\n      e.preventDefault();\n\n    dropPos = { x: e.pageX, y: e.pageY };\n    \n      var dt = e.dataTransfer;\n    var files = dt.files;\n    \n    for (var i = 0, l=files.length; i < l; i++) {\n        var data = files[i];\n        //bytes = new Stream(data);\n        reader = new FileReader();\n        reader.onload = function(e){\n            \n            var img = new Image(),\n                $canvas = $(\"<canvas></canvas>\"),\n                ctx = $canvas.get(0).getContext('2d');\n            \n            img.src = e.target.result;\n            \n            img.onload = function(){\n                \n                  $canvas.attr({\n                    title: data.name,\n                    width: img.width,\n                    height: img.height\n                });\n\n                $canvas.css({ left: dropPos.x-img.width/2, top: dropPos.y-img.height/2, position: \"absolute\" });\n                $canvas.addClass(\"moveable\");\n\n                ctx.drawImage(img, 0, 0);\n\n                $canvas.appendTo($workspace);\n            };\n        };\n        reader.readAsDataURL(data);\n    }\n    \n    $body.removeClass(\"dragging\");\n}\n\nfunction showPickArea(){\n    $body.addClass(\"pick\");\n    // draw the parallel Universe for color picking\n    parallelUniverse.draw();\n    // redraw the parallelUniverse when the layer gets redrawn (\"paint\" event);\n    $(document).bind('paint', $.proxy( parallelUniverse, \"draw\" ));\n    $overlay.bind('mousedown', pick);\n}\n\nfunction hidePickArea(){\n    $body.removeClass(\"pick\");\n    $(document).unbind('paint', $.proxy( parallelUniverse, \"draw\" ));\n    $overlay.unbind('mousedown');\n}\n\nfunction pick(event){\n    var pickedColor = pu.getImageData(event.pageX, event.pageY, 1, 1).data;\n    colorpicker.setHex(color.hexFromRgb(pickedColor));\n    colorpicker.update('hex');\n}\n\nfunction initialise() {\n    // include 'dataTransfer' to jquerys event object\n    jQuery.event.props.push('dataTransfer');\n    \n    // set language \n    // not yet elaborated - whats the best solution to change all titles in the html?\n    // - create the html via js in the first place or select and change them all?\n    // - regex over the all textnodes?\n    lang = localization.en;\n\n    $navElements.click(function(){\n        var pos = $navElements.index(this);\n        localStorage[\"slidePos\"] = pos;\n        showSlide(pos);\n    });\n\n    $numericalInputs.bind({\n        mousedown: function(e){ e.stopPropagation(); },\n        focus: function(e){ numbers.initNumberField(this, 'style'); },\n        keydown: numbers.restrictCharacters,\n        keyup: numbers.keyUp,\n        blur: numbers.validateInput\n    });\n    \n    moveAreas.live('mousedown', function(event){ \n        event.preventDefault();\n        movingWindow = $(this).hasClass(\"head\") ? $(this).parents('#layerstyle') : $(this);\n        movingWindow.addClass(\"moving\");\n        $(document).one('mouseup', function(){ movingWindow.removeClass(\"moving\"); });\n        var myOffset = movingWindow.offset();\n        movePos = { x:event.pageX-myOffset.left, y:event.pageY-myOffset.top };\n        $(document).bind('mousemove.global', moveWindow);\n    }); \n    resizeArea.bind({\n        mousedown: function(event){\n            event.preventDefault();\n            event.stopPropagation();\n            currentStyle.ratio = currentStyle.width/currentStyle.height;\n            $(document).bind('mousemove.global', resizeLayer);\n            $body.addClass(\"resize\");\n            $(document).one('mouseup', function(){ $body.removeClass('resize'); });\n            var my_offset = $(this).offset();\n            offset = { x: 15-(event.pageX-my_offset.left), y: 15-(event.pageY-my_offset.top) };\n        },\n        click: function(event){ event.stopPropagation(); } // prevent bubbling\n    });\n    $(document).bind({\n        mousemove: function(e){ e.preventDefault(); },\n        mouseup: function(){ $(this).unbind('mousemove.global'); },\n        dragenter: dragenter,\n        dragleave: dragleave,\n        dragover: dragover,\n        drop: drop\n    });\n    \n    $(window).bind({\n        resize: function(event){\n            dimensions = { width: $workspace.width(), height: $workspace.height() };\n            $parallelUniverse.attr({'width': dimensions.width, 'height': dimensions.height});\n            $innerShadowUniverse.attr({'width': dimensions.width, 'height': dimensions.height});\n            if (dimensions.width < currentStyle.width) { resizeLayer(null, dimensions.width, currentStyle.height); }\n            if (dimensions.height < currentStyle.height) { resizeLayer(null, currentStyle.width, dimensions.height); }\n        },\n        keydown: function(event){\n            if(event.altKey){\n                $body.addClass('alt');\n                $(this).one('keyup', function(){ $body.removeClass('alt'); });\n            }\n        }\n    });\n    $layer.dblclick(function(event){ $layerstyle.show(); });\n    $buttons.ok.click(function(){ $layerstyle.hide(); });\n    $buttons.cancel.click(function(){ $layerstyle.hide(); });\n    $buttons.newStyle.click( $.proxy( styleStore, \"create\" ) );\n\n    $('#infoButton').click(function(){ $body.removeClass('visited'); });\n\n    styleStore.init();\n    nav.init();\n    colorpicker.init();\n    gradienteditor.init();\n    codeBox.init();\n    style.init();\n    showSlide(localStorage[\"slidePos\"] || 1);\n    nav.goTo(localStorage[\"pageNr\"] || 1);\n    \n    $(document)\n        .bind('paint', $.proxy( codeBox, \"render\" ))\n        .bind('paint', $.proxy( css, \"render\" ))\n        .trigger('styleChange')\n        .trigger('paint');\n}\n\n// isEven: (n % 2) == 0 -> true? even : odd\n\n// GET THE BALL ROLLIN\n$(document).ready(function(){\n    initialise();\n});"
  },
  {
    "path": "js/codebox.js",
    "content": "var codeBox = {\n    options: {\n        visible: true,\n        height: 143\n    },\n    minHeight: 100,\n    init: function(){\n        if(localStorage[\"codeBoxOptions\"]) this.options = JSON.parse(localStorage[\"codeBoxOptions\"]);\n        this.$el = $('#codeBox');\n        this.$box = this.$el.find('code');\n        this.$body = this.$el.find('.body');\n        this.$copyCode = this.$el.find('#copyCode');\n        this.$dragger = this.$el.find('.dragger.y');\n        this.$codeBoxToggle = $('#codeBoxToggle');\n        this.$colorToggle = Object.create(toggle);\n        this.$colorToggle.init(\"colorSwitch\", \"hex\", tools.options, $.proxy( this, \"render\" ));\n        \n        this.location = window.location.href.slice(0, window.location.href.lastIndexOf(\"/\"));\n        this.initClipboard();\n        \n        this.$copyCode.add(this.$body).add(this.$box)\n            .bind('mousedown', function(e){ e.stopPropagation(); });\n        this.$codeBoxToggle.click( $.proxy( this, \"toggle\" ) );\n        this.$dragger.mousedown( $.proxy( this, \"drag\") );\n        \n        this.updateView();\n    },\n    toggle: function(){\n        if(this.$el.height() === 0){\n            this.options.visible = true;\n        } else {\n            this.options.visible = false;\n        }\n        this.storeSettings();\n        this.updateView();\n        $(window).trigger('resize');\n    },\n    updateView: function(){\n        if(this.options.visible){\n            this.$el.height(this.options.height);\n        } else {\n            this.$el.height(0);\n        }\n    },\n    drag: function(event){\n        event.preventDefault();\n        var my_offset = $(event.target).offset();\n        offset = { y: event.pageY-my_offset.top };\n        this.$el.addClass(\"resizing\");\n        this.resize(event);\n        $(document).one('mouseup', function(){ codeBox.$el.removeClass('resizing') } );\n        $(document).bind('mousemove.global', $.proxy( this, \"resize\") );\n    },\n    resize: function(event){\n        this.options.height = Math.max(this.minHeight, $(document).height() - event.pageY + offset.y);\n        this.$el.height(this.options.height);\n        $(window).trigger('resize');\n        this.storeSettings();\n    },\n    storeSettings: function(){\n        localStorage[\"codeBoxOptions\"] = JSON.stringify(this.options);\n    },\n    /**\n     * @method  initClipboard - a click on the button with the id 'copyCode' will copy 'this.$box.text()' into the clipboard\n     * @see        http://code.google.com/p/zeroclipboard/wiki/Instructions\n     */\n    initClipboard: function(){\n        ZeroClipboard.setMoviePath( this.location + '/js/zeroclipboard/ZeroClipboard.swf' );\n        this.clip = new ZeroClipboard.Client();\n        this.clip.addEventListener( 'onMouseDown', $.proxy( this, \"copy\" ) );\n        this.clip.setHandCursor(true);\n        var flash = this.clip.getHTML(this.$copyCode.width(), this.$copyCode.height());\n        this.$copyCode.append(flash);\n    },\n    copy: function(){\n        var text = this.code.replace(/<br>/g, \"\\n\").replace(/&nbsp;/g, \"\");\n        this.clip.setText(text);\n    },\n    tabs: function(count){\n        var tabString = \"\",\n            tabs = count || this.options.tabs;\n        \n        for(;tabs--;){\n            tabString += \"&nbsp;\";\n        }\n        return tabString;\n    },\n    render: function(){\n        var borderRadiusObject;\n        this.code = \"\";\n        // add border\n        this.code += currentStyle.border.isActive ? \"border: \" + css.border(currentStyle) + \";<br>\" : \"\";\n        // add border-radius\n        if(currentStyle.borderRadius.isActive){\n            borderRadiusObject = css.borderRadius(currentStyle);\n            for(var key in borderRadiusObject){\n                var radius = borderRadiusObject[key];\n                if(radius !== 0){\n                    this.code += key + \": \" + radius + \";<br>\";\n                }\n            }\n        }\n        // add gradient\n        if(currentStyle.background.isActive){\n            this.code += \"background-image: \" + css.drawGradient(currentStyle) + \";<br>\";\n        }\n        // add dropShadow and innerShadow\n        if(currentStyle.dropShadow.isActive || currentStyle.innerShadow.isActive){\n            this.code += \"box-shadow: \" + css.boxShadow(currentStyle) + \";<br>\";\n        }\n        this.$box.html(this.code);\n    }\n};"
  },
  {
    "path": "js/color.js",
    "content": "var color = {\n    hsbFromRgb: function(rgb) {\n        r = rgb[0]/255, g = rgb[1]/255, b = rgb[2]/255;\n        var max = Math.max(r, g, b), min = Math.min(r, g, b);\n        var h, s, v = max;\n\n        var d = max - min;\n        s = max === 0 ? 0 : d / max;\n\n        if(max === min){\n            h = 0;\n        }else{\n            switch(max){\n                case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n                case g: h = (b - r) / d + 2; break;\n                case b: h = (r - g) / d + 4; break;\n            }\n            h /= 6;\n        }\n        return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)];\n    },\n    rgbFromHsb: function(hsv) {\n        var r, g, b;\n        h = hsv[0]/360; s = hsv[1]/100; v = hsv[2]/100;\n\n        var i = Math.floor(h * 6);\n        var f = h * 6 - i;\n        var p = v * (1 - s);\n        var q = v * (1 - f * s);\n        var t = v * (1 - (1 - f) * s);\n\n        switch(i % 6){\n            case 0: r = v; g = t; b = p; break;\n            case 1: r = q; g = v; b = p; break;\n            case 2: r = p; g = v; b = t; break;\n            case 3: r = p; g = q; b = v; break;\n            case 4: r = t; g = p; b = v; break;\n            case 5: r = v; g = p; b = q; break;\n        }\n        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n    },\n    rgbFromHex: function(hex){\n        if(hex.length === 3){\n            return [\n                parseInt(hex.substring(0,1)+hex.substring(0,1), 16),\n                parseInt(hex.substring(1,2)+hex.substring(1,2), 16),\n                parseInt(hex.substring(2,3)+hex.substring(2,3), 16)\n            ]\n        } else {\n               return [\n                parseInt(hex.substring(0,2), 16),\n                parseInt(hex.substring(2,4), 16),\n                parseInt(hex.substring(4,6), 16)\n            ]\n        }\n    },\n    hexFromRgb: function(rgb){\n        var hexcode = this.toHex(rgb[0])+this.toHex(rgb[1])+this.toHex(rgb[2]),\n            parts = hexcode.split(\"\");\n        // \"000\" instead of \"000000\"\n        return (parts[0]===parts[1]) && (parts[2]===parts[3]) && (parts[4]==parts[5]) ? parts[0]+parts[2]+parts[4] : hexcode;\n    },\n    toHex: function(n) {\n        if(n === 0) { return '00'; }\n        n = parseInt(n, 10);\n        if (n === 0 || isNaN(n)) { return \"00\"; }\n        return \"0123456789abcdef\".charAt((n-n%16)/16) + \"0123456789abcdef\".charAt(n%16);\n    }\n};"
  },
  {
    "path": "js/colorpicker.js",
    "content": "/*\n *      LayerStyles\n *       http://www.layerstyles.org\n *    \n *    Copyright (c) 2011 Felix Niklas\n *    This script is freely distributable under the terms of the MIT license.\n */\n\nvar colorpicker = {\n    open: false,\n    currentColor: \"000000\", // hex\n    callback: null,\n    thisArg: null,\n    swatches: [\n        {'title': 'White', 'hex': 'ffffff'},\n        {'title': '10% Gray', 'hex': 'e5e5e5'},\n        {'title': '20% Gray', 'hex': 'cccccc'},\n        {'title': '30% Gray', 'hex': 'b3b3b3'},\n        {'title': '40% Gray', 'hex': '999999'},\n        {'title': '50% Gray', 'hex': '808080'},\n        {'title': '60% Gray', 'hex': '666666'},\n        {'title': '70% Gray', 'hex': '4d4d4d'},\n        {'title': '80% Gray', 'hex': '333333'},\n        {'title': '90% Gray', 'hex': '1a1a1a'},\n        {'title': 'Black', 'hex': '000000'}\n    ],\n    $selectedInput: null,\n    colorHistory: [],\n    pointerPos: { 'x': 0, 'y': 0 },\n    hsb: { h: 0, s: 0, b: 0 },\n    rgb: { r: 0, g: 0, b: 0 },\n    hex: '000000',\n    mode: 'hsb_b',\n    max: 0, // the maximum input value\n    ratio: 0, // the ratio for the slider: its 0.7111 (hue), ~1 (rgb) or 2.56 (saturation/brightness)\n    offset: 0, // the offset relative to the document will be stored in here to calculate mouse-dragging\n    pick: function(rgbArray, callback, thisArg) {\n        showPickArea();\n        this.callback = callback;\n        this.thisArg = thisArg;\n        // set rgb\n        this.setRgb(parseInt(rgbArray[0],10),parseInt(rgbArray[1],10),parseInt(rgbArray[2],10));\n        // update\n        this.update('rgb_r');\n        // set currentColor\n        this.setCurrentColor();\n        // show it\n        nav.goTo(3);\n    },\n    setCurrentColor: function(hex) {\n        this.currentColor = hex || this.hex;\n        this.$currentColor.css('background', '#'+this.currentColor);\n    },\n    pickCurrentColor: function(){\n        this.setHex(this.currentColor);\n        this.update('hex');\n    },\n    clickHex: function(){\n        this.$hex.focus();\n    },\n    update: function(customMode) {\n        var updateMode = customMode || this.mode;\n        switch(updateMode){\n        case 'hsb_h': case 'hsb_s': case 'hsb_b':\n            this.getHsb();\n            this.hsbToRgb();\n            this.rgbToHex();\n            break;\n        case 'rgb_r': case 'rgb_g': case 'rgb_b':\n            this.getRgb();\n            this.rgbToHsb();\n            this.rgbToHex();\n            break;\n        case 'hex':\n            this.getHex();\n            this.hexToRgb();\n            this.rgbToHsb();\n            break;\n        }\n        this.paintField();\n        this.paintSlider();\n        this.setNewColor();\n        this.moveSlider(this.$selectedInput.val()*this.ratio);\n        if(this.callback) this.callback.call(this.thisArg, color.rgbFromHex(this.hex));\n    },\n    paintField: function() {\n        var xGradient, yGradient;\n        this.cf.save();\n        this.cf.clearRect(0,0,256,256);\n        xGradient = this.cf.createLinearGradient(0, 0, 0, 256);\n        yGradient = this.cf.createLinearGradient(0, 0, 256, 0);\n        switch (this.mode) {\n        case 'hsb_h': // rainbow\n            var hue = color.rgbFromHsb([this.hsb.h, 100, 100]);\n            yGradient.addColorStop(0, 'white');\n            yGradient.addColorStop(1, 'rgb('+hue[0]+','+hue[1]+','+hue[2]+')');\n            xGradient.addColorStop(0, 'transparent');\n            xGradient.addColorStop(1, 'black');\n            break;\n        case 'hsb_s': // rainbow\n            yGradient.addColorStop(0, 'rgb(255,0,0)');\n            yGradient.addColorStop(1/6, 'rgb(255,255,0)');\n            yGradient.addColorStop(2/6, 'rgb(0,255,0)');\n            yGradient.addColorStop(3/6, 'rgb(0,255,255)');\n            yGradient.addColorStop(4/6, 'rgb(0,0,255)');\n            yGradient.addColorStop(5/6, 'rgb(255,0,255)');\n            yGradient.addColorStop(1, 'rgb(255,0,0)');\n            xGradient.addColorStop(0, 'rgba(0,0,0,'+(1-this.hsb.s/100)+')' );\n            xGradient.addColorStop(1, 'black' );\n            break;\n        case 'hsb_b': // rainbow from saturated to unsaturated\n            var grey = parseInt(this.hsb.b*2.56, 10);\n            yGradient.addColorStop(0, 'rgb(255,0,0)');\n            yGradient.addColorStop(1/6, 'rgb(255,255,0)');\n            yGradient.addColorStop(2/6, 'rgb(0,255,0)');\n            yGradient.addColorStop(3/6, 'rgb(0,255,255)');\n            yGradient.addColorStop(4/6, 'rgb(0,0,255)');\n            yGradient.addColorStop(5/6, 'rgb(255,0,255)');\n            yGradient.addColorStop(1, 'rgb(255,0,0)');\n            xGradient.addColorStop(0, 'rgba('+grey+','+grey+','+grey+','+(1-this.hsb.b/100)+')');\n            xGradient.addColorStop(1, 'rgb('+grey+','+grey+','+grey+')');\n            break;\n        case 'rgb_r':\n            this.cf.globalCompositeOperation = 'lighter';\n            xGradient.addColorStop(0, 'rgb('+this.rgb.r+',255,0)');\n            xGradient.addColorStop(1, 'rgb('+this.rgb.r+',0,0)');\n            yGradient.addColorStop(0, 'rgb('+this.rgb.r+',0,0)');\n            yGradient.addColorStop(1, 'rgb('+this.rgb.r+',0,255)');\n            break;\n        case 'rgb_g':\n            this.cf.globalCompositeOperation = 'lighter';\n            xGradient.addColorStop(0, 'rgb(255,'+this.rgb.g+',0)');\n            xGradient.addColorStop(1, 'rgb(0,'+this.rgb.g+',0)');\n            yGradient.addColorStop(0, 'rgb(0,'+this.rgb.g+',0)');\n            yGradient.addColorStop(1, 'rgb(1,'+this.rgb.g+',255)');\n            break;\n        case 'rgb_b':\n            this.cf.globalCompositeOperation = 'lighter';\n            xGradient.addColorStop(0, 'rgb(0,255,'+this.rgb.b+')');\n            xGradient.addColorStop(1, 'rgb(0,0,'+this.rgb.b+')');\n            yGradient.addColorStop(0, 'rgb(0,0,'+this.rgb.b+')');\n            yGradient.addColorStop(1, 'rgb(255,0,'+this.rgb.b+')');\n            break;\n        }\n        this.cf.beginPath();\n        this.cf.rect(0, 0, 256, 256);\n        this.cf.closePath();\n        this.cf.fillStyle = yGradient;\n        this.cf.fill();\n        this.cf.beginPath();\n        this.cf.rect(0, 0, 256, 256);\n        this.cf.closePath();\n        this.cf.fillStyle = xGradient;\n        this.cf.fill();\n        this.cf.restore();\n        this.movePointer();\n    },\n    startPointer: function(event) {\n        this.offset = this.$circleField.offset();\n        this.calculatePointer(event);\n        $(document).bind('mousemove.global', jQuery.proxy(this, \"calculatePointer\"));\n    },\n    calculatePointer: function(event) {\n        event.preventDefault();\n        this.pointerPos.x = Math.max(0, Math.min(256, event.pageX-this.offset.left));\n        this.pointerPos.y = Math.max(0, Math.min(256, event.pageY-this.offset.top));\n        switch(this.mode){\n        case 'hsb_h':\n            this.$hsb_s.val(parseInt(this.pointerPos.x/2.56, 10));\n            this.$hsb_b.val(100-parseInt(this.pointerPos.y/2.56, 10));\n            break;\n        case 'hsb_s':\n            this.$hsb_h.val(parseInt(this.pointerPos.x/0.71111, 10));\n            this.$hsb_b.val(100-parseInt(this.pointerPos.y/2.56, 10));\n            break;\n        case 'hsb_b':\n            this.$hsb_h.val(parseInt(this.pointerPos.x/0.71111, 10));\n            this.$hsb_s.val(100-parseInt(this.pointerPos.y/2.56, 10));\n            break;\n        case 'rgb_r':\n            this.$rgb_b.val(parseInt(this.pointerPos.x/1.003921, 10));\n            this.$rgb_g.val(255-parseInt(this.pointerPos.y/1.003921, 10));\n            break;\n        case 'rgb_g':\n            this.$rgb_b.val(parseInt(this.pointerPos.x/1.003921, 10));\n            this.$rgb_r.val(255-parseInt(this.pointerPos.y/1.003921, 10));\n            break;\n        case 'rgb_b':\n            this.$rgb_r.val(parseInt(this.pointerPos.x/1.003921, 10));\n            this.$rgb_g.val(255-parseInt(this.pointerPos.y/1.003921, 10));\n            break;\n        }\n        this.movePointer();\n        this.update();\n    },\n    movePointer: function(x, y) {\n        this.pointerPos.x = x >= 0 ? x : this.pointerPos.x;\n        this.pointerPos.y = y >= 0 ? y : this.pointerPos.y;\n        this.cc.clearRect(0,0,256,256);\n        // limit x and y to 0-255 cause we need +1 (=256) space to detect the underlaying color \n        var detectX = Math.min(255, this.pointerPos.x),\n            detectY = Math.min(255, this.pointerPos.y);\n        var background = this.cf.getImageData(detectX, detectY, 1, 1).data;\n        // check if the underlying color is dark or light and set the circle color according to that\n        // -> white circle if the underlying color is dark (treshhold of 128 - where 256 is white) - otherwise black\n        this.cc.strokeStyle = ((background[0]+background[1]+background[2])/3) < 128 ? 'white' : 'black';\n        this.cc.beginPath();\n        this.cc.arc(detectX + 0.5, detectY + 0.5, 5, 0, Math.PI*2, true);\n        this.cc.closePath();\n        this.cc.stroke();\n    },\n    drawPointer: function() {\n        var posX = 0,\n            posY = 0;\n        switch(this.mode){\n        case 'hsb_h':\n            posX = this.hsb.s*2.56;\n            posY = (100-this.hsb.b)*2.56;\n            break;\n        case 'hsb_s':\n            posX = this.hsb.h*0.71111;\n            posY = (100-this.hsb.b)*2.56;\n            break;\n        case 'hsb_b':\n            posX = this.hsb.h*0.71111;\n            posY = (100-this.hsb.s)*2.56;\n            break;\n        case 'rgb_r':\n            posX = this.rgb.b*1.003921;\n            posY = (255-this.rgb.g)*1.003921;\n            break;\n        case 'rgb_g':\n            posX = this.rgb.b*1.003921;\n            posY = (255-this.rgb.r)*1.003921;\n            break;\n        case 'rgb_b':\n            posX = this.rgb.r*1.003921;\n            posY = (255-this.rgb.g)*1.003921;\n            break;\n        }\n        this.movePointer(parseInt(posX, 10), parseInt(posY, 10));\n    },\n    paintSlider: function() {\n        var gradient = this.cs.createLinearGradient(0, 0, 0, 256);\n        this.cs.clearRect(0,0,19,256);\n        switch (this.mode) {\n        case 'hsb_h': // rainbow\n            gradient.addColorStop(0, 'rgb(255,0,0)');\n            gradient.addColorStop(1/6, 'rgb(255,0,255)');\n            gradient.addColorStop(2/6, 'rgb(0,0,255)');\n            gradient.addColorStop(3/6, 'rgb(0,255,255)');\n            gradient.addColorStop(4/6, 'rgb(0,255,0)');\n            gradient.addColorStop(5/6, 'rgb(255,255,0)');\n            gradient.addColorStop(1, 'rgb(255,0,0)');\n            break;\n        case 'hsb_s': // max saturation to unsaturated\n            var brightness = this.hsb.b;\n            if(brightness <= 33) brightness = 33;\n            var saturated = color.rgbFromHsb([this.hsb.h, 100, brightness]);\n            var unsaturated = color.rgbFromHsb([this.hsb.h, 0, brightness]);\n            gradient.addColorStop(0, 'rgb('+saturated[0]+','+saturated[1]+','+saturated[2]+')');\n            gradient.addColorStop(1, 'rgb('+unsaturated[0]+','+unsaturated[1]+','+unsaturated[2]+')');\n            break;\n        case 'hsb_b': // max brightness to black\n            var brightest = color.rgbFromHsb([this.hsb.h, this.hsb.s, 100]);\n            gradient.addColorStop(0, 'rgb('+brightest[0]+','+brightest[1]+','+brightest[2]+')');\n            gradient.addColorStop(1, 'black');\n            break;\n        case 'rgb_r':\n            gradient.addColorStop(0, 'rgb(255,'+this.rgb.g+','+this.rgb.b+')');\n            gradient.addColorStop(1, 'rgb(0,'+this.rgb.g+','+this.rgb.b+')');\n            break;\n        case 'rgb_g':\n            gradient.addColorStop(0, 'rgb('+this.rgb.r+',255,'+this.rgb.b+')');\n            gradient.addColorStop(1, 'rgb('+this.rgb.r+',0,'+this.rgb.b+')');\n            break;\n        case 'rgb_b':\n            gradient.addColorStop(0, 'rgb('+this.rgb.r+','+this.rgb.g+',255)');\n            gradient.addColorStop(1, 'rgb('+this.rgb.r+','+this.rgb.g+',0)');\n            break;\n        }\n        this.cs.beginPath();\n        this.cs.rect(0, 0, 19, 256);\n        this.cs.closePath();\n        this.cs.fillStyle = gradient;\n        this.cs.fill();\n    },\n    startSlider: function(event) {\n        this.offset = this.$slideArea.offset();\n        this.slide(event);\n        $(document).bind('mousemove.global', jQuery.proxy(this, \"slide\"));\n    },\n    slide: function(event) {\n        event.preventDefault();\n        var relativePosition = event.pageY - this.offset.top;\n        if(relativePosition < 0) relativePosition = 0;\n        if(relativePosition > 256) relativePosition = 256;\n        // invert the value because the browsers coordination system has its origin at the top but the slider has its origin at the bottom\n        relativePosition = 256 - relativePosition;\n        this.moveSlider(relativePosition);\n        this.$selectedInput.val(parseInt(relativePosition/this.ratio, 10));\n        this.update();\n    },\n    moveSlider: function(position) {\n        this.$slider.css({'top':(256-position)+'px'});\n    },\n    getHsb: function() {\n        this.hsb.h = this.$hsb_h.val();\n        this.hsb.s = this.$hsb_s.val();\n        this.hsb.b = this.$hsb_b.val();\n    },\n    getRgb: function() {\n        this.rgb.r = this.$rgb_r.val();\n        this.rgb.g = this.$rgb_g.val();\n        this.rgb.b = this.$rgb_b.val();\n    },\n    getHex: function() {\n        var hex = this.$hex.val();\n        var missingLength = 6 - hex.length;\n        if(missingLength === 3){ \n            var parts = hex.split(\"\");\n            hex = parts[0]+parts[0]+parts[1]+parts[1]+parts[2]+parts[2];\n        } else {\n            for(var i = 0; i<missingLength; i++){ \n                hex = \"0\" + hex;\n            }\n        }\n        this.hex = hex;\n    },\n    setHsb: function() {\n        this.$hsb_h.val(this.hsb.h);\n        this.$hsb_s.val(this.hsb.s);\n        this.$hsb_b.val(this.hsb.b);\n    },\n    setRgb: function(r,g,b) {\n        this.$rgb_r.val(r != null ? r : this.rgb.r);\n        this.$rgb_g.val(g != null ? g : this.rgb.g);\n        this.$rgb_b.val(b != null ? b : this.rgb.b);\n    },\n    setHex: function(hex) {\n        var hexcode = hex || this.hex,\n            parts = hexcode.split(\"\");\n        // \"000\" instead of \"000000\"\n        hexcode = (parts[0]===parts[1]) && (parts[2]===parts[3]) && (parts[4]==parts[5]) ? parts[0]+parts[2]+parts[4] : hexcode;\n        this.$hex.val(hexcode);\n    },\n    hsbToRgb: function() {\n        var rgb = color.rgbFromHsb([this.hsb.h, this.hsb.s, this.hsb.b]);\n        this.rgb.r = rgb[0];\n        this.rgb.g = rgb[1];\n        this.rgb.b = rgb[2];\n        this.setRgb();\n    },\n    rgbToHex: function(){\n        this.hex = color.hexFromRgb([this.rgb.r, this.rgb.g, this.rgb.b]);\n        this.setHex();\n    },\n    hexToRgb: function(){\n        var rgb = color.rgbFromHex(this.hex);\n        this.rgb.r = rgb[0];\n        this.rgb.g = rgb[1];\n        this.rgb.b = rgb[2];\n        this.setRgb();\n    },\n    setNewColor: function() {\n        this.$newColor.css('background', '#'+this.hex);\n    },\n    rgbToHsb: function() {\n        var hsb = color.hsbFromRgb([this.rgb.r, this.rgb.g, this.rgb.b]);\n        this.hsb.h = hsb[0];\n        this.hsb.s = hsb[1];\n        this.hsb.b = hsb[2];\n        this.setHsb();\n    },\n    addSwatch: function(title, hex) {\n        return $('<span class=\"swatch\" />')\n                .attr({'title': title, 'data-hex': hex})\n                .css({'background': '#'+hex})\n                .bind('click', {self: this}, this.handleSwatch);\n    },\n    handleSwatch: function(e){\n        e.stopPropagation();\n        var self = e.data.self;\n        // if alt is pressed while clicking: remove swatch\n        if(e.altKey){\n            // find out the swatches position in the swatch array\n            var position = 0;\n            var family = $(this).parent().children();\n            for(var i = 0, length = family.length; i<length; i++){\n                if(this===family[i]){ position = i; }\n            }\n            // slice out the swatch from the swatch array (method by John Resig)\n            var rest = self.swatches.slice(position + 1);\n            self.swatches.length = position;\n            self.swatches.push.apply(self.swatches, rest);\n            localStorage[\"swatches\"] = JSON.stringify(self.swatches);\n            $(this).remove();\n        }\n        // else get that swatches color\n        else {\n            var hex = $(this).attr('data-hex');\n            self.setHex(hex);\n            self.update('hex');\n        }\n    },\n    okAction: function(){\n        this.close(\"ok\");\n    },\n    cancelAction: function(){\n        this.close(\"cancel\");\n    },\n    close: function(mode){\n        var rgb;\n        switch(mode){\n            case \"ok\":\n                this.setCurrentColor();\n                this.colorHistory.push(this.currentColor);\n                rgb = color.rgbFromHex(this.hex);\n                break;\n            case \"cancel\":\n                rgb = color.rgbFromHex(this.currentColor);\n                break;\n        }\n        if(this.callback) this.callback.call(this.thisArg, rgb);\n        this.callback = null;\n        this.open = false;\n        hidePickArea();\n        nav.goTo(-1);\n    },\n    newSwatch: function(event){\n        var self = event.data.self;\n        var title = prompt(lang.ColorSwatchName,\"Swatch \"+self.swatches.length);\n        if(title){\n            self.$swatchHolder.append(self.addSwatch(title, self.hex));\n            self.swatches.push({'title': title, 'hex': self.hex});\n            localStorage[\"swatches\"] = JSON.stringify(self.swatches);\n        }\n    },\n    drawSwatches: function(){\n        var swatches = $('<div/>');\n        for(var i = 0, length = this.swatches.length; i<length; i++){\n            swatches.append( this.addSwatch(this.swatches[i].title, this.swatches[i].hex) );\n        }\n        this.$swatchHolder.append(swatches);\n    },\n    selectInput: function(pos){\n        this.mode = this.$radioInputs.eq(pos).val();\n        this.$selectedInput = this.$textInputs.eq(pos);\n        this.$selectedInput.focus();\n        this.max = this.$selectedInput.attr('data-max');\n        this.ratio = 256/this.max;\n        this.moveSlider(this.$selectedInput.val()*this.ratio);\n        this.drawPointer();\n    },\n    findCheckedInput: function(){\n        for (var i = 0; i<6; i++) {\n            if (this.$radioInputs.eq(i).attr('checked')) {\n                this.selectInput(i);\n            }\n        }\n    },\n    clickAll: function(event) {\n        var self = event.data.self;\n        var $currentRadio = $('input[type=radio]', this);\n        var $currentText = $('input[type=text]', this);\n        var clickTargetType = $(event.target).attr('type');\n        switch(clickTargetType){\n            case \"radio\":\n                $currentText.focus();\n                self.mode = $currentRadio.val();\n                self.max = $currentText.attr('data-max');\n                self.ratio = 256/self.max;\n                self.$selectedInput = $currentText;\n                self.update();\n                self.moveSlider($currentText.val()*self.ratio);\n                self.drawPointer();\n                break;\n            case \"text\": self.update(); break;\n            case \"number\": self.update(); break;\n            default:\n                $currentRadio.attr('checked', 'ckecked');\n                $currentText.focus();\n                self.mode = $currentRadio.val();\n                self.max = $currentText.attr('data-max');\n                self.update();\n        }\n    },\n    init: function() {\n        this.$element = $('#colorpicker');\n        this.$textHolder = this.$element.find('li');\n        this.$hexHolder = $('#hex_holder');\n        this.$swatchHolder = $('#swatches');\n        this.$currentColor = $('#current_color');\n        this.$newColor = $('#new_color');\n        this.$textInputs = this.$element.find('li input[type=text]');\n        this.$radioInputs = this.$element.find('li input[type=radio]');\n        this.$hsb_h = $('#hsb_h');\n        this.$hsb_s = $('#hsb_s');\n        this.$hsb_b = $('#hsb_b');\n        this.$rgb_r = $('#rgb_r');\n        this.$rgb_g = $('#rgb_g');\n        this.$rgb_b = $('#rgb_b');\n        this.$hex = $('#hex');\n        this.$button_ok = $('#color_ok');\n        this.$button_cancel = $('#color_cancel');\n        this.$circleField = $('#circle');\n        this.$slideArea = $('#color_slider');\n        this.$slider = this.$slideArea.find('> div');\n        this.cf = $('#field').get(0).getContext('2d');\n        this.cc = $('#circle').get(0).getContext('2d');\n        this.cs = this.$slideArea.find('canvas').get(0).getContext('2d');\n        \n        if(localStorage[\"swatches\"]) this.swatches = JSON.parse(localStorage[\"swatches\"]);\n        this.$currentColor.click( jQuery.proxy(this, \"pickCurrentColor\") );\n        this.$button_ok.click( jQuery.proxy(this, \"okAction\") );\n        this.$button_cancel.click( jQuery.proxy(this, \"cancelAction\") );\n        this.$circleField.mousedown( jQuery.proxy(this, \"startPointer\") );\n        this.$slideArea.mousedown( jQuery.proxy(this, \"startSlider\") );\n        this.$textHolder.bind('click', {self: this}, this.clickAll);\n        this.$hexHolder.click( jQuery.proxy(this, \"clickHex\") );\n        this.$hex.bind({\n            focus: function(){ numbers.initHexField(this, 'color'); },\n            keydown: numbers.restrictCharacters,\n            keyup: numbers.keyUp\n        });\n        this.$textInputs.bind({\n            focus: function(){ numbers.initNumberField(this, 'color'); },\n            keydown: numbers.restrictCharacters,\n            keyup: numbers.keyUp,\n            blur: numbers.validateInput\n        });\n        this.$swatchHolder.bind('click', {self: this}, this.newSwatch);\n        // find initial checked input\n        this.findCheckedInput();\n        // draw swatches\n        this.drawSwatches();\n        this.update();\n    }\n};"
  },
  {
    "path": "js/css.js",
    "content": "var css = {\n    colors: {\n        'rgb(0,0,0)': \"black\",\n        'rgb(255,255,255)': \"white\"\n    },\n    gradientDirections: {\n        315: \"to bottom right\",\n        270: \"to bottom\",\n        225: \"to bottom left\",\n        180: \"to left\",\n        135: \"to top left\",\n        90: \"to top\",\n        45: \"to top right\",\n        0: \"to right\"\n    },\n    /**\n     * @method  cssGradient    \n     * @param   gradient {object}\n     * @return  {array} decoded color stops: rgb strings\n     * @example cssGradient([0,0,0], 10, [255,255,255]) returns \"-moz-linear-gradient(top, 'rgb(0,0,0)', 'rgb(25,25,25) 10%', 'rgb(255,255,255)')\"\n     */\n    cssGradient: function(stops, angle, style){\n        var tempStops, shape = \"\", cssString = \"\", pos;\n\n        switch(style){\n            case \"linear\": case \"reflected\":\n                tempStops = style === \"reflected\" ? tools.reflectStops(stops) : stops;\n\n                if (this.gradientDirections[angle]) {\n                    pos = this.gradientDirections[angle];\n                } else {\n                    pos = angle+\"deg\";\n                }\n                if(pos == \"to bottom\"){\n                    cssString = 'linear-gradient('+ tools.decodeStops(tempStops).join(\", \") +')';\n                } else {\n                    cssString = 'linear-gradient('+ pos +', '+ tools.decodeStops(tempStops).join(\", \") +')';\n                }\n                break;\n            case \"contain\":\n                cssString = 'radial-gradient(center center, '+shape+'contain, '+ tools.decodeStops(stops).join(\", \") +')';\n                break;\n            case \"cover\":\n                cssString = 'radial-gradient(center center, '+shape+'cover, '+ tools.decodeStops(stops).join(\", \") +')';\n                break;\n        }\n        return cssString;\n    },\n    drawGradient: function(style){\n        var cssString = \"\",\n            model = style.background, \n            tempAngle, tempOpacity, tempStops;\n        \n        if(model.isActive) {\n            tempAngle = model.angle+180;\n            if(tempAngle >= 360) tempAngle -= 360;\n            tempOpacity = model.opacity;\n            if(tempOpacity != 100){\n                tempOpacity = model.opacity/100;\n            }\n            if(!model.translucidStops) model.translucidStops = $.extend(true, [], model.stops);\n            \n            // inject opacity into the rgb values or slice off the injection if opacity is 100\n            for(var i=0, l=model.translucidStops.length; i<l; i++){\n                switch(model.stops[i].length){\n                case 2: // [[255,255,255], 45]\n                    if(tempOpacity === 100){\n                        model.translucidStops[i][0] = model.translucidStops[i][0].slice(0,3);\n                    } else {\n                        model.translucidStops[i][0][3] = tempOpacity;\n                    }\n                    break;\n                case 3: case 4: // [255,255,255] or [255,255,255,0.5]\n                    if(tempOpacity === 100){\n                        model.translucidStops[i] = model.translucidStops[i].slice(0,3);\n                    } else {\n                        model.translucidStops[i][3] = tempOpacity;\n                    }\n                    break;\n                }\n            }\n            tempStops = model.translucidStops.slice(0); // no deep copy!\n            if(model.hasGlobalLight) tempAngle = style.globalAngle;\n            if(model.isReverse) tempStops = tools.reverseStops(tempStops);\n            cssString = this.cssGradient( tempStops, tempAngle, model.style );\n        }\n        return cssString;\n    },\n    boxShadow: function(style){\n        var cssString = \"\", radiants, dropColor, tempSize, tempX, tempY, tempBlur,\n            shadows = [\"dropShadow\", \"innerShadow\"];\n        \n        for(var i=0; i<shadows.length; i++){\n            var model = style[shadows[i]];\n            if(model.isActive){\n                if(cssString != \"\") cssString += \", \";\n                if(model.hasGlobalLight) model.angle = style.globalAngle;\n                radiants = (Math.PI / 180) * model.angle;\n                model.dropX = Math.round(-model.distance * Math.cos(radiants));\n                model.dropY = Math.round(model.distance * Math.sin(radiants));\n                tempX = model.dropX === 0 ? \"0 \" : model.dropX + \"px \";\n                tempY = model.dropY === 0 ? \"0 \" : model.dropY + \"px \";\n                tempBlur = model.blur === 0 ? \"0 \" : model.blur + \"px \";\n                tempSize = model.size === 0 ? \"\" : model.size+\"px \";\n                if(model.opacity != 100){\n                    dropColor = model.color.slice(0);\n                    dropColor.push(model.opacity/100);\n                } else {\n                    dropColor = model.color;\n                }\n                if(model.isInset) cssString += \"inset \";\n                cssString += tempX + tempY + tempBlur + tempSize + tools.toColor(dropColor);\n            }\n        }\n        return cssString;\n    },\n    border: function(style){\n        var cssString = \"\",\n            dropColor, model = style.border;\n        if(model.isActive){\n            if(model.opacity != 100){\n                dropColor = model.color.slice(0);\n                dropColor.push(model.opacity/100);\n            } else {\n                dropColor = model.color;\n            }\n            cssString += model.size+'px '+model.style+' '+tools.toColor(dropColor);\n        }\n        return cssString;\n    },\n    borderRadius: function(style){\n        var cssObject = { \"border-radius\": 0 },\n            model = style.borderRadius;\n        \n        if(model.isActive){\n            var radii = [];\n            for(var i=0; i<4; i++){\n                var radius = model.radii[i]; // [pos, unit]\n                if(radius[0] !== 0){\n                    radii[i] = radius[0] + radius[1];\n                } else {\n                    radii[i] = 0;\n                }\n            }\n            // check if radii are the same\n            if(    radii[0] === radii[1] &&\n                radii[1] === radii[2] &&\n                radii[2] === radii[3] &&\n                radii[3] === radii[0] ){\n                    cssObject[\"border-radius\"] = radii[0];\n            } else {\n                var topLeft = radii[0],\n                    topRight = radii[1],\n                    bottomRight = radii[2],\n                    bottomLeft = radii[3];\n            \n                if(topRight === bottomLeft){\n                    if(topLeft === bottomRight){\n                        cssObject[\"border-radius\"] = topLeft+\" \"+topRight;\n                    } else {\n                        cssObject[\"border-radius\"] = topLeft+\" \"+topRight+\" \"+bottomRight;\n                    }\n                } else {\n                    delete cssObject[\"border-radius\"];\n                    if(topLeft !== 0){\n                        $.extend( cssObject, {'border-top-left-radius': topLeft} );\n                    }\n                    if(topRight !== 0){\n                        $.extend( cssObject, {'border-top-right-radius': topRight} );\n                    }\n                    if(bottomRight !== 0){\n                        $.extend( cssObject, {'border-bottom-right-radius': bottomRight} );\n                    }\n                    if(bottomLeft !== 0){\n                        $.extend( cssObject, {'border-bottom-left-radius': bottomLeft} );\n                    }\n                }\n            }\n        } // if borderRadius active\n        return cssObject;\n    },\n    displayCss: function(style){\n        var cssObj = {\n            'background': this.drawGradient(style),\n            'border': this.border(style),\n            'box-shadow': this.boxShadow(style)\n        };\n\n        $.extend(true, cssObj, this.borderRadius(style));\n        return cssObj;\n    },\n    render: function(){\n        $layer.css( this.displayCss(currentStyle) );\n    }\n};"
  },
  {
    "path": "js/gradienteditor.js",
    "content": "var gradienteditor = {\n    callback: null,\n    thisArg: null,\n    changed: false,\n    puff: null,\n    gradientDimensions: null,\n    gradientOffset: null,\n    prevStops: null,\n    currentGradient: null,\n    currentPick: null,\n    currentStopColor: null,\n    currentPosition: null,\n    currentColorField: null,\n    tempStops: null,\n    gradients: [\n        {'name': \"Black and White\", 'stops': [[255, 255, 255], [0, 0, 0]] },\n        {'name': \"Plain Gray\", 'stops': [[252, 252, 252], 23, [[242, 242, 242], 12], 89, [191, 191, 191]] },\n        {'name': \"Be Water\", 'stops': [[209, 237, 233], 23, [[177, 228, 220], 12], 89, [0, 191, 162]] },\n        {'name': \"Rainbow\", 'stops': [[255, 0, 0], [[255, 0, 255], 15], [[0, 0, 255], 33], [[0, 255, 255], 49], [[0, 255, 0], 67], [[255, 255, 0], 84], [255, 0, 0]] },\n        {'name': \"Teal, Magenta, Yellow\", 'stops': [[255, 185, 13], [[204, 0, 69], 50], [0, 153, 128]] },\n        {'name': \"Peach\", 'stops': [[242, 171, 43], [225, 123, 25]] },\n        {'name': \"Yellow, Orange\", 'stops': [[255, 238, 88], [[252, 199, 54], 28], [[241, 141, 70], 67], [[233, 93, 59], 89], [228, 42, 50]] },\n        {'name': \"PS i love you\", 'stops': [[22,127,232],[0,60,123]] },\n        {'name': \"Vista\", 'stops': [[116,116,116], [[109,109,109], 50], [[126,126,126], 50], [133,133,133]]}\n    ],\n    edit: function(stops, callback, thisArg){\n        var name = lang.Custom;\n        this.callback = callback;\n        this.thisArg = thisArg;\n        this.prevStops = stops;\n        // if the gradient is known, display its name\n        for(var i=0, l=this.gradients.length; i<l; i++){\n            if(this.gradients[i].stops === stops){\n                name = this.gradients[i].name;\n            }\n        }\n        // if the gradient is new, set changed to true to allow it to be stored\n        if(name === lang.Custom) this.changed = true;\n        this.setGradient({ name: name, stops: stops });\n        nav.goTo(2);\n    },\n    picker: {\n        init: function(color, position){\n            this.color = color;\n            this.position = position;\n            this.$el = this.create();\n            this.$colorField = this.$el.find('.color_field');\n            return this.$el;\n        },\n        create: function(){\n            $('<div class=\"picker bottom\" />')\n                .css({ 'left': position+'%' })\n                .bind({\n                    mousedown: $.proxy( this, \"select\" ),\n                    dblclick: $.proxy( this, \"pick\" )\n                })\n                .append($('<div class=\"arrow\" />'))\n                .append($('<div class=\"box\" />')\n                    .append($('<div class=\"color_field\" />').css({ 'background': tools.toColor(color) }))\n                );\n        },\n        select: function(){\n            // fire \"unselect\" event\n            // show middlepoints\n            // add active class to this one\n            // show color and position below\n            // add pick event listener to the colorField\n            // add event listener to the input field to update the position\n            // add event listener on \"unselect\" to unselect\n        },\n        blur: function(){\n            // remove active class\n            // hide middle points\n            // remove \"unselect\" listener\n        },\n        pick: function(){\n            colorpicker.pick(this.color, this.updateColor, this);\n        },\n        updateColor: function(newColor){\n            var colorString = color.toColor(newColor);\n            this.color = newColor;\n            this.$stopColor.css(\"background\", colorString);\n            this.$colorField.css(\"background\", colorString);\n            // add color to stops\n        },\n        updatePosition: function(newPos){\n            this.position = newPos;\n            // update position at stops\n        }\n    },\n    middlepoint: {\n        threshhold: 5,\n        position: null,\n        percentage: null,\n        init: function(position, percentage){\n            this.position = position;\n            this.percentage = percentage;\n            this.$el = this.create();\n            return this.$el;\n        },\n        create: function(){\n            return $('<span class=\"middlepoint bottom\"><span /></span>')\n                .attr({\n                    'data-percentage': this.percentage,\n                })\n                .css({ 'left': this.position+'%' })\n                .bind(mousedown, $.proxy( this, \"startMoving\" ));\n        },\n        startMoving: function(event){\n            event.preventDefault();\n            this.select();\n            gradienteditor.gradientOffset = gradienteditor.$gradient.offset();\n            $(document).bind('mousemove.global', $.proxy(this, \"move\") );\n            // add event listener to listen to input field changes\n            // show percentage in the input field\n        },\n        move: function(event){\n            \n            // stay in the range of the previous and following step +/- 5 (min 5, max 95)\n            // if position is 55-65 round to 50\n            // update input field value\n        },\n        show: function(){\n            this.$el.addClass('visible');\n        },\n        hide: function(){\n            this.$el.removeClass('visible');\n        },\n        select: function(){\n            this.$el.addClass('selected');\n        },\n        unselect: function(){\n            this.$el.removeClass('selected');\n        }\n    },\n    addPicker: function(position, rgb){\n        return $('<div class=\"picker bottom\" />')\n            .css({ 'left': position+'%' })\n            .attr({\n                'data-color': JSON.stringify(rgb),\n                'data-percentage': position\n            })\n            .bind({\n                mousedown: $.proxy( this, \"selectPicker\" ),\n                dblclick: $.proxy( this, \"startPicking\" )\n            })\n            .append($('<div class=\"arrow\" />'))\n            .append($('<div class=\"box\" />')\n                .append($('<div class=\"color_field\" />').css({ 'background': tools.toColor(rgb) }))\n            );\n    },\n    selectPicker: function(event){\n        event.preventDefault();\n        var obj = $(event.target).parents('.picker');\n        this.selectStop(obj);\n        this.showMiddlepoints(obj);\n        this.gradientOffset = this.$gradient.offset();\n        this.extract();\n        $(document).bind('mousemove.global', $.proxy(this, \"movePicker\") );\n        $(document).one('mouseup', $.proxy(this, \"stopPicking\") );\n    },\n    startPicking: function(event){\n        event.preventDefault();\n        colorpicker.pick(this.currentStopColor, this.updatePicker, this);\n    },\n    stopPicking: function(){\n        if(this.changed){\n            this.currentPick.attr('data-percentage', this.currentPercentage);\n        }\n    },\n    extract: function(){\n        this.tempStops = this.expand( $.extend(true, [], this.currentGradient.stops) );\n        this.tempStops.splice(this.currentPosition,1);\n    },\n    inject: function(percentage){\n        if(this._percentage === undefined || percentage !== this._percentage){\n            var injectedStops = $.extend(true, [], this.tempStops),\n                pos = injectedStops.length,\n                stop = [this.currentStopColor, percentage];\n\n            for(var i = 0, l = injectedStops.length; i<l; i++){\n                var tempStop = injectedStops[i];\n                if(typeof tempStop === 'object' && tempStop[1] > percentage){\n                    pos = i;\n                    break;\n                }\n            }\n            injectedStops.splice(pos, 0, stop);\n            this.updateGradient( this.shrink(injectedStops) );\n            this._percentage = percentage;\n        }\n    },\n    expand: function(stops){\n        var last = stops.length-1;\n        if(stops[0].length === 3) stops[0] = [stops[0], 0];\n        if(stops[last].length === 3) stops[last] = [stops[last], 100];\n        return stops;\n    },\n    shrink: function(stops){\n        var last = stops.length-1;\n        if(stops[0][1] === 0) stops[0] = stops[0][0];\n        if(stops[last][1] === 100) stops[last] = stops[last][0];\n        return stops;\n    },\n    getArrayPos: function(percentage, stops){\n        for(var i = 0, l = stops.length; i<l; i++){\n            var stop = stops[i];\n            if(typeof stop === 'object'){\n                if(percentage === 0 || percentage === 100){\n                    return percentage === 0 ? 0 : l-1;\n                }\n                if(stop[1] === percentage){\n                    return i;\n                }\n            }\n        }\n    },\n    movePicker: function(event){\n        event.preventDefault();\n        var x = Math.max(0, Math.min(this.gradientDimensions.width, event.pageX-this.gradientOffset.left)),\n            y = 33,\n            percentage = Math.round(x/this.gradientDimensions.width*100);\n        if( // out of range - remove gesture\n            event.pageX < (this.gradientOffset.left - 26) ||\n            event.pageX > (this.gradientOffset.left + this.gradientDimensions.width + 26) ||\n            event.pageY < (this.gradientOffset.top - 26) ||\n            event.pageY > (this.gradientOffset.top + this.gradientDimensions.height + 69) ){\n                // more than 2 color stops \n                if(!this._hasMinimumSize){\n                    x = event.pageX - this.gradientOffset.left;\n                    y = event.pageY - this.gradientOffset.top;\n                \n                    if (this.puff === null) {\n                        this.puff = $('<div id=\"puff\" />').appendTo($body);\n                        $(document).bind('mouseup.puff', $.proxy( this, \"removeCurrentPicker\" ));\n                    }\n                    this.puff.css({ 'left': event.pageX+2, 'top': event.pageY+16 });\n                    this.updateGradient( this.shrink(this.tempStops) );\n                }    \n        }\n        else {\n            // move picker\n            this.currentPercentage = percentage;\n            this.$stopLocation.val(percentage);\n            this.inject(percentage);\n            \n            if(!this.changed){\n                this.$gradientName.val(lang.Custom);\n                this.changed = true;\n            };\n            \n            if(this.puff != null){\n                $(document).unbind('mouseup.puff');\n                $('#puff').remove();\n                this.puff = null;\n            }\n        }\n        \n        $(this.currentPick).css({ 'left': x+'px', 'top': y+'px' });\n    },\n    removeCurrentPicker: function(event){\n        this.puff = null;\n        $('#puff').remove();\n        $(this).unbind(event);\n    },\n    updatePicker: function(newColor){\n        var colorString, stops;\n        // newColor RGB-{Array}\n        if(!this.changed){\n            this.$gradientName.val(lang.Custom);\n            this.changed = true;\n        };\n        colorString = tools.toColor(newColor);\n        $(this.currentPick).attr('data-color', JSON.stringify(newColor));\n        this.currentColorField.css(\"background\", colorString);\n        this.$stopColor.css(\"background\", colorString);\n        stops = gradienteditor.currentGradient.stops;\n        // search for the position and inject new color\n        if(this.currentPosition > 0 && this.currentPosition < stops.length-1){\n            stops[this.currentPosition][1] = newColor;\n        }\n        else {\n            stops[this.currentPosition] = newColor;\n        }\n        this.updateGradient(stops);\n    },\n    addMiddlepoint: function(position, realpos){\n        return $('<span class=\"middlepoint bottom\"><span /></span>')\n            .attr({\n                'data-percentage': realpos,\n            })\n            .css({ 'left': position+'%' })\n            .bind({\n                mousedown: function(e){ \n                    gradienteditor.selectStop(this);\n                    //gradienteditor.selectMiddlePoint(this);\n                }\n            });\n    },\n    updateGradient: function(stops){\n        gradienteditor.currentGradient.stops = stops;\n        this.$gradient.css('background', css.cssGradient( stops, 0, \"linear\" ));\n        if(gradienteditor.callback) gradienteditor.callback.call(gradienteditor.thisArg, stops);\n    },\n    setGradient: function(gradient){\n        this.hideStop();\n        this.currentGradient = $.extend(true, [], gradient);\n        this.$gradient.css('background', css.cssGradient( this.currentGradient.stops, 0, \"linear\" ));\n        this.$gradientName.val(this.currentGradient.name);\n        this.$gradient.children().remove();\n        var helpers = $('<div/>');\n        for(var i=0,length = this.currentGradient.stops.length; i<length; i++){\n            var stop = this.currentGradient.stops[i];\n            var pos, color;\n            switch(typeof stop){\n            case 'object': // => [255,255,255] or [[255,255,255], 33]\n                if(stop.length === 3){ // => [255,255,255]\n                    color = stop;\n                    pos = i === 0 ? 0 : 100;\n                }\n                else {\n                    color = stop[0];\n                    pos = stop[1];                  \n                }\n                helpers.append( this.addPicker(pos, color) );\n                if(typeof this.currentGradient.stops[i+1] !== 'number' && i != length-1){\n                    var nextStop = this.currentGradient.stops[i+1];\n                    var nextPos = nextStop.length !== 3 ? nextStop[1] : 100;\n                    helpers.append( this.addMiddlepoint(tools.getCenter(pos, nextPos), 50) );\n                }\n                break;\n            case 'number':\n                var middlepoint = tools.getMiddlepoint(this.currentGradient.stops[i-1], stop, this.currentGradient.stops[i+1]);\n                helpers.append( this.addMiddlepoint(middlepoint[1], middlepoint[1]) );\n                break;\n              }\n        }\n        this.$gradient.append(helpers);\n    },\n    addGradientPreset: function(name, stops){\n        var preset = $('<div class=\"swatch\" />')\n                .attr({'title': name})\n                .css({\n                    'background': css.cssGradient( stops, 135, \"linear\" )\n                })\n                .bind('click', $.proxy( this, \"handlePreset\" ))\n         return preset.get(0);\n    },\n    handlePreset: function(e){\n        e.stopPropagation();\n        // find out the gradients position in the gradient array\n        var family = $(e.target).parent().children();\n        var pos = family.index(e.target);\n        // if alt is pressed while clicking: remove gradient\n        if(e.altKey){\n            // slice out the gradient from the gradient array (method by John Resig)\n            var rest = this.gradients.slice(pos + 1);\n            this.gradients.length = pos;\n            this.gradients.push.apply(this.gradients, rest);\n            localStorage[\"gradients\"] = JSON.stringify(this.gradients);\n            $(e.target).remove();\n        }\n        else {\n            // else get the gradient\n            this.setGradient(this.gradients[pos]);\n            this.updateGradient(this.gradients[pos].stops);\n           }\n    },\n    showStop: function(pos, color){\n        this.$stopLocation.prop(\"disabled\", false).val(pos).parent().removeClass(\"disabled\");\n        if (color !== null) {\n            if(!this._hasMinimumSize) this.$removeStop.prop(\"disabled\", false);\n            this.$stopColor.css({'background-color': color}).parent().removeClass(\"disabled\");\n            this.$stopColor.bind('mousedown', $.proxy( this, \"startPicking\" ));\n        }\n        else {\n            this.$removeStop.prop(\"disabled\", true);\n            this.$stopColor.css({'background-color': 'transparent'}).parent().addClass(\"disabled\");\n        }\n    },\n    updateStopColor: function(color){\n        this.$stopColor.css({'background-color': color});\n    },\n    hideStop: function(){\n        this.$removeStop.prop(\"disabled\", true);\n        this.$stopLocation.prop(\"disabled\", true).val(\"\").parent().addClass(\"disabled\");\n        this.$stopColor.css({'background-color': 'transparent'}).parent().addClass(\"disabled\");\n    },\n    selectStop: function(object){\n        var $o = $(object), color;\n        this.currentPick = $o;\n        this.currentPercentage = parseInt($o.attr('data-percentage'), 10);\n        this.currentPosition = this.getArrayPos(this.currentPercentage, this.currentGradient.stops);\n        this.currentColorField = $o.find('.color_field');\n        color = $o.attr('data-color');\n        this.currentStopColor = color ? JSON.parse(color) : null;\n        this._hasMinimumSize = this.currentGradient.stops.length == 2 ? true : false;\n        this.showStop(this.currentPercentage, this.currentStopColor);\n        $o.siblings().removeClass('selected');\n        $o.addClass('selected');\n    },\n    showMiddlepoints: function(object){\n        $(object).siblings('span').removeClass('visible');\n        $(object).next('span').add($(object).prev('span')).addClass('visible');\n    },\n    cancelAction: function(){\n        gradienteditor.updateGradient(gradienteditor.prevStops);\n        nav.goTo(1);\n    },\n    okAction: function(){\n        nav.goTo(1);\n    },\n    newAction: function(){\n        if(this.changed){\n            var newGradient = {\n                'name': this.$gradientName.val(),\n                'stops': this.currentGradient.stops\n            };\n            this.gradients.push(newGradient);\n            this.renderPresets([newGradient]);\n            localStorage[\"gradients\"] = JSON.stringify(this.gradients);\n            this.changed = false;\n        };\n    },\n    renderPresets: function(gradients){\n        var presets = document.createDocumentFragment();\n        for(var i = 0, length = gradients.length; i<length; i++){\n            presets.appendChild( this.addGradientPreset(gradients[i].name, gradients[i].stops) );\n        }\n        this.$gradientPresets.append(presets);\n    },\n    init: function(){\n        this.$o = $('#gradient_editor');\n        this.$gradientPresets = $('#gradient_presets');\n        this.$gradientName = $('#gradient_name');\n        this.$gradientHolder = $('#gradient_holder');\n        this.$gradient = $('#gradient');\n        this.$stopColor = $('#stop_color');\n        this.$stopLocation = $('#stop_location');\n        this.$removeStop = $('#remove_stop');\n        this.$okButton = $('#gradient_ok');\n        this.$cancelButton = $('#gradient_cancel');\n        this.$newButton = $('#gradient_new');\n        \n        if(localStorage[\"gradients\"]) this.gradients = JSON.parse(localStorage[\"gradients\"]);\n        this.currentGradient = this.gradients[0];\n        this.setGradient(this.currentGradient);\n        // draw gradient presets\n        this.renderPresets(this.gradients);\n        \n        this.$removeStop.click( $.proxy( this, \"removeCurrentPicker\") );\n        this.$cancelButton.click( $.proxy( this, \"cancelAction\" ) );\n        this.$okButton.click( $.proxy( this, \"okAction\" ) );\n        this.$newButton.click( $.proxy( this, \"newAction\" ) );\n        this.$gradientName.mousedown( function(e){ e.stopPropagation(); });\n        this.$stopLocation.bind({\n            mousedown: function(e){ e.stopPropagation(); },\n            focus: function(e){ numbers.initNumberField(this, 'style'); },\n            keydown: numbers.restrictCharacters,\n            keyup: numbers.keyUp,\n            blur: numbers.validateInput\n        });\n        \n        this.gradientDimensions = { 'width': this.$gradient.width(), 'height': this.$gradient.height() };\n    }\n};"
  },
  {
    "path": "js/localization.js",
    "content": "var localization = {\n        en: {\n            \"Color\": \"Color\",\n            \"Opacity\": \"Opacity\",\n            \"Angle\": \"Angle\",\n            \"Distance\": \"Distance\",\n            \"Spread\": \"Spread\",\n            \"Size\": \"Size\",\n            \"DropShadow\": \"Drop Shadow\",\n            \"InnerShadow\": \"Inner Shadow\",\n            \"Background\": \"Background\",\n            \"Border\": \"Border\",\n            \"new\": \"new\",\n            \"current\": \"current\",\n            \"PickAColor\": \"Pick a Color\",\n            \"GradientEditor\": \"Gradient Editor\",\n            \"Ok\": \"Ok\",\n            \"Cancel\": \"Cancel\",\n            \"NewStyle\": \"New Style\",\n            \"ColorSwatchName\": \"Color Swatch Name\",\n            \"ClosestValueInserted\": \"Closest value inserted\",\n            \"AnIntegerBetween\": \"An integer between\",\n            \"and\": \"and\",\n            \"isRequired\": \"is required\",\n            \"Custom\": \"Custom\",\n            \"DeleteStyle\": \"Delete Style\"\n        },\n        de: {\n            \"Color\": \"Farbe\",\n            \"Opacity\": \"Transparenz\",\n            \"Angle\": \"Winkel\",\n            \"Distance\": \"Abstand\",\n            \"Spread\": \"Umfang\",\n            \"Size\": \"Größe\",\n            \"DropShadow\": \"Schlagschatten\",\n            \"InnerShadow\": \"Innerer Schatten\",\n            \"Background\": \"Hintergrund\",\n            \"Border\": \"Rahmen\",\n            \"new\": \"neu\",\n            \"current\": \"momentan\",\n            \"PickAColor\": \"Wähl eine Farbe\",\n            \"GradientEditor\": \"Verlaufs Editor\",\n            \"Ok\": \"Ok\",\n            \"Cancel\": \"Abbrechen\",\n            \"NewStyle\": \"Neuer Style\",\n            \"ColorSwatchName\": \"Farbfeld Name\",\n            \"ClosestValueInserted\": \"Naheliegendste Zahl eingesetzt\",\n            \"AnIntegerBetween\": \"Eine Zahl zwischen\",\n            \"and\": \"und\",\n            \"isRequired\": \"wird benötigt\",\n            \"Custom\": \"Unbekannt\",\n            \"DeleteStyle\": \"Style löschen\"\n        }\n}"
  },
  {
    "path": "js/numbers.js",
    "content": "var numbers = {\n    regex: new RegExp(''),\n    min: 0,\n    max: 0,\n    temporaryMode: \"\",\n    match: false,\n    pressed: false,\n    speed: 0,\n    value: \"\",\n    type: \"\",\n    direction: 0,\n    DIGITS: /[-1234567890]/g,\n    HEXCODE: /[A-Fa-f0-9]/g,\n    // control Keys: 8 = backspace, 9 = tab, 13 = enter, 35 = home, 37 = left, 38 = top, 39 = right, 40 = down\n    controlKeys: [ 8, 9, 13, 35, 36, 37, 38, 39, 40 ],\n    // cut, copy & paste keys are 67 = c, 86 = v and 88 = x additional 65 = a ('select all')\n    cutCopyPasteKeys: [ 65, 67, 86, 88 ],\n    numpadKeys: { 96: \"0\", 97: \"1\", 98: \"2\", 99: \"3\", 100: \"4\", 101: \"5\", 102: \"6\", 103: \"7\", 104: \"8\", 105: \"9\" },\n    initNumberField: function(input, type) {\n        numbers.type = type;\n        numbers.$input = $(input);\n        numbers.max = numbers.$input.attr('data-max');\n        numbers.min = numbers.$input.attr('data-min');\n        numbers.restrict = numbers.DIGITS;\n        numbers.temporaryMode = numbers.$input.attr('id');\n        switch (numbers.max) {\n        case \"10\": // 0-10\n            numbers.regex.compile(\"^(0|([1-9]{1}|10))$\");\n            break;\n        case \"100\": // 0-100\n            numbers.regex.compile(\"^(0|([1-9]{1}[0-9]{0,1}|100))$\");\n            break;\n        case \"200\": // 0-200\n            numbers.regex.compile(\"^(0|([1-9]{1}[0-9]{0,1}|[1]{1}[0-9]{0,2}|200))$\");\n            break;\n        case \"255\": // 0-255\n            numbers.regex.compile(\"^(0|([1-9]{1}[0-9]{0,1}|[1]{1}[0-9]{0,2}|[2]{1}([0-4]{1}[0-9]{1}|[5]{1}[0-5]{1})))$\");\n            break;\n        case \"360\": // 0-360\n            numbers.regex.compile(\"^(0|([1-9]{1}[0-9]{0,1}|[1-2]{1}[0-9]{0,2}|[3]{1}([0-5]{1}[0-9]{1}|[6]{1}[0]{1})))$\");\n            break;\n        }\n    },\n    initHexField: function(input, type) {\n        numbers.type = type;\n        numbers.$input = $(input);\n        numbers.temporaryMode = numbers.$input.attr('id');\n        numbers.regex.compile(\"^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$\");\n        numbers.restrict = numbers.HEXCODE;\n    },\n    keyUp: function(event) {\n        var keycode;\n        if (event.keyCode) {\n            keycode = event.keyCode;\n        } \n        else if (event.which) {\n            keycode = event.which;\n        }\n        clearTimeout(numbers.timeout);\n        numbers.value = numbers.$input.val();\n        if(numbers.regex.test(numbers.value)){\n            numbers.match = true;\n            if(!numbers.pressed){\n                numbers.updateField();\n            } else {\n                numbers.pressed = false;\n            }\n        }\n        if(keycode === 91){\n            numbers.commandKeyPressed = false;\n        }\n    },\n    updateField: function() {\n        switch(numbers.type){\n        case 'color':\n            if (numbers.match && numbers.value !== \"\") colorpicker.update(numbers.temporaryMode);\n            break;\n        case 'style':\n            if (numbers.value !== \"\") numbers.$input.change();\n            break;\n        }\n    },\n    restrictCharacters: function(event) {\n        var keycode, character, isControlKey, isCopyCutPasteKey;\n        // future:\n        // - allow copy & paste shortcuts ('windows/apple': 91, 'v': 86, 'c': 67, 'x': 88)\n        //      set boolean for 91 - next click: check for boolean and set false\n        //   oh - on windows it's strg+c and strg+v (check ctrlKey)\n        //\n        // - allowe to paste hexcodes including a '#' at the beginning: slice it out\n        numbers.value = numbers.$input.val();\n        if (event.keyCode) {\n            keycode = event.keyCode;\n        } \n        else if (event.which) {\n            keycode = event.which;\n        }\n        // if pressed key is a numeric pad key use the numpad map object to detect its number\n        if(keycode >= 96 && keycode <= 105){\n            character = numbers.numpadKeys[keycode];\n        } else {\n            character = String.fromCharCode(keycode);\n        }\n        if(numbers.commandKeyPressed){\n            isCopyCutPasteKey = numbers.copyCutPasteKeys.join(\",\").match(new RegExp(keycode));\n            if(isCopyCutPasteKey){\n                return true;\n            }\n        }\n        if(keycode === 91) {\n            numbers.commandKeyPressed = true;\n            return false;\n        }\n        // 1 for key up (keycode 38), -1 for key down (keycode 40), 0 for other keys\n        numbers.direction = 0;\n        switch(keycode){\n            case 38: numbers.direction = 1; break;\n            case 40: numbers.direction = -1; break;\n        }\n        if (numbers.direction !== 0 && numbers.restrict === numbers.DIGITS) {\n            numbers.accelerate();\n            return false;\n        }\n        else {\n            isControlKey = numbers.controlKeys.join(\",\").match(new RegExp(keycode));\n            if (isControlKey) {\n                return true;\n            }\n            else if (character.match(numbers.restrict)) {\n                numbers.value += character;\n                return true;\n            }\n            event.preventDefault();\n            return false;\n        }\n    },\n    accelerate: function() {\n        if(numbers.timeout) clearTimeout(numbers.timeout);\n        if(numbers.value === '') {\n            numbers.value = 0;\n        }\n        var number = parseInt(numbers.value, 10);\n        number += numbers.direction;\n        number = Math.max(numbers.min, Math.min(numbers.max, number));\n        if('-'+numbers.max === numbers.min) { // as in angle from -180 to 180\n            if(number === numbers.min) number = numbers.max;\n            else if(number === numbers.max) number = numbers.min;\n        }\n        numbers.$input.val(number);\n        numbers.value = number;\n        numbers.updateField();\n        if(!numbers.pressed){\n            numbers.speed = 500;\n            numbers.pressed = true;\n        }\n        else {\n            numbers.speed = 150;\n        }\n        numbers.timeout = setTimeout(function(){ jQuery.proxy(numbers, \"accelerate\") }, numbers.speed);\n    },\n    validateInput: function(event) {\n        var integer, errorString, nearestInt;\n        numbers.value = numbers.$input.val();\n        integer = parseInt(numbers.value, 10);\n        if(numbers.regex.test(integer)){\n            console.log(integer);\n            numbers.$input.val(integer ? integer : \"\");\n            return true;\n        }\n        event.preventDefault();\n        errorString = lang.AnIntegerBetween+\" \"+ numbers.min +\" \"+lang.and+\" \"+ numbers.max +\" \"+lang.isRequired+\". \"+lang.ClosestValueInserted+\".\";\n        alert(errorString);\n        nearestInt = Math.abs(numbers.max - integer) < Math.abs(numbers.min - integer) ? numbers.max : numbers.min;\n        numbers.$input.val(nearestInt).focus().change();\n    }\n};"
  },
  {
    "path": "js/style.js",
    "content": "var style = {\n    background: {\n        elements: {\n            \".opacity\": { name: \"opacity\", handle: \"slider\" },\n            \".gradientField\": \"gradientField\",\n            \".reverse\": \"reverse\",\n            \".angle\": { name: \"angle\", handle: \"pot\" },\n            \".globalLight\": \"globalLight\"\n        },\n        $styles: $('#background_style'),\n        init: function(el){\n            this.$el = $(\"#\"+el);\n            this.selector = el;\n            this.$menuItem = $('.nav-'+el);\n            this.$checkbox = this.$menuItem.find('input[type=checkbox]');\n            this.$inputs = this.$el.find('input[type=text]');\n            this.initElements();\n            this.updateStops();\n            this.$gradientField.click( $.proxy( this, \"edit\" ) );\n            this.$reverse.change( $.proxy( this, \"switchReverse\" ) );\n            this.$globalLight.click( $.proxy( this, \"switchLight\" ) );\n            this.$checkbox.click( $.proxy( this, \"check\" ) );\n            this.$menuItem.click( $.proxy( this, \"select\" ) );\n            this.$styles.change( $.proxy( this, \"updateStyle\" ) );\n            $(document).bind('styleChange', $.proxy( this, \"populateInputs\" ));\n        },\n        initElements: function(){\n            for (var key in this.elements) {\n                var el = this.elements[key];\n                if(typeof el === 'object'){\n                    this[\"$\"+el.name] = $(key, this.$el);\n                    switch(el.handle){\n                        case \"slider\":\n                            this[el.name+\"Slider\"] = Object.create(slider);\n                            this[el.name+\"Slider\"].init(this.selector, el.name);\n                            break;\n                        case \"pot\":\n                            this[el.name+\"Pot\"] = Object.create(pot);\n                            this[el.name+\"Pot\"].init(this.selector);\n                            break;\n                    }\n                } else {\n                    this[\"$\"+el] = $(key, this.$el);\n                }\n            }\n        },\n        populateInputs: function(){\n            this.setActive();\n            this.opacitySlider.update(currentStyle[this.selector].opacity);\n            this.updateStops();\n            this.setReverse();\n            this.displayStyle();\n            this.setLight();\n        },\n        select: function(){\n            if(!currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = true;\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n                this.paint();\n            }\n        },\n        check: function(e){\n            e.stopPropagation();\n            if(currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = false;\n            } else {    \n                currentStyle[this.selector].isActive = true;\n            }    \n            this.setActive();\n            this.paint();\n        },\n        setActive: function(){\n            if(currentStyle[this.selector].isActive){\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n            } else {    \n                this.$checkbox.prop('checked', false);\n                this.$el.addClass('inactive');\n                this.$inputs.prop('disabled', true);\n            }\n        },\n        edit: function(){\n            gradienteditor.edit(currentStyle[this.selector].stops, this.updateStops, this);\n        },\n        setReverse: function(){\n            if(currentStyle[this.selector].isReverse){\n                this.$reverse.prop('checked', true);\n            } else {    \n                this.$reverse.prop('checked', false);\n            }    \n            this.updateStops();\n            this.paint();\n        },\n        switchReverse: function(){\n            if(currentStyle[this.selector].isReverse){\n                currentStyle[this.selector].isReverse = false;\n            } else {    \n                currentStyle[this.selector].isReverse = true;\n            }\n            this.setReverse();\n        },\n        setLight: function(){\n            if(currentStyle[this.selector].hasGlobalLight){\n                this.$globalLight.prop('checked', true);\n                this.anglePot.update(currentStyle.globalAngle);\n            } else {\n                this.$globalLight.prop('checked', false);\n                this.anglePot.update(currentStyle[this.selector].angle);\n            }    \n        },\n        switchLight: function(){\n            if(currentStyle[this.selector].hasGlobalLight){\n                currentStyle[this.selector].hasGlobalLight = false;\n            } else {\n                currentStyle[this.selector].hasGlobalLight = true;\n            }\n            this.setLight();\n            this.paint();\n        },\n        updateStyle: function(){\n            currentStyle[this.selector].style = this.$styles.val();\n            this.paint();\n        },\n        displayStyle: function(){\n            this.$styles.val(currentStyle[this.selector].style);\n        },\n        updateStops: function(stops){\n            if(stops){\n                currentStyle[this.selector].stops = stops;\n                currentStyle[this.selector].translucidStops = $.extend(true, [], stops);\n                this.paint();\n            }\n            this.$gradientField.css('background', css.cssGradient( currentStyle[this.selector].stops, currentStyle[this.selector].isReverse ? 180 : 0, \"linear\" ));\n        },\n        paint: function(){\n            $(document).trigger('paint');\n        }\n    },\n    shadow: {\n        elements: {\n            \".opacity\": { name: \"opacity\", handle: \"slider\" },\n            \".color_field\": \"color\",\n            \".angle\": { name: \"angle\", handle: \"pot\" },\n            \".globalLight\": \"globalLight\",\n            \".distance\": { name: \"distance\", handle: \"slider\" },\n            \".blur\": { name: \"blur\", handle: \"slider\" },\n            \".size\": { name: \"size\", handle: \"slider\" }\n        },\n        init: function(el){\n            this.$el = $(\"#\"+el);\n            this.selector = el;\n            this.$menuItem = $('.nav-'+el);\n            this.$checkbox = this.$menuItem.find('input[type=checkbox]');\n            this.$inputs = this.$el.find('input[type=text]');\n            this.initElements();\n            this.updateColor();\n            this.$color.click( $.proxy( this, \"pick\" ) );\n            this.$checkbox.click( $.proxy( this, \"check\" ) );\n            this.$menuItem.click( $.proxy( this, \"select\" ) );\n            this.$globalLight.click( $.proxy( this, \"switchLight\" ) );\n            $(document).bind('styleChange', $.proxy( this, \"populateInputs\" ));\n        },\n        initElements: function(){\n            for (var key in this.elements) {\n                var el = this.elements[key];\n                if(typeof el === 'object'){\n                    this[\"$\"+el.name] = $(key, this.$el);\n                    switch(el.handle){\n                        case \"slider\":\n                            this[el.name+\"Slider\"] = Object.create(slider);\n                            this[el.name+\"Slider\"].init(this.selector, el.name);\n                            //if(el.autoUpdate) currentStyle[this.selector].__defineSetter__( el.name , $.proxy( this[el.name+\"Slider\"], \"set\" ) );\n                            break;\n                        case \"pot\":\n                            this[el.name+\"Pot\"] = Object.create(pot);\n                            this[el.name+\"Pot\"].init(this.selector);\n                            break;\n                    }\n                } else {\n                    this[\"$\"+el] = $(key, this.$el);\n                }\n            }\n        },\n        populateInputs: function(){\n            this.setActive();\n            this.updateColor();\n            this.opacitySlider.update(currentStyle[this.selector].opacity);\n            this.distanceSlider.update(currentStyle[this.selector].distance);\n            this.blurSlider.update(currentStyle[this.selector].blur);\n            this.sizeSlider.update(currentStyle[this.selector].size);\n            this.setLight();\n        },\n        select: function(){\n            if(!currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = true;\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n                this.paint();\n            }\n        },\n        check: function(e){\n            e.stopPropagation();\n            if(currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = false;\n            } else {    \n                currentStyle[this.selector].isActive = true;\n            }    \n            this.setActive();\n            this.paint();\n        },\n        setActive: function(){\n            if(currentStyle[this.selector].isActive){\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n            } else {    \n                this.$checkbox.prop('checked', false);\n                this.$el.addClass('inactive');\n                this.$inputs.prop('disabled', true);\n            }\n        },\n        pick: function(){\n            colorpicker.pick(currentStyle[this.selector].color, this.updateColor, this);\n        },\n        setLight: function(){\n            if(currentStyle[this.selector].hasGlobalLight){\n                this.$globalLight.prop('checked', true);\n                this.anglePot.update(currentStyle.globalAngle);\n            } else {\n                this.$globalLight.prop('checked', false);\n                this.anglePot.update(currentStyle[this.selector].angle);\n            }\n        },\n        switchLight: function(){\n            if(currentStyle[this.selector].hasGlobalLight){\n                currentStyle[this.selector].hasGlobalLight = false;\n            } else {\n                currentStyle[this.selector].hasGlobalLight = true;\n            }\n            this.setLight();    \n            this.paint();\n        },\n        updateColor: function(currentColor){\n            if(currentColor){\n                currentStyle[this.selector].color = currentColor;\n                this.paint();\n            }\n            this.$color.css('background', '#'+color.hexFromRgb(currentStyle[this.selector].color));\n        },\n        paint: function(){\n            $(document).trigger('paint');\n        }\n    },\n    border: {\n        elements: {\n            \".color_field\": \"color\",\n            \".opacity\": { name: \"opacity\", handle: \"slider\" },\n            \".size\": { name: \"size\", handle: \"slider\" }\n        },\n        $styles: $('#border_styles').find('> div'),\n        init: function(el){\n            this.$el = $(\"#\"+el);\n            this.selector = el;\n            this.$menuItem = $('.nav-'+el);\n            this.$checkbox = this.$menuItem.find('input[type=checkbox]');\n            this.$inputs = this.$el.find('input[type=text]');\n            this.initElements();\n            this.updateColor();\n            this.$color.click( $.proxy( this, \"pick\" ) );\n            this.$checkbox.click( $.proxy( this, \"check\" ) );\n            this.$menuItem.click( $.proxy( this, \"select\" ) );\n            this.$styles.click( $.proxy( this, \"updateStyle\" ) );\n            $(document).bind('styleChange', $.proxy( this, \"populateInputs\" ));\n        },\n        initElements: function(){\n            for (var key in this.elements) {\n                var el = this.elements[key];\n                if(typeof el === 'object'){\n                    this[\"$\"+el.name] = $(key, this.$el);\n                    switch(el.handle){\n                        case \"slider\":\n                            this[el.name+\"Slider\"] = Object.create(slider);\n                            this[el.name+\"Slider\"].init(this.selector, el.name);\n                            break;\n                        case \"pot\":\n                            this[el.name+\"Pot\"] = Object.create(pot);\n                            this[el.name+\"Pot\"].init(this.selector);\n                            break;\n                    }\n                } else {\n                    this[\"$\"+el] = $(key, this.$el);\n                }\n            }\n        },\n        populateInputs: function(){\n            this.setActive();\n            this.updateColor();\n            this.opacitySlider.update(currentStyle[this.selector].opacity);\n            this.sizeSlider.update(currentStyle[this.selector].size);\n            this.setStyle();\n        },\n        select: function(){\n            if(!currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = true;\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n                this.paint();\n            }\n        },\n        check: function(e){\n            e.stopPropagation();\n            if(currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = false;\n            } else {    \n                currentStyle[this.selector].isActive = true;\n            }    \n            this.setActive();\n            this.paint();\n        },\n        setActive: function(){\n            if(currentStyle[this.selector].isActive){\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n            } else {    \n                this.$checkbox.prop('checked', false);\n                this.$el.addClass('inactive');\n                this.$inputs.prop('disabled', true);\n            }\n        },\n        pick: function(){\n            colorpicker.pick(currentStyle[this.selector].color, this.updateColor, this);\n        },\n        setStyle: function(){\n            for(var i=0, l=this.$styles.length; i<l; i++){\n                if(this.$styles.eq(i).data('style') === currentStyle[this.selector].style){\n                    this.updateStyle(null, this.$styles.eq(i));\n                    return false;\n                }    \n            }\n        },\n        updateStyle: function(event, setStyle){\n            var obj = $(setStyle || event.target);\n            this.$styles.removeClass('active');\n            obj.addClass('active');\n            currentStyle[this.selector].style = obj.data('style');\n            this.paint();\n        },\n        updateColor: function(currentColor){\n            if(currentColor){\n                currentStyle[this.selector].color = currentColor;\n                this.paint();\n            }\n            this.$color.css('background', '#'+color.hexFromRgb(currentStyle[this.selector].color));\n        },\n        paint: function(){\n            $(document).trigger('paint');\n        }\n    },\n    borderRadius: {\n        $pixel: $('#border_radius_pixel'),\n        $percent: $('#border_radius_percent'),\n        $preview: $('#border_radius_preview'),\n        $topLeft: $('#topLeft'),\n        $topRight: $('#topRight'),\n        $bottomLeft: $('#bottomLeft'),\n        $bottomRight: $('#bottomRight'),\n        maxRadius: 200,\n        init: function(el){\n            this.$el = $(\"#\"+el);\n            this.selector = el;\n            this.$menuItem = $('.nav-'+el);\n            this.$checkbox = this.$menuItem.find('input[type=checkbox]');\n            this.$inputs = this.$el.find('input[type=text]');\n            this.$radius = $('.radius', this.$el);\n            this.radiusSlider = Object.create(slider);\n            this.radiusSlider.init(this.selector, \"radius\");\n            this.$checkbox.click( $.proxy( this, \"check\" ) );\n            this.$menuItem.click( $.proxy( this, \"select\" ) );\n            this.$pixel.add(this.$percent).click( $.proxy( this, \"updateUnit\" ) );\n            this.$preview.mousedown( $.proxy( this, \"startSelection\" ) );\n            this.$fields = this.$preview.children();\n            $(document).bind('styleChange', $.proxy( this, \"populateInputs\" ));\n        },\n        populateInputs: function(){\n            this.setActive();\n            currentStyle[this.selector].radius = 0;\n            currentStyle[this.selector].__defineSetter__( \"radius\", $.proxy( this, \"updateRadius\" ) );\n        },\n        select: function(){\n            if(!currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = true;\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n                this.paint();\n            }\n        },\n        check: function(e){\n            e.stopPropagation();\n            if(currentStyle[this.selector].isActive){\n                currentStyle[this.selector].isActive = false;\n            } else {    \n                currentStyle[this.selector].isActive = true;\n            }    \n            this.setActive();\n            this.paint();\n        },\n        setActive: function(){\n            if(currentStyle[this.selector].isActive){\n                this.$checkbox.prop('checked', true);\n                this.$el.removeClass('inactive');\n                this.$inputs.prop('disabled', false);\n            } else {    \n                this.$checkbox.prop('checked', false);\n                this.$el.addClass('inactive');\n                this.$inputs.prop('disabled', true);\n            }\n        },\n        startSelection: function(event){\n            $(document).bind('mousemove.global', $.proxy( this, \"updateSelection\" ) );\n            this.currentTarget = event.target;\n            $(event.target).toggleClass(\"active\");\n            $(document).one('mouseup', $.proxy( this, \"setSelection\" ) );\n        },\n        updateSelection: function(event){\n            if(event.target != this.currentTarget){\n                $(event.target).toggleClass(\"active\");\n                this.currentTarget = event.target;\n            }\n        },\n        updateRadius: function(value){\n            for(var i=0; i<4; i++){\n                if(currentStyle[this.selector].isSelected[i]){ \n                    currentStyle[this.selector].radii[i] = currentStyle[this.selector].hasPercentage[i] ? [value, \"%\"] : [value, \"px\"];\n                }\n            }\n            this.paint();\n        },\n        setSelection: function(e){\n            var value, sum = 0, amount = 0, average = 0, equal = false;\n            for(var i=0; i<4; i++){\n                if(this.$fields.eq(i).hasClass(\"active\")){ \n                    currentStyle[this.selector].isSelected[i] = true;\n                    // count the sum of all radii\n                    value = parseInt(currentStyle[this.selector].radii[i][0], 10);\n                    sum+=value;\n                    amount++;\n                    if(sum/amount === value){\n                        equal = true;\n                    } else {\n                        equal = false;\n                    }\n                } else {\n                    currentStyle[this.selector].isSelected[i] = false;\n                }\n            }\n            // set radius value (average) but don't set css\n            average = amount === 0 ? 0 : Math.floor(sum/amount);\n            value = equal ? average : 0;\n            this.radiusSlider.set(value);\n            this.radiusSlider.move(this.radiusSlider.toPos(value));\n        },\n        updateUnit: function(event){\n            var $el = $(event.target), average, sum = 0, amount = 0;\n            switch($el.attr('data-unit')){\n                case \"%\":\n                    for(var i=0; i<4; i++){\n                        if(currentStyle[this.selector].isSelected[i]){\n                            var radius = currentStyle[this.selector].radii[i][0];\n                            // recalculate value from pixel to percent and limit to 50\n                            var value = Math.floor(Math.min(50, radius*100/currentStyle.height)); // height or width?\n                            currentStyle[this.selector].radii[i] = [value, \"%\"];\n                            currentStyle[this.selector].hasPercentage[i] = true;\n                            sum += value;\n                            amount++;\n                        }\n                    }\n                    // limit slider to 50\n                    this.radiusSlider.max = 50;\n                    // uncheck pixel button\n                    this.$pixel.removeClass(\"active\");\n                    break;\n                case \"px\":\n                    for(var i=0; i<4; i++){\n                        if(currentStyle[this.selector].isSelected[i]){\n                            var radius = currentStyle[this.selector].radii[i][0];\n                            // recalculate value from percent to pixel and limit to maxRadius\n                            var value = Math.floor(Math.min(currentStyle[this.selector].maxRadius, radius*currentStyle.height/100)); // height or width?\n                            currentStyle[this.selector].radii[i] = [value, \"px\"];\n                            currentStyle[this.selector].hasPercentage[i] = false;\n                            sum += value;\n                            amount++;\n                        }\n                    }\n                    // reset limit\n                    this.radiusSlider.max = this.maxRadius;\n                    // uncheck percent button\n                    this.$percent.removeClass(\"active\");\n                    break;\n            }\n            average = Math.floor(sum/amount);\n            // update input value to the average value and trigger change() to adjust the slider\n            this.radiusSlider.set(average);\n            this.radiusSlider.move(this.radiusSlider.toPos(average));\n            $el.addClass(\"active\");\n            this.paint();\n        },\n        paint: function(){\n            $(document).trigger('paint');\n        }\n    },\n    init: function(){\n        this.background.init(\"background\");\n        \n        this.dropShadow = Object.create(style.shadow);\n        this.dropShadow.init(\"dropShadow\");\n        \n        this.innerShadow = Object.create(style.shadow);\n        this.innerShadow.init(\"innerShadow\");\n        \n        this.border.init(\"border\");\n        \n        this.borderRadius.init(\"borderRadius\");\n    }\n};"
  },
  {
    "path": "js/styleStore.js",
    "content": "var styleStore = {\n    styles: [\n        { \n            name: \"Default Style\", \n            style: { }\n        },\n        { \n            name: \"Inset Box\", \n            style: {\n                dropShadow: { color: [255,255,255], opacity: 100, blur: 0 },\n                innerShadow: { color: [0,0,0], opacity: 40, blur: 7 },\n                background: { stops: [[191, 191, 191], 11, [[242, 242, 242], 88], 77, [252, 252, 252]], reverse: true }\n            }\n        },\n        {\n            name: \"Vista Inset Box\",\n            style: {\n                dropShadow: { color: [255,255,255], opacity: 50, blur: 0 },\n                innerShadow: { color: [0,0,0], opacity: 40, blur: 7 },\n                background: { stops: [[116,116,116], [[109,109,109], 50], [[126,126,126], 50], [133,133,133]] },\n                border: { isActive: false },\n                borderRadius: { radii: [[10, \"px\"],[10, \"px\"],[10, \"px\"],[10, \"px\"]] }\n            }\n        },\n        {\n            name: \"Hello Red\",\n            style: {\n                dropShadow: { color: [255,255,255], opacity: 14, blur: 0 },\n                innerShadow: { color: [255,255,255], opacity: 21 },\n                background: { stops: [[213,87,91], [196,48,51]] },\n                border: { color: [168,0,2] },\n                borderRadius: { radii: [[5, \"px\"],[5, \"px\"],[5, \"px\"],[5, \"px\"]] }\n            }\n        },\n        { \n            name: \"Orange Box\", \n            style: {\n                dropShadow: { isActive: false },\n                innerShadow: { color: [249,169,88], distance: 0, size: 1 },\n                background: { stops: [[255, 225, 173], 42, [[250, 169, 28], 12], 91, [217, 97, 4]] },\n                border: { color: [153,102,52] },\n                borderRadius: { radii: [[2, \"px\"],[2, \"px\"],[2, \"px\"],[2, \"px\"]] }\n            }\n        },\n        {\n            name: \"Apple Promo Box\",\n            style: {\n                dropShadow: { color: [0,0,0], opacity: 40, blur: 3 },\n                innerShadow: { color: [255,255,255], opacity: 100, distance: 0, size: 3 },\n                background: { stops: [[250,250,250], [238,238,238]] },\n                border: { isActive: false },\n                borderRadius: { radii: [[5, \"px\"],[5, \"px\"],[5, \"px\"],[5, \"px\"]] }\n            }\n        },\n        {\n            name: \"iPhone Copy Button\",\n            style: {\n                dropShadow: { color: [0,0,0], opacity: 55, distance: 3, blur: 4 },\n                innerShadow: { color: [255,255,255], opacity: 50 },\n                background: { stops: [[112, 134, 255], [[79, 105, 255], 37], [[53, 83, 255], 41], [49, 79, 254]] },\n                border: { color: [50,50,50] },\n                borderRadius: { radii: [[5, \"px\"],[5, \"px\"],[5, \"px\"],[5, \"px\"]] }\n            }\n        },\n        {\n            name: \"Please don't sue me\",\n            style: {\n                dropShadow: { distance: 0 },\n                innerShadow: { opacity: 55 },\n                background: { stops: [[22, 127, 232], [0, 60, 123]] }\n            }\n        }\n    ],\n    init: function(){\n        this.$el = $('#stylePresets');\n        if(localStorage[\"styles\"]) this.styles = JSON.parse(localStorage[\"styles\"]);\n        this.renderStyles(this.styles);\n        this.loadStyle(0);\n    },\n    renderStyles: function(styleObjects){\n        var styleFragment = document.createDocumentFragment();\n        for(var i = 0, length = styleObjects.length; i<length; i++){\n            styleFragment.appendChild( this.addStyle(styleObjects[i].name, styleObjects[i].style, i) );\n        }\n        this.$el.append(styleFragment);\n    },\n    addStyle: function(name, packedStyle, pos){\n        var expandedStyle = this.decompress(packedStyle);\n        var cssObj = css.displayCss(expandedStyle);\n        var swatch = $('<div class=\"swatch\" />')\n                .attr({ 'title': name, 'data-pos': pos })\n                .bind('mousedown', { self : this }, styleStore.select )\n                    .append( $('<div />').css(cssObj) );\n        return swatch.get(0);\n    },\n    select: function(e){\n        e.stopPropagation();\n        var self = e.data.self;\n        var $obj = $(this);\n        var family = $obj.parent().children();\n        var pos = family.index(this);\n        // if alt is pressed while clicking: remove style\n        if(e.altKey){\n            // double check - styles are precious\n            if(pos !== 0 && window.confirm( lang.DeleteStyle + ' \"'+ self.styles[pos].name +'\"?' )){\n                // slice out the gradient from the gradient array (method by John Resig)\n                var rest = self.styles.slice(pos + 1);\n                self.styles.length = pos;\n                self.styles.push.apply(self.styles, rest);\n                localStorage[\"styles\"] = JSON.stringify(self.styles);\n                $obj.remove();\n            }\n        }\n        else {\n            // else set the style\n            family.removeClass('active');\n            self.loadStyle(pos);\n           }\n    },\n    compress: function(style){\n        var slimStyle = {};\n        var fatStyle = $.extend(true, {}, style);\n        for( key in fatStyle ){\n            var value = fatStyle[key];\n            if(typeof style === \"object\"){\n                if(value.isActive){\n                    slimStyle[key] = {};\n                    for( prop in value ){\n                        var propVal = value[prop];\n                        if( defaults[key][prop] === undefined ) continue;\n                        if( typeof propVal === \"object\" ){\n                            if( !jQuery.compare(propVal, defaults[key][prop]) ){\n                                slimStyle[key][prop] = propVal;\n                            }\n                        } \n                        else if( propVal != defaults[key][prop] && prop !== \"isActive\" ){\n                            slimStyle[key][prop] = propVal;\n                        }\n                    }\n                    if( jQuery.isEmptyObject(slimStyle[key]) ) delete slimStyle[key];\n                } else {\n                    if(defaults[key].isActive){\n                        slimStyle[key] = { isActive: false };\n                    }\n                }\n            }\n            else if(key === \"globalAngle\" && value !== defaults.globalAngle){\n                slimStyle[\"globalAngle\"] = value;\n            }\n        }\n        return slimStyle;\n    },\n    decompress: function(packedStyle){\n        var expandedStyle = $.extend(true, {}, defaults);\n        for(key in packedStyle){\n            expandedStyle[key] = $.extend({}, defaults[key], packedStyle[key]);\n            if(packedStyle[key].isActive !== undefined){\n                expandedStyle[key].isActive = packedStyle[key].isActive;\n            } else {\n                expandedStyle[key].isActive = true;\n            }\n        }\n        return expandedStyle;\n    },\n    loadStyle: function(pos){\n        this.$el.children().eq(pos).addClass('active');\n        currentStyle = this.decompress(this.styles[pos].style);\n        $(document).trigger('styleChange').trigger('paint');\n    },\n    create: function(){\n        var newStyle, name = prompt(lang.NewStyle,\"Style \"+this.styles.length);\n        if(name){\n            newStyle = {'name': name, 'style': this.compress(currentStyle)};\n            this.styles.push(newStyle);\n            this.renderStyles([newStyle]);\n            localStorage[\"styles\"] = JSON.stringify(this.styles);\n        }\n    }\n}\n"
  },
  {
    "path": "js/tools.js",
    "content": "var tools = {\n    options: {\n        hex: true\n    },\n    /**\n     * @method  averageGradientColor\n     * @param   fullStops {stops-array}\n     * @return  color {string}\n     * @example averageGradientColor([[255,255,255], [0,0,0]]) returns gray\n     */\n    averageGradientColor: function(fullStops){\n        var stops = gradienteditor.expand( $.extend(true, [], fullStops) ),\n            reducedArray = [],\n            l = stops.length;\n\n        for(var i = 0; i < l; i++){\n            var stop = stops[i];\n            if(typeof stop === 'number'){\n                stops[i] = this.getMiddlepoint(stops[i-1], stop, stops[i+1]);\n            }\n        }    \n\n        for(var i = 0; i < l-1; i++){\n            var stopA = stops[i],\n                stopB = stops[i+1];\n\n            reducedArray.push(this.averageStop(stopA, stopB));\n        }        \n        // reduce array to one rgb array\n        reducedArray = reducedArray.reduce(this.averageColor, [0,0,0]);\n\n        // round its values\n        for(var i=0; i<3; i++){\n            reducedArray[i] = Math.round(reducedArray[i]);\n        }\n\n        // return said array as color string\n        return this.toColor(reducedArray);\n    },\n    /**\n     * @method  averageStop\n     * @param   stopA {stop-array}\n     * @param   stopB {stop-array}\n     * @return  color-stop {stop-array}\n     * @example averageStop([[255,255,255], 0], [[0,0,0], 100]) returns [[128,128,128], 50]\n     */\n    averageStop: function(stopA, stopB){\n        var colorA = stopA[0],\n            posA = stopA[1],\n            colorB = stopB[0],\n            posB = stopB[1];\n\n        return [\n            [\n                this.getCenter(colorA[0],colorB[0]),\n                this.getCenter(colorA[1],colorB[1]),\n                this.getCenter(colorA[2],colorB[2])\n            ], \n            posB - posA\n        ];\n    },\n    /**\n     * @method  averageColor\n     * @param   previousValue {color-array}\n     * @param   currentValue {stop-array}\n     * @return  color {color-array}\n     */\n    averageColor: function(previousValue, currentValue, index, array){\n        var color = currentValue[0],\n            weight = currentValue[1]/100;\n\n        return [\n            previousValue[0] + color[0] * weight, // r\n            previousValue[1] + color[1] * weight, // g\n            previousValue[2] + color[2] * weight  // b\n        ];\n    },\n    /**\n     * @method  roundToMultiple\n     * @param   number {integer}\n     * @param    multiple {integer}    multiple to round to\n     * @return  rounded number {integer}\n     * @example roundToMultiple(35, 15) returns 30\n     * @usage    in ui.js -> pot; to round to 15° steps\n     */\n    roundToMultiple: function(number, multiple){\n        var value = number/multiple,\n            integer = Math.floor(value),\n            rest = value - integer;\n        return rest > 0.5 ? (integer+1)*multiple : integer*multiple;\n    },\n    /**\n     * @method  toColor\n     * @param   rgb {array}   RGB or RGBA Color Array\n     * @return  CSS Color {string}\n     * @example toColor([255,255,255]) returns 'rgb(255,255,255)'\n     *          toColor([255,255,255,0.5]) returns 'rgba(255,255,255,0.5)'\n     */\n    toColor: function(rgb){\n        var mode = rgb.length === 3 ? 'rgb' : 'rgba',\n            string = mode+'('+rgb.join(',')+')';\n                \n        if (css.colors[string]) {\n            return css.colors[string];\n        }\n        else if(this.options.hex && mode === 'rgb'){\n            return \"#\"+color.hexFromRgb(rgb);\n        }\n        return string;\n    },\n    /**\n     * @method  getCenter    returns the center between a starting and an ending point\n     * @param   start {integer}    \n     *             end {integer}\n     *             offset {integer} [optional] if the center has an offset\n     * @return  center {integer}\n     * @example getCenter(0, 60) returns 30\n     *             getCenter(0, 60, 75) returns 45\n     */\n    getCenter: function(start, end, offset){\n        var o = offset || 50;\n        return start + Math.round(o/100*(end-start));\n    },\n    /**\n     * @method  getMiddlepoint    returns the color at a specific position on a color gradient defined through a start and end color\n     * @param   start {array}    eiter a rgb color (like [255,255,255])or a rgb color and a positon (e.g. [[255,255,255], 10])\n     *             pos {integer}    position\n     *             end {array}        rgb color [r, g, b]\n     * @return  {array} of the rgb color {array} and relative index {integer}\n     * @example getCenter(0, 60) returns 30\n     *             getCenter(0, 60, 75) returns 45\n     */\n    getMiddlepoint: function(start, pos, end){\n        var startColor = start,\n            endColor = end,    \n            startIndex = 0,\n            endIndex = 100,\n            index = 0,\n            color = [];\n        if(start.length === 2){ startIndex = start[1]; startColor = start[0]; }\n        if(end.length === 2){ endIndex = end[1]; endColor = end[0]; }\n        index = this.getCenter(startIndex, endIndex, pos);\n        for (var i=0, l = startColor.length; i<l; i++) {\n            color[i] = startColor[i] + Math.round((endColor[i] - startColor[i])/2);\n        }\n        return [color, index];\n    },\n    /**\n     * @method  decodeStops\n     * @param   stops {array}    encoded color stops\n     * @param    alpha {float} [optional]     opacity value between 0-1\n     * @return  {array} decoded color stops: rgb strings\n     * @example decodeStops([0,0,0], 10, [255,255,255]) returns ['rgb(0,0,0)', 'rgb(25,25,25) 10%', 'rgb(255,255,255)']\n     */\n    decodeStops: function(stops){\n        var steps = [];\n        for(var i=0, length=stops.length; i<length; i++){\n            var stop = stops[i];\n            switch(typeof stop){\n            case 'object': // => [255,255,255] or [[255,255,255], 33]\n                if(stop.length > 2){ // => [255,255,255]\n                    steps[i] = this.toColor(stop);\n                }\n                else { // => [[255,255,255], 33]\n                    steps[i] = this.toColor(stop[0])+\" \"+stop[1]+\"%\";\n                }\n                break;\n            case 'number': // => 11\n                var middlepoint = this.getMiddlepoint(stops[i-1], stop, stops[i+1]);\n                steps[i] = this.toColor(middlepoint[0])+\" \"+middlepoint[1]+\"%\";\n                break;\n            }           \n        }\n        return steps;\n    },\n    /**\n     * @method  decodeCanvasGradient\n     * @param   stops {array} the color stops\n     * @param    angle {integer} the gradients angle\n     * @param   ctx {canvas 2d context}    the context the gradient is for\n     * @param   x {integer}    the x coordinate where the gradient should start\n     * @param   y {integer}    the y coordinate where the gradient should start\n     * @param   width {integer}    the width of the gradients box\n     * @param   height {integer} the height of the gradients box\n     * @return  {canvas-gradient}\n     */\n    decodeCanvasGradient: function(stops, angle, style, ctx, x, y, width, height){\n        var gradient,\n            // looks like stops is still referenced to currentStyle.background.translucentStops at this point\n            tempStops = $.extend(true, [], stops);\n        \n        switch(style){\n            case \"linear\":\n                /*     missing: angle support\n                    \n                    0°     ->     x+width,    y,             x,             y\n                    45° ->    x+width,    y,            x,            y+height\n                    90°    ->    x,            y,            x,            y+height\n                    135°->    x,            y,            x+width,    y+height\n                    180°->    x,            y,            x+width,    y\n                    225°->    x,            y+height,    x+width,    y\n                    270°->    x,            y+height,    x,            y\n                    315°->    x+width,    y+height,    x,            y\n                    \n                    there is a pattern :) something with sin & cos\n                    for now now default to 90\n                */\n                gradient = ctx.createLinearGradient(x, y, x, y+height);\n                break;\n            case \"reflected\":\n                tempStops = this.reflectStops(tempStops);\n                gradient = ctx.createLinearGradient(x, y, x, y+height);\n                break;\n            case \"contain\":\n                var closestSide = width < height ? width/2 : height/2;\n                gradient = ctx.createRadialGradient(x+width/2, y+height/2, 0, x+width/2, y+height/2, closestSide); // centered\n                break;\n            case \"cover\":\n                // farest corner = half diagonal side >> pitagoras\n                var farestCorner = Math.sqrt( width * width + height * height )/2;\n                gradient = ctx.createRadialGradient(x+width/2, y+height/2, 0, x+width/2, y+height/2, farestCorner); // centered\n                break;\n        }\n        // bring the stops in the right order for canvas gradient:\n        for(var i=0, length=tempStops.length; i<length; i++){\n            var stop = tempStops[i], color, pos;\n            // if the first stop has an offset add a color stop to 0\n            if(i === 0 && stop.length === 2){\n                gradient.addColorStop(0, this.toColor(stop[0]));\n            }\n            switch(typeof stop){\n            case 'object': // => [255,255,255] or [[255,255,255], 33]\n                if(stop.length === 3){ // => [255,255,255]\n                    pos = i === 0 ? 0 : 100; // can either be the start or the end\n                    color = this.toColor(stop);\n                }\n                else { // => [[255,255,255], 33]\n                    color = this.toColor(stop[0]);\n                    pos = stop[1];\n                }\n                break;\n            case 'number': // => 11\n                var middlepoint = this.getMiddlepoint(tempStops[i-1], stop, tempStops[i+1]);\n                color = this.toColor(middlepoint[0]);\n                pos = middlepoint[1];\n                break;\n            }\n            // pos is now between 0-100 - for canvas we need it between 0-1\n            pos = pos/100;\n            pos = pos+''; // <-- to change from number to string seems to fix a bug in firefox on ubuntu\n             gradient.addColorStop(pos, color);\n        }\n        return gradient;\n    },\n    /**\n     * @method  opposite    \n     * @param   direction {String}\n     * @return  {String} opposite direction\n     * @example opposite('top') returns 'bottom'\n     */\n    opposite: function(direction) {\n        switch(direction){\n        case 'top':\n            return 'bottom';\n        case 'right':\n            return 'left';\n        case 'bottom':\n            return 'top';\n        case 'left':\n            return 'right';\n        }\n    },\n    reflectStops: function(stops){\n        var first = [],\n            second = [];\n            // bug: turns everything around\n        for(var i=0, l=stops.length; i<l; i++){\n            var stop = stops.shift(),\n                start, end;\n            switch(typeof stop){\n                case \"number\":\n                    start = Math.round(stop/2);\n                    end = 100-start;\n                    break;\n                case \"object\":\n                    start = stop.slice(0);\n                    end = stop.slice(0);\n                    if(stop.length === 2){\n                        start[1] = Math.round(stop[1]/2);\n                        end[1] = 100-start[1];\n                    }\n                    break;\n            }\n            \n            // add 50% to the last element\n            if(i === l-1) start = [start, 50];\n            \n            first.push(start);\n            \n            // don't add the last stop cause we only need one center\n            if(i != l-1) second.unshift(end);\n        }\n        return first.concat(second);\n    },\n    reverseStops: function(stops){\n        var reversed = [],\n            stops = stops.slice(0);\n        while(stops.length){\n            var stop = stops.pop(), rev;\n            switch(typeof stop){\n                case \"number\":\n                    rev = 100-stop;\n                    break;\n                case \"object\":    \n                    rev = stop.slice(0);\n                    if(stop.length === 2){\n                        rev[1] = 100-stop[1];\n                    }\n                    break;\n            }\n            reversed.push(rev);\n        }\n        return reversed;\n    },\n}"
  },
  {
    "path": "js/ui.js",
    "content": "var pot = {\n    init: function(el){\n        // el = background, dropShadow, innerShadow\n        this.$el = $(\"#\"+el+\" .pot\");\n        this.height = this.$el.height();\n        this.width = this.$el.width();\n        this.$pointer = this.$el.find('> div');\n        this.model = el;\n        this.$el.bind(\"mousedown\", $.proxy( this, \"start\" ) );\n        this.$input = this.$el.next('div').children('input:first-child');\n        this.$input.change( $.proxy( this, \"get\" ) );\n    },\n    start: function(event){\n        var myOffset = this.$el.offset();\n        this.offset = { x: myOffset.left+(this.width/2), y: myOffset.top+(this.height/2) };\n        this.turn(event);\n        $(document).bind('mousemove.global', $.proxy( this, \"turn\") );\n    },\n    get: function(){\n        var value = parseInt(this.$input.val());\n        this.update(value);\n    },\n    set: function(value){\n        this.$input.val(value);\n    },\n    update: function(value){\n        this.move(value);\n        if(currentStyle[this.model].hasGlobalLight) currentStyle.globalAngle = value;\n        currentStyle[this.model].angle = value;\n        this.set(value);\n        style[this.model].paint();\n    },\n    move: function(degrees){\n        this.$pointer.css('transform', 'rotate('+-degrees+'deg)');\n    },\n    turn: function(event){\n        event.preventDefault();\n        var opposite = this.offset.y - event.pageY,\n            adjacent = event.pageX - this.offset.x,\n            radiants = Math.atan(opposite/adjacent),\n            degrees = Math.round(radiants*(180/Math.PI), 10);\n        \n        if(event.shiftKey) degrees = tools.roundToMultiple(degrees, 15);\n        \n        if(adjacent < 0 && opposite >= 0){ degrees+= 180; }\n        else if(opposite < 0 && adjacent < 0){ degrees-= 180; }\n        if(degrees === -180) degrees = 180;\n        \n        this.update(degrees);\n    }\n};\n\nvar toggle = {\n    _treshhold: 2,\n    _moving: false,\n    init: function(el, toggle, thisArg, callback){\n        this.$el = $(\"#\"+el);\n        this.$slider = this.$el.find('.slidePanel');\n        this.width = this.$el.width();\n        this.toggle = toggle;\n        this.model = thisArg;\n        // render befor the callback gets asigned to not call the callback at init\n        this.render();\n        this.callback = callback;\n        this.$el.bind('mousedown', $.proxy( this, \"start\" ) );\n    },\n    start: function(event){\n        event.preventDefault();\n        this._startPos = event.pageX - this.$el.offset().left;\n        this.$el.addClass('down');\n        $(document).bind('mousemove.global', $.proxy( this, \"move\") );\n        $(document).one('mouseup', $.proxy( this, \"stop\") );\n    },\n    move: function(event){\n        var distance = event.pageX - this._startPos;\n        if(!this._moving && Math.abs(distance) > this._treshhold){\n            this.$el.addClass('moving');\n            this._moving = true;\n        }\n        if(this._moving){\n            this._pos = Math.min(0, Math.max(-this.width/2, this._offset + distance));\n            this.$slider.css('left', this._pos);\n        }\n    },\n    render: function(){\n        this._offset = this.model[this.toggle] ? -this.width/2 : 0;\n        this.$slider.css('left', this._offset);\n        if(this.callback) this.callback();\n    },\n    stop: function(event){\n        this.$el.removeClass('down');\n        if(this._moving){\n            this._moving = false;\n            this.$el.removeClass('moving');\n            if(this._pos >= -this.width/4){\n                this.model[this.toggle] = false;\n            } else {\n                this.model[this.toggle] = true;\n            }\n        } else {\n            this.model[this.toggle] = !this.model[this.toggle];\n        }    \n        this.render();\n    }\n};\n\nvar slider = {\n    init: function(el, model){\n        this.$el = $(\"#\"+el+\" .\"+model).prev(\"div.slider\");\n        this.$pointer = this.$el.find('> div:nth-child(2)');\n        this.$input = this.$el.next('input');\n        this.max = this.$input.data(\"max\");\n        this.length = this.$el.width();\n        this.ease = this.$el.data(\"easing\");\n        this.style = el;\n        this.model = model;\n        this.$el.bind(\"mousedown\", $.proxy( this, \"start\" ) );\n        this.$input.change( $.proxy( this, \"get\" ) );\n    },\n    acc: function(x){\n        return this.ease ? x*x : x;\n    },\n    invAcc: function(x){\n        return this.ease ? Math.sqrt(x) : x;\n    },\n    get: function(){\n        var value = parseInt(this.$input.val());\n        this.update(value);\n    },\n    set: function(value){\n        this.$input.val(value);\n    },\n    update: function(value, position){\n        this.move(this.toPos(value));\n        currentStyle[this.style][this.model] = value;\n        this.move(position || this.toPos(value));\n        this.set(value);\n        style[this.style].paint();\n    },\n    move: function(x){\n        this.$pointer.css({ left: x+'px' });\n    },\n    toPos: function(value){\n        var percentage = this.invAcc(value/this.max);\n        return Math.round(this.length*percentage);\n    },\n    toValue: function(position){\n        var percentage = this.acc(position/this.length);\n        return Math.round(percentage*this.max);\n    },\n    start: function(event){\n        this.offset = { x: this.$el.offset().left };\n        this.slide(event);\n        $(document).bind('mousemove.global', $.proxy( this, \"slide\" ) );\n    },\n    slide: function(event){\n        event.preventDefault();\n        var value, position = Math.max(0, Math.min(this.length, event.pageX - this.offset.x));    \n        \n        value = this.toValue(position);\n        this.update(value, position);\n    }\n};"
  },
  {
    "path": "js/universe.js",
    "content": "var parallelUniverse = {\n    x: 0,\n    y: 0,\n    KAPPA: 4*(Math.SQRT2-1)/3,\n    roundToHalf: function(value){\n        // makes the borders crisp\n        return (value - parseInt(value, 10)) === 0.5 ? value+1 : value + 1.5;\n    },\n    draw: function(){\n        this.x = this.roundToHalf(dimensions.width/2 - currentStyle.width/2);\n        this.y = this.roundToHalf(dimensions.height/2 - currentStyle.height/2);\n        \n        pu.clearRect(0,0,dimensions.width,dimensions.height);    \n        \n        this.background();\n        this.drawCanvases();\n        \n        this.shadow();\n        pu.beginPath();\n        this.rect(pu);\n        pu.closePath();\n        this.layerBackground();\n        this.innerShadow();\n        this.border();\n    },\n    background: function(){\n        pu.fillStyle = tools.decodeCanvasGradient(\n            background.background[1].stops, background.background[1].angle, background.background[1].style, pu, 0, 0, dimensions.width, dimensions.height\n        );\n        pu.fillRect(0, 0, dimensions.width, dimensions.height);\n    },\n    rect: function(ctx){\n        var br = currentStyle.borderRadius;\n        if(br.isActive){\n            for(var i=3; i>=0; i--){\n                var radiusX, radiusY, unit, percentage;\n                unit = br.radii[i][1];\n                if(unit === \"%\"){\n                    percentage = Math.min(0.5, br.radii[i][0]/100);\n                    radiusY = percentage*currentStyle.height;\n                    radiusX = percentage*currentStyle.width;\n                } else {\n                    radiusX = radiusY = Math.min(currentStyle.width/2, br.radii[i][0]);\n                }\n                switch(i){ // anti-clockwise because of the innerShadow-mask\n                case 3: // start at left middle; then bottom left\n                    ctx.moveTo(this.x, this.y+currentStyle.height/2);\n                    ctx.lineTo(this.x, this.y+currentStyle.height-radiusY);\n                    ctx.bezierCurveTo(this.x, this.y+currentStyle.height-radiusY+radiusY*this.KAPPA, this.x+(radiusX-radiusX*this.KAPPA), this.y+currentStyle.height, this.x+radiusX, this.y+currentStyle.height);\n                    break;\n                case 2: // upper right\n                    ctx.lineTo(this.x+currentStyle.width-radiusX, this.y+currentStyle.height);\n                    ctx.bezierCurveTo(this.x+currentStyle.width-radiusX+radiusX*this.KAPPA, this.y+currentStyle.height, this.x+currentStyle.width, this.y+currentStyle.height-radiusY+radiusY*this.KAPPA, this.x+currentStyle.width, this.y+currentStyle.height-radiusY);\n                    break;\n                case 1: // bottom right\n                    ctx.lineTo(this.x+currentStyle.width, this.y+radiusY);\n                    ctx.bezierCurveTo(this.x+currentStyle.width, this.y+(radiusY-radiusY*this.KAPPA), this.x+currentStyle.width-radiusX+radiusX*this.KAPPA, this.y, this.x+currentStyle.width-radiusX, this.y);\n                    break;\n                case 0: // upper left and then back to left middle;\n                    ctx.lineTo(this.x+radiusX, this.y);\n                    ctx.bezierCurveTo(this.x+(radiusX-radiusX*this.KAPPA), this.y, this.x, this.y+(radiusY-radiusY*this.KAPPA), this.x, this.y+radiusY);\n                    ctx.lineTo(this.x, this.y+currentStyle.height/2);\n                    break;\n                }\n            }\n        } else {\n            // outwritten rect anti-clockwise instead of the ctx.rect(x,y,width,height) because of the innerShadow mask\n            ctx.moveTo(this.x, this.y);\n            ctx.lineTo(this.x, this.y+currentStyle.height);\n            ctx.lineTo(this.x+currentStyle.width, this.y+currentStyle.height);\n            ctx.lineTo(this.x+currentStyle.width, this.y);\n            ctx.lineTo(this.x, this.y);\n        }\n        \n    },\n    drawCanvases: function(){\n        var $canvases = $workspace.find('canvas.moveable');\n        $.each($canvases, function(i, canvas){\n            var $canvas = $(canvas),\n                offset = $canvas.offset();\n            pu.drawImage(canvas, offset.left, offset.top);\n        });\n    },\n    shadow: function(){\n        var sd = currentStyle.dropShadow, dropColor;\n        if(sd.isActive){\n            pu.save();\n            pu.beginPath();\n            \n            this.rect(pu);\n            \n            dropColor = sd.color.slice(0);\n            dropColor.push(sd.opacity/100);\n            dropColor = tools.toColor(dropColor);\n            pu.fillStyle = dropColor;\n            pu.shadowOffsetX = sd.dropX;\n            pu.shadowOffsetY = sd.dropY;\n            pu.shadowBlur = sd.blur;\n            pu.shadowColor = dropColor;\n            pu.fill();\n            pu.closePath();\n            pu.restore();\n        }\n    },\n    innerShadow: function(){\n        var is = currentStyle.innerShadow, dropColor;\n        if(is.isActive){\n            iu.save();\n            iu.beginPath();\n            \n            // draw the layer box as negativ area and use normal dropShadow in another universe\n            // idea by Alistair MacDonald https://gist.github.com/787544\n            \n            iu.rect(0,0,dimensions.width,dimensions.height);\n            iu.moveTo(this.x, this.y);\n            this.rect(iu);\n            \n            dropColor = is.color.slice(0);\n            dropColor.push(is.opacity/100);\n            dropColor = tools.toColor(dropColor);\n            iu.shadowOffsetX = is.dropX;\n            iu.shadowOffsetY = is.dropY;\n            iu.shadowBlur = is.blur;\n            iu.shadowColor = dropColor;\n            iu.fill();\n            iu.closePath();\n            iu.restore();\n            \n            // clip the paralell universe temporarily to the layers size (border-radius!) \n            // and draw the inner shadow from the other universe to the main parallel Universe\n            pu.save();\n            pu.beginPath();\n            this.rect(pu);\n            pu.closePath();\n            pu.clip();\n            pu.drawImage($innerShadowUniverse.get(0), this.x, this.y, currentStyle.width, currentStyle.height, this.x, this.y, currentStyle.width, currentStyle.height);\n            pu.restore();\n            iu.clearRect(0,0,dimensions.width,dimensions.height);\n        }\n    },\n    layerBackground: function(){\n        var bg = currentStyle.background, \n            tempAngle, tempStops;\n    \n        if(bg.isActive) {\n            tempAngle = bg.angle;\n            \n            tempStops = $.extend(true, [], bg.translucidStops); // no deep copy!\n            if(bg.hasGlobalLight) bg.angle = currentStyle.globalAngle;\n            if(bg.isReverse) tempStops = tools.reverseStops(tempStops);\n            pu.fillStyle = tools.decodeCanvasGradient(\n                tempStops, tempAngle, bg.style,\n                pu, this.x, this.y, currentStyle.width, currentStyle.height\n            );\n            pu.fill();\n        }\n    },\n    border: function(){\n        var bd = currentStyle.border, borderColor;\n        if(bd.isActive){\n            borderColor = bd.color.slice(0);\n            borderColor.push(bd.opacity/100);\n            pu.strokeStyle = tools.toColor(borderColor);\n            pu.lineWidth = bd.size;\n            pu.stroke();\n        }\n    }\n};"
  },
  {
    "path": "js/zeroclipboard/ZeroClipboard.as",
    "content": "﻿package {\n\t// Simple Set Clipboard System\n\t// Author: Joseph Huckaby\n\t\n\timport flash.display.Stage;\n\timport flash.display.Sprite;\n\timport flash.display.LoaderInfo;\n\timport flash.display.StageScaleMode;\n\timport flash.events.*;\n\timport flash.display.StageAlign;\n\timport flash.display.StageScaleMode;\n\timport flash.external.ExternalInterface;\n\timport flash.system.Security;\n\timport flash.utils.*;\n\timport flash.system.System;\n \n\tpublic class ZeroClipboard extends Sprite {\n\t\t\n\t\tprivate var id:String = '';\n\t\tprivate var button:Sprite;\n\t\tprivate var clipText:String = '';\n\t\t\n\t\tpublic function ZeroClipboard() {\n\t\t\t// constructor, setup event listeners and external interfaces\n\t\t\tstage.scaleMode = StageScaleMode.EXACT_FIT;\n\t\t\tflash.system.Security.allowDomain(\"*\");\n\t\t\t\n\t\t\t// import flashvars\n\t\t\tvar flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;\n\t\t\tid = flashvars.id;\n\t\t\t\n\t\t\t// invisible button covers entire stage\n\t\t\tbutton = new Sprite();\n\t\t\tbutton.buttonMode = true;\n\t\t\tbutton.useHandCursor = true;\n\t\t\tbutton.graphics.beginFill(0xCCFF00);\n\t\t\tbutton.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));\n\t\t\tbutton.alpha = 0.0;\n\t\t\taddChild(button);\n\t\t\tbutton.addEventListener(MouseEvent.CLICK, clickHandler);\n\t\t\t\n\t\t\tbutton.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event) {\n\t\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseOver', null );\n\t\t\t} );\n\t\t\tbutton.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event) {\n\t\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseOut', null );\n\t\t\t} );\n\t\t\tbutton.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event) {\n\t\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseDown', null );\n\t\t\t} );\n\t\t\tbutton.addEventListener(MouseEvent.MOUSE_UP, function(event:Event) {\n\t\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseUp', null );\n\t\t\t} );\n\t\t\t\n\t\t\t// external functions\n\t\t\tExternalInterface.addCallback(\"setHandCursor\", setHandCursor);\n\t\t\tExternalInterface.addCallback(\"setText\", setText);\n\t\t\t\n\t\t\t// signal to the browser that we are ready\n\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'load', null );\n\t\t}\n\t\t\n\t\tpublic function setText(newText) {\n\t\t\t// set the maximum number of files allowed\n\t\t\tclipText = newText;\n\t\t}\n\t\t\n\t\tpublic function setHandCursor(enabled:Boolean) {\n\t\t\t// control whether the hand cursor is shown on rollover (true)\n\t\t\t// or the default arrow cursor (false)\n\t\t\tbutton.useHandCursor = enabled;\n\t\t}\n\t\t\n\t\tprivate function clickHandler(event:Event):void {\n\t\t\t// user click copies text to clipboard\n\t\t\t// as of flash player 10, this MUST happen from an in-movie flash click event\n\t\t\tSystem.setClipboard( clipText );\n\t\t\tExternalInterface.call( 'ZeroClipboard.dispatch', id, 'complete', clipText );\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "js/zeroclipboard/ZeroClipboard.js",
    "content": "// Simple Set Clipboard System\n// Author: Joseph Huckaby\n\nvar ZeroClipboard = {\n\t\n\tversion: \"1.0.7\",\n\tclients: {}, // registered upload clients on page, indexed by id\n\tmoviePath: 'ZeroClipboard.swf', // URL to movie\n\tnextId: 1, // ID of next movie\n\t\n\t$: function(thingy) {\n\t\t// simple DOM lookup utility function\n\t\tif (typeof(thingy) == 'string') thingy = document.getElementById(thingy);\n\t\tif (!thingy.addClass) {\n\t\t\t// extend element with a few useful methods\n\t\t\tthingy.hide = function() { this.style.display = 'none'; };\n\t\t\tthingy.show = function() { this.style.display = ''; };\n\t\t\tthingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };\n\t\t\tthingy.removeClass = function(name) {\n\t\t\t\tvar classes = this.className.split(/\\s+/);\n\t\t\t\tvar idx = -1;\n\t\t\t\tfor (var k = 0; k < classes.length; k++) {\n\t\t\t\t\tif (classes[k] == name) { idx = k; k = classes.length; }\n\t\t\t\t}\n\t\t\t\tif (idx > -1) {\n\t\t\t\t\tclasses.splice( idx, 1 );\n\t\t\t\t\tthis.className = classes.join(' ');\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tthingy.hasClass = function(name) {\n\t\t\t\treturn !!this.className.match( new RegExp(\"\\\\s*\" + name + \"\\\\s*\") );\n\t\t\t};\n\t\t}\n\t\treturn thingy;\n\t},\n\t\n\tsetMoviePath: function(path) {\n\t\t// set path to ZeroClipboard.swf\n\t\tthis.moviePath = path;\n\t},\n\t\n\tdispatch: function(id, eventName, args) {\n\t\t// receive event from flash movie, send to client\t\t\n\t\tvar client = this.clients[id];\n\t\tif (client) {\n\t\t\tclient.receiveEvent(eventName, args);\n\t\t}\n\t},\n\t\n\tregister: function(id, client) {\n\t\t// register new client to receive events\n\t\tthis.clients[id] = client;\n\t},\n\t\n\tgetDOMObjectPosition: function(obj, stopObj) {\n\t\t// get absolute coordinates for dom element\n\t\tvar info = {\n\t\t\tleft: 0, \n\t\t\ttop: 0, \n\t\t\twidth: obj.width ? obj.width : obj.offsetWidth, \n\t\t\theight: obj.height ? obj.height : obj.offsetHeight\n\t\t};\n\n\t\twhile (obj && (obj != stopObj)) {\n\t\t\tinfo.left += obj.offsetLeft;\n\t\t\tinfo.top += obj.offsetTop;\n\t\t\tobj = obj.offsetParent;\n\t\t}\n\n\t\treturn info;\n\t},\n\t\n\tClient: function(elem) {\n\t\t// constructor for new simple upload client\n\t\tthis.handlers = {};\n\t\t\n\t\t// unique ID\n\t\tthis.id = ZeroClipboard.nextId++;\n\t\tthis.movieId = 'ZeroClipboardMovie_' + this.id;\n\t\t\n\t\t// register client with singleton to receive flash events\n\t\tZeroClipboard.register(this.id, this);\n\t\t\n\t\t// create movie\n\t\tif (elem) this.glue(elem);\n\t}\n};\n\nZeroClipboard.Client.prototype = {\n\t\n\tid: 0, // unique ID for us\n\tready: false, // whether movie is ready to receive events or not\n\tmovie: null, // reference to movie object\n\tclipText: '', // text to copy to clipboard\n\thandCursorEnabled: true, // whether to show hand cursor, or default pointer cursor\n\tcssEffects: true, // enable CSS mouse effects on dom container\n\thandlers: null, // user event handlers\n\t\n\tglue: function(elem, appendElem, stylesToAdd) {\n\t\t// glue to DOM element\n\t\t// elem can be ID or actual DOM element object\n\t\tthis.domElement = ZeroClipboard.$(elem);\n\t\t\n\t\t// float just above object, or zIndex 99 if dom element isn't set\n\t\tvar zIndex = 99;\n\t\tif (this.domElement.style.zIndex) {\n\t\t\tzIndex = parseInt(this.domElement.style.zIndex, 10) + 1;\n\t\t}\n\t\t\n\t\tif (typeof(appendElem) == 'string') {\n\t\t\tappendElem = ZeroClipboard.$(appendElem);\n\t\t}\n\t\telse if (typeof(appendElem) == 'undefined') {\n\t\t\tappendElem = document.getElementsByTagName('body')[0];\n\t\t}\n\t\t\n\t\t// find X/Y position of domElement\n\t\tvar box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem);\n\t\t\n\t\t// create floating DIV above element\n\t\tthis.div = document.createElement('div');\n\t\tvar style = this.div.style;\n\t\tstyle.position = 'absolute';\n\t\tstyle.left = '' + box.left + 'px';\n\t\tstyle.top = '' + box.top + 'px';\n\t\tstyle.width = '' + box.width + 'px';\n\t\tstyle.height = '' + box.height + 'px';\n\t\tstyle.zIndex = zIndex;\n\t\t\n\t\tif (typeof(stylesToAdd) == 'object') {\n\t\t\tfor (addedStyle in stylesToAdd) {\n\t\t\t\tstyle[addedStyle] = stylesToAdd[addedStyle];\n\t\t\t}\n\t\t}\n\t\t\n\t\t// style.backgroundColor = '#f00'; // debug\n\t\t\n\t\tappendElem.appendChild(this.div);\n\t\t\n\t\tthis.div.innerHTML = this.getHTML( box.width, box.height );\n\t},\n\t\n\tgetHTML: function(width, height) {\n\t\t// return HTML for movie\n\t\tvar html = '';\n\t\tvar flashvars = 'id=' + this.id + \n\t\t\t'&width=' + width + \n\t\t\t'&height=' + height;\n\t\t\t\n\t\tif (navigator.userAgent.match(/MSIE/)) {\n\t\t\t// IE gets an OBJECT tag\n\t\t\tvar protocol = location.href.match(/^https/i) ? 'https://' : 'http://';\n\t\t\thtml += '<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0\" width=\"'+width+'\" height=\"'+height+'\" id=\"'+this.movieId+'\" align=\"middle\"><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"allowFullScreen\" value=\"false\" /><param name=\"movie\" value=\"'+ZeroClipboard.moviePath+'\" /><param name=\"loop\" value=\"false\" /><param name=\"menu\" value=\"false\" /><param name=\"quality\" value=\"best\" /><param name=\"bgcolor\" value=\"#ffffff\" /><param name=\"flashvars\" value=\"'+flashvars+'\"/><param name=\"wmode\" value=\"transparent\"/></object>';\n\t\t}\n\t\telse {\n\t\t\t// all other browsers get an EMBED tag\n\t\t\thtml += '<embed id=\"'+this.movieId+'\" src=\"'+ZeroClipboard.moviePath+'\" loop=\"false\" menu=\"false\" quality=\"best\" bgcolor=\"#ffffff\" width=\"'+width+'\" height=\"'+height+'\" name=\"'+this.movieId+'\" align=\"middle\" allowScriptAccess=\"always\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" flashvars=\"'+flashvars+'\" wmode=\"transparent\" />';\n\t\t}\n\t\treturn html;\n\t},\n\t\n\thide: function() {\n\t\t// temporarily hide floater offscreen\n\t\tif (this.div) {\n\t\t\tthis.div.style.left = '-2000px';\n\t\t}\n\t},\n\t\n\tshow: function() {\n\t\t// show ourselves after a call to hide()\n\t\tthis.reposition();\n\t},\n\t\n\tdestroy: function() {\n\t\t// destroy control and floater\n\t\tif (this.domElement && this.div) {\n\t\t\tthis.hide();\n\t\t\tthis.div.innerHTML = '';\n\t\t\t\n\t\t\tvar body = document.getElementsByTagName('body')[0];\n\t\t\ttry { body.removeChild( this.div ); } catch(e) {;}\n\t\t\t\n\t\t\tthis.domElement = null;\n\t\t\tthis.div = null;\n\t\t}\n\t},\n\t\n\treposition: function(elem) {\n\t\t// reposition our floating div, optionally to new container\n\t\t// warning: container CANNOT change size, only position\n\t\tif (elem) {\n\t\t\tthis.domElement = ZeroClipboard.$(elem);\n\t\t\tif (!this.domElement) this.hide();\n\t\t}\n\t\t\n\t\tif (this.domElement && this.div) {\n\t\t\tvar box = ZeroClipboard.getDOMObjectPosition(this.domElement);\n\t\t\tvar style = this.div.style;\n\t\t\tstyle.left = '' + box.left + 'px';\n\t\t\tstyle.top = '' + box.top + 'px';\n\t\t}\n\t},\n\t\n\tsetText: function(newText) {\n\t\t// set text to be copied to clipboard\n\t\tthis.clipText = newText;\n\t\tif (this.ready) this.movie.setText(newText);\n\t},\n\t\n\taddEventListener: function(eventName, func) {\n\t\t// add user event listener for event\n\t\t// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel\n\t\teventName = eventName.toString().toLowerCase().replace(/^on/, '');\n\t\tif (!this.handlers[eventName]) this.handlers[eventName] = [];\n\t\tthis.handlers[eventName].push(func);\n\t},\n\t\n\tsetHandCursor: function(enabled) {\n\t\t// enable hand cursor (true), or default arrow cursor (false)\n\t\tthis.handCursorEnabled = enabled;\n\t\tif (this.ready) this.movie.setHandCursor(enabled);\n\t},\n\t\n\tsetCSSEffects: function(enabled) {\n\t\t// enable or disable CSS effects on DOM container\n\t\tthis.cssEffects = !!enabled;\n\t},\n\t\n\treceiveEvent: function(eventName, args) {\n\t\t// receive event from flash\n\t\teventName = eventName.toString().toLowerCase().replace(/^on/, '');\n\t\t\t\t\n\t\t// special behavior for certain events\n\t\tswitch (eventName) {\n\t\t\tcase 'load':\n\t\t\t\t// movie claims it is ready, but in IE this isn't always the case...\n\t\t\t\t// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function\n\t\t\t\tthis.movie = document.getElementById(this.movieId);\n\t\t\t\tif (!this.movie) {\n\t\t\t\t\tvar self = this;\n\t\t\t\t\tsetTimeout( function() { self.receiveEvent('load', null); }, 1 );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// firefox on pc needs a \"kick\" in order to set these in certain cases\n\t\t\t\tif (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {\n\t\t\t\t\tvar self = this;\n\t\t\t\t\tsetTimeout( function() { self.receiveEvent('load', null); }, 100 );\n\t\t\t\t\tthis.ready = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.ready = true;\n\t\t\t\tthis.movie.setText( this.clipText );\n\t\t\t\tthis.movie.setHandCursor( this.handCursorEnabled );\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 'mouseover':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.domElement.addClass('hover');\n\t\t\t\t\tif (this.recoverActive) this.domElement.addClass('active');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 'mouseout':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.recoverActive = false;\n\t\t\t\t\tif (this.domElement.hasClass('active')) {\n\t\t\t\t\t\tthis.domElement.removeClass('active');\n\t\t\t\t\t\tthis.recoverActive = true;\n\t\t\t\t\t}\n\t\t\t\t\tthis.domElement.removeClass('hover');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 'mousedown':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.domElement.addClass('active');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 'mouseup':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.domElement.removeClass('active');\n\t\t\t\t\tthis.recoverActive = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t} // switch eventName\n\t\t\n\t\tif (this.handlers[eventName]) {\n\t\t\tfor (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {\n\t\t\t\tvar func = this.handlers[eventName][idx];\n\t\t\t\n\t\t\t\tif (typeof(func) == 'function') {\n\t\t\t\t\t// actual function reference\n\t\t\t\t\tfunc(this, args);\n\t\t\t\t}\n\t\t\t\telse if ((typeof(func) == 'object') && (func.length == 2)) {\n\t\t\t\t\t// PHP style object + method, i.e. [myObject, 'myMethod']\n\t\t\t\t\tfunc[0][ func[1] ](this, args);\n\t\t\t\t}\n\t\t\t\telse if (typeof(func) == 'string') {\n\t\t\t\t\t// name of function\n\t\t\t\t\twindow[func](this, args);\n\t\t\t\t}\n\t\t\t} // foreach event handler defined\n\t\t} // user defined handler for event\n\t}\n\t\n};\n"
  }
]