[
  {
    "path": ".gitignore",
    "content": "bower_components\n.idea"
  },
  {
    "path": "README.md",
    "content": "<img alt=\"HTML GL\" src=\"http://pixelscommander.com/polygon/htmlgl/figures/logo-blue.png\"/>\n\n60 FPS and amazing effects by rendering HTML/CSS in WebGL, framework agnostic\n=======================================================================================\n\n[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/PixelsCommander/HTML-GL)\n\nHTML GL solves \"the slow DOM problem\" by creating WebGL representations of DOM elements and hiding actual DOM after. This speeds up HTML/CSS animations and transformations by using 3D hardware acceleration and allows to apply OpenGL effects as modern 3D games have.\n\n- [Demo](http://pixelscommander.com/polygon/htmlgl/demo/filters.html)\n- [Project page](http://htmlgl.com)\n- [Theory behind HTML GL](http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/)\n\nUsing HTML GL you still work with HTML/CSS as you are common to, but DOM elements are just facades to their WebGL representations. These GPU accelerated textures are very effective from resources consuming perspective and are very cheap to transform or animate.\n\nInstall\n-------\nnpm:\n```bash\nnpm install --save html-gl\n```\nBower:\n```bash\nbower install --save htmlgl\n```\n\nUsage\n-----\n\nAs Web Component\n\n```html\n<html-gl>\n    This element`s content is rendered in <h1>WebGL</h1>\n    <span style=\"color: green;\">was it easy?</span>\n    Feel free to use CSS, images and all you are common to in HTML/CSS world.\n</html-gl>\n```\n\nAs jQuery plugin\n\n```js\n$('.some div').htmlgl();\n```\n\nNo DOM + WebGL rendering = highest FPS possible for Web platform\n-------------------------------------------------------\n\n<img alt=\"HTML GL flow diagram\" src=\"http://pixelscommander.com/polygon/htmlgl/figures/htmlgl-flow-diagram.png\"/>\n\nDemos\n-----\n\n- [Filters](http://pixelscommander.com/polygon/htmlgl/demo/filters.html) WebGL is not only about performance. It breaks any HTML/CSS limits in terms of animations and interactivity\n- [Mobile effects](http://pixelscommander.com/polygon/htmlgl/demo/ripples.html) use attribute `effects` on `<html-gl>` element to specify effects you use, this one is nice for mobile\n- [Basic HTML GL](http://pixelscommander.com/polygon/htmlgl/demo/basic-webgl.html) demo shows how to use HTML GL and animate GL Elements. It also demonstrate that HTML GL handle content change events and repaints element`s WebGL representation\n- [Basic DOM](http://pixelscommander.com/polygon/htmlgl/demo/basic-dom.html) this is the same project as previous. The only difference is that htmlgl.js is not included\n- [Advanced content HTML GL](http://pixelscommander.com/polygon/htmlgl/demo/advanced-content-webgl.html) slider with nested content rendered via WebGL and animated, ability to drag with mouse horizontaly, click event listeners on boxes\n- [Advanced content DOM](http://pixelscommander.com/polygon/htmlgl/demo/advanced-content-dom.html)\n\nHow to use?\n-----------\nInclude HTMLGL.js into project. Use tag name `<html-gl>` or jQuery plugin `$(myElement).htmlgl()` for elements you are going to animate. These elements will be rendered in WebGL and their CSS Transform properties will be mapped to WebGL representation transformations. So DOM node itself will not be animated or displayed in order to avoid resources consuming.\nHTML GL is framework agnostic and is easy to inject into existing project which needs performance tweaking.\n\nRasterization API\n-----------------\nIn order to improve technology we are trying to promote standardized native Rasterization API for JavaScript. Help us to be better and to add this cool feature to browsers by spreading the [article](http://pixelscommander.com/en/javascript/state-of-html-content-rasterization-draw-html-to-canvas-image/) and [proposal draft](https://gist.github.com/PixelsCommander/a0b5882139cbb8a1781c#file-proposal-md).\n\nFast way to animate\n-------------------\nThe most performant way to animate HTML-GL tags is to operate on tag's `styleGL.transform` in the same way you operate on `style.transform`. E.g. `style.transform = 'translateX(100px) translateY(50px)'`.\nVelocity.js copy from HTML-GL repository (https://github.com/PixelsCommander/HTML-GL/blob/master/demo/js/vendor/velocity.js) have this optimization built-in. Feel free to use it in the way described in official Velocity.js documentation.\n\nAnimating HTML-GL tag children\n------------------------------\nSince it is very efficient to make transformations (move, rotate, scale, change opacity) on HTML-GL tags it becomes very slow to animate it's children until they are HTML-GL tags too. This happens because of necessity to rasterize and send HTML-GL tag texture to GPU.\n\nRunning demos from repository\n-----------------------------\nPlease run `bower install` before running demos\n\nLicense\n-------\nMIT: http://mit-license.org/\n\nCopyright 2015 Denis Radin aka [PixelsCommander](http://pixelscommander.com)\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"htmlgl\",\n  \"authors\": [\n    \"PixelsCommander <denis.radin@gmail.com>\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"pixi\": \"~3.0.7\",\n    \"webcomponents.js\": \"~0.5.5\",\n    \"promise-polyfill\": \"~2.0.0\",\n    \"jquery\": \"~2.1.3\",\n    \"tween.js\": \"https://github.com/tweenjs/tween.js.git\"\n  },\n  \"keywords\": [\"web-components\"]\n}\n"
  },
  {
    "path": "demo/advanced-content-dom.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"./assets/css/style.css\">\n    <title>DOM content</title>\n    <meta name=\"viewport\" content=\"width=1024 maximum-scale=1.0 minimum-scale=1.0 initial-scale=1.0, user-scalable=no\" />\n</head>\n<body>\n<div class=\"content_wrapper\">\n    <h1>MENU RENDERED IN DOM</h1>\n    <nav class=\"top_nav\">\n        <ul class=\"menu expanded\">\n            <li><a target=\"_blank\" href=\"http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/\">ABOUT HTML-GL</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL\">GITHUB REPO</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL/archive/master.zip\">DOWNLOAD</a></li>\n        </ul>\n        <ul class=\"submenu\">\n            <li>MOVIES</li>\n            <li>TV</li>\n            <li>KIDS</li>\n            <li>\n                <!-- AddThis Button BEGIN -->\n                <div class=\"addthis_toolbox addthis_default_style\">\n                    <iframe style=\"display: inline-block;\"\n                            src=\"http://ghbtns.com/github-btn.html?user=PixelsCommander&repo=HTML-GL&type=watch\"\n                            allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"62\" height=\"20\"></iframe>\n                    <a class=\"addthis_button_tweet\"></a>\n                    <a class=\"addthis_button_google_plusone\" g:plusone:size=\"medium\"></a>\n                </div>\n                <script type=\"text/javascript\">var addthis_config = {\"data_track_addressbar\":true};</script>\n                <script type=\"text/javascript\" src=\"//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4ea2f9164143bcfb\"></script>\n                <!-- AddThis Button END -->\n            </li>\n        </ul>\n    </nav>\n    <section class=\"broadcasts_list\">\n        <h1>DOM SLIDER SINCE HTML GL IS DISABLED FOR THIS DEMO</h1>\n        <html-gl class=\"horizontal_carusel\">\n            <li class=\"broadcast\" onclick=\"alert('Clicked Argo')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_argo.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Select me with DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.8<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Avatar')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_avatar.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Change me in DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>8.0<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Breaking Bad')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_breaking_bad.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Breaking bad\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>9.6<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>6.7<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <div class=\"\">\n\n            </div>\n        </html-gl>\n    </section>\n</div>\n<script src=\"./js/vendor/velocity.js\"></script>\n<script src=\"./js/slider.js\"></script>\n<script>\n    window.addEventListener('load', function () {\n        setTimeout(function () {\n            Velocity(document.getElementsByTagName('html-gl')[0], {translateX: 408}, {duration: 500});\n        }, 500);\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/advanced-content-webgl.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"./assets/css/style.css\">\n    <title>HTML GL nested content</title>\n    <meta name=\"viewport\" content=\"width=1024 maximum-scale=1.0 minimum-scale=1.0 initial-scale=1.0, user-scalable=no\" />\n</head>\n<body>\n<div class=\"content_wrapper\">\n    <h1>MENU RENDERED IN DOM</h1>\n    <nav class=\"top_nav\">\n        <ul class=\"menu expanded\">\n            <li><a target=\"_blank\" href=\"http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/\">ABOUT HTML-GL</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL\">GITHUB REPO</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL/archive/master.zip\">DOWNLOAD</a></li>\n        </ul>\n        <ul class=\"submenu\">\n            <li>MOVIES</li>\n            <li>TV</li>\n            <li>KIDS</li>\n            <li>\n                <!-- AddThis Button BEGIN -->\n                <div class=\"addthis_toolbox addthis_default_style\">\n                    <iframe style=\"display: inline-block;\"\n                            src=\"http://ghbtns.com/github-btn.html?user=PixelsCommander&repo=HTML-GL&type=watch\"\n                            allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"62\" height=\"20\"></iframe>\n                    <a class=\"addthis_button_tweet\"></a>\n                    <a class=\"addthis_button_google_plusone\" g:plusone:size=\"medium\"></a>\n                </div>\n                <script type=\"text/javascript\">var addthis_config = {\"data_track_addressbar\":true};</script>\n                <script type=\"text/javascript\" src=\"//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4ea2f9164143bcfb\"></script>\n                <!-- AddThis Button END -->\n            </li>\n        </ul>\n    </nav>\n    <section class=\"broadcasts_list\">\n        <h1>SLIDER BELOW IS RENDERED IN WEBGL, DRAG IT</h1>\n        <html-gl class=\"horizontal_carusel\">\n            <li class=\"broadcast\" onclick=\"alert('Clicked Argo')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_argo.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Select me with DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.8<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Avatar')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_avatar.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Change me in DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>8.0<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Breaking Bad')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_breaking_bad.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Breaking bad\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>9.6<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>6.7<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <div class=\"\">\n\n            </div>\n        </html-gl>\n    </section>\n</div>\n<script src=\"../dist/htmlgl.js\"></script>\n<script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n<script src=\"./js/vendor/velocity.js\"></script>\n<script src=\"./js/vendor/html2canvas.js\"></script>\n<script src=\"../bower_components/pixi/bin/pixi.js\"></script>\n<script src=\"../src/util.js\"></script>\n<script src=\"../src/gl-element-resolver.js\"></script>\n<script src=\"../src/gl-context.js\"></script>\n<script src=\"../src/images-loaded.js\"></script>\n<script src=\"../src/gl-element.js\"></script>\n<script src=\"./js/slider.js\"></script>\n<script>\n    window.addEventListener('load', function () {\n        setTimeout(function () {\n            Velocity(document.getElementsByTagName('html-gl')[0], {translateX: 408}, {duration: 500});\n        }, 500);\n    });\n\n    document.getElementsByTagName('html-gl')[0].addEventListener('htmlglReady', function(e){\n        alert('htmlglReady');\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/assets/css/appstyle.css",
    "content": "/** Generated by FG **/\n@font-face {\n    font-family: 'Conv_InterstatePro-Bold';\n    src: url('../fonts/InterstatePro-Bold.eot');\n    src: local('☺'), url('../fonts/InterstatePro-Bold.woff') format('woff'), url('../fonts/InterstatePro-Bold.ttf') format('truetype'), url('../fonts/InterstatePro-Bold.svg') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n    font-family: 'Conv_InterstatePro-Light';\n    src: url('../fonts/InterstatePro-Light.eot');\n    src: local('☺'), url('../fonts/InterstatePro-Light.woff') format('woff'), url('../fonts/InterstatePro-Light.ttf') format('truetype'), url('../fonts/InterstatePro-Light.svg') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n    font-family: 'Conv_InterstatePro-ExtraLight';\n    src: url('../fonts/InterstatePro-ExtraLight.eot');\n    src: local('☺'), url('../fonts/InterstatePro-ExtraLight.woff') format('woff'), url('../fonts/InterstatePro-ExtraLight.ttf') format('truetype'), url('../fonts/InterstatePro-ExtraLight.svg') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n    font-family: 'Conv_InterstatePro-Regular';\n    src: url('../fonts/InterstatePro-Regular.eot');\n    src: local('☺'), url('../fonts/InterstatePro-Regular.woff') format('woff'), url('../fonts/InterstatePro-Regular.ttf') format('truetype'), url('../fonts/InterstatePro-Regular.svg') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n@font-face {\n    font-family: \"UPCDigital\";\n    src: url(../fonts/DAWN-UPCDiRg.ttf) format(\"truetype\");\n    font-weight: 400;\n}\n@font-face {\n    font-family: 'UPCDigital-bold';\n    src: url(../fonts/DAWN-UPCDiBd.ttf) format('truetype');\n}\n\nbody {\n    box-sizing: border-box;\n    /* padding: 20px 43px 0 43px; */\n    margin: 0;\n    font-family: Conv_InterstatePro-Regular;\n    font-weight: normal;\n    font-size: 24px;\n    color: #2c3e50;\n    width: 100%;\n    height: 100%;\n    background-color: #ecf0f1;\n    overflow-x: hidden;\n}\n\nul {\n    list-style: none;\n}\n\nli {\n    text-align: center;\n    display: inline-block;\n    vertical-align:top;\n    padding: 20px;\n}\n\np {\n    width: 128px;\n    margin-top: 15px;\n}"
  },
  {
    "path": "demo/assets/css/style.css",
    "content": "/** Generated by FG **/\n@font-face {\n  font-family: 'Conv_InterstatePro-Bold';\n  src: url('../fonts/InterstatePro-Bold.eot');\n  src: local('☺'), url('../fonts/InterstatePro-Bold.woff') format('woff'), url('../fonts/InterstatePro-Bold.ttf') format('truetype'), url('../fonts/InterstatePro-Bold.svg') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n  font-family: 'Conv_InterstatePro-Light';\n  src: url('../fonts/InterstatePro-Light.eot');\n  src: local('☺'), url('../fonts/InterstatePro-Light.woff') format('woff'), url('../fonts/InterstatePro-Light.ttf') format('truetype'), url('../fonts/InterstatePro-Light.svg') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n  font-family: 'Conv_InterstatePro-ExtraLight';\n  src: url('../fonts/InterstatePro-ExtraLight.eot');\n  src: local('☺'), url('../fonts/InterstatePro-ExtraLight.woff') format('woff'), url('../fonts/InterstatePro-ExtraLight.ttf') format('truetype'), url('../fonts/InterstatePro-ExtraLight.svg') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/** Generated by FG **/\n@font-face {\n  font-family: 'Conv_InterstatePro-Regular';\n  src: url('../fonts/InterstatePro-Regular.eot');\n  src: local('☺'), url('../fonts/InterstatePro-Regular.woff') format('woff'), url('../fonts/InterstatePro-Regular.ttf') format('truetype'), url('../fonts/InterstatePro-Regular.svg') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n@font-face {\n  font-family: \"UPCDigital\";\n  src: url(../fonts/DAWN-UPCDiRg.ttf) format(\"truetype\");\n  font-weight: 400;\n}\n@font-face {\n  font-family: 'UPCDigital-bold';\n  src: url(../fonts/DAWN-UPCDiBd.ttf) format('truetype');\n}\n\nhtml {\n    overflow-x: hidden;\n}\nbody {\n  box-sizing: border-box;\n  padding: 30px 93px 0 93px;\n  margin: 0;\n  font-family: Conv_InterstatePro-Regular;\n  font-weight: normal;\n  color: #ffffff;\n  width: 100%;\n  height: 100%;\n  background: url(\"../../pic/bgs/Descendants.png\") no-repeat #000000;\n  overflow-x: hidden;\n}\nhtml-gl {\n  display: block;\n}\n\nh1 {\n  font-family: verdana, sans-serif;\n  font-size: 16px;\n  margin: 0 0 30px 0;\n  font-weight: 300;\n  color: #858382;\n}\n.menu {\n  font-size: 30px;\n}\n.menu.expanded {\n  border-bottom: 1px solid #858382;\n}\na {\n    font-family: verdana, sans-serif;\n    margin: 0 0 30px 0;\n    font-weight: 300;\n    color: #ffffff;\n    text-decoration: none;\n}\na:hover {\n    text-decoration: underline;\n}\nul.menu,\nul.submenu {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  line-height: 1em;\n  padding: 0 0 6px 0;\n}\nul.submenu {\n  padding: 6px 0 0 0;\n}\n.menu li {\n  display: inline;\n  padding-right: 30px;\n}\n.submenu {\n  font-size: 26px;\n}\n.submenu li {\n    overflow: hidden;\n    height: 24px;\n  display: inline-block;\n  padding-right: 30px;\n}\n.broadcasts_list {\n  margin: 36px 0 0 0;\n  padding: 0 0 36px 0;\n    /* TODO Implement overflow masks in WebGL\n    overflow-x: hidden;*/\n}\n.broadcasts_list h1 {\n  font-family: Conv_InterstatePro-Light;\n  font-size: 22px;\n  font-weight: 300;\n  margin: 0 0 5px 0;\n  line-height: 1em;\n}\n.broadcasts_list ul {\n  list-style: none;\n  padding: 0;\n  margin: 0;\n  white-space: nowrap;\n}\n.broadcasts_list li {\n  display: inline-block;\n  width: 186px;\n  margin-right: 15px;\n}\n.broadcast {\n  position: relative;\n  font-family: \"UPCDigital\";\n  font-size: 16px;\n  line-height: 24px;\n}\n.image_overlay,\n.image_background,\n.broadcast > img {\n  width: 186px;\n  height: 270px;\n}\n.image_background {\n  position: absolute;\n  left: 0;\n  top: 0;\n  background-color: #000000;\n}\n.broadcast > img {\n  width: 186px;\n  height: 270px;\n  border: 1px solid #858382;\n  box-sizing: border-box;\n  opacity: 0.8;\n}\n.image_overlay {\n  position: absolute;\n  left: 0;\n  top: 0;\n  background-color: #000000;\n  opacity: 0.2;\n}\n.broadcast p {\n  line-height: 20px;\n  margin: 0 0 3px 0;\n  padding: 0;\n  color: #D2D2D2;\n}\n.broadcast p img {\n  width: 52px;\n  height: 24px;\n  display: inline-block;\n}\n.broadcast p > span {\n  font-family: UPCDigital-bold;\n  display: inline-block;\n  color: #ffffff;\n  vertical-align: top;\n  font-size: 16px;\n  margin-left: 3px;\n}\n.broadcast p > span span {\n  color: #808080;\n  display: inline-block;\n  vertical-align: baseline;\n  font-size: 12px;\n}\n"
  },
  {
    "path": "demo/assets/fonts/README-FONTS.txt",
    "content": "we experienced that web apps could reference their own versions of fonts our app uses\n\nin some cases this broke DAWN for example, special characters began to display incorrectly\n\nin order to avoid this situation, we're namespacing our fonts with the 'DAWN-' prefix\n\nthe rename function of the Typelite application (http://www.cr8software.net/typex.html) was used\nto accomplish this initially\n"
  },
  {
    "path": "demo/basic-dom.html",
    "content": "<!DOCTYPE html>\n<html>\n<head lang=\"en\">\n    <meta charset=\"UTF-8\">\n    <title>HTML GL demo</title>\n    <style>\n        html-gl {\n            display: inline-block;\n        }\n    </style>\n    <script src=\"./js/vendor/velocity.js\"></script>\n</head>\n<body>\n<h1>HTML GL demo</h1>\n<html-gl>\n    This layer is rendered as a <h1>DOM</h1> <span style=\"color: red;\">because</span> <b>HTML GL</b> is disabled\n</html-gl>\n<button onclick=\"window.animate()\">Animate WebGL layer</button>\n<button onclick=\"window.changeNodeContent()\">Change layer content</button>\n<button onclick=\"window.changeNodeTransform()\">Simply change layer`s style.transform</button>\n<h2>\n    TODO\n</h2>\n<ul>\n    <li>Switch to WebGL for more performant animations</li>\n</ul>\n<script>\n    window.changeNodeContent = function () {\n        document.getElementsByTagName('html-gl')[0].textContent = 'DOM is a bit slower, but still ok on desktop. However for mobile WebGL is a way better.';\n    }\n\n    window.changeNodeTransform = function () {\n        var element = document.getElementsByTagName('html-gl')[0];\n        element.style.webkitTransform = 'translateX(400px) translateY(100px)';\n        element.style.transform = 'translateX(400px) translateY(100px)';\n    }\n\n    window.animate = function () {\n        var element = document.getElementsByTagName('html-gl')[0];\n\n        Velocity(element, {\n            translateX: 100,\n            translateY: 100,\n            translateZ: 0,\n            scaleX: 4,\n            scaleY: 4,\n            rotateZ: \"360deg\"\n        }, {duration: 5000})\n        .then(function () {\n            Velocity(element, {\n                translateX: 0,\n                translateY: 0,\n                translateZ: 0,\n                scaleX: 1,\n                scaleY: 1,\n                rotateZ: \"0\"\n            }, {duration: 5000});\n        });\n    }\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/basic-webgl-jquery.html",
    "content": "<!DOCTYPE html>\n<html>\n<head lang=\"en\">\n    <meta charset=\"UTF-8\">\n    <title>HTML GL demo</title>\n    <script src=\"../bower_components/promise-polyfill/Promise.min.js\"></script>\n    <script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n    <script src=\"../bower_components/jquery/dist/jquery.min.js\"></script>\n    <script src=\"./js/vendor/velocity.js\"></script>\n    <script src=\"./js/vendor/html2canvas.js\"></script>\n    <script src=\"../bower_components/pixi/bin/pixi.dev.js\"></script>\n    <script src=\"../src/util.js\"></script>\n    <script src=\"../src/gl-element-resolver.js\"></script>\n    <script src=\"../src/gl-context.js\"></script>\n    <script src=\"../src/images-loaded.js\"></script>\n    <script src=\"../src/gl-element.js\"></script>\n</head>\n<!-- Adding style since demo is designed for inline-block, otherwise will have full screen width -->\n<style>\n    #htmlgl-content {\n        display: inline-block;\n    }\n</style>\n<body>\n<h1>HTML GL demo</h1>\n\n<div id=\"htmlgl-content\">\n    This layer is rendered in <h1>WebGL</h1> <span style=\"color: red;\">because</span> it have tag name <b>html-gl</b>\n</div>\n<button onclick=\"window.animate()\">Animate WebGL layer</button>\n<button onclick=\"window.changeNodeContent()\">Change layer content</button>\n<button onclick=\"window.changeNodeTransform()\">Simply change layer`s style.transform</button>\n<h2>\n    TODO\n</h2>\n<ul>\n    <li>Add retina support in order to avoid blurry content</li>\n</ul>\n<script>\n    $('#htmlgl-content').htmlgl();\n\n    window.changeNodeContent = function () {\n        document.getElementsByTagName('div')[0].textContent = 'Animation was smooth, was not it? This is a new content. It is still visible in dev tools, affects HTML layout and is rendered via WebGL.';\n    }\n\n    window.changeNodeTransform = function () {\n        var element = document.getElementsByTagName('div')[0];\n        element.style.webkitTransform = 'translateX(400px) translateY(100px)';\n        element.style.transform = 'translateX(400px) translateY(100px)';\n    }\n\n    window.animate = function () {\n        $('#htmlgl-content').velocity({\n            translateX: 100,\n            translateY: 100,\n            scaleX: 4,\n            scaleY: 4,\n            rotateZ: \"360deg\"\n        }, { duration: 1000 }).velocity({\n            translateX: 0,\n            translateY: 0,\n            scaleX: 1,\n            scaleY: 1,\n            rotateZ: \"0\"\n        }, { duration: 1000 });\n    }\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/basic-webgl.html",
    "content": "<!DOCTYPE html>\n<html>\n<head lang=\"en\">\n    <meta charset=\"UTF-8\">\n    <title>HTML GL demo</title>\n</head>\n<body style=\"height: 1024px;\">\n<h1>HTML GL demo</h1>\n<html-gl>\n    This layer is rendered in <h1>WebGL</h1> <span style=\"color: red;\">because</span> it have tag name <b>html-gl</b>\n</html-gl>\n<button onclick=\"window.animate()\">Animate WebGL layer</button>\n<button onclick=\"window.changeNodeContent()\">Change layer content</button>\n<button onclick=\"window.changeNodeTransform()\">Simply change layer`s style.transform</button>\n<h2>\n    TODO\n</h2>\n<ul>\n    <li>Add more effects presets</li>\n</ul>\n<script src=\"../dist/htmlgl.js\"></script>\n<script>\n    window.changeNodeContent = function () {\n        document.getElementsByTagName('html-gl')[0].textContent = 'Animation was smooth, was not it? This is a new content. It is still visible in dev tools, affects HTML layout and is rendered via WebGL.';\n    }\n\n    window.changeNodeTransform = function () {\n        var element = document.getElementsByTagName('html-gl')[0];\n        element.style.webkitTransform = 'translateX(400px) translateY(100px)';\n        element.style.transform = 'translateX(400px) translateY(100px)';\n    }\n\n    document.addEventListener('keydown', function(){\n        window.devicePixelRatio = window.devicePixelRatio === 1 ? 2 : 1;\n        HTMLGL.context.resizeViewer();\n    });\n\n    window.animate = function () {\n        var element = document.getElementsByTagName('html-gl')[0];\n\n        var v = Velocity(element, {\n            translateX: 100,\n            translateY: 100,\n            scaleX: 4,\n            scaleY: 4,\n            rotateZ: \"360deg\"\n        }, {duration: 5000}).then(function () {\n            Velocity(element, {\n                translateX: 0,\n                translateY: 0,\n                scaleX: 1,\n                scaleY: 1,\n                rotateZ: \"0\"\n            }, {duration: 5000});\n        });\n    }\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/filters.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"./assets/css/style.css\">\n    <title>HTML GL filters demo</title>\n    <meta name=\"viewport\" content=\"width=1024 maximum-scale=1.0 minimum-scale=1.0 initial-scale=1.0, user-scalable=no\" />\n</head>\n<body>\n<div class=\"content_wrapper\">\n    <h1>MENU RENDERED IN DOM</h1>\n    <nav class=\"top_nav\">\n        <ul class=\"menu expanded\">\n            <li><a target=\"_blank\" href=\"http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/\">ABOUT HTML-GL</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL\">GITHUB REPO</a></li>\n        </ul>\n        <ul class=\"submenu\">\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL/archive/master.zip\">DOWNLOAD</a></li>\n            <li>\n                <!-- AddThis Button BEGIN -->\n                <div class=\"addthis_toolbox addthis_default_style\">\n                    <iframe style=\"display: inline-block;\"\n                            src=\"http://ghbtns.com/github-btn.html?user=PixelsCommander&repo=HTML-GL&type=watch\"\n                            allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"62\" height=\"20\"></iframe>\n                    <a class=\"addthis_button_tweet\"></a>\n                    <a class=\"addthis_button_google_plusone\" g:plusone:size=\"medium\"></a>\n                </div>\n                <script type=\"text/javascript\">var addthis_config = {\"data_track_addressbar\":true};</script>\n                <script type=\"text/javascript\" src=\"//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4ea2f9164143bcfb\"></script>\n                <!-- AddThis Button END -->\n            </li>\n        </ul>\n    </nav>\n    <section class=\"broadcasts_list\">\n        <h1>SLIDER BELOW IS RENDERED IN WEBGL, DRAG IT</h1>\n        <html-gl class=\"horizontal_carusel\">\n            <li class=\"broadcast\" onclick=\"alert('Clicked Argo')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_argo.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Select me with DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.8<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Avatar')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_avatar.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Change me in DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>8.0<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Breaking Bad')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_breaking_bad.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Breaking bad\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>9.6<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>6.7<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <div class=\"\">\n\n            </div>\n        </html-gl>\n    </section>\n</div>\n\n<script src=\"../bower_components/promise-polyfill/Promise.min.js\"></script>\n<script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n<script src=\"./js/vendor/velocity.js\"></script>\n<script src=\"./js/vendor/html2canvas.js\"></script>\n<script src=\"../bower_components/pixi/bin/pixi.js\"></script>\n<script src=\"../src/util.js\"></script>\n<script src=\"../src/gl-element-resolver.js\"></script>\n<script src=\"../src/gl-context.js\"></script>\n<script src=\"../src/images-loaded.js\"></script>\n<script src=\"../src/gl-element.js\"></script>\n<script src=\"./js/slider.js\"></script>\n<script src=\"./js/vendor/dat.gui.min.js\"></script>\n<script>\n\n    var renderer = window.HTMLGL.renderer;\n\n    var filtersSwitchs = [true, false, false, false, false, false, false, false, false, false, false];\n\n    var gui = new dat.GUI({});\n\n\n\n    var displacementSprite = new PIXI.TilingSprite.fromImage(\"assets/img/displacement_map.jpg\");\n    window.HTMLGL.stage.addChild(displacementSprite);\n    var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);\n\n    var displacementFolder = gui.addFolder('Displacement');\n    displacementFolder.add(filtersSwitchs, '0').name(\"apply\");\n    displacementFolder.add(displacementFilter.scale, 'x', 1, 200).name(\"scaleX\");\n    displacementFolder.add(displacementFilter.scale, 'y', 1, 200).name(\"scaleY\");\n    displacementFolder.open();\n\n    var blurFilter = new PIXI.filters.BlurFilter();\n\n    var blurFolder = gui.addFolder('Blur');\n    blurFolder.add(filtersSwitchs, '1').name(\"apply\");\n    blurFolder.add(blurFilter, 'blurX', 0, 32).name(\"blurX\");\n    blurFolder.add(blurFilter, 'blurY', 0, 32).name(\"blurY\");\n\n    ////\n\n    var pixelateFilter = new PIXI.filters.PixelateFilter();\n\n    var pixelateFolder = gui.addFolder('Pixelate');\n    pixelateFolder.add(filtersSwitchs, '2').name(\"apply\");\n    pixelateFolder.add(pixelateFilter.size, 'x', 1, 32).name(\"PixelSizeX\");\n    pixelateFolder.add(pixelateFilter.size, 'y', 1, 32).name(\"PixelSizeY\");\n\n    ////\n\n    var invertFilter = new PIXI.filters.InvertFilter();\n\n    var invertFolder = gui.addFolder('Invert');\n    invertFolder.add(filtersSwitchs, '3').name(\"apply\");\n    invertFolder.add(invertFilter, 'invert', 0, 1).name(\"Invert\");\n\n    ////\n\n    var grayFilter = new PIXI.filters.GrayFilter();\n\n    var grayFolder = gui.addFolder('Gray');\n    grayFolder.add(filtersSwitchs, '4').name(\"apply\");\n    grayFolder.add(grayFilter, 'gray', 0, 1).name(\"Gray\");\n\n    ////\n\n    var sepiaFilter = new PIXI.filters.SepiaFilter();\n\n    var sepiaFolder = gui.addFolder('Sepia');\n    sepiaFolder.add(filtersSwitchs, '5').name(\"apply\");\n    sepiaFolder.add(sepiaFilter, 'sepia', 0, 1).name(\"Sepia\");\n\n    ////\n\n    var twistFilter = new PIXI.filters.TwistFilter();\n\n    var twistFolder = gui.addFolder('Twist');\n    twistFolder.add(filtersSwitchs, '6').name(\"apply\");\n    twistFolder.add(twistFilter, 'angle', 0, 10).name(\"Angle\");\n    twistFolder.add(twistFilter, 'radius', 0, 1).name(\"Radius\");\n\n    twistFolder.add(twistFilter.offset, 'x', 0, 1).name(\"offset.x\");;\n    twistFolder.add(twistFilter.offset, 'y', 0, 1).name(\"offset.y\");;\n\n    ////\n\n    var dotScreenFilter = new PIXI.filters.DotScreenFilter();\n\n    var dotScreenFolder = gui.addFolder('DotScreen');\n    dotScreenFolder.add(filtersSwitchs, '7').name(\"apply\");\n    dotScreenFolder.add(dotScreenFilter, 'angle', 0, 10);\n    dotScreenFolder.add(dotScreenFilter, 'scale', 0, 1);\n\n    ////\n\n    var colorStepFilter = new PIXI.filters.ColorStepFilter();\n\n    var colorStepFolder = gui.addFolder('ColorStep');\n    colorStepFolder.add(filtersSwitchs, '8').name(\"apply\");\n\n    colorStepFolder.add(colorStepFilter, 'step', 1, 100);\n    colorStepFolder.add(colorStepFilter, 'step', 1, 100);\n\n    ////\n\n    var crossHatchFilter = new PIXI.filters.CrossHatchFilter();\n\n    var crossHatchFolder = gui.addFolder('CrossHatch');\n    crossHatchFolder.add(filtersSwitchs, '9').name(\"apply\");\n\n    var rgbSplitterFilter = new PIXI.filters.RGBSplitFilter();\n\n    rgbSplitterFilter.blue = new PIXI.Point(10, 10);\n    rgbSplitterFilter.green = new PIXI.Point(-10, 10);\n    rgbSplitterFilter.red = new PIXI.Point(10, -10);\n\n    var rgbSplitFolder = gui.addFolder('RGB Splitter');\n    rgbSplitFolder.add(filtersSwitchs, '10').name(\"apply\");\n\n\n    var filterCollection = [displacementFilter, blurFilter, pixelateFilter, invertFilter, grayFilter, sepiaFilter, twistFilter, dotScreenFilter, colorStepFilter, crossHatchFilter, rgbSplitterFilter];\n\n    // create an new instance of a pixi stage\n    var stage = window.HTMLGL.stage;\n\n    var pondContainer = window.HTMLGL.document;\n    stage.addChild(pondContainer);\n\n    stage.interactive = true;\n\n    var padding = 100;\n    var bounds = new PIXI.Rectangle(-padding, -padding, window.HTMLGL.renderer.width + padding * 2, window.HTMLGL.renderer.height + padding * 2)\n\n    var overlay = new PIXI.TilingSprite(PIXI.Texture.fromImage(\"assets/img/zeldaWaves.png\"), window.HTMLGL.renderer.width, window.HTMLGL.renderer.height);\n    overlay.alpha = 0.1//0.2\n    pondContainer.addChild(overlay);\n\n    displacementFilter.scale.x = 50;\n    displacementFilter.scale.y = 50;\n\n    var count = 0;\n    var switchy = false;\n\n    function animate() {\n\n        count += 0.1;\n\n        var blurAmount = Math.cos(count) ;\n        var blurAmount2 = Math.sin(count * 0.8)  ;\n\n        var filtersToApply = [];\n\n        filtersSwitchs[0] ? overlay.visible = true : overlay.visible = false;\n\n        for (var i = 0; i < filterCollection.length; i++) {\n            if(filtersSwitchs[i])filtersToApply.push(filterCollection[i]);\n        };\n\n        var rgbFilterIndex = filtersToApply.indexOf(rgbSplitterFilter);\n\n        if (rgbFilterIndex !== -1) {\n            HTMLGL.elements[0].sprite.filters = [rgbSplitterFilter];\n            filtersToApply.splice(rgbFilterIndex, 1);\n        } else {\n            if (HTMLGL.elements[0].sprite.filters) {\n                var rgbFilterIndexOnSlider = HTMLGL.elements[0].sprite.filters.indexOf(rgbSplitterFilter);\n                if (rgbFilterIndexOnSlider !== -1) {\n                    HTMLGL.elements[0].sprite.filters = null;\n                }\n            }\n        }\n\n        pondContainer.filters = filtersToApply.length > 0 ? filtersToApply : null;\n\n        displacementSprite.x = count * 10;\n        displacementSprite.y = count * 10;\n\n        overlay.tilePosition.x = count * -10;\n        overlay.tilePosition.y = count * -10;\n\n        renderer.render(stage);\n        requestAnimationFrame( animate );\n    }\n\n    renderer.render(stage);\n    requestAnimationFrame( animate );\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/js/slider.js",
    "content": "//Slider logic, written in HTML / JS.\n//The only difference between HTML GL and basic HTML is that you should use element.styleGL.transform instead of element.style.transform\n\nvar images = document.getElementsByTagName('img'),\n    dragStart = false,\n    slider = document.getElementsByTagName('html-gl')[0],\n    startX = 0,\n    startLeft = 0,\n    transformPropertyName = document.body.style.transform !== undefined ? 'transform' : 'WebkitTransform';\n\nfor (var i = 0; i < images.length; i++) {\n    images[i].ondragstart = function () {\n        return false;\n    };\n}\n\nfunction setSliderX(x) {\n    (slider.styleGL || slider.style)[transformPropertyName] = 'translateZ(0) translateX(' + (startLeft - (startX - (x || 0))) + 'px)';\n}\n\nfunction getSliderX() {\n    return parseInt(parseCSSTransform((slider.styleGL || slider.style)[transformPropertyName]).translateX) || 0\n}\n\nfunction onDragStart(event) {\n    dragStart = true;\n    startX = (event.pageX || event.x) || event.touches[0].pageX;\n    startLeft = getSliderX();\n}\n\nfunction onDragEnd() {\n    dragStart = false;\n}\n\nfunction onMove(event) {\n    if (dragStart) {\n        var pageX = (event.pageX || event.x) || event.touches[0].pageX,\n            moveTime = new Date();\n\n        setSliderX(pageX);\n    }\n}\n\nslider.addEventListener('mousedown', onDragStart);\nslider.addEventListener('mouseup', onDragEnd);\nslider.addEventListener('mousemove', onMove);\nslider.addEventListener('touchstart', onDragStart);\nslider.addEventListener('touchend', onDragEnd);\nslider.addEventListener('touchmove', onMove);\n\nparseCSSTransform = function (transformString) {\n    return (transformString.match(/([\\w]+)\\(([^\\)]+)\\)/g) || [])\n        //make pairs of prop and value\n        .map(function (it) {\n            return it.replace(/\\)$/, \"\").split(/\\(/)\n        })\n        //convert to key-value map/object\n        .reduce(function (m, it) {\n            return m[it[0]] = it[1], m\n        }, {});\n}"
  },
  {
    "path": "demo/js/vendor/html2canvas.js",
    "content": "/*\n  html2canvas 0.5.0-alpha2 <http://html2canvas.hertzen.com>\n  Copyright (c) 2015 Niklas von Hertzen\n\n  Released under MIT License\n*/\n\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.html2canvas = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/*!\n * @overview es6-promise - a tiny implementation of Promises/A+.\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)\n * @license   Licensed under MIT license\n *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE\n * @version   2.3.0\n */\n\n(function() {\n    \"use strict\";\n    function lib$es6$promise$utils$$objectOrFunction(x) {\n      return typeof x === 'function' || (typeof x === 'object' && x !== null);\n    }\n\n    function lib$es6$promise$utils$$isFunction(x) {\n      return typeof x === 'function';\n    }\n\n    function lib$es6$promise$utils$$isMaybeThenable(x) {\n      return typeof x === 'object' && x !== null;\n    }\n\n    var lib$es6$promise$utils$$_isArray;\n    if (!Array.isArray) {\n      lib$es6$promise$utils$$_isArray = function (x) {\n        return Object.prototype.toString.call(x) === '[object Array]';\n      };\n    } else {\n      lib$es6$promise$utils$$_isArray = Array.isArray;\n    }\n\n    var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;\n    var lib$es6$promise$asap$$len = 0;\n    var lib$es6$promise$asap$$toString = {}.toString;\n    var lib$es6$promise$asap$$vertxNext;\n    var lib$es6$promise$asap$$customSchedulerFn;\n\n    var lib$es6$promise$asap$$asap = function asap(callback, arg) {\n      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;\n      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;\n      lib$es6$promise$asap$$len += 2;\n      if (lib$es6$promise$asap$$len === 2) {\n        // If len is 2, that means that we need to schedule an async flush.\n        // If additional callbacks are queued before the queue is flushed, they\n        // will be processed by this flush that we are scheduling.\n        if (lib$es6$promise$asap$$customSchedulerFn) {\n          lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);\n        } else {\n          lib$es6$promise$asap$$scheduleFlush();\n        }\n      }\n    }\n\n    function lib$es6$promise$asap$$setScheduler(scheduleFn) {\n      lib$es6$promise$asap$$customSchedulerFn = scheduleFn;\n    }\n\n    function lib$es6$promise$asap$$setAsap(asapFn) {\n      lib$es6$promise$asap$$asap = asapFn;\n    }\n\n    var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;\n    var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};\n    var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;\n    var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';\n\n    // test for web worker but not in IE10\n    var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&\n      typeof importScripts !== 'undefined' &&\n      typeof MessageChannel !== 'undefined';\n\n    // node\n    function lib$es6$promise$asap$$useNextTick() {\n      var nextTick = process.nextTick;\n      // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n      // setImmediate should be used instead instead\n      var version = process.versions.node.match(/^(?:(\\d+)\\.)?(?:(\\d+)\\.)?(\\*|\\d+)$/);\n      if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {\n        nextTick = setImmediate;\n      }\n      return function() {\n        nextTick(lib$es6$promise$asap$$flush);\n      };\n    }\n\n    // vertx\n    function lib$es6$promise$asap$$useVertxTimer() {\n      return function() {\n        lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);\n      };\n    }\n\n    function lib$es6$promise$asap$$useMutationObserver() {\n      var iterations = 0;\n      var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);\n      var node = document.createTextNode('');\n      observer.observe(node, { characterData: true });\n\n      return function() {\n        node.data = (iterations = ++iterations % 2);\n      };\n    }\n\n    // web worker\n    function lib$es6$promise$asap$$useMessageChannel() {\n      var channel = new MessageChannel();\n      channel.port1.onmessage = lib$es6$promise$asap$$flush;\n      return function () {\n        channel.port2.postMessage(0);\n      };\n    }\n\n    function lib$es6$promise$asap$$useSetTimeout() {\n      return function() {\n        setTimeout(lib$es6$promise$asap$$flush, 1);\n      };\n    }\n\n    var lib$es6$promise$asap$$queue = new Array(1000);\n    function lib$es6$promise$asap$$flush() {\n      for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {\n        var callback = lib$es6$promise$asap$$queue[i];\n        var arg = lib$es6$promise$asap$$queue[i+1];\n\n        callback(arg);\n\n        lib$es6$promise$asap$$queue[i] = undefined;\n        lib$es6$promise$asap$$queue[i+1] = undefined;\n      }\n\n      lib$es6$promise$asap$$len = 0;\n    }\n\n    function lib$es6$promise$asap$$attemptVertex() {\n      try {\n        var r = require;\n        var vertx = r('vertx');\n        lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;\n        return lib$es6$promise$asap$$useVertxTimer();\n      } catch(e) {\n        return lib$es6$promise$asap$$useSetTimeout();\n      }\n    }\n\n    var lib$es6$promise$asap$$scheduleFlush;\n    // Decide what async method to use to triggering processing of queued callbacks:\n    if (lib$es6$promise$asap$$isNode) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();\n    } else if (lib$es6$promise$asap$$BrowserMutationObserver) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();\n    } else if (lib$es6$promise$asap$$isWorker) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();\n    } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();\n    } else {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();\n    }\n\n    function lib$es6$promise$$internal$$noop() {}\n\n    var lib$es6$promise$$internal$$PENDING   = void 0;\n    var lib$es6$promise$$internal$$FULFILLED = 1;\n    var lib$es6$promise$$internal$$REJECTED  = 2;\n\n    var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n    function lib$es6$promise$$internal$$selfFullfillment() {\n      return new TypeError(\"You cannot resolve a promise with itself\");\n    }\n\n    function lib$es6$promise$$internal$$cannotReturnOwn() {\n      return new TypeError('A promises callback cannot return that same promise.');\n    }\n\n    function lib$es6$promise$$internal$$getThen(promise) {\n      try {\n        return promise.then;\n      } catch(error) {\n        lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;\n        return lib$es6$promise$$internal$$GET_THEN_ERROR;\n      }\n    }\n\n    function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {\n      try {\n        then.call(value, fulfillmentHandler, rejectionHandler);\n      } catch(e) {\n        return e;\n      }\n    }\n\n    function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {\n       lib$es6$promise$asap$$asap(function(promise) {\n        var sealed = false;\n        var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {\n          if (sealed) { return; }\n          sealed = true;\n          if (thenable !== value) {\n            lib$es6$promise$$internal$$resolve(promise, value);\n          } else {\n            lib$es6$promise$$internal$$fulfill(promise, value);\n          }\n        }, function(reason) {\n          if (sealed) { return; }\n          sealed = true;\n\n          lib$es6$promise$$internal$$reject(promise, reason);\n        }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n        if (!sealed && error) {\n          sealed = true;\n          lib$es6$promise$$internal$$reject(promise, error);\n        }\n      }, promise);\n    }\n\n    function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {\n      if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {\n        lib$es6$promise$$internal$$fulfill(promise, thenable._result);\n      } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {\n        lib$es6$promise$$internal$$reject(promise, thenable._result);\n      } else {\n        lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {\n          lib$es6$promise$$internal$$resolve(promise, value);\n        }, function(reason) {\n          lib$es6$promise$$internal$$reject(promise, reason);\n        });\n      }\n    }\n\n    function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {\n      if (maybeThenable.constructor === promise.constructor) {\n        lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);\n      } else {\n        var then = lib$es6$promise$$internal$$getThen(maybeThenable);\n\n        if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {\n          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);\n        } else if (then === undefined) {\n          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n        } else if (lib$es6$promise$utils$$isFunction(then)) {\n          lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);\n        } else {\n          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n        }\n      }\n    }\n\n    function lib$es6$promise$$internal$$resolve(promise, value) {\n      if (promise === value) {\n        lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());\n      } else if (lib$es6$promise$utils$$objectOrFunction(value)) {\n        lib$es6$promise$$internal$$handleMaybeThenable(promise, value);\n      } else {\n        lib$es6$promise$$internal$$fulfill(promise, value);\n      }\n    }\n\n    function lib$es6$promise$$internal$$publishRejection(promise) {\n      if (promise._onerror) {\n        promise._onerror(promise._result);\n      }\n\n      lib$es6$promise$$internal$$publish(promise);\n    }\n\n    function lib$es6$promise$$internal$$fulfill(promise, value) {\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n\n      promise._result = value;\n      promise._state = lib$es6$promise$$internal$$FULFILLED;\n\n      if (promise._subscribers.length !== 0) {\n        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);\n      }\n    }\n\n    function lib$es6$promise$$internal$$reject(promise, reason) {\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n      promise._state = lib$es6$promise$$internal$$REJECTED;\n      promise._result = reason;\n\n      lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);\n    }\n\n    function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {\n      var subscribers = parent._subscribers;\n      var length = subscribers.length;\n\n      parent._onerror = null;\n\n      subscribers[length] = child;\n      subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;\n      subscribers[length + lib$es6$promise$$internal$$REJECTED]  = onRejection;\n\n      if (length === 0 && parent._state) {\n        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);\n      }\n    }\n\n    function lib$es6$promise$$internal$$publish(promise) {\n      var subscribers = promise._subscribers;\n      var settled = promise._state;\n\n      if (subscribers.length === 0) { return; }\n\n      var child, callback, detail = promise._result;\n\n      for (var i = 0; i < subscribers.length; i += 3) {\n        child = subscribers[i];\n        callback = subscribers[i + settled];\n\n        if (child) {\n          lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);\n        } else {\n          callback(detail);\n        }\n      }\n\n      promise._subscribers.length = 0;\n    }\n\n    function lib$es6$promise$$internal$$ErrorObject() {\n      this.error = null;\n    }\n\n    var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n    function lib$es6$promise$$internal$$tryCatch(callback, detail) {\n      try {\n        return callback(detail);\n      } catch(e) {\n        lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;\n        return lib$es6$promise$$internal$$TRY_CATCH_ERROR;\n      }\n    }\n\n    function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {\n      var hasCallback = lib$es6$promise$utils$$isFunction(callback),\n          value, error, succeeded, failed;\n\n      if (hasCallback) {\n        value = lib$es6$promise$$internal$$tryCatch(callback, detail);\n\n        if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {\n          failed = true;\n          error = value.error;\n          value = null;\n        } else {\n          succeeded = true;\n        }\n\n        if (promise === value) {\n          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());\n          return;\n        }\n\n      } else {\n        value = detail;\n        succeeded = true;\n      }\n\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) {\n        // noop\n      } else if (hasCallback && succeeded) {\n        lib$es6$promise$$internal$$resolve(promise, value);\n      } else if (failed) {\n        lib$es6$promise$$internal$$reject(promise, error);\n      } else if (settled === lib$es6$promise$$internal$$FULFILLED) {\n        lib$es6$promise$$internal$$fulfill(promise, value);\n      } else if (settled === lib$es6$promise$$internal$$REJECTED) {\n        lib$es6$promise$$internal$$reject(promise, value);\n      }\n    }\n\n    function lib$es6$promise$$internal$$initializePromise(promise, resolver) {\n      try {\n        resolver(function resolvePromise(value){\n          lib$es6$promise$$internal$$resolve(promise, value);\n        }, function rejectPromise(reason) {\n          lib$es6$promise$$internal$$reject(promise, reason);\n        });\n      } catch(e) {\n        lib$es6$promise$$internal$$reject(promise, e);\n      }\n    }\n\n    function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {\n      var enumerator = this;\n\n      enumerator._instanceConstructor = Constructor;\n      enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n      if (enumerator._validateInput(input)) {\n        enumerator._input     = input;\n        enumerator.length     = input.length;\n        enumerator._remaining = input.length;\n\n        enumerator._init();\n\n        if (enumerator.length === 0) {\n          lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n        } else {\n          enumerator.length = enumerator.length || 0;\n          enumerator._enumerate();\n          if (enumerator._remaining === 0) {\n            lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n          }\n        }\n      } else {\n        lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());\n      }\n    }\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {\n      return lib$es6$promise$utils$$isArray(input);\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {\n      return new Error('Array Methods must be provided an Array');\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {\n      this._result = new Array(this.length);\n    };\n\n    var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {\n      var enumerator = this;\n\n      var length  = enumerator.length;\n      var promise = enumerator.promise;\n      var input   = enumerator._input;\n\n      for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n        enumerator._eachEntry(input[i], i);\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {\n      var enumerator = this;\n      var c = enumerator._instanceConstructor;\n\n      if (lib$es6$promise$utils$$isMaybeThenable(entry)) {\n        if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {\n          entry._onerror = null;\n          enumerator._settledAt(entry._state, i, entry._result);\n        } else {\n          enumerator._willSettleAt(c.resolve(entry), i);\n        }\n      } else {\n        enumerator._remaining--;\n        enumerator._result[i] = entry;\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {\n      var enumerator = this;\n      var promise = enumerator.promise;\n\n      if (promise._state === lib$es6$promise$$internal$$PENDING) {\n        enumerator._remaining--;\n\n        if (state === lib$es6$promise$$internal$$REJECTED) {\n          lib$es6$promise$$internal$$reject(promise, value);\n        } else {\n          enumerator._result[i] = value;\n        }\n      }\n\n      if (enumerator._remaining === 0) {\n        lib$es6$promise$$internal$$fulfill(promise, enumerator._result);\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {\n      var enumerator = this;\n\n      lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {\n        enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);\n      }, function(reason) {\n        enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);\n      });\n    };\n    function lib$es6$promise$promise$all$$all(entries) {\n      return new lib$es6$promise$enumerator$$default(this, entries).promise;\n    }\n    var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;\n    function lib$es6$promise$promise$race$$race(entries) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n      if (!lib$es6$promise$utils$$isArray(entries)) {\n        lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));\n        return promise;\n      }\n\n      var length = entries.length;\n\n      function onFulfillment(value) {\n        lib$es6$promise$$internal$$resolve(promise, value);\n      }\n\n      function onRejection(reason) {\n        lib$es6$promise$$internal$$reject(promise, reason);\n      }\n\n      for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n        lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);\n      }\n\n      return promise;\n    }\n    var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;\n    function lib$es6$promise$promise$resolve$$resolve(object) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      if (object && typeof object === 'object' && object.constructor === Constructor) {\n        return object;\n      }\n\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n      lib$es6$promise$$internal$$resolve(promise, object);\n      return promise;\n    }\n    var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;\n    function lib$es6$promise$promise$reject$$reject(reason) {\n      /*jshint validthis:true */\n      var Constructor = this;\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n      lib$es6$promise$$internal$$reject(promise, reason);\n      return promise;\n    }\n    var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;\n\n    var lib$es6$promise$promise$$counter = 0;\n\n    function lib$es6$promise$promise$$needsResolver() {\n      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n    }\n\n    function lib$es6$promise$promise$$needsNew() {\n      throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n    }\n\n    var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;\n    /**\n      Promise objects represent the eventual result of an asynchronous operation. The\n      primary way of interacting with a promise is through its `then` method, which\n      registers callbacks to receive either a promise's eventual value or the reason\n      why the promise cannot be fulfilled.\n\n      Terminology\n      -----------\n\n      - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n      - `thenable` is an object or function that defines a `then` method.\n      - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n      - `exception` is a value that is thrown using the throw statement.\n      - `reason` is a value that indicates why a promise was rejected.\n      - `settled` the final resting state of a promise, fulfilled or rejected.\n\n      A promise can be in one of three states: pending, fulfilled, or rejected.\n\n      Promises that are fulfilled have a fulfillment value and are in the fulfilled\n      state.  Promises that are rejected have a rejection reason and are in the\n      rejected state.  A fulfillment value is never a thenable.\n\n      Promises can also be said to *resolve* a value.  If this value is also a\n      promise, then the original promise's settled state will match the value's\n      settled state.  So a promise that *resolves* a promise that rejects will\n      itself reject, and a promise that *resolves* a promise that fulfills will\n      itself fulfill.\n\n\n      Basic Usage:\n      ------------\n\n      ```js\n      var promise = new Promise(function(resolve, reject) {\n        // on success\n        resolve(value);\n\n        // on failure\n        reject(reason);\n      });\n\n      promise.then(function(value) {\n        // on fulfillment\n      }, function(reason) {\n        // on rejection\n      });\n      ```\n\n      Advanced Usage:\n      ---------------\n\n      Promises shine when abstracting away asynchronous interactions such as\n      `XMLHttpRequest`s.\n\n      ```js\n      function getJSON(url) {\n        return new Promise(function(resolve, reject){\n          var xhr = new XMLHttpRequest();\n\n          xhr.open('GET', url);\n          xhr.onreadystatechange = handler;\n          xhr.responseType = 'json';\n          xhr.setRequestHeader('Accept', 'application/json');\n          xhr.send();\n\n          function handler() {\n            if (this.readyState === this.DONE) {\n              if (this.status === 200) {\n                resolve(this.response);\n              } else {\n                reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));\n              }\n            }\n          };\n        });\n      }\n\n      getJSON('/posts.json').then(function(json) {\n        // on fulfillment\n      }, function(reason) {\n        // on rejection\n      });\n      ```\n\n      Unlike callbacks, promises are great composable primitives.\n\n      ```js\n      Promise.all([\n        getJSON('/posts'),\n        getJSON('/comments')\n      ]).then(function(values){\n        values[0] // => postsJSON\n        values[1] // => commentsJSON\n\n        return values;\n      });\n      ```\n\n      @class Promise\n      @param {function} resolver\n      Useful for tooling.\n      @constructor\n    */\n    function lib$es6$promise$promise$$Promise(resolver) {\n      this._id = lib$es6$promise$promise$$counter++;\n      this._state = undefined;\n      this._result = undefined;\n      this._subscribers = [];\n\n      if (lib$es6$promise$$internal$$noop !== resolver) {\n        if (!lib$es6$promise$utils$$isFunction(resolver)) {\n          lib$es6$promise$promise$$needsResolver();\n        }\n\n        if (!(this instanceof lib$es6$promise$promise$$Promise)) {\n          lib$es6$promise$promise$$needsNew();\n        }\n\n        lib$es6$promise$$internal$$initializePromise(this, resolver);\n      }\n    }\n\n    lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;\n    lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;\n    lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;\n    lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;\n    lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;\n    lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;\n    lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;\n\n    lib$es6$promise$promise$$Promise.prototype = {\n      constructor: lib$es6$promise$promise$$Promise,\n\n    /**\n      The primary way of interacting with a promise is through its `then` method,\n      which registers callbacks to receive either a promise's eventual value or the\n      reason why the promise cannot be fulfilled.\n\n      ```js\n      findUser().then(function(user){\n        // user is available\n      }, function(reason){\n        // user is unavailable, and you are given the reason why\n      });\n      ```\n\n      Chaining\n      --------\n\n      The return value of `then` is itself a promise.  This second, 'downstream'\n      promise is resolved with the return value of the first promise's fulfillment\n      or rejection handler, or rejected if the handler throws an exception.\n\n      ```js\n      findUser().then(function (user) {\n        return user.name;\n      }, function (reason) {\n        return 'default name';\n      }).then(function (userName) {\n        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n        // will be `'default name'`\n      });\n\n      findUser().then(function (user) {\n        throw new Error('Found user, but still unhappy');\n      }, function (reason) {\n        throw new Error('`findUser` rejected and we're unhappy');\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n      });\n      ```\n      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n\n      ```js\n      findUser().then(function (user) {\n        throw new PedagogicalException('Upstream error');\n      }).then(function (value) {\n        // never reached\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // The `PedgagocialException` is propagated all the way down to here\n      });\n      ```\n\n      Assimilation\n      ------------\n\n      Sometimes the value you want to propagate to a downstream promise can only be\n      retrieved asynchronously. This can be achieved by returning a promise in the\n      fulfillment or rejection handler. The downstream promise will then be pending\n      until the returned promise is settled. This is called *assimilation*.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // The user's comments are now available\n      });\n      ```\n\n      If the assimliated promise rejects, then the downstream promise will also reject.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // If `findCommentsByAuthor` fulfills, we'll have the value here\n      }, function (reason) {\n        // If `findCommentsByAuthor` rejects, we'll have the reason here\n      });\n      ```\n\n      Simple Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var result;\n\n      try {\n        result = findResult();\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n      findResult(function(result, err){\n        if (err) {\n          // failure\n        } else {\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findResult().then(function(result){\n        // success\n      }, function(reason){\n        // failure\n      });\n      ```\n\n      Advanced Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var author, books;\n\n      try {\n        author = findAuthor();\n        books  = findBooksByAuthor(author);\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n\n      function foundBooks(books) {\n\n      }\n\n      function failure(reason) {\n\n      }\n\n      findAuthor(function(author, err){\n        if (err) {\n          failure(err);\n          // failure\n        } else {\n          try {\n            findBoooksByAuthor(author, function(books, err) {\n              if (err) {\n                failure(err);\n              } else {\n                try {\n                  foundBooks(books);\n                } catch(reason) {\n                  failure(reason);\n                }\n              }\n            });\n          } catch(error) {\n            failure(err);\n          }\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findAuthor().\n        then(findBooksByAuthor).\n        then(function(books){\n          // found books\n      }).catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method then\n      @param {Function} onFulfilled\n      @param {Function} onRejected\n      Useful for tooling.\n      @return {Promise}\n    */\n      then: function(onFulfillment, onRejection) {\n        var parent = this;\n        var state = parent._state;\n\n        if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {\n          return this;\n        }\n\n        var child = new this.constructor(lib$es6$promise$$internal$$noop);\n        var result = parent._result;\n\n        if (state) {\n          var callback = arguments[state - 1];\n          lib$es6$promise$asap$$asap(function(){\n            lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);\n          });\n        } else {\n          lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);\n        }\n\n        return child;\n      },\n\n    /**\n      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n      as the catch block of a try/catch statement.\n\n      ```js\n      function findAuthor(){\n        throw new Error('couldn't find that author');\n      }\n\n      // synchronous\n      try {\n        findAuthor();\n      } catch(reason) {\n        // something went wrong\n      }\n\n      // async with promises\n      findAuthor().catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method catch\n      @param {Function} onRejection\n      Useful for tooling.\n      @return {Promise}\n    */\n      'catch': function(onRejection) {\n        return this.then(null, onRejection);\n      }\n    };\n    function lib$es6$promise$polyfill$$polyfill() {\n      var local;\n\n      if (typeof global !== 'undefined') {\n          local = global;\n      } else if (typeof self !== 'undefined') {\n          local = self;\n      } else {\n          try {\n              local = Function('return this')();\n          } catch (e) {\n              throw new Error('polyfill failed because global object is unavailable in this environment');\n          }\n      }\n\n      var P = local.Promise;\n\n      if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {\n        return;\n      }\n\n      local.Promise = lib$es6$promise$promise$$default;\n    }\n    var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;\n\n    var lib$es6$promise$umd$$ES6Promise = {\n      'Promise': lib$es6$promise$promise$$default,\n      'polyfill': lib$es6$promise$polyfill$$default\n    };\n\n    /* global define:true module:true window: true */\n    if (typeof define === 'function' && define['amd']) {\n      define(function() { return lib$es6$promise$umd$$ES6Promise; });\n    } else if (typeof module !== 'undefined' && module['exports']) {\n      module['exports'] = lib$es6$promise$umd$$ES6Promise;\n    } else if (typeof this !== 'undefined') {\n      this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;\n    }\n\n    lib$es6$promise$polyfill$$default();\n}).call(this);\n\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"_process\":2}],2:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            currentQueue[queueIndex].run();\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],3:[function(require,module,exports){\n(function (global){\n/*! https://mths.be/punycode v1.3.2 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t    counter = 0,\n\t\t    length = string.length,\n\t\t    value,\n\t\t    extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t//  0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * http://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t    inputLength = input.length,\n\t\t    out,\n\t\t    i = 0,\n\t\t    n = initialN,\n\t\t    bias = initialBias,\n\t\t    basic,\n\t\t    j,\n\t\t    index,\n\t\t    oldi,\n\t\t    w,\n\t\t    k,\n\t\t    digit,\n\t\t    t,\n\t\t    /** Cached calculation results */\n\t\t    baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols (e.g. a domain name label) to a\n\t * Punycode string of ASCII-only symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t    delta,\n\t\t    handledCPCount,\n\t\t    basicLength,\n\t\t    bias,\n\t\t    j,\n\t\t    m,\n\t\t    q,\n\t\t    k,\n\t\t    t,\n\t\t    currentValue,\n\t\t    output = [],\n\t\t    /** `inputLength` will hold the number of code points in `input`. */\n\t\t    inputLength,\n\t\t    /** Cached calculation results */\n\t\t    handledCPCountPlusOne,\n\t\t    baseMinusT,\n\t\t    qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name or an email address\n\t * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n\t * it doesn't matter if you call it on a string that has already been\n\t * converted to Unicode.\n\t * @memberOf punycode\n\t * @param {String} input The Punycoded domain name or email address to\n\t * convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name or an email address to\n\t * Punycode. Only the non-ASCII parts of the domain name will be converted,\n\t * i.e. it doesn't matter if you call it with a domain that's already in\n\t * ASCII.\n\t * @memberOf punycode\n\t * @param {String} input The domain name or email address to convert, as a\n\t * Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name or\n\t * email address.\n\t */\n\tfunction toASCII(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.3.2',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine('punycode', function() {\n\t\t\treturn punycode;\n\t\t});\n\t} else if (freeExports && freeModule) {\n\t\tif (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = punycode;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (key in punycode) {\n\t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.punycode = punycode;\n\t}\n\n}(this));\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],4:[function(require,module,exports){\nvar log = require('./log');\nvar Promise = require('./promise');\n\nfunction restoreOwnerScroll(ownerDocument, x, y) {\n    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {\n        ownerDocument.defaultView.scrollTo(x, y);\n    }\n}\n\nfunction cloneCanvasContents(canvas, clonedCanvas) {\n    try {\n        if (clonedCanvas) {\n            clonedCanvas.width = canvas.width;\n            clonedCanvas.height = canvas.height;\n            clonedCanvas.getContext(\"2d\").putImageData(canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height), 0, 0);\n        }\n    } catch(e) {\n        log(\"Unable to copy canvas content from\", canvas, e);\n    }\n}\n\nfunction cloneNode(node, javascriptEnabled) {\n    var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);\n\n    var child = node.firstChild;\n    while(child) {\n        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {\n            clone.appendChild(cloneNode(child, javascriptEnabled));\n        }\n        child = child.nextSibling;\n    }\n\n    if (node.nodeType === 1 && node.tagName !== 'BODY') {\n        clone._scrollTop = node.scrollTop;\n        clone._scrollLeft = node.scrollLeft;\n        if (node.nodeName === \"CANVAS\") {\n            cloneCanvasContents(node, clone);\n        } else if (node.nodeName === \"TEXTAREA\" || node.nodeName === \"SELECT\") {\n            clone.value = node.value;\n        }\n    }\n\n    return clone;\n}\n\nfunction initNode(node) {\n    if (node.nodeType === 1) {\n        node.scrollTop = node._scrollTop;\n        node.scrollLeft = node._scrollLeft;\n\n        var child = node.firstChild;\n        while(child) {\n            initNode(child);\n            child = child.nextSibling;\n        }\n    }\n}\n\nmodule.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {\n    var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);\n    var container = containerDocument.createElement(\"iframe\");\n\n    container.className = \"html2canvas-container\";\n    container.style.visibility = \"hidden\";\n    container.style.position = \"fixed\";\n    container.style.left = \"-10000px\";\n    container.style.top = \"0px\";\n    container.style.border = \"0\";\n    container.style.border = \"0\";\n    container.width = width;\n    container.height = height;\n    container.scrolling = \"no\"; // ios won't scroll without it\n    containerDocument.body.appendChild(container);\n\n    return new Promise(function(resolve) {\n        var documentClone = container.contentWindow.document;\n\n        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle\n         if window url is about:blank, we can assign the url to current by writing onto the document\n         */\n        container.contentWindow.onload = container.onload = function() {\n            var interval = setInterval(function() {\n                if (documentClone.body.childNodes.length > 0) {\n                    initNode(documentClone.documentElement);\n                    clearInterval(interval);\n                    if (options.type === \"view\") {\n                        container.contentWindow.scrollTo(x, y);\n                        if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {\n                            documentClone.documentElement.style.top = (-y) + \"px\";\n                            documentClone.documentElement.style.left = (-x) + \"px\";\n                            documentClone.documentElement.style.position = 'absolute';\n                        }\n                    }\n                    resolve(container);\n                }\n            }, 50);\n        };\n\n        documentClone.open();\n        documentClone.write(\"<!DOCTYPE html><html></html>\");\n        // Chrome scrolls the parent document for some reason after the write to the cloned window???\n        restoreOwnerScroll(ownerDocument, x, y);\n        documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);\n        documentClone.close();\n    });\n};\n\n},{\"./log\":15,\"./promise\":18}],5:[function(require,module,exports){\n// http://dev.w3.org/csswg/css-color/\n\nfunction Color(value) {\n    this.r = 0;\n    this.g = 0;\n    this.b = 0;\n    this.a = null;\n    var result = this.fromArray(value) ||\n        this.namedColor(value) ||\n        this.rgb(value) ||\n        this.rgba(value) ||\n        this.hex6(value) ||\n        this.hex3(value);\n}\n\nColor.prototype.darken = function(amount) {\n    var a = 1 - amount;\n    return  new Color([\n        Math.round(this.r * a),\n        Math.round(this.g * a),\n        Math.round(this.b * a),\n        this.a\n    ]);\n};\n\nColor.prototype.isTransparent = function() {\n    return this.a === 0;\n};\n\nColor.prototype.isBlack = function() {\n    return this.r === 0 && this.g === 0 && this.b === 0;\n};\n\nColor.prototype.fromArray = function(array) {\n    if (Array.isArray(array)) {\n        this.r = Math.min(array[0], 255);\n        this.g = Math.min(array[1], 255);\n        this.b = Math.min(array[2], 255);\n        if (array.length > 3) {\n            this.a = array[3];\n        }\n    }\n\n    return (Array.isArray(array));\n};\n\nvar _hex3 = /^#([a-f0-9]{3})$/i;\n\nColor.prototype.hex3 = function(value) {\n    var match = null;\n    if ((match = value.match(_hex3)) !== null) {\n        this.r = parseInt(match[1][0] + match[1][0], 16);\n        this.g = parseInt(match[1][1] + match[1][1], 16);\n        this.b = parseInt(match[1][2] + match[1][2], 16);\n    }\n    return match !== null;\n};\n\nvar _hex6 = /^#([a-f0-9]{6})$/i;\n\nColor.prototype.hex6 = function(value) {\n    var match = null;\n    if ((match = value.match(_hex6)) !== null) {\n        this.r = parseInt(match[1].substring(0, 2), 16);\n        this.g = parseInt(match[1].substring(2, 4), 16);\n        this.b = parseInt(match[1].substring(4, 6), 16);\n    }\n    return match !== null;\n};\n\n\nvar _rgb = /^rgb\\((\\d{1,3}) *, *(\\d{1,3}) *, *(\\d{1,3})\\)$/;\n\nColor.prototype.rgb = function(value) {\n    var match = null;\n    if ((match = value.match(_rgb)) !== null) {\n        this.r = Number(match[1]);\n        this.g = Number(match[2]);\n        this.b = Number(match[3]);\n    }\n    return match !== null;\n};\n\nvar _rgba = /^rgba\\((\\d{1,3}) *, *(\\d{1,3}) *, *(\\d{1,3}) *, *(\\d+\\.?\\d*)\\)$/;\n\nColor.prototype.rgba = function(value) {\n    var match = null;\n    if ((match = value.match(_rgba)) !== null) {\n        this.r = Number(match[1]);\n        this.g = Number(match[2]);\n        this.b = Number(match[3]);\n        this.a = Number(match[4]);\n    }\n    return match !== null;\n};\n\nColor.prototype.toString = function() {\n    return this.a !== null && this.a !== 1 ?\n    \"rgba(\" + [this.r, this.g, this.b, this.a].join(\",\") + \")\" :\n    \"rgb(\" + [this.r, this.g, this.b].join(\",\") + \")\";\n};\n\nColor.prototype.namedColor = function(value) {\n    var color = colors[value.toLowerCase()];\n    if (color) {\n        this.r = color[0];\n        this.g = color[1];\n        this.b = color[2];\n    } else if (value.toLowerCase() === \"transparent\") {\n        this.r = this.g = this.b = this.a = 0;\n        return true;\n    }\n\n    return !!color;\n};\n\nColor.prototype.isColor = true;\n\n// JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(\",\").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))\nvar colors = {\n    \"aliceblue\": [240, 248, 255],\n    \"antiquewhite\": [250, 235, 215],\n    \"aqua\": [0, 255, 255],\n    \"aquamarine\": [127, 255, 212],\n    \"azure\": [240, 255, 255],\n    \"beige\": [245, 245, 220],\n    \"bisque\": [255, 228, 196],\n    \"black\": [0, 0, 0],\n    \"blanchedalmond\": [255, 235, 205],\n    \"blue\": [0, 0, 255],\n    \"blueviolet\": [138, 43, 226],\n    \"brown\": [165, 42, 42],\n    \"burlywood\": [222, 184, 135],\n    \"cadetblue\": [95, 158, 160],\n    \"chartreuse\": [127, 255, 0],\n    \"chocolate\": [210, 105, 30],\n    \"coral\": [255, 127, 80],\n    \"cornflowerblue\": [100, 149, 237],\n    \"cornsilk\": [255, 248, 220],\n    \"crimson\": [220, 20, 60],\n    \"cyan\": [0, 255, 255],\n    \"darkblue\": [0, 0, 139],\n    \"darkcyan\": [0, 139, 139],\n    \"darkgoldenrod\": [184, 134, 11],\n    \"darkgray\": [169, 169, 169],\n    \"darkgreen\": [0, 100, 0],\n    \"darkgrey\": [169, 169, 169],\n    \"darkkhaki\": [189, 183, 107],\n    \"darkmagenta\": [139, 0, 139],\n    \"darkolivegreen\": [85, 107, 47],\n    \"darkorange\": [255, 140, 0],\n    \"darkorchid\": [153, 50, 204],\n    \"darkred\": [139, 0, 0],\n    \"darksalmon\": [233, 150, 122],\n    \"darkseagreen\": [143, 188, 143],\n    \"darkslateblue\": [72, 61, 139],\n    \"darkslategray\": [47, 79, 79],\n    \"darkslategrey\": [47, 79, 79],\n    \"darkturquoise\": [0, 206, 209],\n    \"darkviolet\": [148, 0, 211],\n    \"deeppink\": [255, 20, 147],\n    \"deepskyblue\": [0, 191, 255],\n    \"dimgray\": [105, 105, 105],\n    \"dimgrey\": [105, 105, 105],\n    \"dodgerblue\": [30, 144, 255],\n    \"firebrick\": [178, 34, 34],\n    \"floralwhite\": [255, 250, 240],\n    \"forestgreen\": [34, 139, 34],\n    \"fuchsia\": [255, 0, 255],\n    \"gainsboro\": [220, 220, 220],\n    \"ghostwhite\": [248, 248, 255],\n    \"gold\": [255, 215, 0],\n    \"goldenrod\": [218, 165, 32],\n    \"gray\": [128, 128, 128],\n    \"green\": [0, 128, 0],\n    \"greenyellow\": [173, 255, 47],\n    \"grey\": [128, 128, 128],\n    \"honeydew\": [240, 255, 240],\n    \"hotpink\": [255, 105, 180],\n    \"indianred\": [205, 92, 92],\n    \"indigo\": [75, 0, 130],\n    \"ivory\": [255, 255, 240],\n    \"khaki\": [240, 230, 140],\n    \"lavender\": [230, 230, 250],\n    \"lavenderblush\": [255, 240, 245],\n    \"lawngreen\": [124, 252, 0],\n    \"lemonchiffon\": [255, 250, 205],\n    \"lightblue\": [173, 216, 230],\n    \"lightcoral\": [240, 128, 128],\n    \"lightcyan\": [224, 255, 255],\n    \"lightgoldenrodyellow\": [250, 250, 210],\n    \"lightgray\": [211, 211, 211],\n    \"lightgreen\": [144, 238, 144],\n    \"lightgrey\": [211, 211, 211],\n    \"lightpink\": [255, 182, 193],\n    \"lightsalmon\": [255, 160, 122],\n    \"lightseagreen\": [32, 178, 170],\n    \"lightskyblue\": [135, 206, 250],\n    \"lightslategray\": [119, 136, 153],\n    \"lightslategrey\": [119, 136, 153],\n    \"lightsteelblue\": [176, 196, 222],\n    \"lightyellow\": [255, 255, 224],\n    \"lime\": [0, 255, 0],\n    \"limegreen\": [50, 205, 50],\n    \"linen\": [250, 240, 230],\n    \"magenta\": [255, 0, 255],\n    \"maroon\": [128, 0, 0],\n    \"mediumaquamarine\": [102, 205, 170],\n    \"mediumblue\": [0, 0, 205],\n    \"mediumorchid\": [186, 85, 211],\n    \"mediumpurple\": [147, 112, 219],\n    \"mediumseagreen\": [60, 179, 113],\n    \"mediumslateblue\": [123, 104, 238],\n    \"mediumspringgreen\": [0, 250, 154],\n    \"mediumturquoise\": [72, 209, 204],\n    \"mediumvioletred\": [199, 21, 133],\n    \"midnightblue\": [25, 25, 112],\n    \"mintcream\": [245, 255, 250],\n    \"mistyrose\": [255, 228, 225],\n    \"moccasin\": [255, 228, 181],\n    \"navajowhite\": [255, 222, 173],\n    \"navy\": [0, 0, 128],\n    \"oldlace\": [253, 245, 230],\n    \"olive\": [128, 128, 0],\n    \"olivedrab\": [107, 142, 35],\n    \"orange\": [255, 165, 0],\n    \"orangered\": [255, 69, 0],\n    \"orchid\": [218, 112, 214],\n    \"palegoldenrod\": [238, 232, 170],\n    \"palegreen\": [152, 251, 152],\n    \"paleturquoise\": [175, 238, 238],\n    \"palevioletred\": [219, 112, 147],\n    \"papayawhip\": [255, 239, 213],\n    \"peachpuff\": [255, 218, 185],\n    \"peru\": [205, 133, 63],\n    \"pink\": [255, 192, 203],\n    \"plum\": [221, 160, 221],\n    \"powderblue\": [176, 224, 230],\n    \"purple\": [128, 0, 128],\n    \"rebeccapurple\": [102, 51, 153],\n    \"red\": [255, 0, 0],\n    \"rosybrown\": [188, 143, 143],\n    \"royalblue\": [65, 105, 225],\n    \"saddlebrown\": [139, 69, 19],\n    \"salmon\": [250, 128, 114],\n    \"sandybrown\": [244, 164, 96],\n    \"seagreen\": [46, 139, 87],\n    \"seashell\": [255, 245, 238],\n    \"sienna\": [160, 82, 45],\n    \"silver\": [192, 192, 192],\n    \"skyblue\": [135, 206, 235],\n    \"slateblue\": [106, 90, 205],\n    \"slategray\": [112, 128, 144],\n    \"slategrey\": [112, 128, 144],\n    \"snow\": [255, 250, 250],\n    \"springgreen\": [0, 255, 127],\n    \"steelblue\": [70, 130, 180],\n    \"tan\": [210, 180, 140],\n    \"teal\": [0, 128, 128],\n    \"thistle\": [216, 191, 216],\n    \"tomato\": [255, 99, 71],\n    \"turquoise\": [64, 224, 208],\n    \"violet\": [238, 130, 238],\n    \"wheat\": [245, 222, 179],\n    \"white\": [255, 255, 255],\n    \"whitesmoke\": [245, 245, 245],\n    \"yellow\": [255, 255, 0],\n    \"yellowgreen\": [154, 205, 50]\n};\n\nmodule.exports = Color;\n\n},{}],6:[function(require,module,exports){\nvar Promise = require('./promise');\nvar Support = require('./support');\nvar CanvasRenderer = require('./renderers/canvas');\nvar ImageLoader = require('./imageloader');\nvar NodeParser = require('./nodeparser');\nvar NodeContainer = require('./nodecontainer');\nvar log = require('./log');\nvar utils = require('./utils');\nvar createWindowClone = require('./clone');\nvar loadUrlDocument = require('./proxy').loadUrlDocument;\nvar getBounds = utils.getBounds;\n\nvar html2canvasNodeAttribute = \"data-html2canvas-node\";\nvar html2canvasCloneIndex = 0;\n\nfunction html2canvas(nodeList, options) {\n    var index = html2canvasCloneIndex++;\n    options = options || {};\n    if (options.logging) {\n        window.html2canvas.logging = true;\n        window.html2canvas.start = Date.now();\n    }\n\n    options.async = typeof(options.async) === \"undefined\" ? true : options.async;\n    options.allowTaint = typeof(options.allowTaint) === \"undefined\" ? false : options.allowTaint;\n    options.removeContainer = typeof(options.removeContainer) === \"undefined\" ? true : options.removeContainer;\n    options.javascriptEnabled = typeof(options.javascriptEnabled) === \"undefined\" ? false : options.javascriptEnabled;\n    options.imageTimeout = typeof(options.imageTimeout) === \"undefined\" ? 10000 : options.imageTimeout;\n    options.renderer = typeof(options.renderer) === \"function\" ? options.renderer : CanvasRenderer;\n    options.strict = !!options.strict;\n\n    if (typeof(nodeList) === \"string\") {\n        if (typeof(options.proxy) !== \"string\") {\n            return Promise.reject(\"Proxy must be used when rendering url\");\n        }\n        var width = options.width != null ? options.width : window.innerWidth;\n        var height = options.height != null ? options.height : window.innerHeight;\n        return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {\n            return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);\n        });\n    }\n\n    var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];\n    node.setAttribute(html2canvasNodeAttribute + index, index);\n    return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {\n        if (typeof(options.onrendered) === \"function\") {\n            log(\"options.onrendered is deprecated, html2canvas returns a Promise containing the canvas\");\n            options.onrendered(canvas);\n        }\n        return canvas;\n    });\n}\n\nhtml2canvas.Promise = Promise;\nhtml2canvas.CanvasRenderer = CanvasRenderer;\nhtml2canvas.NodeContainer = NodeContainer;\nhtml2canvas.log = log;\nhtml2canvas.utils = utils;\n\nmodule.exports = (typeof(document) === \"undefined\" || typeof(Object.create) !== \"function\" || typeof(document.createElement(\"canvas\").getContext) !== \"function\") ? function() {\n    return Promise.reject(\"No canvas support\");\n} : html2canvas;\n\nfunction renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {\n    return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {\n        log(\"Document cloned\");\n\n        var attributeName = html2canvasNodeAttribute + html2canvasIndex;\n        var selector = \"[\" + attributeName + \"='\" + html2canvasIndex + \"']\";\n        document.querySelector(selector).removeAttribute(attributeName);\n        var clonedWindow = container.contentWindow;\n        var node = clonedWindow.document.querySelector(selector);\n        node.style.opacity === \"0\" && node.getAttribute('renderer') === \"webgl\" ? node.style.opacity = 1 : null;\n        var oncloneHandler = (typeof(options.onclone) === \"function\") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);\n        return oncloneHandler.then(function() {\n            return renderWindow(node, container, options, windowWidth, windowHeight);\n        });\n    });\n}\n\nfunction renderWindow(node, container, options, windowWidth, windowHeight) {\n    var clonedWindow = container.contentWindow;\n    var support = new Support(clonedWindow.document);\n    var imageLoader = new ImageLoader(options, support);\n    var bounds = getBounds(node);\n    var width = options.type === \"view\" ? windowWidth : documentWidth(clonedWindow.document);\n    var height = options.type === \"view\" ? windowHeight : documentHeight(clonedWindow.document);\n    var renderer = new options.renderer(width, height, imageLoader, options, document);\n    var parser = new NodeParser(node, renderer, support, imageLoader, options);\n    return parser.ready.then(function() {\n        log(\"Finished rendering\");\n        var canvas;\n\n        if (options.type === \"view\") {\n            canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});\n        } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {\n            canvas = renderer.canvas;\n        } else {\n            //If retina - increase bounds by two since we ve got 2x canvas from renderer\n            if (window.devicePixelRatio !== 1) {\n                bounds.top = bounds.top * window.devicePixelRatio;\n                bounds.left = bounds.left * window.devicePixelRatio;\n                bounds.right = bounds.right * window.devicePixelRatio;\n                bounds.bottom = bounds.bottom * window.devicePixelRatio;\n            }\n\n            canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: clonedWindow.pageXOffset, y: clonedWindow.pageYOffset});\n        }\n\n        cleanupContainer(container, options);\n        return canvas;\n    });\n}\n\nfunction cleanupContainer(container, options) {\n    if (options.removeContainer) {\n        container.parentNode.removeChild(container);\n        log(\"Cleaned up container\");\n    }\n}\n\nfunction crop(canvas, bounds) {\n    var croppedCanvas = document.createElement(\"canvas\");\n    var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));\n    var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));\n    var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));\n    var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));\n    croppedCanvas.width = bounds.width;\n    croppedCanvas.height =  bounds.height;\n    log(\"Cropping canvas at:\", \"left:\", bounds.left, \"top:\", bounds.top, \"width:\", (x2-x1), \"height:\", (y2-y1));\n    log(\"Resulting crop with width\", bounds.width, \"and height\", bounds.height, \" with x\", x1, \"and y\", y1);\n    croppedCanvas.getContext(\"2d\").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1);\n    return croppedCanvas;\n}\n\nfunction documentWidth (doc) {\n    return Math.max(\n        Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),\n        Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),\n        Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)\n    );\n}\n\nfunction documentHeight (doc) {\n    return Math.max(\n        Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),\n        Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),\n        Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)\n    );\n}\n\nfunction absoluteUrl(url) {\n    var link = document.createElement(\"a\");\n    link.href = url;\n    link.href = link.href;\n    return link;\n}\n\n},{\"./clone\":4,\"./imageloader\":13,\"./log\":15,\"./nodecontainer\":16,\"./nodeparser\":17,\"./promise\":18,\"./proxy\":19,\"./renderers/canvas\":23,\"./support\":25,\"./utils\":29}],7:[function(require,module,exports){\nvar Promise = require('./promise');\nvar log = require('./log');\nvar smallImage = require('./utils').smallImage;\n\nfunction DummyImageContainer(src) {\n    this.src = src;\n    log(\"DummyImageContainer for\", src);\n    if (!this.promise || !this.image) {\n        log(\"Initiating DummyImageContainer\");\n        DummyImageContainer.prototype.image = new Image();\n        var image = this.image;\n        DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {\n            image.onload = resolve;\n            image.onerror = reject;\n            image.src = smallImage();\n            if (image.complete === true) {\n                resolve(image);\n            }\n        });\n    }\n}\n\nmodule.exports = DummyImageContainer;\n\n},{\"./log\":15,\"./promise\":18,\"./utils\":29}],8:[function(require,module,exports){\nvar smallImage = require('./utils').smallImage;\n\nfunction Font(family, size) {\n    var container = document.createElement('div'),\n        img = document.createElement('img'),\n        span = document.createElement('span'),\n        sampleText = 'Hidden Text',\n        baseline,\n        middle;\n\n    container.style.visibility = \"hidden\";\n    container.style.fontFamily = family;\n    container.style.fontSize = size;\n    container.style.margin = 0;\n    container.style.padding = 0;\n\n    document.body.appendChild(container);\n\n    img.src = smallImage();\n    img.width = 1;\n    img.height = 1;\n\n    img.style.margin = 0;\n    img.style.padding = 0;\n    img.style.verticalAlign = \"baseline\";\n\n    span.style.fontFamily = family;\n    span.style.fontSize = size;\n    span.style.margin = 0;\n    span.style.padding = 0;\n\n    span.appendChild(document.createTextNode(sampleText));\n    container.appendChild(span);\n    container.appendChild(img);\n    baseline = (img.offsetTop - span.offsetTop) + 1;\n\n    container.removeChild(span);\n    container.appendChild(document.createTextNode(sampleText));\n\n    container.style.lineHeight = \"normal\";\n    img.style.verticalAlign = \"super\";\n\n    middle = (img.offsetTop-container.offsetTop) + 1;\n\n    document.body.removeChild(container);\n\n    this.baseline = baseline;\n    this.lineWidth = 1;\n    this.middle = middle;\n}\n\nmodule.exports = Font;\n\n},{\"./utils\":29}],9:[function(require,module,exports){\nvar Font = require('./font');\n\nfunction FontMetrics() {\n    this.data = {};\n}\n\nFontMetrics.prototype.getMetrics = function(family, size) {\n    if (this.data[family + \"-\" + size] === undefined) {\n        this.data[family + \"-\" + size] = new Font(family, size);\n    }\n    return this.data[family + \"-\" + size];\n};\n\nmodule.exports = FontMetrics;\n\n},{\"./font\":8}],10:[function(require,module,exports){\nvar utils = require('./utils');\nvar Promise = require('./promise');\nvar getBounds = utils.getBounds;\nvar loadUrlDocument = require('./proxy').loadUrlDocument;\n\nfunction FrameContainer(container, sameOrigin, options) {\n    this.image = null;\n    this.src = container;\n    var self = this;\n    var bounds = getBounds(container);\n    this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {\n        if (container.contentWindow.document.URL === \"about:blank\" || container.contentWindow.document.documentElement == null) {\n            container.contentWindow.onload = container.onload = function() {\n                resolve(container);\n            };\n        } else {\n            resolve(container);\n        }\n    })).then(function(container) {\n        var html2canvas = require('./core');\n        return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});\n    }).then(function(canvas) {\n        return self.image = canvas;\n    });\n}\n\nFrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {\n    var container = this.src;\n    return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);\n};\n\nmodule.exports = FrameContainer;\n\n},{\"./core\":6,\"./promise\":18,\"./proxy\":19,\"./utils\":29}],11:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction GradientContainer(imageData) {\n    this.src = imageData.value;\n    this.colorStops = [];\n    this.type = null;\n    this.x0 = 0.5;\n    this.y0 = 0.5;\n    this.x1 = 0.5;\n    this.y1 = 0.5;\n    this.promise = Promise.resolve(true);\n}\n\nGradientContainer.prototype.TYPES = {\n    LINEAR: 1,\n    RADIAL: 2\n};\n\nmodule.exports = GradientContainer;\n\n},{\"./promise\":18}],12:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction ImageContainer(src, cors) {\n    this.src = src;\n    this.image = new Image();\n    var self = this;\n    this.tainted = null;\n    this.promise = new Promise(function(resolve, reject) {\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n        if (cors) {\n            self.image.crossOrigin = \"anonymous\";\n        }\n        self.image.src = src;\n        if (self.image.complete === true) {\n            resolve(self.image);\n        }\n    });\n}\n\nmodule.exports = ImageContainer;\n\n},{\"./promise\":18}],13:[function(require,module,exports){\nvar Promise = require('./promise');\nvar log = require('./log');\nvar ImageContainer = require('./imagecontainer');\nvar DummyImageContainer = require('./dummyimagecontainer');\nvar ProxyImageContainer = require('./proxyimagecontainer');\nvar FrameContainer = require('./framecontainer');\nvar SVGContainer = require('./svgcontainer');\nvar SVGNodeContainer = require('./svgnodecontainer');\nvar LinearGradientContainer = require('./lineargradientcontainer');\nvar WebkitGradientContainer = require('./webkitgradientcontainer');\nvar bind = require('./utils').bind;\n\nfunction ImageLoader(options, support) {\n    this.link = null;\n    this.options = options;\n    this.support = support;\n    this.origin = this.getOrigin(window.location.href);\n}\n\nImageLoader.prototype.findImages = function(nodes) {\n    var images = [];\n    nodes.reduce(function(imageNodes, container) {\n        switch(container.node.nodeName) {\n        case \"IMG\":\n            return imageNodes.concat([{\n                args: [container.node.src],\n                method: \"url\"\n            }]);\n        case \"svg\":\n        case \"IFRAME\":\n            return imageNodes.concat([{\n                args: [container.node],\n                method: container.node.nodeName\n            }]);\n        }\n        return imageNodes;\n    }, []).forEach(this.addImage(images, this.loadImage), this);\n    return images;\n};\n\nImageLoader.prototype.findBackgroundImage = function(images, container) {\n    container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);\n    return images;\n};\n\nImageLoader.prototype.addImage = function(images, callback) {\n    return function(newImage) {\n        newImage.args.forEach(function(image) {\n            if (!this.imageExists(images, image)) {\n                images.splice(0, 0, callback.call(this, newImage));\n                log('Added image #' + (images.length), typeof(image) === \"string\" ? image.substring(0, 100) : image);\n            }\n        }, this);\n    };\n};\n\nImageLoader.prototype.hasImageBackground = function(imageData) {\n    return imageData.method !== \"none\";\n};\n\nImageLoader.prototype.loadImage = function(imageData) {\n    if (imageData.method === \"url\") {\n        var src = imageData.args[0];\n        if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {\n            return new SVGContainer(src);\n        } else if (src.match(/data:image\\/.*;base64,/i)) {\n            return new ImageContainer(src.replace(/url\\(['\"]{0,}|['\"]{0,}\\)$/ig, ''), false);\n        } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {\n            return new ImageContainer(src, false);\n        } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {\n            return new ImageContainer(src, true);\n        } else if (this.options.proxy) {\n            return new ProxyImageContainer(src, this.options.proxy);\n        } else {\n            return new DummyImageContainer(src);\n        }\n    } else if (imageData.method === \"linear-gradient\") {\n        return new LinearGradientContainer(imageData);\n    } else if (imageData.method === \"gradient\") {\n        return new WebkitGradientContainer(imageData);\n    } else if (imageData.method === \"svg\") {\n        return new SVGNodeContainer(imageData.args[0], this.support.svg);\n    } else if (imageData.method === \"IFRAME\") {\n        return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);\n    } else {\n        return new DummyImageContainer(imageData);\n    }\n};\n\nImageLoader.prototype.isSVG = function(src) {\n    return src.substring(src.length - 3).toLowerCase() === \"svg\" || SVGContainer.prototype.isInline(src);\n};\n\nImageLoader.prototype.imageExists = function(images, src) {\n    return images.some(function(image) {\n        return image.src === src;\n    });\n};\n\nImageLoader.prototype.isSameOrigin = function(url) {\n    return (this.getOrigin(url) === this.origin);\n};\n\nImageLoader.prototype.getOrigin = function(url) {\n    var link = this.link || (this.link = document.createElement(\"a\"));\n    link.href = url;\n    link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/\n    return link.protocol + link.hostname + link.port;\n};\n\nImageLoader.prototype.getPromise = function(container) {\n    return this.timeout(container, this.options.imageTimeout)['catch'](function() {\n        var dummy = new DummyImageContainer(container.src);\n        return dummy.promise.then(function(image) {\n            container.image = image;\n        });\n    });\n};\n\nImageLoader.prototype.get = function(src) {\n    var found = null;\n    return this.images.some(function(img) {\n        return (found = img).src === src;\n    }) ? found : null;\n};\n\nImageLoader.prototype.fetch = function(nodes) {\n    this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));\n    this.images.forEach(function(image, index) {\n        image.promise.then(function() {\n            log(\"Succesfully loaded image #\"+ (index+1), image);\n        }, function(e) {\n            log(\"Failed loading image #\"+ (index+1), image, e);\n        });\n    });\n    this.ready = Promise.all(this.images.map(this.getPromise, this));\n    log(\"Finished searching images\");\n    return this;\n};\n\nImageLoader.prototype.timeout = function(container, timeout) {\n    var timer;\n    var promise = Promise.race([container.promise, new Promise(function(res, reject) {\n        timer = setTimeout(function() {\n            log(\"Timed out loading image\", container);\n            reject(container);\n        }, timeout);\n    })]).then(function(container) {\n        clearTimeout(timer);\n        return container;\n    });\n    promise['catch'](function() {\n        clearTimeout(timer);\n    });\n    return promise;\n};\n\nmodule.exports = ImageLoader;\n\n},{\"./dummyimagecontainer\":7,\"./framecontainer\":10,\"./imagecontainer\":12,\"./lineargradientcontainer\":14,\"./log\":15,\"./promise\":18,\"./proxyimagecontainer\":20,\"./svgcontainer\":26,\"./svgnodecontainer\":27,\"./utils\":29,\"./webkitgradientcontainer\":30}],14:[function(require,module,exports){\nvar GradientContainer = require('./gradientcontainer');\nvar Color = require('./color');\n\nfunction LinearGradientContainer(imageData) {\n    GradientContainer.apply(this, arguments);\n    this.type = this.TYPES.LINEAR;\n\n    var hasDirection = imageData.args[0].match(this.stepRegExp) === null;\n\n    if (hasDirection) {\n        imageData.args[0].split(\" \").reverse().forEach(function(position) {\n            switch(position) {\n            case \"left\":\n                this.x0 = 0;\n                this.x1 = 1;\n                break;\n            case \"top\":\n                this.y0 = 0;\n                this.y1 = 1;\n                break;\n            case \"right\":\n                this.x0 = 1;\n                this.x1 = 0;\n                break;\n            case \"bottom\":\n                this.y0 = 1;\n                this.y1 = 0;\n                break;\n            case \"to\":\n                var y0 = this.y0;\n                var x0 = this.x0;\n                this.y0 = this.y1;\n                this.x0 = this.x1;\n                this.x1 = x0;\n                this.y1 = y0;\n                break;\n            }\n        }, this);\n    } else {\n        this.y0 = 0;\n        this.y1 = 1;\n    }\n\n    this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {\n        var colorStopMatch = colorStop.match(/((?:rgb|rgba)\\(\\d{1,3},\\s\\d{1,3},\\s\\d{1,3}(?:,\\s[0-9\\.]+)?\\)|\\w+)\\s*(\\d{1,3})?(%|px)?/);\n        return {\n            color: new Color(colorStopMatch[1]),\n            stop: colorStopMatch[3] === \"%\" ? colorStopMatch[2] / 100 : null\n        };\n    }, this);\n\n    if (this.colorStops[0].stop === null) {\n        this.colorStops[0].stop = 0;\n    }\n\n    if (this.colorStops[this.colorStops.length - 1].stop === null) {\n        this.colorStops[this.colorStops.length - 1].stop = 1;\n    }\n\n    this.colorStops.forEach(function(colorStop, index) {\n        if (colorStop.stop === null) {\n            this.colorStops.slice(index).some(function(find, count) {\n                if (find.stop !== null) {\n                    colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;\n                    return true;\n                } else {\n                    return false;\n                }\n            }, this);\n        }\n    }, this);\n}\n\nLinearGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\nLinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\\(\\d{1,3},\\s\\d{1,3},\\s\\d{1,3}(?:,\\s[0-9\\.]+)?\\))\\s*(\\d{1,3})?(%|px)?/;\n\nmodule.exports = LinearGradientContainer;\n\n},{\"./color\":5,\"./gradientcontainer\":11}],15:[function(require,module,exports){\nmodule.exports = function() {\n    if (window.html2canvas.logging && window.console && window.console.log) {\n        Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + \"ms\", \"html2canvas:\"].concat([].slice.call(arguments, 0)));\n    }\n};\n\n},{}],16:[function(require,module,exports){\nvar Color = require('./color');\nvar utils = require('./utils');\nvar getBounds = utils.getBounds;\nvar parseBackgrounds = utils.parseBackgrounds;\nvar offsetBounds = utils.offsetBounds;\n\nfunction NodeContainer(node, parent) {\n    this.node = node;\n    this.parent = parent;\n    this.stack = null;\n    this.bounds = null;\n    this.borders = null;\n    this.clip = [];\n    this.backgroundClip = [];\n    this.offsetBounds = null;\n    this.visible = null;\n    this.computedStyles = null;\n    this.colors = {};\n    this.styles = {};\n    this.backgroundImages = null;\n    this.transformData = null;\n    this.transformMatrix = null;\n    this.isPseudoElement = false;\n    this.opacity = null;\n}\n\nNodeContainer.prototype.cloneTo = function(stack) {\n    stack.visible = this.visible;\n    stack.borders = this.borders;\n    stack.bounds = this.bounds;\n    stack.clip = this.clip;\n    stack.backgroundClip = this.backgroundClip;\n    stack.computedStyles = this.computedStyles;\n    stack.styles = this.styles;\n    stack.backgroundImages = this.backgroundImages;\n    stack.opacity = this.opacity;\n};\n\nNodeContainer.prototype.getOpacity = function() {\n    return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;\n};\n\nNodeContainer.prototype.assignStack = function(stack) {\n    this.stack = stack;\n    stack.children.push(this);\n};\n\nNodeContainer.prototype.isElementVisible = function() {\n    return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (\n        this.css('display') !== \"none\" &&\n        this.css('visibility') !== \"hidden\" &&\n        !this.node.hasAttribute(\"data-html2canvas-ignore\") &&\n        (this.node.nodeName !== \"INPUT\" || this.node.getAttribute(\"type\") !== \"hidden\")\n    );\n};\n\nNodeContainer.prototype.css = function(attribute) {\n    if (!this.computedStyles) {\n        this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? \":before\" : \":after\") : this.computedStyle(null);\n    }\n\n    return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);\n};\n\nNodeContainer.prototype.prefixedCss = function(attribute) {\n    var prefixes = [\"webkit\", \"moz\", \"ms\", \"o\"];\n    var value = this.css(attribute);\n    if (value === undefined) {\n        prefixes.some(function(prefix) {\n            value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));\n            return value !== undefined;\n        }, this);\n    }\n    return value === undefined ? null : value;\n};\n\nNodeContainer.prototype.computedStyle = function(type) {\n    return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);\n};\n\nNodeContainer.prototype.cssInt = function(attribute) {\n    var value = parseInt(this.css(attribute), 10);\n    return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html\n};\n\nNodeContainer.prototype.color = function(attribute) {\n    return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));\n};\n\nNodeContainer.prototype.cssFloat = function(attribute) {\n    var value = parseFloat(this.css(attribute));\n    return (isNaN(value)) ? 0 : value;\n};\n\nNodeContainer.prototype.fontWeight = function() {\n    var weight = this.css(\"fontWeight\");\n    switch(parseInt(weight, 10)){\n    case 401:\n        weight = \"bold\";\n        break;\n    case 400:\n        weight = \"normal\";\n        break;\n    }\n    return weight;\n};\n\nNodeContainer.prototype.parseClip = function() {\n    var matches = this.css('clip').match(this.CLIP);\n    if (matches) {\n        return {\n            top: parseInt(matches[1], 10),\n            right: parseInt(matches[2], 10),\n            bottom: parseInt(matches[3], 10),\n            left: parseInt(matches[4], 10)\n        };\n    }\n    return null;\n};\n\nNodeContainer.prototype.parseBackgroundImages = function() {\n    return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css(\"backgroundImage\")));\n};\n\nNodeContainer.prototype.cssList = function(property, index) {\n    var value = (this.css(property) || '').split(',');\n    value = value[index || 0] || value[0] || 'auto';\n    value = value.trim().split(' ');\n    if (value.length === 1) {\n        value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];\n    }\n    return value;\n};\n\nNodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {\n    var size = this.cssList(\"backgroundSize\", index);\n    var width, height;\n\n    if (isPercentage(size[0])) {\n        width = bounds.width * parseFloat(size[0]) / 100;\n    } else if (/contain|cover/.test(size[0])) {\n        var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;\n        return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};\n    } else {\n        width = parseInt(size[0], 10);\n    }\n\n    if (size[0] === 'auto' && size[1] === 'auto') {\n        height = image.height;\n    } else if (size[1] === 'auto') {\n        height = width / image.width * image.height;\n    } else if (isPercentage(size[1])) {\n        height =  bounds.height * parseFloat(size[1]) / 100;\n    } else {\n        height = parseInt(size[1], 10);\n    }\n\n    if (size[0] === 'auto') {\n        width = height / image.height * image.width;\n    }\n\n    return {width: width, height: height};\n};\n\nNodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {\n    var position = this.cssList('backgroundPosition', index);\n    var left, top;\n\n    if (isPercentage(position[0])){\n        left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);\n    } else {\n        left = parseInt(position[0], 10);\n    }\n\n    if (position[1] === 'auto') {\n        top = left / image.width * image.height;\n    } else if (isPercentage(position[1])){\n        top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;\n    } else {\n        top = parseInt(position[1], 10);\n    }\n\n    if (position[0] === 'auto') {\n        left = top / image.height * image.width;\n    }\n\n    return {left: left, top: top};\n};\n\nNodeContainer.prototype.parseBackgroundRepeat = function(index) {\n    return this.cssList(\"backgroundRepeat\", index)[0];\n};\n\nNodeContainer.prototype.parseTextShadows = function() {\n    var textShadow = this.css(\"textShadow\");\n    var results = [];\n\n    if (textShadow && textShadow !== 'none') {\n        var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);\n        for (var i = 0; shadows && (i < shadows.length); i++) {\n            var s = shadows[i].match(this.TEXT_SHADOW_VALUES);\n            results.push({\n                color: new Color(s[0]),\n                offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,\n                offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,\n                blur: s[3] ? s[3].replace('px', '') : 0\n            });\n        }\n    }\n    return results;\n};\n\nNodeContainer.prototype.parseTransform = function() {\n    if (!this.transformData) {\n        if (this.hasTransform()) {\n            var offset = this.parseBounds();\n            var origin = this.prefixedCss(\"transformOrigin\").split(\" \").map(removePx).map(asFloat);\n            origin[0] += offset.left;\n            origin[1] += offset.top;\n            this.transformData = {\n                origin: origin,\n                matrix: this.parseTransformMatrix()\n            };\n        } else {\n            this.transformData = {\n                origin: [0, 0],\n                matrix: [1, 0, 0, 1, 0, 0]\n            };\n        }\n    }\n    return this.transformData;\n};\n\nNodeContainer.prototype.parseTransformMatrix = function() {\n    if (!this.transformMatrix) {\n        var transform = this.prefixedCss(\"transform\");\n        var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;\n        this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];\n    }\n    return this.transformMatrix;\n};\n\nNodeContainer.prototype.parseBounds = function() {\n    return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));\n};\n\nNodeContainer.prototype.hasTransform = function() {\n    return this.parseTransformMatrix().join(\",\") !== \"1,0,0,1,0,0\" || (this.parent && this.parent.hasTransform());\n};\n\nNodeContainer.prototype.getValue = function() {\n    var value = this.node.value || \"\";\n    if (this.node.tagName === \"SELECT\") {\n        value = selectionValue(this.node);\n    } else if (this.node.type === \"password\") {\n        value = Array(value.length + 1).join('\\u2022'); // jshint ignore:line\n    }\n    return value.length === 0 ? (this.node.placeholder || \"\") : value;\n};\n\nNodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\\((.+)\\)/;\nNodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\\([^\\)]+\\)(\\s-?\\d+px){0,})/g;\nNodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\\d+px)|(#.+)|(rgb\\(.+\\))|(rgba\\(.+\\))/g;\nNodeContainer.prototype.CLIP = /^rect\\((\\d+)px,? (\\d+)px,? (\\d+)px,? (\\d+)px\\)$/;\n\nfunction selectionValue(node) {\n    var option = node.options[node.selectedIndex || 0];\n    return option ? (option.text || \"\") : \"\";\n}\n\nfunction parseMatrix(match) {\n    if (match && match[1] === \"matrix\") {\n        return match[2].split(\",\").map(function(s) {\n            return parseFloat(s.trim());\n        });\n    } else if (match && match[1] === \"matrix3d\") {\n        var matrix3d = match[2].split(\",\").map(function(s) {\n          return parseFloat(s.trim());\n        });\n        return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];\n    }\n}\n\nfunction isPercentage(value) {\n    return value.toString().indexOf(\"%\") !== -1;\n}\n\nfunction removePx(str) {\n    return str.replace(\"px\", \"\");\n}\n\nfunction asFloat(str) {\n    return parseFloat(str);\n}\n\nmodule.exports = NodeContainer;\n\n},{\"./color\":5,\"./utils\":29}],17:[function(require,module,exports){\nvar log = require('./log');\nvar punycode = require('punycode');\nvar NodeContainer = require('./nodecontainer');\nvar TextContainer = require('./textcontainer');\nvar PseudoElementContainer = require('./pseudoelementcontainer');\nvar FontMetrics = require('./fontmetrics');\nvar Color = require('./color');\nvar Promise = require('./promise');\nvar StackingContext = require('./stackingcontext');\nvar utils = require('./utils');\nvar bind = utils.bind;\nvar getBounds = utils.getBounds;\nvar parseBackgrounds = utils.parseBackgrounds;\nvar offsetBounds = utils.offsetBounds;\n\nfunction NodeParser(element, renderer, support, imageLoader, options) {\n    log(\"Starting NodeParser\");\n    this.renderer = renderer;\n    this.options = options;\n    this.range = null;\n    this.support = support;\n    this.renderQueue = [];\n    this.stack = new StackingContext(true, 1, element.ownerDocument, null);\n    var parent = new NodeContainer(element, null);\n    if (options.background) {\n        renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));\n    }\n    if (element === element.ownerDocument.documentElement) {\n        // http://www.w3.org/TR/css3-background/#special-backgrounds\n        var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);\n        renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));\n    }\n    parent.visibile = parent.isElementVisible();\n    this.createPseudoHideStyles(element.ownerDocument);\n    this.disableAnimations(element.ownerDocument);\n    this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {\n        return container.visible = container.isElementVisible();\n    }).map(this.getPseudoElements, this));\n    this.fontMetrics = new FontMetrics();\n    log(\"Fetched nodes, total:\", this.nodes.length);\n    log(\"Calculate overflow clips\");\n    this.calculateOverflowClips();\n    log(\"Start fetching images\");\n    this.images = imageLoader.fetch(this.nodes.filter(isElement));\n    this.ready = this.images.ready.then(bind(function() {\n        log(\"Images loaded, starting parsing\");\n        log(\"Creating stacking contexts\");\n        this.createStackingContexts();\n        log(\"Sorting stacking contexts\");\n        this.sortStackingContexts(this.stack);\n        this.parse(this.stack);\n        log(\"Render queue created with \" + this.renderQueue.length + \" items\");\n        return new Promise(bind(function(resolve) {\n            if (!options.async) {\n                this.renderQueue.forEach(this.paint, this);\n                resolve();\n            } else if (typeof(options.async) === \"function\") {\n                options.async.call(this, this.renderQueue, resolve);\n            } else if (this.renderQueue.length > 0){\n                this.renderIndex = 0;\n                this.asyncRenderer(this.renderQueue, resolve);\n            } else {\n                resolve();\n            }\n        }, this));\n    }, this));\n}\n\nNodeParser.prototype.calculateOverflowClips = function() {\n    this.nodes.forEach(function(container) {\n        if (isElement(container)) {\n            if (isPseudoElement(container)) {\n                container.appendToDOM();\n            }\n            container.borders = this.parseBorders(container);\n            var clip = (container.css('overflow') === \"hidden\") ? [container.borders.clip] : [];\n            var cssClip = container.parseClip();\n            if (cssClip && [\"absolute\", \"fixed\"].indexOf(container.css('position')) !== -1) {\n                clip.push([[\"rect\",\n                        container.bounds.left + cssClip.left,\n                        container.bounds.top + cssClip.top,\n                        cssClip.right - cssClip.left,\n                        cssClip.bottom - cssClip.top\n                ]]);\n            }\n            container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;\n            container.backgroundClip = (container.css('overflow') !== \"hidden\") ? container.clip.concat([container.borders.clip]) : container.clip;\n            if (isPseudoElement(container)) {\n                container.cleanDOM();\n            }\n        } else if (isTextNode(container)) {\n            container.clip = hasParentClip(container) ? container.parent.clip : [];\n        }\n        if (!isPseudoElement(container)) {\n            container.bounds = null;\n        }\n    }, this);\n};\n\nfunction hasParentClip(container) {\n    return container.parent && container.parent.clip.length;\n}\n\nNodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {\n    asyncTimer = asyncTimer || Date.now();\n    this.paint(queue[this.renderIndex++]);\n    if (queue.length === this.renderIndex) {\n        resolve();\n    } else if (asyncTimer + 20 > Date.now()) {\n        this.asyncRenderer(queue, resolve, asyncTimer);\n    } else {\n        setTimeout(bind(function() {\n            this.asyncRenderer(queue, resolve);\n        }, this), 0);\n    }\n};\n\nNodeParser.prototype.createPseudoHideStyles = function(document) {\n    this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: \"\" !important; display: none !important; }' +\n        '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: \"\" !important; display: none !important; }');\n};\n\nNodeParser.prototype.disableAnimations = function(document) {\n    this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +\n        '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');\n};\n\nNodeParser.prototype.createStyles = function(document, styles) {\n    var hidePseudoElements = document.createElement('style');\n    hidePseudoElements.innerHTML = styles;\n    document.body.appendChild(hidePseudoElements);\n};\n\nNodeParser.prototype.getPseudoElements = function(container) {\n    var nodes = [[container]];\n    if (container.node.nodeType === Node.ELEMENT_NODE) {\n        var before = this.getPseudoElement(container, \":before\");\n        var after = this.getPseudoElement(container, \":after\");\n\n        if (before) {\n            nodes.push(before);\n        }\n\n        if (after) {\n            nodes.push(after);\n        }\n    }\n    return flatten(nodes);\n};\n\nfunction toCamelCase(str) {\n    return str.replace(/(\\-[a-z])/g, function(match){\n        return match.toUpperCase().replace('-','');\n    });\n}\n\nNodeParser.prototype.getPseudoElement = function(container, type) {\n    var style = container.computedStyle(type);\n    if(!style || !style.content || style.content === \"none\" || style.content === \"-moz-alt-content\" || style.display === \"none\") {\n        return null;\n    }\n\n    var content = stripQuotes(style.content);\n    var isImage = content.substr(0, 3) === 'url';\n    var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');\n    var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);\n\n    for (var i = style.length-1; i >= 0; i--) {\n        var property = toCamelCase(style.item(i));\n        pseudoNode.style[property] = style[property];\n    }\n\n    pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + \" \" + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;\n\n    if (isImage) {\n        pseudoNode.src = parseBackgrounds(content)[0].args[0];\n        return [pseudoContainer];\n    } else {\n        var text = document.createTextNode(content);\n        pseudoNode.appendChild(text);\n        return [pseudoContainer, new TextContainer(text, pseudoContainer)];\n    }\n};\n\n\nNodeParser.prototype.getChildren = function(parentContainer) {\n    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {\n        var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);\n        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== \"TEXTAREA\" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;\n    }, this));\n};\n\nNodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {\n    var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);\n    container.cloneTo(stack);\n    var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;\n    parentStack.contexts.push(stack);\n    container.stack = stack;\n};\n\nNodeParser.prototype.createStackingContexts = function() {\n    this.nodes.forEach(function(container) {\n        if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {\n            this.newStackingContext(container, true);\n        } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {\n            this.newStackingContext(container, false);\n        } else {\n            container.assignStack(container.parent.stack);\n        }\n    }, this);\n};\n\nNodeParser.prototype.isBodyWithTransparentRoot = function(container) {\n    return container.node.nodeName === \"BODY\" && container.parent.color('backgroundColor').isTransparent();\n};\n\nNodeParser.prototype.isRootElement = function(container) {\n    return container.parent === null;\n};\n\nNodeParser.prototype.sortStackingContexts = function(stack) {\n    stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));\n    stack.contexts.forEach(this.sortStackingContexts, this);\n};\n\nNodeParser.prototype.parseTextBounds = function(container) {\n    return function(text, index, textList) {\n        if (container.parent.css(\"textDecoration\").substr(0, 4) !== \"none\" || text.trim().length !== 0) {\n            if (this.support.rangeBounds && !container.parent.hasTransform()) {\n                var offset = textList.slice(0, index).join(\"\").length;\n                return this.getRangeBounds(container.node, offset, text.length);\n            } else if (container.node && typeof(container.node.data) === \"string\") {\n                var replacementNode = container.node.splitText(text.length);\n                var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());\n                container.node = replacementNode;\n                return bounds;\n            }\n        } else if(!this.support.rangeBounds || container.parent.hasTransform()){\n            container.node = container.node.splitText(text.length);\n        }\n        return {};\n    };\n};\n\nNodeParser.prototype.getWrapperBounds = function(node, transform) {\n    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');\n    var parent = node.parentNode,\n        backupText = node.cloneNode(true);\n\n    wrapper.appendChild(node.cloneNode(true));\n    parent.replaceChild(wrapper, node);\n    var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);\n    parent.replaceChild(backupText, wrapper);\n    return bounds;\n};\n\nNodeParser.prototype.getRangeBounds = function(node, offset, length) {\n    var range = this.range || (this.range = node.ownerDocument.createRange());\n    range.setStart(node, offset);\n    range.setEnd(node, offset + length);\n    return range.getBoundingClientRect();\n};\n\nfunction ClearTransform() {}\n\nNodeParser.prototype.parse = function(stack) {\n    // http://www.w3.org/TR/CSS21/visuren.html#z-index\n    var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).\n    var descendantElements = stack.children.filter(isElement);\n    var descendantNonFloats = descendantElements.filter(not(isFloating));\n    var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.\n    var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.\n    var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.\n    var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.\n    var text = stack.children.filter(isTextNode).filter(hasText);\n    var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).\n    negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)\n        .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {\n            this.renderQueue.push(container);\n            if (isStackingContext(container)) {\n                this.parse(container);\n                this.renderQueue.push(new ClearTransform());\n            }\n        }, this);\n};\n\nNodeParser.prototype.paint = function(container) {\n    try {\n        if (container instanceof ClearTransform) {\n            this.renderer.ctx.restore();\n        } else if (isTextNode(container)) {\n            if (isPseudoElement(container.parent)) {\n                container.parent.appendToDOM();\n            }\n            this.paintText(container);\n            if (isPseudoElement(container.parent)) {\n                container.parent.cleanDOM();\n            }\n        } else {\n            this.paintNode(container);\n        }\n    } catch(e) {\n        log(e);\n        if (this.options.strict) {\n            throw e;\n        }\n    }\n};\n\nNodeParser.prototype.paintNode = function(container) {\n    if (isStackingContext(container)) {\n        this.renderer.setOpacity(container.opacity);\n        this.renderer.ctx.save();\n        if (container.hasTransform()) {\n            this.renderer.setTransform(container.parseTransform());\n        }\n    }\n\n    if (container.node.nodeName === \"INPUT\" && container.node.type === \"checkbox\") {\n        this.paintCheckbox(container);\n    } else if (container.node.nodeName === \"INPUT\" && container.node.type === \"radio\") {\n        this.paintRadio(container);\n    } else {\n        this.paintElement(container);\n    }\n};\n\nNodeParser.prototype.paintElement = function(container) {\n    var bounds = container.parseBounds();\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));\n    }, this);\n\n    this.renderer.clip(container.clip, function() {\n        this.renderer.renderBorders(container.borders.borders);\n    }, this);\n\n    this.renderer.clip(container.backgroundClip, function() {\n        switch (container.node.nodeName) {\n        case \"svg\":\n        case \"IFRAME\":\n            var imgContainer = this.images.get(container.node);\n            if (imgContainer) {\n                this.renderer.renderImage(container, bounds, container.borders, imgContainer);\n            } else {\n                log(\"Error loading <\" + container.node.nodeName + \">\", container.node);\n            }\n            break;\n        case \"IMG\":\n            var imageContainer = this.images.get(container.node.src);\n            if (imageContainer) {\n                this.renderer.renderImage(container, bounds, container.borders, imageContainer);\n            } else {\n                log(\"Error loading <img>\", container.node.src);\n            }\n            break;\n        case \"CANVAS\":\n            this.renderer.renderImage(container, bounds, container.borders, {image: container.node});\n            break;\n        case \"SELECT\":\n        case \"INPUT\":\n        case \"TEXTAREA\":\n            this.paintFormValue(container);\n            break;\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintCheckbox = function(container) {\n    var b = container.parseBounds();\n\n    var size = Math.min(b.width, b.height);\n    var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};\n    var r = [3, 3];\n    var radius = [r, r, r, r];\n    var borders = [1,1,1,1].map(function(w) {\n        return {color: new Color('#A5A5A5'), width: w};\n    });\n\n    var borderPoints = calculateCurvePoints(bounds, radius, borders);\n\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color(\"#DEDEDE\"));\n        this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));\n        if (container.node.checked) {\n            this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + \"px\", 'arial');\n            this.renderer.text(\"\\u2714\", bounds.left + size / 6, bounds.top + size - 1);\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintRadio = function(container) {\n    var bounds = container.parseBounds();\n\n    var size = Math.min(bounds.width, bounds.height) - 2;\n\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));\n        if (container.node.checked) {\n            this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintFormValue = function(container) {\n    var value = container.getValue();\n    if (value.length > 0) {\n        var document = container.node.ownerDocument;\n        var wrapper = document.createElement('html2canvaswrapper');\n        var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',\n            'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',\n            'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',\n            'boxSizing', 'whiteSpace', 'wordWrap'];\n\n        properties.forEach(function(property) {\n            try {\n                wrapper.style[property] = container.css(property);\n            } catch(e) {\n                // Older IE has issues with \"border\"\n                log(\"html2canvas: Parse: Exception caught in renderFormValue: \" + e.message);\n            }\n        });\n        var bounds = container.parseBounds();\n        wrapper.style.position = \"fixed\";\n        wrapper.style.left = bounds.left + \"px\";\n        wrapper.style.top = bounds.top + \"px\";\n        wrapper.textContent = value;\n        document.body.appendChild(wrapper);\n        this.paintText(new TextContainer(wrapper.firstChild, container));\n        document.body.removeChild(wrapper);\n    }\n};\n\nNodeParser.prototype.paintText = function(container) {\n    container.applyTextTransform();\n    var characters = punycode.ucs2.decode(container.node.data);\n    var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {\n        return punycode.ucs2.encode([character]);\n    });\n\n    var weight = container.parent.fontWeight();\n    var size = container.parent.css('fontSize');\n    var family = container.parent.css('fontFamily');\n    var shadows = container.parent.parseTextShadows();\n\n    this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);\n    if (shadows.length) {\n        // TODO: support multiple text shadows\n        this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);\n    } else {\n        this.renderer.clearShadow();\n    }\n\n    this.renderer.clip(container.parent.clip, function() {\n        textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {\n            if (bounds) {\n                this.renderer.text(textList[index], bounds.left, bounds.bottom);\n                this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));\n            }\n        }, this);\n    }, this);\n};\n\nNodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {\n    switch(container.css(\"textDecoration\").split(\" \")[0]) {\n    case \"underline\":\n        // Draws a line at the baseline of the font\n        // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size\n        this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n        break;\n    case \"overline\":\n        this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color(\"color\"));\n        break;\n    case \"line-through\":\n        // TODO try and find exact position for line-through\n        this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n        break;\n    }\n};\n\nvar borderColorTransforms = {\n    inset: [\n        [\"darken\", 0.60],\n        [\"darken\", 0.10],\n        [\"darken\", 0.10],\n        [\"darken\", 0.60]\n    ]\n};\n\nNodeParser.prototype.parseBorders = function(container) {\n    var nodeBounds = container.parseBounds();\n    var radius = getBorderRadiusData(container);\n    var borders = [\"Top\", \"Right\", \"Bottom\", \"Left\"].map(function(side, index) {\n        var style = container.css('border' + side + 'Style');\n        var color = container.color('border' + side + 'Color');\n        if (style === \"inset\" && color.isBlack()) {\n            color = new Color([255, 255, 255, color.a]); // this is wrong, but\n        }\n        var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;\n        return {\n            width: container.cssInt('border' + side + 'Width'),\n            color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,\n            args: null\n        };\n    });\n    var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);\n\n    return {\n        clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),\n        borders: calculateBorders(borders, nodeBounds, borderPoints, radius)\n    };\n};\n\nfunction calculateBorders(borders, nodeBounds, borderPoints, radius) {\n    return borders.map(function(border, borderSide) {\n        if (border.width > 0) {\n            var bx = nodeBounds.left;\n            var by = nodeBounds.top;\n            var bw = nodeBounds.width;\n            var bh = nodeBounds.height - (borders[2].width);\n\n            switch(borderSide) {\n            case 0:\n                // top border\n                bh = borders[0].width;\n                border.args = drawSide({\n                        c1: [bx, by],\n                        c2: [bx + bw, by],\n                        c3: [bx + bw - borders[1].width, by + bh],\n                        c4: [bx + borders[3].width, by + bh]\n                    }, radius[0], radius[1],\n                    borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);\n                break;\n            case 1:\n                // right border\n                bx = nodeBounds.left + nodeBounds.width - (borders[1].width);\n                bw = borders[1].width;\n\n                border.args = drawSide({\n                        c1: [bx + bw, by],\n                        c2: [bx + bw, by + bh + borders[2].width],\n                        c3: [bx, by + bh],\n                        c4: [bx, by + borders[0].width]\n                    }, radius[1], radius[2],\n                    borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);\n                break;\n            case 2:\n                // bottom border\n                by = (by + nodeBounds.height) - (borders[2].width);\n                bh = borders[2].width;\n                border.args = drawSide({\n                        c1: [bx + bw, by + bh],\n                        c2: [bx, by + bh],\n                        c3: [bx + borders[3].width, by],\n                        c4: [bx + bw - borders[3].width, by]\n                    }, radius[2], radius[3],\n                    borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);\n                break;\n            case 3:\n                // left border\n                bw = borders[3].width;\n                border.args = drawSide({\n                        c1: [bx, by + bh + borders[2].width],\n                        c2: [bx, by],\n                        c3: [bx + bw, by + borders[0].width],\n                        c4: [bx + bw, by + bh]\n                    }, radius[3], radius[0],\n                    borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);\n                break;\n            }\n        }\n        return border;\n    });\n}\n\nNodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {\n    var backgroundClip = container.css('backgroundClip'),\n        borderArgs = [];\n\n    switch(backgroundClip) {\n    case \"content-box\":\n    case \"padding-box\":\n        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);\n        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);\n        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);\n        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);\n        break;\n\n    default:\n        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);\n        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);\n        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);\n        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);\n        break;\n    }\n\n    return borderArgs;\n};\n\nfunction getCurvePoints(x, y, r1, r2) {\n    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);\n    var ox = (r1) * kappa, // control point offset horizontal\n        oy = (r2) * kappa, // control point offset vertical\n        xm = x + r1, // x-middle\n        ym = y + r2; // y-middle\n    return {\n        topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),\n        topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),\n        bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),\n        bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})\n    };\n}\n\nfunction calculateCurvePoints(bounds, borderRadius, borders) {\n    var x = bounds.left,\n        y = bounds.top,\n        width = bounds.width,\n        height = bounds.height,\n\n        tlh = borderRadius[0][0],\n        tlv = borderRadius[0][1],\n        trh = borderRadius[1][0],\n        trv = borderRadius[1][1],\n        brh = borderRadius[2][0],\n        brv = borderRadius[2][1],\n        blh = borderRadius[3][0],\n        blv = borderRadius[3][1];\n\n        var halfHeight = Math.floor(height / 2);\n        tlh = tlh > halfHeight ? halfHeight : tlh;\n        tlv = tlv > halfHeight ? halfHeight : tlv;\n        trh = trh > halfHeight ? halfHeight : trh;\n        trv = trv > halfHeight ? halfHeight : trv;\n        brh = brh > halfHeight ? halfHeight : brh;\n        brv = brv > halfHeight ? halfHeight : brv;\n        blh = blh > halfHeight ? halfHeight : blh;\n        blv = blv > halfHeight ? halfHeight : blv;\n\n        var topWidth = width - trh,\n        rightHeight = height - brv,\n        bottomWidth = width - brh,\n        leftHeight = height - blv;\n\n    return {\n        topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),\n        topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),\n        topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),\n        topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),\n        bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),\n        bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),\n        bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),\n        bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)\n    };\n}\n\nfunction bezierCurve(start, startControl, endControl, end) {\n    var lerp = function (a, b, t) {\n        return {\n            x: a.x + (b.x - a.x) * t,\n            y: a.y + (b.y - a.y) * t\n        };\n    };\n\n    return {\n        start: start,\n        startControl: startControl,\n        endControl: endControl,\n        end: end,\n        subdivide: function(t) {\n            var ab = lerp(start, startControl, t),\n                bc = lerp(startControl, endControl, t),\n                cd = lerp(endControl, end, t),\n                abbc = lerp(ab, bc, t),\n                bccd = lerp(bc, cd, t),\n                dest = lerp(abbc, bccd, t);\n            return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];\n        },\n        curveTo: function(borderArgs) {\n            borderArgs.push([\"bezierCurve\", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);\n        },\n        curveToReversed: function(borderArgs) {\n            borderArgs.push([\"bezierCurve\", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);\n        }\n    };\n}\n\nfunction drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {\n    var borderArgs = [];\n\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", outer1[1].start.x, outer1[1].start.y]);\n        outer1[1].curveTo(borderArgs);\n    } else {\n        borderArgs.push([ \"line\", borderData.c1[0], borderData.c1[1]]);\n    }\n\n    if (radius2[0] > 0 || radius2[1] > 0) {\n        borderArgs.push([\"line\", outer2[0].start.x, outer2[0].start.y]);\n        outer2[0].curveTo(borderArgs);\n        borderArgs.push([\"line\", inner2[0].end.x, inner2[0].end.y]);\n        inner2[0].curveToReversed(borderArgs);\n    } else {\n        borderArgs.push([\"line\", borderData.c2[0], borderData.c2[1]]);\n        borderArgs.push([\"line\", borderData.c3[0], borderData.c3[1]]);\n    }\n\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", inner1[1].end.x, inner1[1].end.y]);\n        inner1[1].curveToReversed(borderArgs);\n    } else {\n        borderArgs.push([\"line\", borderData.c4[0], borderData.c4[1]]);\n    }\n\n    return borderArgs;\n}\n\nfunction parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", corner1[0].start.x, corner1[0].start.y]);\n        corner1[0].curveTo(borderArgs);\n        corner1[1].curveTo(borderArgs);\n    } else {\n        borderArgs.push([\"line\", x, y]);\n    }\n\n    if (radius2[0] > 0 || radius2[1] > 0) {\n        borderArgs.push([\"line\", corner2[0].start.x, corner2[0].start.y]);\n    }\n}\n\nfunction negativeZIndex(container) {\n    return container.cssInt(\"zIndex\") < 0;\n}\n\nfunction positiveZIndex(container) {\n    return container.cssInt(\"zIndex\") > 0;\n}\n\nfunction zIndex0(container) {\n    return container.cssInt(\"zIndex\") === 0;\n}\n\nfunction inlineLevel(container) {\n    return [\"inline\", \"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n}\n\nfunction isStackingContext(container) {\n    return (container instanceof StackingContext);\n}\n\nfunction hasText(container) {\n    return container.node.data.trim().length > 0;\n}\n\nfunction noLetterSpacing(container) {\n    return (/^(normal|none|0px)$/.test(container.parent.css(\"letterSpacing\")));\n}\n\nfunction getBorderRadiusData(container) {\n    return [\"TopLeft\", \"TopRight\", \"BottomRight\", \"BottomLeft\"].map(function(side) {\n        var value = container.css('border' + side + 'Radius');\n        var arr = value.split(\" \");\n        if (arr.length <= 1) {\n            arr[1] = arr[0];\n        }\n        return arr.map(asInt);\n    });\n}\n\nfunction renderableNode(node) {\n    return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);\n}\n\nfunction isPositionedForStacking(container) {\n    var position = container.css(\"position\");\n    var zIndex = ([\"absolute\", \"relative\", \"fixed\"].indexOf(position) !== -1) ? container.css(\"zIndex\") : \"auto\";\n    return zIndex !== \"auto\";\n}\n\nfunction isPositioned(container) {\n    return container.css(\"position\") !== \"static\";\n}\n\nfunction isFloating(container) {\n    return container.css(\"float\") !== \"none\";\n}\n\nfunction isInlineBlock(container) {\n    return [\"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n}\n\nfunction not(callback) {\n    var context = this;\n    return function() {\n        return !callback.apply(context, arguments);\n    };\n}\n\nfunction isElement(container) {\n    return container.node.nodeType === Node.ELEMENT_NODE;\n}\n\nfunction isPseudoElement(container) {\n    return container.isPseudoElement === true;\n}\n\nfunction isTextNode(container) {\n    return container.node.nodeType === Node.TEXT_NODE;\n}\n\nfunction zIndexSort(contexts) {\n    return function(a, b) {\n        return (a.cssInt(\"zIndex\") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt(\"zIndex\") + (contexts.indexOf(b) / contexts.length));\n    };\n}\n\nfunction hasOpacity(container) {\n    return container.getOpacity() < 1;\n}\n\nfunction asInt(value) {\n    return parseInt(value, 10);\n}\n\nfunction getWidth(border) {\n    return border.width;\n}\n\nfunction nonIgnoredElement(nodeContainer) {\n    return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || [\"SCRIPT\", \"HEAD\", \"TITLE\", \"OBJECT\", \"BR\", \"OPTION\"].indexOf(nodeContainer.node.nodeName) === -1);\n}\n\nfunction flatten(arrays) {\n    return [].concat.apply([], arrays);\n}\n\nfunction stripQuotes(content) {\n    var first = content.substr(0, 1);\n    return (first === content.substr(content.length - 1) && first.match(/'|\"/)) ? content.substr(1, content.length - 2) : content;\n}\n\nfunction getWords(characters) {\n    var words = [], i = 0, onWordBoundary = false, word;\n    while(characters.length) {\n        if (isWordBoundary(characters[i]) === onWordBoundary) {\n            word = characters.splice(0, i);\n            if (word.length) {\n                words.push(punycode.ucs2.encode(word));\n            }\n            onWordBoundary =! onWordBoundary;\n            i = 0;\n        } else {\n            i++;\n        }\n\n        if (i >= characters.length) {\n            word = characters.splice(0, i);\n            if (word.length) {\n                words.push(punycode.ucs2.encode(word));\n            }\n        }\n    }\n    return words;\n}\n\nfunction isWordBoundary(characterCode) {\n    return [\n        32, // <space>\n        13, // \\r\n        10, // \\n\n        9, // \\t\n        45 // -\n    ].indexOf(characterCode) !== -1;\n}\n\nfunction hasUnicode(string) {\n    return (/[^\\u0000-\\u00ff]/).test(string);\n}\n\nmodule.exports = NodeParser;\n\n},{\"./color\":5,\"./fontmetrics\":9,\"./log\":15,\"./nodecontainer\":16,\"./promise\":18,\"./pseudoelementcontainer\":21,\"./stackingcontext\":24,\"./textcontainer\":28,\"./utils\":29,\"punycode\":3}],18:[function(require,module,exports){\nmodule.exports = require('es6-promise').Promise;\n\n},{\"es6-promise\":1}],19:[function(require,module,exports){\nvar Promise = require('./promise');\nvar XHR = require('./xhr');\nvar utils = require('./utils');\nvar log = require('./log');\nvar createWindowClone = require('./clone');\nvar decode64 = utils.decode64;\n\nfunction Proxy(src, proxyUrl, document) {\n    var supportsCORS = ('withCredentials' in new XMLHttpRequest());\n    if (!proxyUrl) {\n        return Promise.reject(\"No proxy configured\");\n    }\n    var callback = createCallback(supportsCORS);\n    var url = createProxyUrl(proxyUrl, src, callback);\n\n    return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {\n        return decode64(response.content);\n    }));\n}\nvar proxyCount = 0;\n\nfunction ProxyURL(src, proxyUrl, document) {\n    var supportsCORSImage = ('crossOrigin' in new Image());\n    var callback = createCallback(supportsCORSImage);\n    var url = createProxyUrl(proxyUrl, src, callback);\n    return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {\n        return \"data:\" + response.type + \";base64,\" + response.content;\n    }));\n}\n\nfunction jsonp(document, url, callback) {\n    return new Promise(function(resolve, reject) {\n        var s = document.createElement(\"script\");\n        var cleanup = function() {\n            delete window.html2canvas.proxy[callback];\n            document.body.removeChild(s);\n        };\n        window.html2canvas.proxy[callback] = function(response) {\n            cleanup();\n            resolve(response);\n        };\n        s.src = url;\n        s.onerror = function(e) {\n            cleanup();\n            reject(e);\n        };\n        document.body.appendChild(s);\n    });\n}\n\nfunction createCallback(useCORS) {\n    return !useCORS ? \"html2canvas_\" + Date.now() + \"_\" + (++proxyCount) + \"_\" + Math.round(Math.random() * 100000) : \"\";\n}\n\nfunction createProxyUrl(proxyUrl, src, callback) {\n    return proxyUrl + \"?url=\" + encodeURIComponent(src) + (callback.length ? \"&callback=html2canvas.proxy.\" + callback : \"\");\n}\n\nfunction documentFromHTML(src) {\n    return function(html) {\n        var parser = new DOMParser(), doc;\n        try {\n            doc = parser.parseFromString(html, \"text/html\");\n        } catch(e) {\n            log(\"DOMParser not supported, falling back to createHTMLDocument\");\n            doc = document.implementation.createHTMLDocument(\"\");\n            try {\n                doc.open();\n                doc.write(html);\n                doc.close();\n            } catch(ee) {\n                log(\"createHTMLDocument write not supported, falling back to document.body.innerHTML\");\n                doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement\n            }\n        }\n\n        var b = doc.querySelector(\"base\");\n        if (!b || !b.href.host) {\n            var base = doc.createElement(\"base\");\n            base.href = src;\n            doc.head.insertBefore(base, doc.head.firstChild);\n        }\n\n        return doc;\n    };\n}\n\nfunction loadUrlDocument(src, proxy, document, width, height, options) {\n    return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {\n        return createWindowClone(doc, document, width, height, options, 0, 0);\n    });\n}\n\nexports.Proxy = Proxy;\nexports.ProxyURL = ProxyURL;\nexports.loadUrlDocument = loadUrlDocument;\n\n},{\"./clone\":4,\"./log\":15,\"./promise\":18,\"./utils\":29,\"./xhr\":31}],20:[function(require,module,exports){\nvar ProxyURL = require('./proxy').ProxyURL;\nvar Promise = require('./promise');\n\nfunction ProxyImageContainer(src, proxy) {\n    var link = document.createElement(\"a\");\n    link.href = src;\n    src = link.href;\n    this.src = src;\n    this.image = new Image();\n    var self = this;\n    this.promise = new Promise(function(resolve, reject) {\n        self.image.crossOrigin = \"Anonymous\";\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n\n        new ProxyURL(src, proxy, document).then(function(url) {\n            self.image.src = url;\n        })['catch'](reject);\n    });\n}\n\nmodule.exports = ProxyImageContainer;\n\n},{\"./promise\":18,\"./proxy\":19}],21:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction PseudoElementContainer(node, parent, type) {\n    NodeContainer.call(this, node, parent);\n    this.isPseudoElement = true;\n    this.before = type === \":before\";\n}\n\nPseudoElementContainer.prototype.cloneTo = function(stack) {\n    PseudoElementContainer.prototype.cloneTo.call(this, stack);\n    stack.isPseudoElement = true;\n    stack.before = this.before;\n};\n\nPseudoElementContainer.prototype = Object.create(NodeContainer.prototype);\n\nPseudoElementContainer.prototype.appendToDOM = function() {\n    if (this.before) {\n        this.parent.node.insertBefore(this.node, this.parent.node.firstChild);\n    } else {\n        this.parent.node.appendChild(this.node);\n    }\n    this.parent.node.className += \" \" + this.getHideClass();\n};\n\nPseudoElementContainer.prototype.cleanDOM = function() {\n    this.node.parentNode.removeChild(this.node);\n    this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), \"\");\n};\n\nPseudoElementContainer.prototype.getHideClass = function() {\n    return this[\"PSEUDO_HIDE_ELEMENT_CLASS_\" + (this.before ? \"BEFORE\" : \"AFTER\")];\n};\n\nPseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = \"___html2canvas___pseudoelement_before\";\nPseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = \"___html2canvas___pseudoelement_after\";\n\nmodule.exports = PseudoElementContainer;\n\n},{\"./nodecontainer\":16}],22:[function(require,module,exports){\nvar log = require('./log');\n\nfunction Renderer(width, height, images, options, document) {\n    this.width = width;\n    this.height = height;\n    this.images = images;\n    this.options = options;\n    this.document = document;\n}\n\nRenderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {\n    var paddingLeft = container.cssInt('paddingLeft'),\n        paddingTop = container.cssInt('paddingTop'),\n        paddingRight = container.cssInt('paddingRight'),\n        paddingBottom = container.cssInt('paddingBottom'),\n        borders = borderData.borders;\n\n    var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);\n    var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);\n    this.drawImage(\n        imageContainer,\n        0,\n        0,\n        imageContainer.image.width || width,\n        imageContainer.image.height || height,\n        bounds.left + paddingLeft + borders[3].width,\n        bounds.top + paddingTop + borders[0].width,\n        width,\n        height\n    );\n};\n\nRenderer.prototype.renderBackground = function(container, bounds, borderData) {\n    if (bounds.height > 0 && bounds.width > 0) {\n        this.renderBackgroundColor(container, bounds);\n        this.renderBackgroundImage(container, bounds, borderData);\n    }\n};\n\nRenderer.prototype.renderBackgroundColor = function(container, bounds) {\n    var color = container.color(\"backgroundColor\");\n    if (!color.isTransparent()) {\n        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);\n    }\n};\n\nRenderer.prototype.renderBorders = function(borders) {\n    borders.forEach(this.renderBorder, this);\n};\n\nRenderer.prototype.renderBorder = function(data) {\n    if (!data.color.isTransparent() && data.args !== null) {\n        this.drawShape(data.args, data.color);\n    }\n};\n\nRenderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {\n    var backgroundImages = container.parseBackgroundImages();\n    backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {\n        switch(backgroundImage.method) {\n        case \"url\":\n            var image = this.images.get(backgroundImage.args[0]);\n            if (image) {\n                this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);\n            } else {\n                log(\"Error loading background-image\", backgroundImage.args[0]);\n            }\n            break;\n        case \"linear-gradient\":\n        case \"gradient\":\n            var gradientImage = this.images.get(backgroundImage.value);\n            if (gradientImage) {\n                this.renderBackgroundGradient(gradientImage, bounds, borderData);\n            } else {\n                log(\"Error loading background-image\", backgroundImage.args[0]);\n            }\n            break;\n        case \"none\":\n            break;\n        default:\n            log(\"Unknown background-image type\", backgroundImage.args[0]);\n        }\n    }, this);\n};\n\nRenderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {\n    var size = container.parseBackgroundSize(bounds, imageContainer.image, index);\n    var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);\n    var repeat = container.parseBackgroundRepeat(index);\n    switch (repeat) {\n    case \"repeat-x\":\n    case \"repeat no-repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);\n        break;\n    case \"repeat-y\":\n    case \"no-repeat repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);\n        break;\n    case \"no-repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);\n        break;\n    default:\n        this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);\n        break;\n    }\n};\n\nmodule.exports = Renderer;\n\n},{\"./log\":15}],23:[function(require,module,exports){\nvar Renderer = require('../renderer');\nvar LinearGradientContainer = require('../lineargradientcontainer');\nvar Utils = require('../utils');\nvar log = require('../log');\n\nfunction CanvasRenderer(width, height) {\n    this.ratio = Utils.getDeviceRatio();\n\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    Renderer.apply(this, arguments);\n    this.canvas = this.options.canvas || this.document.createElement(\"canvas\");\n    if (!this.options.canvas) {\n        this.canvas.width = width;\n        this.canvas.height = height;\n\n        if (this.ratio !== 1) {\n            var scale = 1 / this.ratio;\n            this.canvas.style.transform = 'scaleX(' + scale + ') scaleY(' + scale + ')';\n            this.canvas.style.transformOrigin = '0 0';\n        }\n    }\n\n    this.ctx = this.canvas.getContext(\"2d\");\n    this.taintCtx = this.document.createElement(\"canvas\").getContext(\"2d\");\n    this.ctx.textBaseline = \"bottom\";\n    this.variables = {};\n    log(\"Initialized CanvasRenderer with size\", width, \"x\", height);\n}\n\nCanvasRenderer.prototype = Object.create(Renderer.prototype);\n\nCanvasRenderer.prototype.setFillStyle = function(fillStyle) {\n    this.ctx.fillStyle = typeof(fillStyle) === \"object\" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;\n    return this.ctx;\n};\n\nCanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    this.setFillStyle(color).fillRect(left, top, width, height);\n};\n\nCanvasRenderer.prototype.circle = function(left, top, size, color) {\n    this.setFillStyle(color);\n    this.ctx.beginPath();\n    this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);\n    this.ctx.closePath();\n    this.ctx.fill();\n};\n\nCanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    size = Utils.applyRatio(size);\n\n    this.circle(left, top, size, color);\n    this.ctx.strokeStyle = strokeColor.toString();\n    this.ctx.stroke();\n};\n\nCanvasRenderer.prototype.drawShape = function(shape, color) {\n    shape = Utils.applyRatioToShape(shape);\n\n    this.shape(shape);\n    this.setFillStyle(color).fill();\n};\n\nCanvasRenderer.prototype.taints = function(imageContainer) {\n    if (imageContainer.tainted === null) {\n        this.taintCtx.drawImage(imageContainer.image, 0, 0);\n        try {\n            this.taintCtx.getImageData(0, 0, 1, 1);\n            imageContainer.tainted = false;\n        } catch(e) {\n            this.taintCtx = document.createElement(\"canvas\").getContext(\"2d\");\n            imageContainer.tainted = true;\n        }\n    }\n\n    return imageContainer.tainted;\n};\n\nCanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {\n    //Do not scale source coordinates\n    //sx = Utils.applyRatio(sx);\n    //sy = Utils.applyRatio(sy);\n    //sw = Utils.applyRatio(sw);\n    //sh = Utils.applyRatio(sh);\n\n    dx = Utils.applyRatio(dx);\n    dy = Utils.applyRatio(dy);\n    dw = Utils.applyRatio(dw);\n    dh = Utils.applyRatio(dh);\n\n    if (!this.taints(imageContainer) || this.options.allowTaint) {\n        this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);\n    }\n};\n\nCanvasRenderer.prototype.clip = function(shapes, callback, context) {\n    this.ctx.save();\n    shapes.filter(hasEntries).forEach(function(shape) {\n        shape = Utils.applyRatioToShape(shape);\n        this.shape(shape)//.clip();\n    }, this);\n    callback.call(context);\n    this.ctx.restore();\n};\n\nCanvasRenderer.prototype.shape = function(shape) {\n    this.ctx.beginPath();\n    shape.forEach(function(point, index) {\n        if (point[0] === \"rect\") {\n            this.ctx.rect.apply(this.ctx, point.slice(1));\n        } else {\n            this.ctx[(index === 0) ? \"moveTo\" : point[0] + \"To\" ].apply(this.ctx, point.slice(1));\n        }\n    }, this);\n    this.ctx.closePath();\n    return this.ctx;\n};\n\nCanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {\n    size = Utils.applyRatioToFontSize(size);\n    this.setFillStyle(color).font = [style, variant, weight, size, family].join(\" \").split(\",\")[0];\n};\n\nCanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {\n    offsetX = Utils.applyRatio(offsetX);\n    offsetY = Utils.applyRatio(offsetY);\n\n    this.setVariable(\"shadowColor\", color.toString())\n        .setVariable(\"shadowOffsetY\", offsetX)\n        .setVariable(\"shadowOffsetX\", offsetY)\n        .setVariable(\"shadowBlur\", blur);\n};\n\nCanvasRenderer.prototype.clearShadow = function() {\n    this.setVariable(\"shadowColor\", \"rgba(0,0,0,0)\");\n};\n\nCanvasRenderer.prototype.setOpacity = function(opacity) {\n    this.ctx.globalAlpha = opacity;\n};\n\nCanvasRenderer.prototype.setTransform = function(transform) {\n    debugger;\n    this.ctx.translate(transform.origin[0], transform.origin[1]);\n    this.ctx.transform.apply(this.ctx, transform.matrix);\n    this.ctx.translate(-transform.origin[0], -transform.origin[1]);\n};\n\nCanvasRenderer.prototype.setVariable = function(property, value) {\n    if (this.variables[property] !== value) {\n        this.variables[property] = this.ctx[property] = value;\n    }\n\n    return this;\n};\n\nCanvasRenderer.prototype.text = function(text, left, bottom) {\n    left = Utils.applyRatio(left);\n    bottom = Utils.applyRatio(bottom);\n\n    this.ctx.fillText(text, left, bottom);\n};\n\nCanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {\n    debugger;\n    size = Utils.applyRatio(size);\n    bounds = Utils.applyRatioToBounds(bounds);\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    var shape = [\n        [\"line\", Math.round(left), Math.round(top)],\n        [\"line\", Math.round(left + width), Math.round(top)],\n        [\"line\", Math.round(left + width), Math.round(height + top)],\n        [\"line\", Math.round(left), Math.round(height + top)]\n    ];\n    this.clip([shape], function() {\n        this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);\n    }, this);\n};\n\nCanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {\n    debugger;\n    bounds = Utils.applyRatioToBounds(bounds);\n    size = Utils.applyRatioToBounds(size);\n    backgroundPosition = Utils.applyRatioToBounds(backgroundPosition);\n    borderLeft = Utils.applyRatio(borderLeft);\n    borderTop = Utils.applyRatio(borderTop);\n\n    var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);\n    this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), \"repeat\"));\n    this.ctx.translate(offsetX, offsetY);\n    this.ctx.fill();\n    this.ctx.translate(-offsetX, -offsetY);\n};\n\nCanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {\n    debugger;\n    bounds = Utils.applyRatioToBounds(bounds);\n\n    if (gradientImage instanceof LinearGradientContainer) {\n        var gradient = this.ctx.createLinearGradient(\n            bounds.left + bounds.width * gradientImage.x0,\n            bounds.top + bounds.height * gradientImage.y0,\n            bounds.left +  bounds.width * gradientImage.x1,\n            bounds.top +  bounds.height * gradientImage.y1);\n        gradientImage.colorStops.forEach(function(colorStop) {\n            gradient.addColorStop(colorStop.stop, colorStop.color.toString());\n        });\n        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);\n    }\n};\n\nCanvasRenderer.prototype.resizeImage = function(imageContainer, size) {\n    size = Utils.applyRatioToBounds(size);\n\n    var image = imageContainer.image;\n    if(image.width === size.width && image.height === size.height) {\n        return image;\n    }\n\n    var ctx, canvas = document.createElement('canvas');\n    canvas.width = size.width;\n    canvas.height = size.height;\n    ctx = canvas.getContext(\"2d\");\n    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );\n    return canvas;\n};\n\nfunction hasEntries(array) {\n    return array.length > 0;\n}\n\nmodule.exports = CanvasRenderer;\n\n},{\"../lineargradientcontainer\":14,\"../log\":15,\"../renderer\":22,\"../utils\":29}],24:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction StackingContext(hasOwnStacking, opacity, element, parent) {\n    NodeContainer.call(this, element, parent);\n    this.ownStacking = hasOwnStacking;\n    this.contexts = [];\n    this.children = [];\n    this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;\n}\n\nStackingContext.prototype = Object.create(NodeContainer.prototype);\n\nStackingContext.prototype.getParentStack = function(context) {\n    var parentStack = (this.parent) ? this.parent.stack : null;\n    return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;\n};\n\nmodule.exports = StackingContext;\n\n},{\"./nodecontainer\":16}],25:[function(require,module,exports){\nfunction Support(document) {\n    this.rangeBounds = this.testRangeBounds(document);\n    this.cors = this.testCORS();\n    this.svg = this.testSVG();\n}\n\nSupport.prototype.testRangeBounds = function(document) {\n    var range, testElement, rangeBounds, rangeHeight, support = false;\n\n    if (document.createRange) {\n        range = document.createRange();\n        if (range.getBoundingClientRect) {\n            testElement = document.createElement('boundtest');\n            testElement.style.height = \"123px\";\n            testElement.style.display = \"block\";\n            document.body.appendChild(testElement);\n\n            range.selectNode(testElement);\n            rangeBounds = range.getBoundingClientRect();\n            rangeHeight = rangeBounds.height;\n\n            if (rangeHeight === 123) {\n                support = true;\n            }\n            document.body.removeChild(testElement);\n        }\n    }\n\n    return support;\n};\n\nSupport.prototype.testCORS = function() {\n    return typeof((new Image()).crossOrigin) !== \"undefined\";\n};\n\nSupport.prototype.testSVG = function() {\n    var img = new Image();\n    var canvas = document.createElement(\"canvas\");\n    var ctx =  canvas.getContext(\"2d\");\n    img.src = \"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>\";\n\n    try {\n        ctx.drawImage(img, 0, 0);\n        canvas.toDataURL();\n    } catch(e) {\n        return false;\n    }\n    return true;\n};\n\nmodule.exports = Support;\n\n},{}],26:[function(require,module,exports){\nvar Promise = require('./promise');\nvar XHR = require('./xhr');\nvar decode64 = require('./utils').decode64;\n\nfunction SVGContainer(src) {\n    this.src = src;\n    this.image = null;\n    var self = this;\n\n    this.promise = this.hasFabric().then(function() {\n        return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));\n    }).then(function(svg) {\n        return new Promise(function(resolve) {\n            window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));\n        });\n    });\n}\n\nSVGContainer.prototype.hasFabric = function() {\n    return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error(\"html2canvas.svg.js is not loaded, cannot render svg\")) : Promise.resolve();\n};\n\nSVGContainer.prototype.inlineFormatting = function(src) {\n    return (/^data:image\\/svg\\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);\n};\n\nSVGContainer.prototype.removeContentType = function(src) {\n    return src.replace(/^data:image\\/svg\\+xml(;base64)?,/,'');\n};\n\nSVGContainer.prototype.isInline = function(src) {\n    return (/^data:image\\/svg\\+xml/i.test(src));\n};\n\nSVGContainer.prototype.createCanvas = function(resolve) {\n    var self = this;\n    return function (objects, options) {\n        var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');\n        self.image = canvas.lowerCanvasEl;\n        canvas\n            .setWidth(options.width)\n            .setHeight(options.height)\n            .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))\n            .renderAll();\n        resolve(canvas.lowerCanvasEl);\n    };\n};\n\nSVGContainer.prototype.decode64 = function(str) {\n    return (typeof(window.atob) === \"function\") ? window.atob(str) : decode64(str);\n};\n\nmodule.exports = SVGContainer;\n\n},{\"./promise\":18,\"./utils\":29,\"./xhr\":31}],27:[function(require,module,exports){\nvar SVGContainer = require('./svgcontainer');\nvar Promise = require('./promise');\n\nfunction SVGNodeContainer(node, _native) {\n    this.src = node;\n    this.image = null;\n    var self = this;\n\n    this.promise = _native ? new Promise(function(resolve, reject) {\n        self.image = new Image();\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n        self.image.src = \"data:image/svg+xml,\" + (new XMLSerializer()).serializeToString(node);\n        if (self.image.complete === true) {\n            resolve(self.image);\n        }\n    }) : this.hasFabric().then(function() {\n        return new Promise(function(resolve) {\n            window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));\n        });\n    });\n}\n\nSVGNodeContainer.prototype = Object.create(SVGContainer.prototype);\n\nmodule.exports = SVGNodeContainer;\n\n},{\"./promise\":18,\"./svgcontainer\":26}],28:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction TextContainer(node, parent) {\n    NodeContainer.call(this, node, parent);\n}\n\nTextContainer.prototype = Object.create(NodeContainer.prototype);\n\nTextContainer.prototype.applyTextTransform = function() {\n    this.node.data = this.transform(this.parent.css(\"textTransform\"));\n};\n\nTextContainer.prototype.transform = function(transform) {\n    var text = this.node.data;\n    switch(transform){\n        case \"lowercase\":\n            return text.toLowerCase();\n        case \"capitalize\":\n            return text.replace(/(^|\\s|:|-|\\(|\\))([a-z])/g, capitalize);\n        case \"uppercase\":\n            return text.toUpperCase();\n        default:\n            return text;\n    }\n};\n\nfunction capitalize(m, p1, p2) {\n    if (m.length > 0) {\n        return p1 + p2.toUpperCase();\n    }\n}\n\nmodule.exports = TextContainer;\n\n},{\"./nodecontainer\":16}],29:[function(require,module,exports){\nexports.smallImage = function smallImage() {\n    return \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n};\n\nexports.bind = function(callback, context) {\n    return function() {\n        return callback.apply(context, arguments);\n    };\n};\n\n/*\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n\nexports.decode64 = function(base64) {\n    var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n    var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;\n\n    var output = \"\";\n\n    for (i = 0; i < len; i+=4) {\n        encoded1 = chars.indexOf(base64[i]);\n        encoded2 = chars.indexOf(base64[i+1]);\n        encoded3 = chars.indexOf(base64[i+2]);\n        encoded4 = chars.indexOf(base64[i+3]);\n\n        byte1 = (encoded1 << 2) | (encoded2 >> 4);\n        byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        byte3 = ((encoded3 & 3) << 6) | encoded4;\n        if (encoded3 === 64) {\n            output += String.fromCharCode(byte1);\n        } else if (encoded4 === 64 || encoded4 === -1) {\n            output += String.fromCharCode(byte1, byte2);\n        } else{\n            output += String.fromCharCode(byte1, byte2, byte3);\n        }\n    }\n\n    return output;\n};\n\nexports.getBounds = function(node) {\n    if (node.getBoundingClientRect) {\n        var clientRect = node.getBoundingClientRect();\n        var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;\n        return {\n            top: clientRect.top,\n            bottom: clientRect.bottom || (clientRect.top + clientRect.height),\n            right: clientRect.left + width,\n            left: clientRect.left,\n            width:  width,\n            height: node.offsetHeight == null ? clientRect.height : node.offsetHeight\n        };\n    }\n    return {};\n};\n\nexports.offsetBounds = function(node) {\n    var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};\n\n    return {\n        top: node.offsetTop + parent.top,\n        bottom: node.offsetTop + node.offsetHeight + parent.top,\n        right: node.offsetLeft + parent.left + node.offsetWidth,\n        left: node.offsetLeft + parent.left,\n        width: node.offsetWidth,\n        height: node.offsetHeight\n    };\n};\n\nexports.parseBackgrounds = function(backgroundImage) {\n    var whitespace = ' \\r\\n\\t',\n        method, definition, prefix, prefix_i, block, results = [],\n        mode = 0, numParen = 0, quote, args;\n    var appendResult = function() {\n        if(method) {\n            if (definition.substr(0, 1) === '\"') {\n                definition = definition.substr(1, definition.length - 2);\n            }\n            if (definition) {\n                args.push(definition);\n            }\n            if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {\n                prefix = method.substr(0, prefix_i);\n                method = method.substr(prefix_i);\n            }\n            results.push({\n                prefix: prefix,\n                method: method.toLowerCase(),\n                value: block,\n                args: args,\n                image: null\n            });\n        }\n        args = [];\n        method = prefix = definition = block = '';\n    };\n    args = [];\n    method = prefix = definition = block = '';\n    backgroundImage.split(\"\").forEach(function(c) {\n        if (mode === 0 && whitespace.indexOf(c) > -1) {\n            return;\n        }\n        switch(c) {\n        case '\"':\n            if(!quote) {\n                quote = c;\n            } else if(quote === c) {\n                quote = null;\n            }\n            break;\n        case '(':\n            if(quote) {\n                break;\n            } else if(mode === 0) {\n                mode = 1;\n                block += c;\n                return;\n            } else {\n                numParen++;\n            }\n            break;\n        case ')':\n            if (quote) {\n                break;\n            } else if(mode === 1) {\n                if(numParen === 0) {\n                    mode = 0;\n                    block += c;\n                    appendResult();\n                    return;\n                } else {\n                    numParen--;\n                }\n            }\n            break;\n\n        case ',':\n            if (quote) {\n                break;\n            } else if(mode === 0) {\n                appendResult();\n                return;\n            } else if (mode === 1) {\n                if (numParen === 0 && !method.match(/^url$/i)) {\n                    args.push(definition);\n                    definition = '';\n                    block += c;\n                    return;\n                }\n            }\n            break;\n        }\n\n        block += c;\n        if (mode === 0) {\n            method += c;\n        } else {\n            definition += c;\n        }\n    });\n\n    appendResult();\n    return results;\n};\n\nexports.getDeviceRatio = function() {\n    return window.devicePixelRatio;\n};\n\nexports.applyRatio = function(value) {\n    return value * exports.getDeviceRatio();\n}\n\nexports.applyRatioToBounds = function(bounds) {\n    bounds.width = bounds.width * exports.getDeviceRatio();\n    bounds.top = bounds.top * exports.getDeviceRatio();\n\n    //In case this is a size\n    try {\n        bounds.left = bounds.left * exports.getDeviceRatio();\n        bounds.height = bounds.height * exports.getDeviceRatio();\n    } catch (e) {\n\n    }\n\n    return bounds;\n}\n\nexports.applyRatioToPosition = function(position) {\n    position.left = position.left * exports.getDeviceRatio();\n    position.height = position.height * exports.getDeviceRatio();\n\n    return bounds;\n}\n\nexports.applyRatioToShape = function(shape) {\n    for (var i = 0; i < shape.length; i++) {\n        if (shape[i] instanceof Array) {\n            for (var k = 1; k < shape[i].length; k++) {\n                shape[i][k] = this.applyRatio(shape[i][k]);\n            }\n        }\n    }\n    return shape;\n}\n\nexports.applyRatioToFontSize = function(fontSize) {\n    var numericPart = parseFloat(fontSize) * exports.getDeviceRatio();\n    var stringPart = fontSize.replace(/[0-9]/g, '');\n\n    fontSize = numericPart + stringPart;\n\n    return fontSize;\n}\n\n\n\n},{}],30:[function(require,module,exports){\nvar GradientContainer = require('./gradientcontainer');\n\nfunction WebkitGradientContainer(imageData) {\n    GradientContainer.apply(this, arguments);\n    this.type = (imageData.args[0] === \"linear\") ? this.TYPES.LINEAR : this.TYPES.RADIAL;\n}\n\nWebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\nmodule.exports = WebkitGradientContainer;\n\n},{\"./gradientcontainer\":11}],31:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction XHR(url) {\n    return new Promise(function(resolve, reject) {\n        var xhr = new XMLHttpRequest();\n        xhr.open('GET', url);\n\n        xhr.onload = function() {\n            if (xhr.status === 200) {\n                resolve(xhr.responseText);\n            } else {\n                reject(new Error(xhr.statusText));\n            }\n        };\n\n        xhr.onerror = function() {\n            reject(new Error(\"Network Error\"));\n        };\n\n        xhr.send();\n    });\n}\n\nmodule.exports = XHR;\n\n},{\"./promise\":18}]},{},[6])(6)\n});"
  },
  {
    "path": "demo/js/vendor/velocity.js",
    "content": "/*! VelocityJS.org (1.2.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */\n\n/*************************\n   Velocity jQuery Shim\n*************************/\n\n/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */\n\n/* This file contains the jQuery functions that Velocity relies on, thereby removing Velocity's dependency on a full copy of jQuery, and allowing it to work in any environment. */\n/* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */\n/* Browser support: Using this shim instead of jQuery proper removes support for IE8. */\n\n;(function (window) {\n    /***************\n         Setup\n    ***************/\n\n    /* If jQuery is already loaded, there's no point in loading this shim. */\n    if (window.jQuery) {\n        return;\n    }\n\n    /* jQuery base. */\n    var $ = function (selector, context) {\n        return new $.fn.init(selector, context);\n    };\n\n    /********************\n       Private Methods\n    ********************/\n\n    /* jQuery */\n    $.isWindow = function (obj) {\n        /* jshint eqeqeq: false */\n        return obj != null && obj == obj.window;\n    };\n\n    /* jQuery */\n    $.type = function (obj) {\n        if (obj == null) {\n            return obj + \"\";\n        }\n\n        return typeof obj === \"object\" || typeof obj === \"function\" ?\n            class2type[toString.call(obj)] || \"object\" :\n            typeof obj;\n    };\n\n    /* jQuery */\n    $.isArray = Array.isArray || function (obj) {\n        return $.type(obj) === \"array\";\n    };\n\n    /* jQuery */\n    function isArraylike (obj) {\n        var length = obj.length,\n            type = $.type(obj);\n\n        if (type === \"function\" || $.isWindow(obj)) {\n            return false;\n        }\n\n        if (obj.nodeType === 1 && length) {\n            return true;\n        }\n\n        return type === \"array\" || length === 0 || typeof length === \"number\" && length > 0 && (length - 1) in obj;\n    }\n\n    /***************\n       $ Methods\n    ***************/\n\n    /* jQuery: Support removed for IE<9. */\n    $.isPlainObject = function (obj) {\n        var key;\n\n        if (!obj || $.type(obj) !== \"object\" || obj.nodeType || $.isWindow(obj)) {\n            return false;\n        }\n\n        try {\n            if (obj.constructor &&\n                !hasOwn.call(obj, \"constructor\") &&\n                !hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\")) {\n                return false;\n            }\n        } catch (e) {\n            return false;\n        }\n\n        for (key in obj) {}\n\n        return key === undefined || hasOwn.call(obj, key);\n    };\n\n    /* jQuery */\n    $.each = function(obj, callback, args) {\n        var value,\n            i = 0,\n            length = obj.length,\n            isArray = isArraylike(obj);\n\n        if (args) {\n            if (isArray) {\n                for (; i < length; i++) {\n                    value = callback.apply(obj[i], args);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            } else {\n                for (i in obj) {\n                    value = callback.apply(obj[i], args);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            }\n\n        } else {\n            if (isArray) {\n                for (; i < length; i++) {\n                    value = callback.call(obj[i], i, obj[i]);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            } else {\n                for (i in obj) {\n                    value = callback.call(obj[i], i, obj[i]);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            }\n        }\n\n        return obj;\n    };\n\n    /* Custom */\n    $.data = function (node, key, value) {\n        /* $.getData() */\n        if (value === undefined) {\n            var id = node[$.expando],\n                store = id && cache[id];\n\n            if (key === undefined) {\n                return store;\n            } else if (store) {\n                if (key in store) {\n                    return store[key];\n                }\n            }\n        /* $.setData() */\n        } else if (key !== undefined) {\n            var id = node[$.expando] || (node[$.expando] = ++$.uuid);\n\n            cache[id] = cache[id] || {};\n            cache[id][key] = value;\n\n            return value;\n        }\n    };\n\n    /* Custom */\n    $.removeData = function (node, keys) {\n        var id = node[$.expando],\n            store = id && cache[id];\n\n        if (store) {\n            $.each(keys, function(_, key) {\n                delete store[key];\n            });\n        }\n    };\n\n    /* jQuery */\n    $.extend = function () {\n        var src, copyIsArray, copy, name, options, clone,\n            target = arguments[0] || {},\n            i = 1,\n            length = arguments.length,\n            deep = false;\n\n        if (typeof target === \"boolean\") {\n            deep = target;\n\n            target = arguments[i] || {};\n            i++;\n        }\n\n        if (typeof target !== \"object\" && $.type(target) !== \"function\") {\n            target = {};\n        }\n\n        if (i === length) {\n            target = this;\n            i--;\n        }\n\n        for (; i < length; i++) {\n            if ((options = arguments[i]) != null) {\n                for (name in options) {\n                    src = target[name];\n                    copy = options[name];\n\n                    if (target === copy) {\n                        continue;\n                    }\n\n                    if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {\n                        if (copyIsArray) {\n                            copyIsArray = false;\n                            clone = src && $.isArray(src) ? src : [];\n\n                        } else {\n                            clone = src && $.isPlainObject(src) ? src : {};\n                        }\n\n                        target[name] = $.extend(deep, clone, copy);\n\n                    } else if (copy !== undefined) {\n                        target[name] = copy;\n                    }\n                }\n            }\n        }\n\n        return target;\n    };\n\n    /* jQuery 1.4.3 */\n    $.queue = function (elem, type, data) {\n        function $makeArray (arr, results) {\n            var ret = results || [];\n\n            if (arr != null) {\n                if (isArraylike(Object(arr))) {\n                    /* $.merge */\n                    (function(first, second) {\n                        var len = +second.length,\n                            j = 0,\n                            i = first.length;\n\n                        while (j < len) {\n                            first[i++] = second[j++];\n                        }\n\n                        if (len !== len) {\n                            while (second[j] !== undefined) {\n                                first[i++] = second[j++];\n                            }\n                        }\n\n                        first.length = i;\n\n                        return first;\n                    })(ret, typeof arr === \"string\" ? [arr] : arr);\n                } else {\n                    [].push.call(ret, arr);\n                }\n            }\n\n            return ret;\n        }\n\n        if (!elem) {\n            return;\n        }\n\n        type = (type || \"fx\") + \"queue\";\n\n        var q = $.data(elem, type);\n\n        if (!data) {\n            return q || [];\n        }\n\n        if (!q || $.isArray(data)) {\n            q = $.data(elem, type, $makeArray(data));\n        } else {\n            q.push(data);\n        }\n\n        return q;\n    };\n\n    /* jQuery 1.4.3 */\n    $.dequeue = function (elems, type) {\n        /* Custom: Embed element iteration. */\n        $.each(elems.nodeType ? [ elems ] : elems, function(i, elem) {\n            type = type || \"fx\";\n\n            var queue = $.queue(elem, type),\n                fn = queue.shift();\n\n            if (fn === \"inprogress\") {\n                fn = queue.shift();\n            }\n\n            if (fn) {\n                if (type === \"fx\") {\n                    queue.unshift(\"inprogress\");\n                }\n\n                fn.call(elem, function() {\n                    $.dequeue(elem, type);\n                });\n            }\n        });\n    };\n\n    /******************\n       $.fn Methods\n    ******************/\n\n    /* jQuery */\n    $.fn = $.prototype = {\n        init: function (selector) {\n            /* Just return the element wrapped inside an array; don't proceed with the actual jQuery node wrapping process. */\n            if (selector.nodeType) {\n                this[0] = selector;\n\n                return this;\n            } else {\n                throw new Error(\"Not a DOM node.\");\n            }\n        },\n\n        offset: function () {\n            /* jQuery altered code: Dropped disconnected DOM node checking. */\n            var box = this[0].getBoundingClientRect ? this[0].getBoundingClientRect() : { top: 0, left: 0 };\n\n            return {\n                top: box.top + (window.pageYOffset || document.scrollTop  || 0)  - (document.clientTop  || 0),\n                left: box.left + (window.pageXOffset || document.scrollLeft  || 0) - (document.clientLeft || 0)\n            };\n        },\n\n        position: function () {\n            /* jQuery */\n            function offsetParent() {\n                var offsetParent = this.offsetParent || document;\n\n                while (offsetParent && (!offsetParent.nodeType.toLowerCase === \"html\" && offsetParent.style.position === \"static\")) {\n                    offsetParent = offsetParent.offsetParent;\n                }\n\n                return offsetParent || document;\n            }\n\n            /* Zepto */\n            var elem = this[0],\n                offsetParent = offsetParent.apply(elem),\n                offset = this.offset(),\n                parentOffset = /^(?:body|html)$/i.test(offsetParent.nodeName) ? { top: 0, left: 0 } : $(offsetParent).offset()\n\n            offset.top -= parseFloat(elem.style.marginTop) || 0;\n            offset.left -= parseFloat(elem.style.marginLeft) || 0;\n\n            if (offsetParent.style) {\n                parentOffset.top += parseFloat(offsetParent.style.borderTopWidth) || 0\n                parentOffset.left += parseFloat(offsetParent.style.borderLeftWidth) || 0\n            }\n\n            return {\n                top: offset.top - parentOffset.top,\n                left: offset.left - parentOffset.left\n            };\n        }\n    };\n\n    /**********************\n       Private Variables\n    **********************/\n\n    /* For $.data() */\n    var cache = {};\n    $.expando = \"velocity\" + (new Date().getTime());\n    $.uuid = 0;\n\n    /* For $.queue() */\n    var class2type = {},\n        hasOwn = class2type.hasOwnProperty,\n        toString = class2type.toString;\n\n    var types = \"Boolean Number String Function Array Date RegExp Object Error\".split(\" \");\n    for (var i = 0; i < types.length; i++) {\n        class2type[\"[object \" + types[i] + \"]\"] = types[i].toLowerCase();\n    }\n\n    /* Makes $(node) possible, without having to call init. */\n    $.fn.init.prototype = $.fn;\n\n    /* Globalize Velocity onto the window, and assign its Utilities property. */\n    window.Velocity = { Utilities: $ };\n})(window);\n\n/******************\n    Velocity.js\n******************/\n\n;(function (factory) {\n    /* CommonJS module. */\n    if (typeof module === \"object\" && typeof module.exports === \"object\") {\n        module.exports = factory();\n    /* AMD module. */\n    } else if (typeof define === \"function\" && define.amd) {\n        define(factory);\n    /* Browser globals. */\n    } else {\n        factory();\n    }\n}(function() {\nreturn function (global, window, document, undefined) {\n\n    /***************\n        Summary\n    ***************/\n\n    /*\n    - CSS: CSS stack that works independently from the rest of Velocity.\n    - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually.\n      - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options.\n      - Queueing: The logic that runs once the call has reached its point of execution in the element's $.queue() stack.\n                  Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed).\n      - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.\n    - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls.\n    - completeCall(): Handles the cleanup process for each Velocity call.\n    */\n\n    /*********************\n       Helper Functions\n    *********************/\n\n    /* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */\n    var IE = (function() {\n        if (document.documentMode) {\n            return document.documentMode;\n        } else {\n            for (var i = 7; i > 4; i--) {\n                var div = document.createElement(\"div\");\n\n                div.innerHTML = \"<!--[if IE \" + i + \"]><span></span><![endif]-->\";\n\n                if (div.getElementsByTagName(\"span\").length) {\n                    div = null;\n\n                    return i;\n                }\n            }\n        }\n\n        return undefined;\n    })();\n\n    /* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */\n    var rAFShim = (function() {\n        var timeLast = 0;\n\n        return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {\n            var timeCurrent = (new Date()).getTime(),\n                timeDelta;\n\n            /* Dynamically set delay on a per-tick basis to match 60fps. */\n            /* Technique by Erik Moller. MIT license: https://gist.github.com/paulirish/1579671 */\n            timeDelta = Math.max(0, 16 - (timeCurrent - timeLast));\n            timeLast = timeCurrent + timeDelta;\n\n            return setTimeout(function() { callback(timeCurrent + timeDelta); }, timeDelta);\n        };\n    })();\n\n    /* Array compacting. Copyright Lo-Dash. MIT License: https://github.com/lodash/lodash/blob/master/LICENSE.txt */\n    function compactSparseArray (array) {\n        var index = -1,\n            length = array ? array.length : 0,\n            result = [];\n\n        while (++index < length) {\n            var value = array[index];\n\n            if (value) {\n                result.push(value);\n            }\n        }\n\n        return result;\n    }\n\n    function sanitizeElements (elements) {\n        /* Unwrap jQuery/Zepto objects. */\n        if (Type.isWrapped(elements)) {\n            elements = [].slice.call(elements);\n        /* Wrap a single element in an array so that $.each() can iterate with the element instead of its node's children. */\n        } else if (Type.isNode(elements)) {\n            elements = [ elements ];\n        }\n\n        return elements;\n    }\n\n    var Type = {\n        isString: function (variable) {\n            return (typeof variable === \"string\");\n        },\n        isArray: Array.isArray || function (variable) {\n            return Object.prototype.toString.call(variable) === \"[object Array]\";\n        },\n        isFunction: function (variable) {\n            return Object.prototype.toString.call(variable) === \"[object Function]\";\n        },\n        isNode: function (variable) {\n            return variable && variable.nodeType;\n        },\n        /* Copyright Martin Bohm. MIT License: https://gist.github.com/Tomalak/818a78a226a0738eaade */\n        isNodeList: function (variable) {\n            return typeof variable === \"object\" &&\n                /^\\[object (HTMLCollection|NodeList|Object)\\]$/.test(Object.prototype.toString.call(variable)) &&\n                variable.length !== undefined &&\n                (variable.length === 0 || (typeof variable[0] === \"object\" && variable[0].nodeType > 0));\n        },\n        /* Determine if variable is a wrapped jQuery or Zepto element. */\n        isWrapped: function (variable) {\n            return variable && (variable.jquery || (window.Zepto && window.Zepto.zepto.isZ(variable)));\n        },\n        isSVG: function (variable) {\n            return window.SVGElement && (variable instanceof window.SVGElement);\n        },\n        isEmptyObject: function (variable) {\n            for (var name in variable) {\n                return false;\n            }\n\n            return true;\n        }\n    };\n\n    /*****************\n       Dependencies\n    *****************/\n\n    var $,\n        isJQuery = false;\n\n    if (global.fn && global.fn.jquery) {\n        $ = global;\n        isJQuery = true;\n    } else {\n        $ = window.Velocity.Utilities;\n    }\n\n    if (IE <= 8 && !isJQuery) {\n        throw new Error(\"Velocity: IE8 and below require jQuery to be loaded before Velocity.\");\n    } else if (IE <= 7) {\n        /* Revert to jQuery's $.animate(), and lose Velocity's extra features. */\n        jQuery.fn.velocity = jQuery.fn.animate;\n\n        /* Now that $.fn.velocity is aliased, abort this Velocity declaration. */\n        return;\n    }\n\n    /*****************\n        Constants\n    *****************/\n\n    var DURATION_DEFAULT = 400,\n        EASING_DEFAULT = \"swing\";\n\n    /*************\n        State\n    *************/\n\n    var Velocity = {\n        /* Container for page-wide Velocity state data. */\n        State: {\n            /* Detect mobile devices to determine if mobileHA should be turned on. */\n            isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),\n            /* The mobileHA option's behavior changes on older Android devices (Gingerbread, versions 2.3.3-2.3.7). */\n            isAndroid: /Android/i.test(navigator.userAgent),\n            isGingerbread: /Android 2\\.3\\.[3-7]/i.test(navigator.userAgent),\n            isChrome: window.chrome,\n            isFirefox: /Firefox/i.test(navigator.userAgent),\n            /* Create a cached element for re-use when checking for CSS property prefixes. */\n            prefixElement: document.createElement(\"div\"),\n            /* Cache every prefix match to avoid repeating lookups. */\n            prefixMatches: {},\n            /* Cache the anchor used for animating window scrolling. */\n            scrollAnchor: null,\n            /* Cache the browser-specific property names associated with the scroll anchor. */\n            scrollPropertyLeft: null,\n            scrollPropertyTop: null,\n            /* Keep track of whether our RAF tick is running. */\n            isTicking: false,\n            /* Container for every in-progress call to Velocity. */\n            calls: []\n        },\n        /* Velocity's custom CSS stack. Made global for unit testing. */\n        CSS: { /* Defined below. */ },\n        /* A shim of the jQuery utility functions used by Velocity -- provided by Velocity's optional jQuery shim. */\n        Utilities: $,\n        /* Container for the user's custom animation redirects that are referenced by name in place of the properties map argument. */\n        Redirects: { /* Manually registered by the user. */ },\n        Easings: { /* Defined below. */ },\n        /* Attempt to use ES6 Promises by default. Users can override this with a third-party promises library. */\n        Promise: window.Promise,\n        /* Velocity option defaults, which can be overriden by the user. */\n        defaults: {\n            queue: \"\",\n            duration: DURATION_DEFAULT,\n            easing: EASING_DEFAULT,\n            begin: undefined,\n            complete: undefined,\n            progress: undefined,\n            display: undefined,\n            visibility: undefined,\n            loop: false,\n            delay: false,\n            mobileHA: true,\n            /* Advanced: Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */\n            _cacheValues: true\n        },\n        /* A design goal of Velocity is to cache data wherever possible in order to avoid DOM requerying. Accordingly, each element has a data cache. */\n        init: function (element) {\n            $.data(element, \"velocity\", {\n                /* Store whether this is an SVG element, since its properties are retrieved and updated differently than standard HTML elements. */\n                isSVG: Type.isSVG(element),\n                /* Keep track of whether the element is currently being animated by Velocity.\n                   This is used to ensure that property values are not transferred between non-consecutive (stale) calls. */\n                isAnimating: false,\n                /* A reference to the element's live computedStyle object. Learn more here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */\n                computedStyle: null,\n                /* Tween data is cached for each animation on the element so that data can be passed across calls --\n                   in particular, end values are used as subsequent start values in consecutive Velocity calls. */\n                tweensContainer: null,\n                /* The full root property values of each CSS hook being animated on this element are cached so that:\n                   1) Concurrently-animating hooks sharing the same root can have their root values' merged into one while tweening.\n                   2) Post-hook-injection root values can be transferred over to consecutively chained Velocity calls as starting root values. */\n                rootPropertyValueCache: {},\n                /* A cache for transform updates, which must be manually flushed via CSS.flushTransformCache(). */\n                transformCache: {}\n            });\n        },\n        /* A parallel to jQuery's $.css(), used for getting/setting Velocity's hooked CSS properties. */\n        hook: null, /* Defined below. */\n        /* Velocity-wide animation time remapping for testing purposes. */\n        mock: false,\n        version: { major: 1, minor: 2, patch: 2 },\n        /* Set to 1 or 2 (most verbose) to output debug info to console. */\n        debug: false\n    };\n\n    /* Retrieve the appropriate scroll anchor and property name for the browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY */\n    if (window.pageYOffset !== undefined) {\n        Velocity.State.scrollAnchor = window;\n        Velocity.State.scrollPropertyLeft = \"pageXOffset\";\n        Velocity.State.scrollPropertyTop = \"pageYOffset\";\n    } else {\n        Velocity.State.scrollAnchor = document.documentElement || document.body.parentNode || document.body;\n        Velocity.State.scrollPropertyLeft = \"scrollLeft\";\n        Velocity.State.scrollPropertyTop = \"scrollTop\";\n    }\n\n    /* Shorthand alias for jQuery's $.data() utility. */\n    function Data (element) {\n        /* Hardcode a reference to the plugin name. */\n        var response = $.data(element, \"velocity\");\n\n        /* jQuery <=1.4.2 returns null instead of undefined when no match is found. We normalize this behavior. */\n        return response === null ? undefined : response;\n    };\n\n    /**************\n        Easing\n    **************/\n\n    /* Step easing generator. */\n    function generateStep (steps) {\n        return function (p) {\n            return Math.round(p * steps) * (1 / steps);\n        };\n    }\n\n    /* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n    function generateBezier (mX1, mY1, mX2, mY2) {\n        var NEWTON_ITERATIONS = 4,\n            NEWTON_MIN_SLOPE = 0.001,\n            SUBDIVISION_PRECISION = 0.0000001,\n            SUBDIVISION_MAX_ITERATIONS = 10,\n            kSplineTableSize = 11,\n            kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),\n            float32ArraySupported = \"Float32Array\" in window;\n\n        /* Must contain four arguments. */\n        if (arguments.length !== 4) {\n            return false;\n        }\n\n        /* Arguments must be numbers. */\n        for (var i = 0; i < 4; ++i) {\n            if (typeof arguments[i] !== \"number\" || isNaN(arguments[i]) || !isFinite(arguments[i])) {\n                return false;\n            }\n        }\n\n        /* X values must be in the [0, 1] range. */\n        mX1 = Math.min(mX1, 1);\n        mX2 = Math.min(mX2, 1);\n        mX1 = Math.max(mX1, 0);\n        mX2 = Math.max(mX2, 0);\n\n        var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);\n\n        function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }\n        function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }\n        function C (aA1)      { return 3.0 * aA1; }\n\n        function calcBezier (aT, aA1, aA2) {\n            return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;\n        }\n\n        function getSlope (aT, aA1, aA2) {\n            return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);\n        }\n\n        function newtonRaphsonIterate (aX, aGuessT) {\n            for (var i = 0; i < NEWTON_ITERATIONS; ++i) {\n                var currentSlope = getSlope(aGuessT, mX1, mX2);\n\n                if (currentSlope === 0.0) return aGuessT;\n\n                var currentX = calcBezier(aGuessT, mX1, mX2) - aX;\n                aGuessT -= currentX / currentSlope;\n            }\n\n            return aGuessT;\n        }\n\n        function calcSampleValues () {\n            for (var i = 0; i < kSplineTableSize; ++i) {\n                mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);\n            }\n        }\n\n        function binarySubdivide (aX, aA, aB) {\n            var currentX, currentT, i = 0;\n\n            do {\n                currentT = aA + (aB - aA) / 2.0;\n                currentX = calcBezier(currentT, mX1, mX2) - aX;\n                if (currentX > 0.0) {\n                  aB = currentT;\n                } else {\n                  aA = currentT;\n                }\n            } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);\n\n            return currentT;\n        }\n\n        function getTForX (aX) {\n            var intervalStart = 0.0,\n                currentSample = 1,\n                lastSample = kSplineTableSize - 1;\n\n            for (; currentSample != lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {\n                intervalStart += kSampleStepSize;\n            }\n\n            --currentSample;\n\n            var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]),\n                guessForT = intervalStart + dist * kSampleStepSize,\n                initialSlope = getSlope(guessForT, mX1, mX2);\n\n            if (initialSlope >= NEWTON_MIN_SLOPE) {\n                return newtonRaphsonIterate(aX, guessForT);\n            } else if (initialSlope == 0.0) {\n                return guessForT;\n            } else {\n                return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);\n            }\n        }\n\n        var _precomputed = false;\n\n        function precompute() {\n            _precomputed = true;\n            if (mX1 != mY1 || mX2 != mY2) calcSampleValues();\n        }\n\n        var f = function (aX) {\n            if (!_precomputed) precompute();\n            if (mX1 === mY1 && mX2 === mY2) return aX;\n            if (aX === 0) return 0;\n            if (aX === 1) return 1;\n\n            return calcBezier(getTForX(aX), mY1, mY2);\n        };\n\n        f.getControlPoints = function() { return [{ x: mX1, y: mY1 }, { x: mX2, y: mY2 }]; };\n\n        var str = \"generateBezier(\" + [mX1, mY1, mX2, mY2] + \")\";\n        f.toString = function () { return str; };\n\n        return f;\n    }\n\n    /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n    /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass\n       then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */\n    var generateSpringRK4 = (function () {\n        function springAccelerationForState (state) {\n            return (-state.tension * state.x) - (state.friction * state.v);\n        }\n\n        function springEvaluateStateWithDerivative (initialState, dt, derivative) {\n            var state = {\n                x: initialState.x + derivative.dx * dt,\n                v: initialState.v + derivative.dv * dt,\n                tension: initialState.tension,\n                friction: initialState.friction\n            };\n\n            return { dx: state.v, dv: springAccelerationForState(state) };\n        }\n\n        function springIntegrateState (state, dt) {\n            var a = {\n                    dx: state.v,\n                    dv: springAccelerationForState(state)\n                },\n                b = springEvaluateStateWithDerivative(state, dt * 0.5, a),\n                c = springEvaluateStateWithDerivative(state, dt * 0.5, b),\n                d = springEvaluateStateWithDerivative(state, dt, c),\n                dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),\n                dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);\n\n            state.x = state.x + dxdt * dt;\n            state.v = state.v + dvdt * dt;\n\n            return state;\n        }\n\n        return function springRK4Factory (tension, friction, duration) {\n\n            var initState = {\n                    x: -1,\n                    v: 0,\n                    tension: null,\n                    friction: null\n                },\n                path = [0],\n                time_lapsed = 0,\n                tolerance = 1 / 10000,\n                DT = 16 / 1000,\n                have_duration, dt, last_state;\n\n            tension = parseFloat(tension) || 500;\n            friction = parseFloat(friction) || 20;\n            duration = duration || null;\n\n            initState.tension = tension;\n            initState.friction = friction;\n\n            have_duration = duration !== null;\n\n            /* Calculate the actual time it takes for this animation to complete with the provided conditions. */\n            if (have_duration) {\n                /* Run the simulation without a duration. */\n                time_lapsed = springRK4Factory(tension, friction);\n                /* Compute the adjusted time delta. */\n                dt = time_lapsed / duration * DT;\n            } else {\n                dt = DT;\n            }\n\n            while (true) {\n                /* Next/step function .*/\n                last_state = springIntegrateState(last_state || initState, dt);\n                /* Store the position. */\n                path.push(1 + last_state.x);\n                time_lapsed += 16;\n                /* If the change threshold is reached, break. */\n                if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {\n                    break;\n                }\n            }\n\n            /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the\n               computed path and returns a snapshot of the position according to a given percentComplete. */\n            return !have_duration ? time_lapsed : function(percentComplete) { return path[ (percentComplete * (path.length - 1)) | 0 ]; };\n        };\n    }());\n\n    /* jQuery easings. */\n    Velocity.Easings = {\n        linear: function(p) { return p; },\n        swing: function(p) { return 0.5 - Math.cos( p * Math.PI ) / 2 },\n        /* Bonus \"spring\" easing, which is a less exaggerated version of easeInOutElastic. */\n        spring: function(p) { return 1 - (Math.cos(p * 4.5 * Math.PI) * Math.exp(-p * 6)); }\n    };\n\n    /* CSS3 and Robert Penner easings. */\n    $.each(\n        [\n            [ \"ease\", [ 0.25, 0.1, 0.25, 1.0 ] ],\n            [ \"ease-in\", [ 0.42, 0.0, 1.00, 1.0 ] ],\n            [ \"ease-out\", [ 0.00, 0.0, 0.58, 1.0 ] ],\n            [ \"ease-in-out\", [ 0.42, 0.0, 0.58, 1.0 ] ],\n            [ \"easeInSine\", [ 0.47, 0, 0.745, 0.715 ] ],\n            [ \"easeOutSine\", [ 0.39, 0.575, 0.565, 1 ] ],\n            [ \"easeInOutSine\", [ 0.445, 0.05, 0.55, 0.95 ] ],\n            [ \"easeInQuad\", [ 0.55, 0.085, 0.68, 0.53 ] ],\n            [ \"easeOutQuad\", [ 0.25, 0.46, 0.45, 0.94 ] ],\n            [ \"easeInOutQuad\", [ 0.455, 0.03, 0.515, 0.955 ] ],\n            [ \"easeInCubic\", [ 0.55, 0.055, 0.675, 0.19 ] ],\n            [ \"easeOutCubic\", [ 0.215, 0.61, 0.355, 1 ] ],\n            [ \"easeInOutCubic\", [ 0.645, 0.045, 0.355, 1 ] ],\n            [ \"easeInQuart\", [ 0.895, 0.03, 0.685, 0.22 ] ],\n            [ \"easeOutQuart\", [ 0.165, 0.84, 0.44, 1 ] ],\n            [ \"easeInOutQuart\", [ 0.77, 0, 0.175, 1 ] ],\n            [ \"easeInQuint\", [ 0.755, 0.05, 0.855, 0.06 ] ],\n            [ \"easeOutQuint\", [ 0.23, 1, 0.32, 1 ] ],\n            [ \"easeInOutQuint\", [ 0.86, 0, 0.07, 1 ] ],\n            [ \"easeInExpo\", [ 0.95, 0.05, 0.795, 0.035 ] ],\n            [ \"easeOutExpo\", [ 0.19, 1, 0.22, 1 ] ],\n            [ \"easeInOutExpo\", [ 1, 0, 0, 1 ] ],\n            [ \"easeInCirc\", [ 0.6, 0.04, 0.98, 0.335 ] ],\n            [ \"easeOutCirc\", [ 0.075, 0.82, 0.165, 1 ] ],\n            [ \"easeInOutCirc\", [ 0.785, 0.135, 0.15, 0.86 ] ]\n        ], function(i, easingArray) {\n            Velocity.Easings[easingArray[0]] = generateBezier.apply(null, easingArray[1]);\n        });\n\n    /* Determine the appropriate easing type given an easing input. */\n    function getEasing(value, duration) {\n        var easing = value;\n\n        /* The easing option can either be a string that references a pre-registered easing,\n           or it can be a two-/four-item array of integers to be converted into a bezier/spring function. */\n        if (Type.isString(value)) {\n            /* Ensure that the easing has been assigned to jQuery's Velocity.Easings object. */\n            if (!Velocity.Easings[value]) {\n                easing = false;\n            }\n        } else if (Type.isArray(value) && value.length === 1) {\n            easing = generateStep.apply(null, value);\n        } else if (Type.isArray(value) && value.length === 2) {\n            /* springRK4 must be passed the animation's duration. */\n            /* Note: If the springRK4 array contains non-numbers, generateSpringRK4() returns an easing\n               function generated with default tension and friction values. */\n            easing = generateSpringRK4.apply(null, value.concat([ duration ]));\n        } else if (Type.isArray(value) && value.length === 4) {\n            /* Note: If the bezier array contains non-numbers, generateBezier() returns false. */\n            easing = generateBezier.apply(null, value);\n        } else {\n            easing = false;\n        }\n\n        /* Revert to the Velocity-wide default easing type, or fall back to \"swing\" (which is also jQuery's default)\n           if the Velocity-wide default has been incorrectly modified. */\n        if (easing === false) {\n            if (Velocity.Easings[Velocity.defaults.easing]) {\n                easing = Velocity.defaults.easing;\n            } else {\n                easing = EASING_DEFAULT;\n            }\n        }\n\n        return easing;\n    }\n\n    /*****************\n        CSS Stack\n    *****************/\n\n    /* The CSS object is a highly condensed and performant CSS stack that fully replaces jQuery's.\n       It handles the validation, getting, and setting of both standard CSS properties and CSS property hooks. */\n    /* Note: A \"CSS\" shorthand is aliased so that our code is easier to read. */\n    var CSS = Velocity.CSS = {\n\n        /*************\n            RegEx\n        *************/\n\n        RegEx: {\n            isHex: /^#([A-f\\d]{3}){1,2}$/i,\n            /* Unwrap a property value's surrounding text, e.g. \"rgba(4, 3, 2, 1)\" ==> \"4, 3, 2, 1\" and \"rect(4px 3px 2px 1px)\" ==> \"4px 3px 2px 1px\". */\n            valueUnwrap: /^[A-z]+\\((.*)\\)$/i,\n            wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,\n            /* Split a multi-value property into an array of subvalues, e.g. \"rgba(4, 3, 2, 1) 4px 3px 2px 1px\" ==> [ \"rgba(4, 3, 2, 1)\", \"4px\", \"3px\", \"2px\", \"1px\" ]. */\n            valueSplit: /([A-z]+\\(.+\\))|(([A-z0-9#-.]+?)(?=\\s|$))/ig\n        },\n\n        /************\n            Lists\n        ************/\n\n        Lists: {\n            colors: [ \"fill\", \"stroke\", \"stopColor\", \"color\", \"backgroundColor\", \"borderColor\", \"borderTopColor\", \"borderRightColor\", \"borderBottomColor\", \"borderLeftColor\", \"outlineColor\" ],\n            transformsBase: [ \"translateX\", \"translateY\", \"scale\", \"scaleX\", \"scaleY\", \"skewX\", \"skewY\", \"rotateZ\" ],\n            transforms3D: [ \"transformPerspective\", \"translateZ\", \"scaleZ\", \"rotateX\", \"rotateY\" ]\n        },\n\n        /************\n            Hooks\n        ************/\n\n        /* Hooks allow a subproperty (e.g. \"boxShadowBlur\") of a compound-value CSS property\n           (e.g. \"boxShadow: X Y Blur Spread Color\") to be animated as if it were a discrete property. */\n        /* Note: Beyond enabling fine-grained property animation, hooking is necessary since Velocity only\n           tweens properties with single numeric values; unlike CSS transitions, Velocity does not interpolate compound-values. */\n        Hooks: {\n            /********************\n                Registration\n            ********************/\n\n            /* Templates are a concise way of indicating which subproperties must be individually registered for each compound-value CSS property. */\n            /* Each template consists of the compound-value's base name, its constituent subproperty names, and those subproperties' default values. */\n            templates: {\n                \"textShadow\": [ \"Color X Y Blur\", \"black 0px 0px 0px\" ],\n                \"boxShadow\": [ \"Color X Y Blur Spread\", \"black 0px 0px 0px 0px\" ],\n                \"clip\": [ \"Top Right Bottom Left\", \"0px 0px 0px 0px\" ],\n                \"backgroundPosition\": [ \"X Y\", \"0% 0%\" ],\n                \"transformOrigin\": [ \"X Y Z\", \"50% 50% 0px\" ],\n                \"perspectiveOrigin\": [ \"X Y\", \"50% 50%\" ]\n            },\n\n            /* A \"registered\" hook is one that has been converted from its template form into a live,\n               tweenable property. It contains data to associate it with its root property. */\n            registered: {\n                /* Note: A registered hook looks like this ==> textShadowBlur: [ \"textShadow\", 3 ],\n                   which consists of the subproperty's name, the associated root property's name,\n                   and the subproperty's position in the root's value. */\n            },\n            /* Convert the templates into individual hooks then append them to the registered object above. */\n            register: function () {\n                /* Color hooks registration: Colors are defaulted to white -- as opposed to black -- since colors that are\n                   currently set to \"transparent\" default to their respective template below when color-animated,\n                   and white is typically a closer match to transparent than black is. An exception is made for text (\"color\"),\n                   which is almost always set closer to black than white. */\n                for (var i = 0; i < CSS.Lists.colors.length; i++) {\n                    var rgbComponents = (CSS.Lists.colors[i] === \"color\") ? \"0 0 0 1\" : \"255 255 255 1\";\n                    CSS.Hooks.templates[CSS.Lists.colors[i]] = [ \"Red Green Blue Alpha\", rgbComponents ];\n                }\n\n                var rootProperty,\n                    hookTemplate,\n                    hookNames;\n\n                /* In IE, color values inside compound-value properties are positioned at the end the value instead of at the beginning.\n                   Thus, we re-arrange the templates accordingly. */\n                if (IE) {\n                    for (rootProperty in CSS.Hooks.templates) {\n                        hookTemplate = CSS.Hooks.templates[rootProperty];\n                        hookNames = hookTemplate[0].split(\" \");\n\n                        var defaultValues = hookTemplate[1].match(CSS.RegEx.valueSplit);\n\n                        if (hookNames[0] === \"Color\") {\n                            /* Reposition both the hook's name and its default value to the end of their respective strings. */\n                            hookNames.push(hookNames.shift());\n                            defaultValues.push(defaultValues.shift());\n\n                            /* Replace the existing template for the hook's root property. */\n                            CSS.Hooks.templates[rootProperty] = [ hookNames.join(\" \"), defaultValues.join(\" \") ];\n                        }\n                    }\n                }\n\n                /* Hook registration. */\n                for (rootProperty in CSS.Hooks.templates) {\n                    hookTemplate = CSS.Hooks.templates[rootProperty];\n                    hookNames = hookTemplate[0].split(\" \");\n\n                    for (var i in hookNames) {\n                        var fullHookName = rootProperty + hookNames[i],\n                            hookPosition = i;\n\n                        /* For each hook, register its full name (e.g. textShadowBlur) with its root property (e.g. textShadow)\n                           and the hook's position in its template's default value string. */\n                        CSS.Hooks.registered[fullHookName] = [ rootProperty, hookPosition ];\n                    }\n                }\n            },\n\n            /*****************************\n               Injection and Extraction\n            *****************************/\n\n            /* Look up the root property associated with the hook (e.g. return \"textShadow\" for \"textShadowBlur\"). */\n            /* Since a hook cannot be set directly (the browser won't recognize it), style updating for hooks is routed through the hook's root property. */\n            getRoot: function (property) {\n                var hookData = CSS.Hooks.registered[property];\n\n                if (hookData) {\n                    return hookData[0];\n                } else {\n                    /* If there was no hook match, return the property name untouched. */\n                    return property;\n                }\n            },\n            /* Convert any rootPropertyValue, null or otherwise, into a space-delimited list of hook values so that\n               the targeted hook can be injected or extracted at its standard position. */\n            cleanRootPropertyValue: function(rootProperty, rootPropertyValue) {\n                /* If the rootPropertyValue is wrapped with \"rgb()\", \"clip()\", etc., remove the wrapping to normalize the value before manipulation. */\n                if (CSS.RegEx.valueUnwrap.test(rootPropertyValue)) {\n                    rootPropertyValue = rootPropertyValue.match(CSS.RegEx.valueUnwrap)[1];\n                }\n\n                /* If rootPropertyValue is a CSS null-value (from which there's inherently no hook value to extract),\n                   default to the root's default value as defined in CSS.Hooks.templates. */\n                /* Note: CSS null-values include \"none\", \"auto\", and \"transparent\". They must be converted into their\n                   zero-values (e.g. textShadow: \"none\" ==> textShadow: \"0px 0px 0px black\") for hook manipulation to proceed. */\n                if (CSS.Values.isCSSNullValue(rootPropertyValue)) {\n                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];\n                }\n\n                return rootPropertyValue;\n            },\n            /* Extracted the hook's value from its root property's value. This is used to get the starting value of an animating hook. */\n            extractValue: function (fullHookName, rootPropertyValue) {\n                var hookData = CSS.Hooks.registered[fullHookName];\n\n                if (hookData) {\n                    var hookRoot = hookData[0],\n                        hookPosition = hookData[1];\n\n                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);\n\n                    /* Split rootPropertyValue into its constituent hook values then grab the desired hook at its standard position. */\n                    return rootPropertyValue.toString().match(CSS.RegEx.valueSplit)[hookPosition];\n                } else {\n                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */\n                    return rootPropertyValue;\n                }\n            },\n            /* Inject the hook's value into its root property's value. This is used to piece back together the root property\n               once Velocity has updated one of its individually hooked values through tweening. */\n            injectValue: function (fullHookName, hookValue, rootPropertyValue) {\n                var hookData = CSS.Hooks.registered[fullHookName];\n\n                if (hookData) {\n                    var hookRoot = hookData[0],\n                        hookPosition = hookData[1],\n                        rootPropertyValueParts,\n                        rootPropertyValueUpdated;\n\n                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);\n\n                    /* Split rootPropertyValue into its individual hook values, replace the targeted value with hookValue,\n                       then reconstruct the rootPropertyValue string. */\n                    rootPropertyValueParts = rootPropertyValue.toString().match(CSS.RegEx.valueSplit);\n                    rootPropertyValueParts[hookPosition] = hookValue;\n                    rootPropertyValueUpdated = rootPropertyValueParts.join(\" \");\n\n                    return rootPropertyValueUpdated;\n                } else {\n                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */\n                    return rootPropertyValue;\n                }\n            }\n        },\n\n        /*******************\n           Normalizations\n        *******************/\n\n        /* Normalizations standardize CSS property manipulation by pollyfilling browser-specific implementations (e.g. opacity)\n           and reformatting special properties (e.g. clip, rgba) to look like standard ones. */\n        Normalizations: {\n            /* Normalizations are passed a normalization target (either the property's name, its extracted value, or its injected value),\n               the targeted element (which may need to be queried), and the targeted property value. */\n            registered: {\n                clip: function (type, element, propertyValue) {\n                    switch (type) {\n                        case \"name\":\n                            return \"clip\";\n                        /* Clip needs to be unwrapped and stripped of its commas during extraction. */\n                        case \"extract\":\n                            var extracted;\n\n                            /* If Velocity also extracted this value, skip extraction. */\n                            if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {\n                                extracted = propertyValue;\n                            } else {\n                                /* Remove the \"rect()\" wrapper. */\n                                extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap);\n\n                                /* Strip off commas. */\n                                extracted = extracted ? extracted[1].replace(/,(\\s+)?/g, \" \") : propertyValue;\n                            }\n\n                            return extracted;\n                        /* Clip needs to be re-wrapped during injection. */\n                        case \"inject\":\n                            return \"rect(\" + propertyValue + \")\";\n                    }\n                },\n\n                blur: function(type, element, propertyValue) {\n                    switch (type) {\n                        case \"name\":\n                            return Velocity.State.isFirefox ? \"filter\" : \"-webkit-filter\";\n                        case \"extract\":\n                            var extracted = parseFloat(propertyValue);\n\n                            /* If extracted is NaN, meaning the value isn't already extracted. */\n                            if (!(extracted || extracted === 0)) {\n                                var blurComponent = propertyValue.toString().match(/blur\\(([0-9]+[A-z]+)\\)/i);\n\n                                /* If the filter string had a blur component, return just the blur value and unit type. */\n                                if (blurComponent) {\n                                    extracted = blurComponent[1];\n                                /* If the component doesn't exist, default blur to 0. */\n                                } else {\n                                    extracted = 0;\n                                }\n                            }\n\n                            return extracted;\n                        /* Blur needs to be re-wrapped during injection. */\n                        case \"inject\":\n                            /* For the blur effect to be fully de-applied, it needs to be set to \"none\" instead of 0. */\n                            if (!parseFloat(propertyValue)) {\n                                return \"none\";\n                            } else {\n                                return \"blur(\" + propertyValue + \")\";\n                            }\n                    }\n                },\n\n                /* <=IE8 do not support the standard opacity property. They use filter:alpha(opacity=INT) instead. */\n                opacity: function (type, element, propertyValue) {\n                    if (IE <= 8) {\n                        switch (type) {\n                            case \"name\":\n                                return \"filter\";\n                            case \"extract\":\n                                /* <=IE8 return a \"filter\" value of \"alpha(opacity=\\d{1,3})\".\n                                   Extract the value and convert it to a decimal value to match the standard CSS opacity property's formatting. */\n                                var extracted = propertyValue.toString().match(/alpha\\(opacity=(.*)\\)/i);\n\n                                if (extracted) {\n                                    /* Convert to decimal value. */\n                                    propertyValue = extracted[1] / 100;\n                                } else {\n                                    /* When extracting opacity, default to 1 since a null value means opacity hasn't been set. */\n                                    propertyValue = 1;\n                                }\n\n                                return propertyValue;\n                            case \"inject\":\n                                /* Opacified elements are required to have their zoom property set to a non-zero value. */\n                                element.style.zoom = 1;\n\n                                /* Setting the filter property on elements with certain font property combinations can result in a\n                                   highly unappealing ultra-bolding effect. There's no way to remedy this throughout a tween, but dropping the\n                                   value altogether (when opacity hits 1) at leasts ensures that the glitch is gone post-tweening. */\n                                if (parseFloat(propertyValue) >= 1) {\n                                    return \"\";\n                                } else {\n                                  /* As per the filter property's spec, convert the decimal value to a whole number and wrap the value. */\n                                  return \"alpha(opacity=\" + parseInt(parseFloat(propertyValue) * 100, 10) + \")\";\n                                }\n                        }\n                    /* With all other browsers, normalization is not required; return the same values that were passed in. */\n                    } else {\n                        switch (type) {\n                            case \"name\":\n                                return \"opacity\";\n                            case \"extract\":\n                                return propertyValue;\n                            case \"inject\":\n                                return propertyValue;\n                        }\n                    }\n                }\n            },\n\n            /*****************************\n                Batched Registrations\n            *****************************/\n\n            /* Note: Batched normalizations extend the CSS.Normalizations.registered object. */\n            register: function () {\n\n                /*****************\n                    Transforms\n                *****************/\n\n                /* Transforms are the subproperties contained by the CSS \"transform\" property. Transforms must undergo normalization\n                   so that they can be referenced in a properties map by their individual names. */\n                /* Note: When transforms are \"set\", they are actually assigned to a per-element transformCache. When all transform\n                   setting is complete complete, CSS.flushTransformCache() must be manually called to flush the values to the DOM.\n                   Transform setting is batched in this way to improve performance: the transform style only needs to be updated\n                   once when multiple transform subproperties are being animated simultaneously. */\n                /* Note: IE9 and Android Gingerbread have support for 2D -- but not 3D -- transforms. Since animating unsupported\n                   transform properties results in the browser ignoring the *entire* transform string, we prevent these 3D values\n                   from being normalized for these browsers so that tweening skips these properties altogether\n                   (since it will ignore them as being unsupported by the browser.) */\n                if (!(IE <= 9) && !Velocity.State.isGingerbread) {\n                    /* Note: Since the standalone CSS \"perspective\" property and the CSS transform \"perspective\" subproperty\n                    share the same name, the latter is given a unique token within Velocity: \"transformPerspective\". */\n                    CSS.Lists.transformsBase = CSS.Lists.transformsBase.concat(CSS.Lists.transforms3D);\n                }\n\n                for (var i = 0; i < CSS.Lists.transformsBase.length; i++) {\n                    /* Wrap the dynamically generated normalization function in a new scope so that transformName's value is\n                    paired with its respective function. (Otherwise, all functions would take the final for loop's transformName.) */\n                    (function() {\n                        var transformName = CSS.Lists.transformsBase[i];\n\n                        CSS.Normalizations.registered[transformName] = function (type, element, propertyValue) {\n                            switch (type) {\n                                /* The normalized property name is the parent \"transform\" property -- the property that is actually set in CSS. */\n                                case \"name\":\n                                    return \"transform\";\n                                /* Transform values are cached onto a per-element transformCache object. */\n                                case \"extract\":\n                                    /* If this transform has yet to be assigned a value, return its null value. */\n                                    if (Data(element) === undefined || Data(element).transformCache[transformName] === undefined) {\n                                        /* Scale CSS.Lists.transformsBase default to 1 whereas all other transform properties default to 0. */\n                                        return /^scale/i.test(transformName) ? 1 : 0;\n                                    /* When transform values are set, they are wrapped in parentheses as per the CSS spec.\n                                       Thus, when extracting their values (for tween calculations), we strip off the parentheses. */\n                                    } else {\n                                        return Data(element).transformCache[transformName].replace(/[()]/g, \"\");\n                                    }\n                                case \"inject\":\n                                    var invalid = false;\n\n                                    /* If an individual transform property contains an unsupported unit type, the browser ignores the *entire* transform property.\n                                       Thus, protect users from themselves by skipping setting for transform values supplied with invalid unit types. */\n                                    /* Switch on the base transform type; ignore the axis by removing the last letter from the transform's name. */\n                                    switch (transformName.substr(0, transformName.length - 1)) {\n                                        /* Whitelist unit types for each transform. */\n                                        case \"translate\":\n                                            invalid = !/(%|px|em|rem|vw|vh|\\d)$/i.test(propertyValue);\n                                            break;\n                                        /* Since an axis-free \"scale\" property is supported as well, a little hack is used here to detect it by chopping off its last letter. */\n                                        case \"scal\":\n                                        case \"scale\":\n                                            /* Chrome on Android has a bug in which scaled elements blur if their initial scale\n                                               value is below 1 (which can happen with forcefeeding). Thus, we detect a yet-unset scale property\n                                               and ensure that its first value is always 1. More info: http://stackoverflow.com/questions/10417890/css3-animations-with-transform-causes-blurred-elements-on-webkit/10417962#10417962 */\n                                            if (Velocity.State.isAndroid && Data(element).transformCache[transformName] === undefined && propertyValue < 1) {\n                                                propertyValue = 1;\n                                            }\n\n                                            invalid = !/(\\d)$/i.test(propertyValue);\n                                            break;\n                                        case \"skew\":\n                                            invalid = !/(deg|\\d)$/i.test(propertyValue);\n                                            break;\n                                        case \"rotate\":\n                                            invalid = !/(deg|\\d)$/i.test(propertyValue);\n                                            break;\n                                    }\n\n                                    if (!invalid) {\n                                        /* As per the CSS spec, wrap the value in parentheses. */\n                                        Data(element).transformCache[transformName] = \"(\" + propertyValue + \")\";\n                                    }\n\n                                    /* Although the value is set on the transformCache object, return the newly-updated value for the calling code to process as normal. */\n                                    return Data(element).transformCache[transformName];\n                            }\n                        };\n                    })();\n                }\n\n                /*************\n                    Colors\n                *************/\n\n                /* Since Velocity only animates a single numeric value per property, color animation is achieved by hooking the individual RGBA components of CSS color properties.\n                   Accordingly, color values must be normalized (e.g. \"#ff0000\", \"red\", and \"rgb(255, 0, 0)\" ==> \"255 0 0 1\") so that their components can be injected/extracted by CSS.Hooks logic. */\n                for (var i = 0; i < CSS.Lists.colors.length; i++) {\n                    /* Wrap the dynamically generated normalization function in a new scope so that colorName's value is paired with its respective function.\n                       (Otherwise, all functions would take the final for loop's colorName.) */\n                    (function () {\n                        var colorName = CSS.Lists.colors[i];\n\n                        /* Note: In IE<=8, which support rgb but not rgba, color properties are reverted to rgb by stripping off the alpha component. */\n                        CSS.Normalizations.registered[colorName] = function(type, element, propertyValue) {\n                            switch (type) {\n                                case \"name\":\n                                    return colorName;\n                                /* Convert all color values into the rgb format. (Old IE can return hex values and color names instead of rgb/rgba.) */\n                                case \"extract\":\n                                    var extracted;\n\n                                    /* If the color is already in its hookable form (e.g. \"255 255 255 1\") due to having been previously extracted, skip extraction. */\n                                    if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {\n                                        extracted = propertyValue;\n                                    } else {\n                                        var converted,\n                                            colorNames = {\n                                                black: \"rgb(0, 0, 0)\",\n                                                blue: \"rgb(0, 0, 255)\",\n                                                gray: \"rgb(128, 128, 128)\",\n                                                green: \"rgb(0, 128, 0)\",\n                                                red: \"rgb(255, 0, 0)\",\n                                                white: \"rgb(255, 255, 255)\"\n                                            };\n\n                                        /* Convert color names to rgb. */\n                                        if (/^[A-z]+$/i.test(propertyValue)) {\n                                            if (colorNames[propertyValue] !== undefined) {\n                                                converted = colorNames[propertyValue]\n                                            } else {\n                                                /* If an unmatched color name is provided, default to black. */\n                                                converted = colorNames.black;\n                                            }\n                                        /* Convert hex values to rgb. */\n                                        } else if (CSS.RegEx.isHex.test(propertyValue)) {\n                                            converted = \"rgb(\" + CSS.Values.hexToRgb(propertyValue).join(\" \") + \")\";\n                                        /* If the provided color doesn't match any of the accepted color formats, default to black. */\n                                        } else if (!(/^rgba?\\(/i.test(propertyValue))) {\n                                            converted = colorNames.black;\n                                        }\n\n                                        /* Remove the surrounding \"rgb/rgba()\" string then replace commas with spaces and strip\n                                           repeated spaces (in case the value included spaces to begin with). */\n                                        extracted = (converted || propertyValue).toString().match(CSS.RegEx.valueUnwrap)[1].replace(/,(\\s+)?/g, \" \");\n                                    }\n\n                                    /* So long as this isn't <=IE8, add a fourth (alpha) component if it's missing and default it to 1 (visible). */\n                                    if (!(IE <= 8) && extracted.split(\" \").length === 3) {\n                                        extracted += \" 1\";\n                                    }\n\n                                    return extracted;\n                                case \"inject\":\n                                    /* If this is IE<=8 and an alpha component exists, strip it off. */\n                                    if (IE <= 8) {\n                                        if (propertyValue.split(\" \").length === 4) {\n                                            propertyValue = propertyValue.split(/\\s+/).slice(0, 3).join(\" \");\n                                        }\n                                    /* Otherwise, add a fourth (alpha) component if it's missing and default it to 1 (visible). */\n                                    } else if (propertyValue.split(\" \").length === 3) {\n                                        propertyValue += \" 1\";\n                                    }\n\n                                    /* Re-insert the browser-appropriate wrapper(\"rgb/rgba()\"), insert commas, and strip off decimal units\n                                       on all values but the fourth (R, G, and B only accept whole numbers). */\n                                    return (IE <= 8 ? \"rgb\" : \"rgba\") + \"(\" + propertyValue.replace(/\\s+/g, \",\").replace(/\\.(\\d)+(?=,)/g, \"\") + \")\";\n                            }\n                        };\n                    })();\n                }\n            }\n        },\n\n        /************************\n           CSS Property Names\n        ************************/\n\n        Names: {\n            /* Camelcase a property name into its JavaScript notation (e.g. \"background-color\" ==> \"backgroundColor\").\n               Camelcasing is used to normalize property names between and across calls. */\n            camelCase: function (property) {\n                return property.replace(/-(\\w)/g, function (match, subMatch) {\n                    return subMatch.toUpperCase();\n                });\n            },\n\n            /* For SVG elements, some properties (namely, dimensional ones) are GET/SET via the element's HTML attributes (instead of via CSS styles). */\n            SVGAttribute: function (property) {\n                var SVGAttributes = \"width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2\";\n\n                /* Certain browsers require an SVG transform to be applied as an attribute. (Otherwise, application via CSS is preferable due to 3D support.) */\n                if (IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) {\n                    SVGAttributes += \"|transform\";\n                }\n\n                return new RegExp(\"^(\" + SVGAttributes + \")$\", \"i\").test(property);\n            },\n\n            /* Determine whether a property should be set with a vendor prefix. */\n            /* If a prefixed version of the property exists, return it. Otherwise, return the original property name.\n               If the property is not at all supported by the browser, return a false flag. */\n            prefixCheck: function (property) {\n                /* If this property has already been checked, return the cached value. */\n                if (Velocity.State.prefixMatches[property]) {\n                    return [ Velocity.State.prefixMatches[property], true ];\n                } else {\n                    var vendors = [ \"\", \"Webkit\", \"Moz\", \"ms\", \"O\" ];\n\n                    for (var i = 0, vendorsLength = vendors.length; i < vendorsLength; i++) {\n                        var propertyPrefixed;\n\n                        if (i === 0) {\n                            propertyPrefixed = property;\n                        } else {\n                            /* Capitalize the first letter of the property to conform to JavaScript vendor prefix notation (e.g. webkitFilter). */\n                            propertyPrefixed = vendors[i] + property.replace(/^\\w/, function(match) { return match.toUpperCase(); });\n                        }\n\n                        /* Check if the browser supports this property as prefixed. */\n                        if (Type.isString(Velocity.State.prefixElement.style[propertyPrefixed])) {\n                            /* Cache the match. */\n                            Velocity.State.prefixMatches[property] = propertyPrefixed;\n\n                            return [ propertyPrefixed, true ];\n                        }\n                    }\n\n                    /* If the browser doesn't support this property in any form, include a false flag so that the caller can decide how to proceed. */\n                    return [ property, false ];\n                }\n            }\n        },\n\n        /************************\n           CSS Property Values\n        ************************/\n\n        Values: {\n            /* Hex to RGB conversion. Copyright Tim Down: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */\n            hexToRgb: function (hex) {\n                var shortformRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n                    longformRegex = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i,\n                    rgbParts;\n\n                hex = hex.replace(shortformRegex, function (m, r, g, b) {\n                    return r + r + g + g + b + b;\n                });\n\n                rgbParts = longformRegex.exec(hex);\n\n                return rgbParts ? [ parseInt(rgbParts[1], 16), parseInt(rgbParts[2], 16), parseInt(rgbParts[3], 16) ] : [ 0, 0, 0 ];\n            },\n\n            isCSSNullValue: function (value) {\n                /* The browser defaults CSS values that have not been set to either 0 or one of several possible null-value strings.\n                   Thus, we check for both falsiness and these special strings. */\n                /* Null-value checking is performed to default the special strings to 0 (for the sake of tweening) or their hook\n                   templates as defined as CSS.Hooks (for the sake of hook injection/extraction). */\n                /* Note: Chrome returns \"rgba(0, 0, 0, 0)\" for an undefined color whereas IE returns \"transparent\". */\n                return (value == 0 || /^(none|auto|transparent|(rgba\\(0, ?0, ?0, ?0\\)))$/i.test(value));\n            },\n\n            /* Retrieve a property's default unit type. Used for assigning a unit type when one is not supplied by the user. */\n            getUnitType: function (property) {\n                if (/^(rotate|skew)/i.test(property)) {\n                    return \"deg\";\n                } else if (/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(property)) {\n                    /* The above properties are unitless. */\n                    return \"\";\n                } else {\n                    /* Default to px for all other properties. */\n                    return \"px\";\n                }\n            },\n\n            /* HTML elements default to an associated display type when they're not set to display:none. */\n            /* Note: This function is used for correctly setting the non-\"none\" display value in certain Velocity redirects, such as fadeIn/Out. */\n            getDisplayType: function (element) {\n                var tagName = element && element.tagName.toString().toLowerCase();\n\n                if (/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(tagName)) {\n                    return \"inline\";\n                } else if (/^(li)$/i.test(tagName)) {\n                    return \"list-item\";\n                } else if (/^(tr)$/i.test(tagName)) {\n                    return \"table-row\";\n                } else if (/^(table)$/i.test(tagName)) {\n                    return \"table\";\n                } else if (/^(tbody)$/i.test(tagName)) {\n                    return \"table-row-group\";\n                /* Default to \"block\" when no match is found. */\n                } else {\n                    return \"block\";\n                }\n            },\n\n            /* The class add/remove functions are used to temporarily apply a \"velocity-animating\" class to elements while they're animating. */\n            addClass: function (element, className) {\n                if (element.classList) {\n                    element.classList.add(className);\n                } else {\n                    element.className += (element.className.length ? \" \" : \"\") + className;\n                }\n            },\n\n            removeClass: function (element, className) {\n                if (element.classList) {\n                    element.classList.remove(className);\n                } else {\n                    element.className = element.className.toString().replace(new RegExp(\"(^|\\\\s)\" + className.split(\" \").join(\"|\") + \"(\\\\s|$)\", \"gi\"), \" \");\n                }\n            }\n        },\n\n        /****************************\n           Style Getting & Setting\n        ****************************/\n\n        /* The singular getPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */\n        getPropertyValue: function (element, property, rootPropertyValue, forceStyleLookup) {\n            /* Get an element's computed property value. */\n            /* Note: Retrieving the value of a CSS property cannot simply be performed by checking an element's\n               style attribute (which only reflects user-defined values). Instead, the browser must be queried for a property's\n               *computed* value. You can read more about getComputedStyle here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */\n            function computePropertyValue (element, property) {\n                /* When box-sizing isn't set to border-box, height and width style values are incorrectly computed when an\n                   element's scrollbars are visible (which expands the element's dimensions). Thus, we defer to the more accurate\n                   offsetHeight/Width property, which includes the total dimensions for interior, border, padding, and scrollbar.\n                   We subtract border and padding to get the sum of interior + scrollbar. */\n                var computedValue = 0;\n\n                /* IE<=8 doesn't support window.getComputedStyle, thus we defer to jQuery, which has an extensive array\n                   of hacks to accurately retrieve IE8 property values. Re-implementing that logic here is not worth bloating the\n                   codebase for a dying browser. The performance repercussions of using jQuery here are minimal since\n                   Velocity is optimized to rarely (and sometimes never) query the DOM. Further, the $.css() codepath isn't that slow. */\n                if (IE <= 8) {\n                    computedValue = $.css(element, property); /* GET */\n                /* All other browsers support getComputedStyle. The returned live object reference is cached onto its\n                   associated element so that it does not need to be refetched upon every GET. */\n                } else {\n                    /* Browsers do not return height and width values for elements that are set to display:\"none\". Thus, we temporarily\n                       toggle display to the element type's default value. */\n                    var toggleDisplay = false;\n\n                    if (/^(width|height)$/.test(property) && CSS.getPropertyValue(element, \"display\") === 0) {\n                        toggleDisplay = true;\n                        CSS.setPropertyValue(element, \"display\", CSS.Values.getDisplayType(element));\n                    }\n\n                    function revertDisplay () {\n                        if (toggleDisplay) {\n                            CSS.setPropertyValue(element, \"display\", \"none\");\n                        }\n                    }\n\n                    if (!forceStyleLookup) {\n                        if (property === \"height\" && CSS.getPropertyValue(element, \"boxSizing\").toString().toLowerCase() !== \"border-box\") {\n                            var contentBoxHeight = element.offsetHeight - (parseFloat(CSS.getPropertyValue(element, \"borderTopWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"borderBottomWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingTop\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingBottom\")) || 0);\n                            revertDisplay();\n\n                            return contentBoxHeight;\n                        } else if (property === \"width\" && CSS.getPropertyValue(element, \"boxSizing\").toString().toLowerCase() !== \"border-box\") {\n                            var contentBoxWidth = element.offsetWidth - (parseFloat(CSS.getPropertyValue(element, \"borderLeftWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"borderRightWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingLeft\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingRight\")) || 0);\n                            revertDisplay();\n\n                            return contentBoxWidth;\n                        }\n                    }\n\n                    var computedStyle;\n\n                    /* For elements that Velocity hasn't been called on directly (e.g. when Velocity queries the DOM on behalf\n                       of a parent of an element its animating), perform a direct getComputedStyle lookup since the object isn't cached. */\n                    if (Data(element) === undefined) {\n                        computedStyle = window.getComputedStyle(element, null); /* GET */\n                    /* If the computedStyle object has yet to be cached, do so now. */\n                    } else if (!Data(element).computedStyle) {\n                        computedStyle = Data(element).computedStyle = window.getComputedStyle(element, null); /* GET */\n                    /* If computedStyle is cached, use it. */\n                    } else {\n                        computedStyle = Data(element).computedStyle;\n                    }\n\n                    /* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color.\n                       Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse.\n                       So, as a polyfill for querying individual border side colors, we just return the top border's color and animate all borders from that value. */\n                    if (property === \"borderColor\") {\n                        property = \"borderTopColor\";\n                    }\n\n                    /* IE9 has a bug in which the \"filter\" property must be accessed from computedStyle using the getPropertyValue method\n                       instead of a direct property lookup. The getPropertyValue method is slower than a direct lookup, which is why we avoid it by default. */\n                    if (IE === 9 && property === \"filter\") {\n                        computedValue = computedStyle.getPropertyValue(property); /* GET */\n                    } else {\n                        computedValue = computedStyle[property];\n                    }\n\n                    /* Fall back to the property's style value (if defined) when computedValue returns nothing,\n                       which can happen when the element hasn't been painted. */\n                    if (computedValue === \"\" || computedValue === null) {\n                        computedValue = element.style[property];\n                    }\n\n                    revertDisplay();\n                }\n\n                /* For top, right, bottom, and left (TRBL) values that are set to \"auto\" on elements of \"fixed\" or \"absolute\" position,\n                   defer to jQuery for converting \"auto\" to a numeric value. (For elements with a \"static\" or \"relative\" position, \"auto\" has the same\n                   effect as being set to 0, so no conversion is necessary.) */\n                /* An example of why numeric conversion is necessary: When an element with \"position:absolute\" has an untouched \"left\"\n                   property, which reverts to \"auto\", left's value is 0 relative to its parent element, but is often non-zero relative\n                   to its *containing* (not parent) element, which is the nearest \"position:relative\" ancestor or the viewport (and always the viewport in the case of \"position:fixed\"). */\n                if (computedValue === \"auto\" && /^(top|right|bottom|left)$/i.test(property)) {\n                    var position = computePropertyValue(element, \"position\"); /* GET */\n\n                    /* For absolute positioning, jQuery's $.position() only returns values for top and left;\n                       right and bottom will have their \"auto\" value reverted to 0. */\n                    /* Note: A jQuery object must be created here since jQuery doesn't have a low-level alias for $.position().\n                       Not a big deal since we're currently in a GET batch anyway. */\n                    if (position === \"fixed\" || (position === \"absolute\" && /top|left/i.test(property))) {\n                        /* Note: jQuery strips the pixel unit from its returned values; we re-add it here to conform with computePropertyValue's behavior. */\n                        computedValue = $(element).position()[property] + \"px\"; /* GET */\n                    }\n                }\n\n                return computedValue;\n            }\n\n            var propertyValue;\n\n            /* If this is a hooked property (e.g. \"clipLeft\" instead of the root property of \"clip\"),\n               extract the hook's value from a normalized rootPropertyValue using CSS.Hooks.extractValue(). */\n            if (CSS.Hooks.registered[property]) {\n                var hook = property,\n                    hookRoot = CSS.Hooks.getRoot(hook);\n\n                /* If a cached rootPropertyValue wasn't passed in (which Velocity always attempts to do in order to avoid requerying the DOM),\n                   query the DOM for the root property's value. */\n                if (rootPropertyValue === undefined) {\n                    /* Since the browser is now being directly queried, use the official post-prefixing property name for this lookup. */\n                    rootPropertyValue = CSS.getPropertyValue(element, CSS.Names.prefixCheck(hookRoot)[0]); /* GET */\n                }\n\n                /* If this root has a normalization registered, peform the associated normalization extraction. */\n                if (CSS.Normalizations.registered[hookRoot]) {\n                    rootPropertyValue = CSS.Normalizations.registered[hookRoot](\"extract\", element, rootPropertyValue);\n                }\n\n                /* Extract the hook's value. */\n                propertyValue = CSS.Hooks.extractValue(hook, rootPropertyValue);\n\n            /* If this is a normalized property (e.g. \"opacity\" becomes \"filter\" in <=IE8) or \"translateX\" becomes \"transform\"),\n               normalize the property's name and value, and handle the special case of transforms. */\n            /* Note: Normalizing a property is mutually exclusive from hooking a property since hook-extracted values are strictly\n               numerical and therefore do not require normalization extraction. */\n            } else if (CSS.Normalizations.registered[property]) {\n                var normalizedPropertyName,\n                    normalizedPropertyValue;\n\n                normalizedPropertyName = CSS.Normalizations.registered[property](\"name\", element);\n\n                /* Transform values are calculated via normalization extraction (see below), which checks against the element's transformCache.\n                   At no point do transform GETs ever actually query the DOM; initial stylesheet values are never processed.\n                   This is because parsing 3D transform matrices is not always accurate and would bloat our codebase;\n                   thus, normalization extraction defaults initial transform values to their zero-values (e.g. 1 for scaleX and 0 for translateX). */\n                if (normalizedPropertyName !== \"transform\") {\n                    normalizedPropertyValue = computePropertyValue(element, CSS.Names.prefixCheck(normalizedPropertyName)[0]); /* GET */\n\n                    /* If the value is a CSS null-value and this property has a hook template, use that zero-value template so that hooks can be extracted from it. */\n                    if (CSS.Values.isCSSNullValue(normalizedPropertyValue) && CSS.Hooks.templates[property]) {\n                        normalizedPropertyValue = CSS.Hooks.templates[property][1];\n                    }\n                }\n\n                propertyValue = CSS.Normalizations.registered[property](\"extract\", element, normalizedPropertyValue);\n            }\n\n            /* If a (numeric) value wasn't produced via hook extraction or normalization, query the DOM. */\n            if (!/^[\\d-]/.test(propertyValue)) {\n                /* For SVG elements, dimensional properties (which SVGAttribute() detects) are tweened via\n                   their HTML attribute values instead of their CSS style values. */\n                if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {\n                    /* Since the height/width attribute values must be set manually, they don't reflect computed values.\n                       Thus, we use use getBBox() to ensure we always get values for elements with undefined height/width attributes. */\n                    if (/^(height|width)$/i.test(property)) {\n                        /* Firefox throws an error if .getBBox() is called on an SVG that isn't attached to the DOM. */\n                        try {\n                            propertyValue = element.getBBox()[property];\n                        } catch (error) {\n                            propertyValue = 0;\n                        }\n                    /* Otherwise, access the attribute value directly. */\n                    } else {\n                        propertyValue = element.getAttribute(property);\n                    }\n                } else {\n                    propertyValue = computePropertyValue(element, CSS.Names.prefixCheck(property)[0]); /* GET */\n                }\n            }\n\n            /* Since property lookups are for animation purposes (which entails computing the numeric delta between start and end values),\n               convert CSS null-values to an integer of value 0. */\n            if (CSS.Values.isCSSNullValue(propertyValue)) {\n                propertyValue = 0;\n            }\n\n            if (Velocity.debug >= 2) console.log(\"Get \" + property + \": \" + propertyValue);\n\n            return propertyValue;\n        },\n\n        /* The singular setPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */\n        setPropertyValue: function(element, property, propertyValue, rootPropertyValue, scrollData) {\n            var propertyName = property;\n\n            /* In order to be subjected to call options and element queueing, scroll animation is routed through Velocity as if it were a standard CSS property. */\n            if (property === \"scroll\") {\n                /* If a container option is present, scroll the container instead of the browser window. */\n                if (scrollData.container) {\n                    scrollData.container[\"scroll\" + scrollData.direction] = propertyValue;\n                /* Otherwise, Velocity defaults to scrolling the browser window. */\n                } else {\n                    if (scrollData.direction === \"Left\") {\n                        window.scrollTo(propertyValue, scrollData.alternateValue);\n                    } else {\n                        window.scrollTo(scrollData.alternateValue, propertyValue);\n                    }\n                }\n            } else {\n                /* Transforms (translateX, rotateZ, etc.) are applied to a per-element transformCache object, which is manually flushed via flushTransformCache().\n                   Thus, for now, we merely cache transforms being SET. */\n                if (CSS.Normalizations.registered[property] && CSS.Normalizations.registered[property](\"name\", element) === \"transform\") {\n                    /* Perform a normalization injection. */\n                    /* Note: The normalization logic handles the transformCache updating. */\n                    CSS.Normalizations.registered[property](\"inject\", element, propertyValue);\n\n                    propertyName = \"transform\";\n                    propertyValue = Data(element).transformCache[property];\n                } else {\n                    /* Inject hooks. */\n                    if (CSS.Hooks.registered[property]) {\n                        var hookName = property,\n                            hookRoot = CSS.Hooks.getRoot(property);\n\n                        /* If a cached rootPropertyValue was not provided, query the DOM for the hookRoot's current value. */\n                        rootPropertyValue = rootPropertyValue || CSS.getPropertyValue(element, hookRoot); /* GET */\n\n                        propertyValue = CSS.Hooks.injectValue(hookName, propertyValue, rootPropertyValue);\n                        property = hookRoot;\n                    }\n\n                    /* Normalize names and values. */\n                    if (CSS.Normalizations.registered[property]) {\n                        propertyValue = CSS.Normalizations.registered[property](\"inject\", element, propertyValue);\n                        property = CSS.Normalizations.registered[property](\"name\", element);\n                    }\n\n                    /* Assign the appropriate vendor prefix before performing an official style update. */\n                    propertyName = CSS.Names.prefixCheck(property)[0];\n\n                    /* A try/catch is used for IE<=8, which throws an error when \"invalid\" CSS values are set, e.g. a negative width.\n                       Try/catch is avoided for other browsers since it incurs a performance overhead. */\n                    if (IE <= 8) {\n                        try {\n                            element.style[propertyName] = propertyValue;\n                        } catch (error) { if (Velocity.debug) console.log(\"Browser does not support [\" + propertyValue + \"] for [\" + propertyName + \"]\"); }\n                    /* SVG elements have their dimensional properties (width, height, x, y, cx, etc.) applied directly as attributes instead of as styles. */\n                    /* Note: IE8 does not support SVG elements, so it's okay that we skip it for SVG animation. */\n                    } else if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {\n                        /* Note: For SVG attributes, vendor-prefixed property names are never used. */\n                        /* Note: Not all CSS properties can be animated via attributes, but the browser won't throw an error for unsupported properties. */\n                        element.setAttribute(property, propertyValue);\n                    } else {\n                        var style = element.renderer === \"webgl\" ? element.styleGL : element.style;\n                        style[propertyName] = propertyValue;\n                    }\n\n                    if (Velocity.debug >= 2) console.log(\"Set \" + property + \" (\" + propertyName + \"): \" + propertyValue);\n                }\n            }\n\n            /* Return the normalized property name and value in case the caller wants to know how these values were modified before being applied to the DOM. */\n            return [ propertyName, propertyValue ];\n        },\n\n        /* To increase performance by batching transform updates into a single SET, transforms are not directly applied to an element until flushTransformCache() is called. */\n        /* Note: Velocity applies transform properties in the same order that they are chronogically introduced to the element's CSS styles. */\n        flushTransformCache: function(element) {\n            var transformString = \"\";\n\n            /* Certain browsers require that SVG transforms be applied as an attribute. However, the SVG transform attribute takes a modified version of CSS's transform string\n               (units are dropped and, except for skewX/Y, subproperties are merged into their master property -- e.g. scaleX and scaleY are merged into scale(X Y). */\n            if ((IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) && Data(element).isSVG) {\n                /* Since transform values are stored in their parentheses-wrapped form, we use a helper function to strip out their numeric values.\n                   Further, SVG transform properties only take unitless (representing pixels) values, so it's okay that parseFloat() strips the unit suffixed to the float value. */\n                function getTransformFloat (transformProperty) {\n                    return parseFloat(CSS.getPropertyValue(element, transformProperty));\n                }\n\n                /* Create an object to organize all the transforms that we'll apply to the SVG element. To keep the logic simple,\n                   we process *all* transform properties -- even those that may not be explicitly applied (since they default to their zero-values anyway). */\n                var SVGTransforms = {\n                    translate: [ getTransformFloat(\"translateX\"), getTransformFloat(\"translateY\") ],\n                    skewX: [ getTransformFloat(\"skewX\") ], skewY: [ getTransformFloat(\"skewY\") ],\n                    /* If the scale property is set (non-1), use that value for the scaleX and scaleY values\n                       (this behavior mimics the result of animating all these properties at once on HTML elements). */\n                    scale: getTransformFloat(\"scale\") !== 1 ? [ getTransformFloat(\"scale\"), getTransformFloat(\"scale\") ] : [ getTransformFloat(\"scaleX\"), getTransformFloat(\"scaleY\") ],\n                    /* Note: SVG's rotate transform takes three values: rotation degrees followed by the X and Y values\n                       defining the rotation's origin point. We ignore the origin values (default them to 0). */\n                    rotate: [ getTransformFloat(\"rotateZ\"), 0, 0 ]\n                };\n\n                /* Iterate through the transform properties in the user-defined property map order.\n                   (This mimics the behavior of non-SVG transform animation.) */\n                $.each(Data(element).transformCache, function(transformName) {\n                    /* Except for with skewX/Y, revert the axis-specific transform subproperties to their axis-free master\n                       properties so that they match up with SVG's accepted transform properties. */\n                    if (/^translate/i.test(transformName)) {\n                        transformName = \"translate\";\n                    } else if (/^scale/i.test(transformName)) {\n                        transformName = \"scale\";\n                    } else if (/^rotate/i.test(transformName)) {\n                        transformName = \"rotate\";\n                    }\n\n                    /* Check that we haven't yet deleted the property from the SVGTransforms container. */\n                    if (SVGTransforms[transformName]) {\n                        /* Append the transform property in the SVG-supported transform format. As per the spec, surround the space-delimited values in parentheses. */\n                        transformString += transformName + \"(\" + SVGTransforms[transformName].join(\" \") + \")\" + \" \";\n\n                        /* After processing an SVG transform property, delete it from the SVGTransforms container so we don't\n                           re-insert the same master property if we encounter another one of its axis-specific properties. */\n                        delete SVGTransforms[transformName];\n                    }\n                });\n            } else {\n                var transformValue,\n                    perspective;\n\n                /* Transform properties are stored as members of the transformCache object. Concatenate all the members into a string. */\n                $.each(Data(element).transformCache, function(transformName) {\n                    transformValue = Data(element).transformCache[transformName];\n\n                    /* Transform's perspective subproperty must be set first in order to take effect. Store it temporarily. */\n                    if (transformName === \"transformPerspective\") {\n                        perspective = transformValue;\n                        return true;\n                    }\n\n                    /* IE9 only supports one rotation type, rotateZ, which it refers to as \"rotate\". */\n                    if (IE === 9 && transformName === \"rotateZ\") {\n                        transformName = \"rotate\";\n                    }\n\n                    transformString += transformName + transformValue + \" \";\n                });\n\n                /* If present, set the perspective subproperty first. */\n                if (perspective) {\n                    transformString = \"perspective\" + perspective + \" \" + transformString;\n                }\n            }\n\n            CSS.setPropertyValue(element, \"transform\", transformString);\n        }\n    };\n\n    /* Register hooks and normalizations. */\n    CSS.Hooks.register();\n    CSS.Normalizations.register();\n\n    /* Allow hook setting in the same fashion as jQuery's $.css(). */\n    Velocity.hook = function (elements, arg2, arg3) {\n        var value = undefined;\n\n        elements = sanitizeElements(elements);\n\n        $.each(elements, function(i, element) {\n            /* Initialize Velocity's per-element data cache if this element hasn't previously been animated. */\n            if (Data(element) === undefined) {\n                Velocity.init(element);\n            }\n\n            /* Get property value. If an element set was passed in, only return the value for the first element. */\n            if (arg3 === undefined) {\n                if (value === undefined) {\n                    value = Velocity.CSS.getPropertyValue(element, arg2);\n                }\n            /* Set property value. */\n            } else {\n                /* sPV returns an array of the normalized propertyName/propertyValue pair used to update the DOM. */\n                var adjustedSet = Velocity.CSS.setPropertyValue(element, arg2, arg3);\n\n                /* Transform properties don't automatically set. They have to be flushed to the DOM. */\n                if (adjustedSet[0] === \"transform\") {\n                    Velocity.CSS.flushTransformCache(element);\n                }\n\n                value = adjustedSet;\n            }\n        });\n\n        return value;\n    };\n\n    /*****************\n        Animation\n    *****************/\n\n    var animate = function() {\n\n        /******************\n            Call Chain\n        ******************/\n\n        /* Logic for determining what to return to the call stack when exiting out of Velocity. */\n        function getChain () {\n            /* If we are using the utility function, attempt to return this call's promise. If no promise library was detected,\n               default to null instead of returning the targeted elements so that utility function's return value is standardized. */\n            if (isUtility) {\n                return promiseData.promise || null;\n            /* Otherwise, if we're using $.fn, return the jQuery-/Zepto-wrapped element set. */\n            } else {\n                return elementsWrapped;\n            }\n        }\n\n        /*************************\n           Arguments Assignment\n        *************************/\n\n        /* To allow for expressive CoffeeScript code, Velocity supports an alternative syntax in which \"elements\" (or \"e\"), \"properties\" (or \"p\"), and \"options\" (or \"o\")\n           objects are defined on a container object that's passed in as Velocity's sole argument. */\n        /* Note: Some browsers automatically populate arguments with a \"properties\" object. We detect it by checking for its default \"names\" property. */\n        var syntacticSugar = (arguments[0] && (arguments[0].p || (($.isPlainObject(arguments[0].properties) && !arguments[0].properties.names) || Type.isString(arguments[0].properties)))),\n            /* Whether Velocity was called via the utility function (as opposed to on a jQuery/Zepto object). */\n            isUtility,\n            /* When Velocity is called via the utility function ($.Velocity()/Velocity()), elements are explicitly\n               passed in as the first parameter. Thus, argument positioning varies. We normalize them here. */\n            elementsWrapped,\n            argumentIndex;\n\n        var elements,\n            propertiesMap,\n            options;\n\n        /* Detect jQuery/Zepto elements being animated via the $.fn method. */\n        if (Type.isWrapped(this)) {\n            isUtility = false;\n\n            argumentIndex = 0;\n            elements = this;\n            elementsWrapped = this;\n        /* Otherwise, raw elements are being animated via the utility function. */\n        } else {\n            isUtility = true;\n\n            argumentIndex = 1;\n            elements = syntacticSugar ? (arguments[0].elements || arguments[0].e) : arguments[0];\n        }\n\n        elements = sanitizeElements(elements);\n\n        if (!elements) {\n            return;\n        }\n\n        if (syntacticSugar) {\n            propertiesMap = arguments[0].properties || arguments[0].p;\n            options = arguments[0].options || arguments[0].o;\n        } else {\n            propertiesMap = arguments[argumentIndex];\n            options = arguments[argumentIndex + 1];\n        }\n\n        /* The length of the element set (in the form of a nodeList or an array of elements) is defaulted to 1 in case a\n           single raw DOM element is passed in (which doesn't contain a length property). */\n        var elementsLength = elements.length,\n            elementsIndex = 0;\n\n        /***************************\n            Argument Overloading\n        ***************************/\n\n        /* Support is included for jQuery's argument overloading: $.animate(propertyMap [, duration] [, easing] [, complete]).\n           Overloading is detected by checking for the absence of an object being passed into options. */\n        /* Note: The stop and finish actions do not accept animation options, and are therefore excluded from this check. */\n        if (!/^(stop|finish)$/i.test(propertiesMap) && !$.isPlainObject(options)) {\n            /* The utility function shifts all arguments one position to the right, so we adjust for that offset. */\n            var startingArgumentPosition = argumentIndex + 1;\n\n            options = {};\n\n            /* Iterate through all options arguments */\n            for (var i = startingArgumentPosition; i < arguments.length; i++) {\n                /* Treat a number as a duration. Parse it out. */\n                /* Note: The following RegEx will return true if passed an array with a number as its first item.\n                   Thus, arrays are skipped from this check. */\n                if (!Type.isArray(arguments[i]) && (/^(fast|normal|slow)$/i.test(arguments[i]) || /^\\d/.test(arguments[i]))) {\n                    options.duration = arguments[i];\n                /* Treat strings and arrays as easings. */\n                } else if (Type.isString(arguments[i]) || Type.isArray(arguments[i])) {\n                    options.easing = arguments[i];\n                /* Treat a function as a complete callback. */\n                } else if (Type.isFunction(arguments[i])) {\n                    options.complete = arguments[i];\n                }\n            }\n        }\n\n        /***************\n            Promises\n        ***************/\n\n        var promiseData = {\n                promise: null,\n                resolver: null,\n                rejecter: null\n            };\n\n        /* If this call was made via the utility function (which is the default method of invocation when jQuery/Zepto are not being used), and if\n           promise support was detected, create a promise object for this call and store references to its resolver and rejecter methods. The resolve\n           method is used when a call completes naturally or is prematurely stopped by the user. In both cases, completeCall() handles the associated\n           call cleanup and promise resolving logic. The reject method is used when an invalid set of arguments is passed into a Velocity call. */\n        /* Note: Velocity employs a call-based queueing architecture, which means that stopping an animating element actually stops the full call that\n           triggered it -- not that one element exclusively. Similarly, there is one promise per call, and all elements targeted by a Velocity call are\n           grouped together for the purposes of resolving and rejecting a promise. */\n        if (isUtility && Velocity.Promise) {\n            promiseData.promise = new Velocity.Promise(function (resolve, reject) {\n                promiseData.resolver = resolve;\n                promiseData.rejecter = reject;\n            });\n        }\n\n        /*********************\n           Action Detection\n        *********************/\n\n        /* Velocity's behavior is categorized into \"actions\": Elements can either be specially scrolled into view,\n           or they can be started, stopped, or reversed. If a literal or referenced properties map is passed in as Velocity's\n           first argument, the associated action is \"start\". Alternatively, \"scroll\", \"reverse\", or \"stop\" can be passed in instead of a properties map. */\n        var action;\n\n        switch (propertiesMap) {\n            case \"scroll\":\n                action = \"scroll\";\n                break;\n\n            case \"reverse\":\n                action = \"reverse\";\n                break;\n\n            case \"finish\":\n            case \"stop\":\n                /*******************\n                    Action: Stop\n                *******************/\n\n                /* Clear the currently-active delay on each targeted element. */\n                $.each(elements, function(i, element) {\n                    if (Data(element) && Data(element).delayTimer) {\n                        /* Stop the timer from triggering its cached next() function. */\n                        clearTimeout(Data(element).delayTimer.setTimeout);\n\n                        /* Manually call the next() function so that the subsequent queue items can progress. */\n                        if (Data(element).delayTimer.next) {\n                            Data(element).delayTimer.next();\n                        }\n\n                        delete Data(element).delayTimer;\n                    }\n                });\n\n                var callsToStop = [];\n\n                /* When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have\n                   been applied to multiple elements, in which case all of the call's elements will be stopped. When an element\n                   is stopped, the next item in its animation queue is immediately triggered. */\n                /* An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the \"fx\" queue)\n                   or a custom queue string can be passed in. */\n                /* Note: The stop command runs prior to Velocity's Queueing phase since its behavior is intended to take effect *immediately*,\n                   regardless of the element's current queue state. */\n\n                /* Iterate through every active call. */\n                $.each(Velocity.State.calls, function(i, activeCall) {\n                    /* Inactive calls are set to false by the logic inside completeCall(). Skip them. */\n                    if (activeCall) {\n                        /* Iterate through the active call's targeted elements. */\n                        $.each(activeCall[1], function(k, activeElement) {\n                            /* If true was passed in as a secondary argument, clear absolutely all calls on this element. Otherwise, only\n                               clear calls associated with the relevant queue. */\n                            /* Call stopping logic works as follows:\n                               - options === true --> stop current default queue calls (and queue:false calls), including remaining queued ones.\n                               - options === undefined --> stop current queue:\"\" call and all queue:false calls.\n                               - options === false --> stop only queue:false calls.\n                               - options === \"custom\" --> stop current queue:\"custom\" call, including remaining queued ones (there is no functionality to only clear the currently-running queue:\"custom\" call). */\n                            var queueName = (options === undefined) ? \"\" : options;\n\n                            if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {\n                                return true;\n                            }\n\n                            /* Iterate through the calls targeted by the stop command. */\n                            $.each(elements, function(l, element) {                                \n                                /* Check that this call was applied to the target element. */\n                                if (element === activeElement) {\n                                    /* Optionally clear the remaining queued calls. */\n                                    if (options === true || Type.isString(options)) {\n                                        /* Iterate through the items in the element's queue. */\n                                        $.each($.queue(element, Type.isString(options) ? options : \"\"), function(_, item) {\n                                            /* The queue array can contain an \"inprogress\" string, which we skip. */\n                                            if (Type.isFunction(item)) {\n                                                /* Pass the item's callback a flag indicating that we want to abort from the queue call.\n                                                   (Specifically, the queue will resolve the call's associated promise then abort.)  */\n                                                item(null, true);\n                                            }\n                                        });\n\n                                        /* Clearing the $.queue() array is achieved by resetting it to []. */\n                                        $.queue(element, Type.isString(options) ? options : \"\", []);\n                                    }\n\n                                    if (propertiesMap === \"stop\") {\n                                        /* Since \"reverse\" uses cached start values (the previous call's endValues), these values must be\n                                           changed to reflect the final value that the elements were actually tweened to. */\n                                        /* Note: If only queue:false animations are currently running on an element, it won't have a tweensContainer\n                                           object. Also, queue:false animations can't be reversed. */\n                                        if (Data(element) && Data(element).tweensContainer && queueName !== false) {\n                                            $.each(Data(element).tweensContainer, function(m, activeTween) {\n                                                activeTween.endValue = activeTween.currentValue;\n                                            });\n                                        }\n\n                                        callsToStop.push(i);\n                                    } else if (propertiesMap === \"finish\") {\n                                        /* To get active tweens to finish immediately, we forcefully shorten their durations to 1ms so that\n                                        they finish upon the next rAf tick then proceed with normal call completion logic. */\n                                        activeCall[2].duration = 1;\n                                    }\n                                }\n                            });\n                        });\n                    }\n                });\n\n                /* Prematurely call completeCall() on each matched active call. Pass an additional flag for \"stop\" to indicate\n                   that the complete callback and display:none setting should be skipped since we're completing prematurely. */\n                if (propertiesMap === \"stop\") {\n                    $.each(callsToStop, function(i, j) {\n                        completeCall(j, true);\n                    });\n\n                    if (promiseData.promise) {\n                        /* Immediately resolve the promise associated with this stop call since stop runs synchronously. */\n                        promiseData.resolver(elements);\n                    }\n                }\n\n                /* Since we're stopping, and not proceeding with queueing, exit out of Velocity. */\n                return getChain();\n\n            default:\n                /* Treat a non-empty plain object as a literal properties map. */\n                if ($.isPlainObject(propertiesMap) && !Type.isEmptyObject(propertiesMap)) {\n                    action = \"start\";\n\n                /****************\n                    Redirects\n                ****************/\n\n                /* Check if a string matches a registered redirect (see Redirects above). */\n                } else if (Type.isString(propertiesMap) && Velocity.Redirects[propertiesMap]) {\n                    var opts = $.extend({}, options),\n                        durationOriginal = opts.duration,\n                        delayOriginal = opts.delay || 0;\n\n                    /* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */\n                    if (opts.backwards === true) {\n                        elements = $.extend(true, [], elements).reverse();\n                    }\n\n                    /* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */\n                    $.each(elements, function(elementIndex, element) {\n                        /* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */\n                        if (parseFloat(opts.stagger)) {\n                            opts.delay = delayOriginal + (parseFloat(opts.stagger) * elementIndex);\n                        } else if (Type.isFunction(opts.stagger)) {\n                            opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elementsLength);\n                        }\n\n                        /* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards)\n                           the duration of each element's animation, using floors to prevent producing very short durations. */\n                        if (opts.drag) {\n                            /* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */\n                            opts.duration = parseFloat(durationOriginal) || (/^(callout|transition)/.test(propertiesMap) ? 1000 : DURATION_DEFAULT);\n\n                            /* For each element, take the greater duration of: A) animation completion percentage relative to the original duration,\n                               B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value).\n                               The end result is a baseline of 75% of the redirect's duration that increases/decreases as the end of the element set is approached. */\n                            opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex/elementsLength : (elementIndex + 1) / elementsLength), opts.duration * 0.75, 200);\n                        }\n\n                        /* Pass in the call's opts object so that the redirect can optionally extend it. It defaults to an empty object instead of null to\n                           reduce the opts checking logic required inside the redirect. */\n                        Velocity.Redirects[propertiesMap].call(element, element, opts || {}, elementIndex, elementsLength, elements, promiseData.promise ? promiseData : undefined);\n                    });\n\n                    /* Since the animation logic resides within the redirect's own code, abort the remainder of this call.\n                       (The performance overhead up to this point is virtually non-existant.) */\n                    /* Note: The jQuery call chain is kept intact by returning the complete element set. */\n                    return getChain();\n                } else {\n                    var abortError = \"Velocity: First argument (\" + propertiesMap + \") was not a property map, a known action, or a registered redirect. Aborting.\";\n\n                    if (promiseData.promise) {\n                        promiseData.rejecter(new Error(abortError));\n                    } else {\n                        console.log(abortError);\n                    }\n\n                    return getChain();\n                }\n        }\n\n        /**************************\n            Call-Wide Variables\n        **************************/\n\n        /* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements\n           being animated in a single Velocity call. Calculating unit ratios necessitates DOM querying and updating, and is therefore\n           avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale\n           conversion metrics across Velocity animations that are not immediately consecutively chained. */\n        var callUnitConversionData = {\n                lastParent: null,\n                lastPosition: null,\n                lastFontSize: null,\n                lastPercentToPxWidth: null,\n                lastPercentToPxHeight: null,\n                lastEmToPx: null,\n                remToPx: null,\n                vwToPx: null,\n                vhToPx: null\n            };\n\n        /* A container for all the ensuing tween data and metadata associated with this call. This container gets pushed to the page-wide\n           Velocity.State.calls array that is processed during animation ticking. */\n        var call = [];\n\n        /************************\n           Element Processing\n        ************************/\n\n        /* Element processing consists of three parts -- data processing that cannot go stale and data processing that *can* go stale (i.e. third-party style modifications):\n           1) Pre-Queueing: Element-wide variables, including the element's data storage, are instantiated. Call options are prepared. If triggered, the Stop action is executed.\n           2) Queueing: The logic that runs once this call has reached its point of execution in the element's $.queue() stack. Most logic is placed here to avoid risking it becoming stale.\n           3) Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.\n        */\n\n        function processElement () {\n\n            /*************************\n               Part I: Pre-Queueing\n            *************************/\n\n            /***************************\n               Element-Wide Variables\n            ***************************/\n\n            var element = this,\n                /* The runtime opts object is the extension of the current call's options and Velocity's page-wide option defaults. */\n                opts = $.extend({}, Velocity.defaults, options),\n                /* A container for the processed data associated with each property in the propertyMap.\n                   (Each property in the map produces its own \"tween\".) */\n                tweensContainer = {},\n                elementUnitConversionData;\n\n            /******************\n               Element Init\n            ******************/\n\n            if (Data(element) === undefined) {\n                Velocity.init(element);\n            }\n\n            /******************\n               Option: Delay\n            ******************/\n\n            /* Since queue:false doesn't respect the item's existing queue, we avoid injecting its delay here (it's set later on). */\n            /* Note: Velocity rolls its own delay function since jQuery doesn't have a utility alias for $.fn.delay()\n               (and thus requires jQuery element creation, which we avoid since its overhead includes DOM querying). */\n            if (parseFloat(opts.delay) && opts.queue !== false) {\n                $.queue(element, opts.queue, function(next) {\n                    /* This is a flag used to indicate to the upcoming completeCall() function that this queue entry was initiated by Velocity. See completeCall() for further details. */\n                    Velocity.velocityQueueEntryFlag = true;\n\n                    /* The ensuing queue item (which is assigned to the \"next\" argument that $.queue() automatically passes in) will be triggered after a setTimeout delay.\n                       The setTimeout is stored so that it can be subjected to clearTimeout() if this animation is prematurely stopped via Velocity's \"stop\" command. */\n                    Data(element).delayTimer = {\n                        setTimeout: setTimeout(next, parseFloat(opts.delay)),\n                        next: next\n                    };\n                });\n            }\n\n            /*********************\n               Option: Duration\n            *********************/\n\n            /* Support for jQuery's named durations. */\n            switch (opts.duration.toString().toLowerCase()) {\n                case \"fast\":\n                    opts.duration = 200;\n                    break;\n\n                case \"normal\":\n                    opts.duration = DURATION_DEFAULT;\n                    break;\n\n                case \"slow\":\n                    opts.duration = 600;\n                    break;\n\n                default:\n                    /* Remove the potential \"ms\" suffix and default to 1 if the user is attempting to set a duration of 0 (in order to produce an immediate style change). */\n                    opts.duration = parseFloat(opts.duration) || 1;\n            }\n\n            /************************\n               Global Option: Mock\n            ************************/\n\n            if (Velocity.mock !== false) {\n                /* In mock mode, all animations are forced to 1ms so that they occur immediately upon the next rAF tick.\n                   Alternatively, a multiplier can be passed in to time remap all delays and durations. */\n                if (Velocity.mock === true) {\n                    opts.duration = opts.delay = 1;\n                } else {\n                    opts.duration *= parseFloat(Velocity.mock) || 1;\n                    opts.delay *= parseFloat(Velocity.mock) || 1;\n                }\n            }\n\n            /*******************\n               Option: Easing\n            *******************/\n\n            opts.easing = getEasing(opts.easing, opts.duration);\n\n            /**********************\n               Option: Callbacks\n            **********************/\n\n            /* Callbacks must functions. Otherwise, default to null. */\n            if (opts.begin && !Type.isFunction(opts.begin)) {\n                opts.begin = null;\n            }\n\n            if (opts.progress && !Type.isFunction(opts.progress)) {\n                opts.progress = null;\n            }\n\n            if (opts.complete && !Type.isFunction(opts.complete)) {\n                opts.complete = null;\n            }\n\n            /*********************************\n               Option: Display & Visibility\n            *********************************/\n\n            /* Refer to Velocity's documentation (VelocityJS.org/#displayAndVisibility) for a description of the display and visibility options' behavior. */\n            /* Note: We strictly check for undefined instead of falsiness because display accepts an empty string value. */\n            if (opts.display !== undefined && opts.display !== null) {\n                opts.display = opts.display.toString().toLowerCase();\n\n                /* Users can pass in a special \"auto\" value to instruct Velocity to set the element to its default display value. */\n                if (opts.display === \"auto\") {\n                    opts.display = Velocity.CSS.Values.getDisplayType(element);\n                }\n            }\n\n            if (opts.visibility !== undefined && opts.visibility !== null) {\n                opts.visibility = opts.visibility.toString().toLowerCase();\n            }\n\n            /**********************\n               Option: mobileHA\n            **********************/\n\n            /* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack)\n               on animating elements. HA is removed from the element at the completion of its animation. */\n            /* Note: Android Gingerbread doesn't support HA. If a null transform hack (mobileHA) is in fact set, it will prevent other tranform subproperties from taking effect. */\n            /* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */\n            opts.mobileHA = (opts.mobileHA && Velocity.State.isMobile && !Velocity.State.isGingerbread);\n\n            /***********************\n               Part II: Queueing\n            ***********************/\n\n            /* When a set of elements is targeted by a Velocity call, the set is broken up and each element has the current Velocity call individually queued onto it.\n               In this way, each element's existing queue is respected; some elements may already be animating and accordingly should not have this current Velocity call triggered immediately. */\n            /* In each queue, tween data is processed for each animating property then pushed onto the call-wide calls array. When the last element in the set has had its tweens processed,\n               the call array is pushed to Velocity.State.calls for live processing by the requestAnimationFrame tick. */\n            function buildQueue (next) {\n\n                /*******************\n                   Option: Begin\n                *******************/\n\n                /* The begin callback is fired once per call -- not once per elemenet -- and is passed the full raw DOM element set as both its context and its first argument. */\n                if (opts.begin && elementsIndex === 0) {\n                    /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */\n                    try {\n                        opts.begin.call(elements, elements);\n                    } catch (error) {\n                        setTimeout(function() { throw error; }, 1);\n                    }\n                }\n\n                /*****************************************\n                   Tween Data Construction (for Scroll)\n                *****************************************/\n\n                /* Note: In order to be subjected to chaining and animation options, scroll's tweening is routed through Velocity as if it were a standard CSS property animation. */\n                if (action === \"scroll\") {\n                    /* The scroll action uniquely takes an optional \"offset\" option -- specified in pixels -- that offsets the targeted scroll position. */\n                    var scrollDirection = (/^x$/i.test(opts.axis) ? \"Left\" : \"Top\"),\n                        scrollOffset = parseFloat(opts.offset) || 0,\n                        scrollPositionCurrent,\n                        scrollPositionCurrentAlternate,\n                        scrollPositionEnd;\n\n                    /* Scroll also uniquely takes an optional \"container\" option, which indicates the parent element that should be scrolled --\n                       as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */\n                    if (opts.container) {\n                        /* Ensure that either a jQuery object or a raw DOM element was passed in. */\n                        if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) {\n                            /* Extract the raw DOM element from the jQuery wrapper. */\n                            opts.container = opts.container[0] || opts.container;\n                            /* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes\n                               (due to the user's natural interaction with the page). */\n                            scrollPositionCurrent = opts.container[\"scroll\" + scrollDirection]; /* GET */\n\n                            /* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions\n                               -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and*\n                               the scroll container's current scroll position. */\n                            scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; /* GET */\n                        /* If a value other than a jQuery object or a raw DOM element was passed in, default to null so that this option is ignored. */\n                        } else {\n                            opts.container = null;\n                        }\n                    } else {\n                        /* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using\n                           the appropriate cached property names (which differ based on browser type). */\n                        scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State[\"scrollProperty\" + scrollDirection]]; /* GET */\n                        /* When scrolling the browser window, cache the alternate axis's current value since window.scrollTo() doesn't let us change only one value at a time. */\n                        scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State[\"scrollProperty\" + (scrollDirection === \"Left\" ? \"Top\" : \"Left\")]]; /* GET */\n\n                        /* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area --\n                           and therefore end values do not need to be compounded onto current values. */\n                        scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */\n                    }\n\n                    /* Since there's only one format that scroll's associated tweensContainer can take, we create it manually. */\n                    tweensContainer = {\n                        scroll: {\n                            rootPropertyValue: false,\n                            startValue: scrollPositionCurrent,\n                            currentValue: scrollPositionCurrent,\n                            endValue: scrollPositionEnd,\n                            unitType: \"\",\n                            easing: opts.easing,\n                            scrollData: {\n                                container: opts.container,\n                                direction: scrollDirection,\n                                alternateValue: scrollPositionCurrentAlternate\n                            }\n                        },\n                        element: element\n                    };\n\n                    if (Velocity.debug) console.log(\"tweensContainer (scroll): \", tweensContainer.scroll, element);\n\n                /******************************************\n                   Tween Data Construction (for Reverse)\n                ******************************************/\n\n                /* Reverse acts like a \"start\" action in that a property map is animated toward. The only difference is\n                   that the property map used for reverse is the inverse of the map used in the previous call. Thus, we manipulate\n                   the previous call to construct our new map: use the previous map's end values as our new map's start values. Copy over all other data. */\n                /* Note: Reverse can be directly called via the \"reverse\" parameter, or it can be indirectly triggered via the loop option. (Loops are composed of multiple reverses.) */\n                /* Note: Reverse calls do not need to be consecutively chained onto a currently-animating element in order to operate on cached values;\n                   there is no harm to reverse being called on a potentially stale data cache since reverse's behavior is simply defined\n                   as reverting to the element's values as they were prior to the previous *Velocity* call. */\n                } else if (action === \"reverse\") {\n                    /* Abort if there is no prior animation data to reverse to. */\n                    if (!Data(element).tweensContainer) {\n                        /* Dequeue the element so that this queue entry releases itself immediately, allowing subsequent queue entries to run. */\n                        $.dequeue(element, opts.queue);\n\n                        return;\n                    } else {\n                        /*********************\n                           Options Parsing\n                        *********************/\n\n                        /* If the element was hidden via the display option in the previous call,\n                           revert display to \"auto\" prior to reversal so that the element is visible again. */\n                        if (Data(element).opts.display === \"none\") {\n                            Data(element).opts.display = \"auto\";\n                        }\n\n                        if (Data(element).opts.visibility === \"hidden\") {\n                            Data(element).opts.visibility = \"visible\";\n                        }\n\n                        /* If the loop option was set in the previous call, disable it so that \"reverse\" calls aren't recursively generated.\n                           Further, remove the previous call's callback options; typically, users do not want these to be refired. */\n                        Data(element).opts.loop = false;\n                        Data(element).opts.begin = null;\n                        Data(element).opts.complete = null;\n\n                        /* Since we're extending an opts object that has already been extended with the defaults options object,\n                           we remove non-explicitly-defined properties that are auto-assigned values. */\n                        if (!options.easing) {\n                            delete opts.easing;\n                        }\n\n                        if (!options.duration) {\n                            delete opts.duration;\n                        }\n\n                        /* The opts object used for reversal is an extension of the options object optionally passed into this\n                           reverse call plus the options used in the previous Velocity call. */\n                        opts = $.extend({}, Data(element).opts, opts);\n\n                        /*************************************\n                           Tweens Container Reconstruction\n                        *************************************/\n\n                        /* Create a deepy copy (indicated via the true flag) of the previous call's tweensContainer. */\n                        var lastTweensContainer = $.extend(true, {}, Data(element).tweensContainer);\n\n                        /* Manipulate the previous tweensContainer by replacing its end values and currentValues with its start values. */\n                        for (var lastTween in lastTweensContainer) {\n                            /* In addition to tween data, tweensContainers contain an element property that we ignore here. */\n                            if (lastTween !== \"element\") {\n                                var lastStartValue = lastTweensContainer[lastTween].startValue;\n\n                                lastTweensContainer[lastTween].startValue = lastTweensContainer[lastTween].currentValue = lastTweensContainer[lastTween].endValue;\n                                lastTweensContainer[lastTween].endValue = lastStartValue;\n\n                                /* Easing is the only option that embeds into the individual tween data (since it can be defined on a per-property basis).\n                                   Accordingly, every property's easing value must be updated when an options object is passed in with a reverse call.\n                                   The side effect of this extensibility is that all per-property easing values are forcefully reset to the new value. */\n                                if (!Type.isEmptyObject(options)) {\n                                    lastTweensContainer[lastTween].easing = opts.easing;\n                                }\n\n                                if (Velocity.debug) console.log(\"reverse tweensContainer (\" + lastTween + \"): \" + JSON.stringify(lastTweensContainer[lastTween]), element);\n                            }\n                        }\n\n                        tweensContainer = lastTweensContainer;\n                    }\n\n                /*****************************************\n                   Tween Data Construction (for Start)\n                *****************************************/\n\n                } else if (action === \"start\") {\n\n                    /*************************\n                        Value Transferring\n                    *************************/\n\n                    /* If this queue entry follows a previous Velocity-initiated queue entry *and* if this entry was created\n                       while the element was in the process of being animated by Velocity, then this current call is safe to use\n                       the end values from the prior call as its start values. Velocity attempts to perform this value transfer\n                       process whenever possible in order to avoid requerying the DOM. */\n                    /* If values aren't transferred from a prior call and start values were not forcefed by the user (more on this below),\n                       then the DOM is queried for the element's current values as a last resort. */\n                    /* Note: Conversely, animation reversal (and looping) *always* perform inter-call value transfers; they never requery the DOM. */\n                    var lastTweensContainer;\n\n                    /* The per-element isAnimating flag is used to indicate whether it's safe (i.e. the data isn't stale)\n                       to transfer over end values to use as start values. If it's set to true and there is a previous\n                       Velocity call to pull values from, do so. */\n                    if (Data(element).tweensContainer && Data(element).isAnimating === true) {\n                        lastTweensContainer = Data(element).tweensContainer;\n                    }\n\n                    /***************************\n                       Tween Data Calculation\n                    ***************************/\n\n                    /* This function parses property data and defaults endValue, easing, and startValue as appropriate. */\n                    /* Property map values can either take the form of 1) a single value representing the end value,\n                       or 2) an array in the form of [ endValue, [, easing] [, startValue] ].\n                       The optional third parameter is a forcefed startValue to be used instead of querying the DOM for\n                       the element's current value. Read Velocity's docmentation to learn more about forcefeeding: VelocityJS.org/#forcefeeding */\n                    function parsePropertyValue (valueData, skipResolvingEasing) {\n                        var endValue = undefined,\n                            easing = undefined,\n                            startValue = undefined;\n\n                        /* Handle the array format, which can be structured as one of three potential overloads:\n                           A) [ endValue, easing, startValue ], B) [ endValue, easing ], or C) [ endValue, startValue ] */\n                        if (Type.isArray(valueData)) {\n                            /* endValue is always the first item in the array. Don't bother validating endValue's value now\n                               since the ensuing property cycling logic does that. */\n                            endValue = valueData[0];\n\n                            /* Two-item array format: If the second item is a number, function, or hex string, treat it as a\n                               start value since easings can only be non-hex strings or arrays. */\n                            if ((!Type.isArray(valueData[1]) && /^[\\d-]/.test(valueData[1])) || Type.isFunction(valueData[1]) || CSS.RegEx.isHex.test(valueData[1])) {\n                                startValue = valueData[1];\n                            /* Two or three-item array: If the second item is a non-hex string or an array, treat it as an easing. */\n                            } else if ((Type.isString(valueData[1]) && !CSS.RegEx.isHex.test(valueData[1])) || Type.isArray(valueData[1])) {\n                                easing = skipResolvingEasing ? valueData[1] : getEasing(valueData[1], opts.duration);\n\n                                /* Don't bother validating startValue's value now since the ensuing property cycling logic inherently does that. */\n                                if (valueData[2] !== undefined) {\n                                    startValue = valueData[2];\n                                }\n                            }\n                        /* Handle the single-value format. */\n                        } else {\n                            endValue = valueData;\n                        }\n\n                        /* Default to the call's easing if a per-property easing type was not defined. */\n                        if (!skipResolvingEasing) {\n                            easing = easing || opts.easing;\n                        }\n\n                        /* If functions were passed in as values, pass the function the current element as its context,\n                           plus the element's index and the element set's size as arguments. Then, assign the returned value. */\n                        if (Type.isFunction(endValue)) {\n                            endValue = endValue.call(element, elementsIndex, elementsLength);\n                        }\n\n                        if (Type.isFunction(startValue)) {\n                            startValue = startValue.call(element, elementsIndex, elementsLength);\n                        }\n\n                        /* Allow startValue to be left as undefined to indicate to the ensuing code that its value was not forcefed. */\n                        return [ endValue || 0, easing, startValue ];\n                    }\n\n                    /* Cycle through each property in the map, looking for shorthand color properties (e.g. \"color\" as opposed to \"colorRed\"). Inject the corresponding\n                       colorRed, colorGreen, and colorBlue RGB component tweens into the propertiesMap (which Velocity understands) and remove the shorthand property. */\n                    $.each(propertiesMap, function(property, value) {\n                        /* Find shorthand color properties that have been passed a hex string. */\n                        if (RegExp(\"^\" + CSS.Lists.colors.join(\"$|^\") + \"$\").test(property)) {\n                            /* Parse the value data for each shorthand. */\n                            var valueData = parsePropertyValue(value, true),\n                                endValue = valueData[0],\n                                easing = valueData[1],\n                                startValue = valueData[2];\n\n                            if (CSS.RegEx.isHex.test(endValue)) {\n                                /* Convert the hex strings into their RGB component arrays. */\n                                var colorComponents = [ \"Red\", \"Green\", \"Blue\" ],\n                                    endValueRGB = CSS.Values.hexToRgb(endValue),\n                                    startValueRGB = startValue ? CSS.Values.hexToRgb(startValue) : undefined;\n\n                                /* Inject the RGB component tweens into propertiesMap. */\n                                for (var i = 0; i < colorComponents.length; i++) {\n                                    var dataArray = [ endValueRGB[i] ];\n\n                                    if (easing) {\n                                        dataArray.push(easing);\n                                    }\n\n                                    if (startValueRGB !== undefined) {\n                                        dataArray.push(startValueRGB[i]);\n                                    }\n\n                                    propertiesMap[property + colorComponents[i]] = dataArray;\n                                }\n\n                                /* Remove the intermediary shorthand property entry now that we've processed it. */\n                                delete propertiesMap[property];\n                            }\n                        }\n                    });\n\n                    /* Create a tween out of each property, and append its associated data to tweensContainer. */\n                    for (var property in propertiesMap) {\n\n                        /**************************\n                           Start Value Sourcing\n                        **************************/\n\n                        /* Parse out endValue, easing, and startValue from the property's data. */\n                        var valueData = parsePropertyValue(propertiesMap[property]),\n                            endValue = valueData[0],\n                            easing = valueData[1],\n                            startValue = valueData[2];\n\n                        /* Now that the original property name's format has been used for the parsePropertyValue() lookup above,\n                           we force the property to its camelCase styling to normalize it for manipulation. */\n                        property = CSS.Names.camelCase(property);\n\n                        /* In case this property is a hook, there are circumstances where we will intend to work on the hook's root property and not the hooked subproperty. */\n                        var rootProperty = CSS.Hooks.getRoot(property),\n                            rootPropertyValue = false;\n\n                        /* Other than for the dummy tween property, properties that are not supported by the browser (and do not have an associated normalization) will\n                           inherently produce no style changes when set, so they are skipped in order to decrease animation tick overhead.\n                           Property support is determined via prefixCheck(), which returns a false flag when no supported is detected. */\n                        /* Note: Since SVG elements have some of their properties directly applied as HTML attributes,\n                           there is no way to check for their explicit browser support, and so we skip skip this check for them. */\n                        if (!Data(element).isSVG && rootProperty !== \"tween\" && CSS.Names.prefixCheck(rootProperty)[1] === false && CSS.Normalizations.registered[rootProperty] === undefined) {\n                            if (Velocity.debug) console.log(\"Skipping [\" + rootProperty + \"] due to a lack of browser support.\");\n\n                            continue;\n                        }\n\n                        /* If the display option is being set to a non-\"none\" (e.g. \"block\") and opacity (filter on IE<=8) is being\n                           animated to an endValue of non-zero, the user's intention is to fade in from invisible, thus we forcefeed opacity\n                           a startValue of 0 if its startValue hasn't already been sourced by value transferring or prior forcefeeding. */\n                        if (((opts.display !== undefined && opts.display !== null && opts.display !== \"none\") || (opts.visibility !== undefined && opts.visibility !== \"hidden\")) && /opacity|filter/.test(property) && !startValue && endValue !== 0) {\n                            startValue = 0;\n                        }\n\n                        /* If values have been transferred from the previous Velocity call, extract the endValue and rootPropertyValue\n                           for all of the current call's properties that were *also* animated in the previous call. */\n                        /* Note: Value transferring can optionally be disabled by the user via the _cacheValues option. */\n                        if (opts._cacheValues && lastTweensContainer && lastTweensContainer[property]) {\n                            if (startValue === undefined) {\n                                startValue = lastTweensContainer[property].endValue + lastTweensContainer[property].unitType;\n                            }\n\n                            /* The previous call's rootPropertyValue is extracted from the element's data cache since that's the\n                               instance of rootPropertyValue that gets freshly updated by the tweening process, whereas the rootPropertyValue\n                               attached to the incoming lastTweensContainer is equal to the root property's value prior to any tweening. */\n                            rootPropertyValue = Data(element).rootPropertyValueCache[rootProperty];\n                        /* If values were not transferred from a previous Velocity call, query the DOM as needed. */\n                        } else {\n                            /* Handle hooked properties. */\n                            if (CSS.Hooks.registered[property]) {\n                               if (startValue === undefined) {\n                                    rootPropertyValue = CSS.getPropertyValue(element, rootProperty); /* GET */\n                                    /* Note: The following getPropertyValue() call does not actually trigger a DOM query;\n                                       getPropertyValue() will extract the hook from rootPropertyValue. */\n                                    startValue = CSS.getPropertyValue(element, property, rootPropertyValue);\n                                /* If startValue is already defined via forcefeeding, do not query the DOM for the root property's value;\n                                   just grab rootProperty's zero-value template from CSS.Hooks. This overwrites the element's actual\n                                   root property value (if one is set), but this is acceptable since the primary reason users forcefeed is\n                                   to avoid DOM queries, and thus we likewise avoid querying the DOM for the root property's value. */\n                                } else {\n                                    /* Grab this hook's zero-value template, e.g. \"0px 0px 0px black\". */\n                                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];\n                                }\n                            /* Handle non-hooked properties that haven't already been defined via forcefeeding. */\n                            } else if (startValue === undefined) {\n                                startValue = CSS.getPropertyValue(element, property); /* GET */\n                            }\n                        }\n\n                        /**************************\n                           Value Data Extraction\n                        **************************/\n\n                        var separatedValue,\n                            endValueUnitType,\n                            startValueUnitType,\n                            operator = false;\n\n                        /* Separates a property value into its numeric value and its unit type. */\n                        function separateValue (property, value) {\n                            var unitType,\n                                numericValue;\n\n                            numericValue = (value || \"0\")\n                                .toString()\n                                .toLowerCase()\n                                /* Match the unit type at the end of the value. */\n                                .replace(/[%A-z]+$/, function(match) {\n                                    /* Grab the unit type. */\n                                    unitType = match;\n\n                                    /* Strip the unit type off of value. */\n                                    return \"\";\n                                });\n\n                            /* If no unit type was supplied, assign one that is appropriate for this property (e.g. \"deg\" for rotateZ or \"px\" for width). */\n                            if (!unitType) {\n                                unitType = CSS.Values.getUnitType(property);\n                            }\n\n                            return [ numericValue, unitType ];\n                        }\n\n                        /* Separate startValue. */\n                        separatedValue = separateValue(property, startValue);\n                        startValue = separatedValue[0];\n                        startValueUnitType = separatedValue[1];\n\n                        /* Separate endValue, and extract a value operator (e.g. \"+=\", \"-=\") if one exists. */\n                        separatedValue = separateValue(property, endValue);\n                        endValue = separatedValue[0].replace(/^([+-\\/*])=/, function(match, subMatch) {\n                            operator = subMatch;\n\n                            /* Strip the operator off of the value. */\n                            return \"\";\n                        });\n                        endValueUnitType = separatedValue[1];\n\n                        /* Parse float values from endValue and startValue. Default to 0 if NaN is returned. */\n                        startValue = parseFloat(startValue) || 0;\n                        endValue = parseFloat(endValue) || 0;\n\n                        /***************************************\n                           Property-Specific Value Conversion\n                        ***************************************/\n\n                        /* Custom support for properties that don't actually accept the % unit type, but where pollyfilling is trivial and relatively foolproof. */\n                        if (endValueUnitType === \"%\") {\n                            /* A %-value fontSize/lineHeight is relative to the parent's fontSize (as opposed to the parent's dimensions),\n                               which is identical to the em unit's behavior, so we piggyback off of that. */\n                            if (/^(fontSize|lineHeight)$/.test(property)) {\n                                /* Convert % into an em decimal value. */\n                                endValue = endValue / 100;\n                                endValueUnitType = \"em\";\n                            /* For scaleX and scaleY, convert the value into its decimal format and strip off the unit type. */\n                            } else if (/^scale/.test(property)) {\n                                endValue = endValue / 100;\n                                endValueUnitType = \"\";\n                            /* For RGB components, take the defined percentage of 255 and strip off the unit type. */\n                            } else if (/(Red|Green|Blue)$/i.test(property)) {\n                                endValue = (endValue / 100) * 255;\n                                endValueUnitType = \"\";\n                            }\n                        }\n\n                        /***************************\n                           Unit Ratio Calculation\n                        ***************************/\n\n                        /* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of\n                           %, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order\n                           for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred\n                           from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:\n                           1) Calculating the ratio of %/em/rem/vh/vw relative to pixels\n                           2) Converting startValue into the same unit of measurement as endValue based on these ratios. */\n                        /* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,\n                           setting values with the target unit type then comparing the returned pixel value. */\n                        /* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead\n                           of batching the SETs and GETs together upfront outweights the potential overhead\n                           of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */\n                        /* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */\n                        function calculateUnitRatios () {\n\n                            /************************\n                                Same Ratio Checks\n                            ************************/\n\n                            /* The properties below are used to determine whether the element differs sufficiently from this call's\n                               previously iterated element to also differ in its unit conversion ratios. If the properties match up with those\n                               of the prior element, the prior element's conversion ratios are used. Like most optimizations in Velocity,\n                               this is done to minimize DOM querying. */\n                            var sameRatioIndicators = {\n                                    myParent: element.parentNode || document.body, /* GET */\n                                    position: CSS.getPropertyValue(element, \"position\"), /* GET */\n                                    fontSize: CSS.getPropertyValue(element, \"fontSize\") /* GET */\n                                },\n                                /* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */\n                                samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent)),\n                                /* Determine if the same em ratio can be used. em is relative to the element's fontSize. */\n                                sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);\n\n                            /* Store these ratio indicators call-wide for the next element to compare against. */\n                            callUnitConversionData.lastParent = sameRatioIndicators.myParent;\n                            callUnitConversionData.lastPosition = sameRatioIndicators.position;\n                            callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;\n\n                            /***************************\n                               Element-Specific Units\n                            ***************************/\n\n                            /* Note: IE8 rounds to the nearest pixel when returning CSS values, thus we perform conversions using a measurement\n                               of 100 (instead of 1) to give our ratios a precision of at least 2 decimal values. */\n                            var measurement = 100,\n                                unitRatios = {};\n\n                            if (!sameEmRatio || !samePercentRatio) {\n                                var dummy = Data(element).isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\") : document.createElement(\"div\");\n\n                                Velocity.init(dummy);\n                                sameRatioIndicators.myParent.appendChild(dummy);\n\n                                /* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.\n                                   Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */\n                                /* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */\n                                $.each([ \"overflow\", \"overflowX\", \"overflowY\" ], function(i, property) {\n                                    Velocity.CSS.setPropertyValue(dummy, property, \"hidden\");\n                                });\n                                Velocity.CSS.setPropertyValue(dummy, \"position\", sameRatioIndicators.position);\n                                Velocity.CSS.setPropertyValue(dummy, \"fontSize\", sameRatioIndicators.fontSize);\n                                Velocity.CSS.setPropertyValue(dummy, \"boxSizing\", \"content-box\");\n\n                                /* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */\n                                $.each([ \"minWidth\", \"maxWidth\", \"width\", \"minHeight\", \"maxHeight\", \"height\" ], function(i, property) {\n                                    Velocity.CSS.setPropertyValue(dummy, property, measurement + \"%\");\n                                });\n                                /* paddingLeft arbitrarily acts as our proxy property for the em ratio. */\n                                Velocity.CSS.setPropertyValue(dummy, \"paddingLeft\", measurement + \"em\");\n\n                                /* Divide the returned value by the measurement to get the ratio between 1% and 1px. Default to 1 since working with 0 can produce Infinite. */\n                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, \"width\", null, true)) || 1) / measurement; /* GET */\n                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, \"height\", null, true)) || 1) / measurement; /* GET */\n                                unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, \"paddingLeft\")) || 1) / measurement; /* GET */\n\n                                sameRatioIndicators.myParent.removeChild(dummy);\n                            } else {\n                                unitRatios.emToPx = callUnitConversionData.lastEmToPx;\n                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;\n                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;\n                            }\n\n                            /***************************\n                               Element-Agnostic Units\n                            ***************************/\n\n                            /* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked\n                               once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time\n                               that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,\n                               so we calculate it now. */\n                            if (callUnitConversionData.remToPx === null) {\n                                /* Default to browsers' default fontSize of 16px in the case of 0. */\n                                callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, \"fontSize\")) || 16; /* GET */\n                            }\n\n                            /* Similarly, viewport units are %-relative to the window's inner dimensions. */\n                            if (callUnitConversionData.vwToPx === null) {\n                                callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */\n                                callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */\n                            }\n\n                            unitRatios.remToPx = callUnitConversionData.remToPx;\n                            unitRatios.vwToPx = callUnitConversionData.vwToPx;\n                            unitRatios.vhToPx = callUnitConversionData.vhToPx;\n\n                            if (Velocity.debug >= 1) console.log(\"Unit ratios: \" + JSON.stringify(unitRatios), element);\n\n                            return unitRatios;\n                        }\n\n                        /********************\n                           Unit Conversion\n                        ********************/\n\n                        /* The * and / operators, which are not passed in with an associated unit, inherently use startValue's unit. Skip value and unit conversion. */\n                        if (/[\\/*]/.test(operator)) {\n                            endValueUnitType = startValueUnitType;\n                        /* If startValue and endValue differ in unit type, convert startValue into the same unit type as endValue so that if endValueUnitType\n                           is a relative unit (%, em, rem), the values set during tweening will continue to be accurately relative even if the metrics they depend\n                           on are dynamically changing during the course of the animation. Conversely, if we always normalized into px and used px for setting values, the px ratio\n                           would become stale if the original unit being animated toward was relative and the underlying metrics change during the animation. */\n                        /* Since 0 is 0 in any unit type, no conversion is necessary when startValue is 0 -- we just start at 0 with endValueUnitType. */\n                        } else if ((startValueUnitType !== endValueUnitType) && startValue !== 0) {\n                            /* Unit conversion is also skipped when endValue is 0, but *startValueUnitType* must be used for tween values to remain accurate. */\n                            /* Note: Skipping unit conversion here means that if endValueUnitType was originally a relative unit, the animation won't relatively\n                               match the underlying metrics if they change, but this is acceptable since we're animating toward invisibility instead of toward visibility,\n                               which remains past the point of the animation's completion. */\n                            if (endValue === 0) {\n                                endValueUnitType = startValueUnitType;\n                            } else {\n                                /* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).\n                                   If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */\n                                elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();\n\n                                /* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */\n                                /* Note: W3C spec mandates that all of margin and padding's properties (even top and bottom) are %-relative to the *width* of the parent element. */\n                                var axis = (/margin|padding|left|right|width|text|word|letter/i.test(property) || /X$/.test(property) || property === \"x\") ? \"x\" : \"y\";\n\n                                /* In order to avoid generating n^2 bespoke conversion functions, unit conversion is a two-step process:\n                                   1) Convert startValue into pixels. 2) Convert this new pixel value into endValue's unit type. */\n                                switch (startValueUnitType) {\n                                    case \"%\":\n                                        /* Note: translateX and translateY are the only properties that are %-relative to an element's own dimensions -- not its parent's dimensions.\n                                           Velocity does not include a special conversion process to account for this behavior. Therefore, animating translateX/Y from a % value\n                                           to a non-% value will produce an incorrect start value. Fortunately, this sort of cross-unit conversion is rarely done by users in practice. */\n                                        startValue *= (axis === \"x\" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);\n                                        break;\n\n                                    case \"px\":\n                                        /* px acts as our midpoint in the unit conversion process; do nothing. */\n                                        break;\n\n                                    default:\n                                        startValue *= elementUnitConversionData[startValueUnitType + \"ToPx\"];\n                                }\n\n                                /* Invert the px ratios to convert into to the target unit. */\n                                switch (endValueUnitType) {\n                                    case \"%\":\n                                        startValue *= 1 / (axis === \"x\" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);\n                                        break;\n\n                                    case \"px\":\n                                        /* startValue is already in px, do nothing; we're done. */\n                                        break;\n\n                                    default:\n                                        startValue *= 1 / elementUnitConversionData[endValueUnitType + \"ToPx\"];\n                                }\n                            }\n                        }\n\n                        /*********************\n                           Relative Values\n                        *********************/\n\n                        /* Operator logic must be performed last since it requires unit-normalized start and end values. */\n                        /* Note: Relative *percent values* do not behave how most people think; while one would expect \"+=50%\"\n                           to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms:\n                           50 points is added on top of the current % value. */\n                        switch (operator) {\n                            case \"+\":\n                                endValue = startValue + endValue;\n                                break;\n\n                            case \"-\":\n                                endValue = startValue - endValue;\n                                break;\n\n                            case \"*\":\n                                endValue = startValue * endValue;\n                                break;\n\n                            case \"/\":\n                                endValue = startValue / endValue;\n                                break;\n                        }\n\n                        /**************************\n                           tweensContainer Push\n                        **************************/\n\n                        /* Construct the per-property tween object, and push it to the element's tweensContainer. */\n                        tweensContainer[property] = {\n                            rootPropertyValue: rootPropertyValue,\n                            startValue: startValue,\n                            currentValue: startValue,\n                            endValue: endValue,\n                            unitType: endValueUnitType,\n                            easing: easing\n                        };\n\n                        if (Velocity.debug) console.log(\"tweensContainer (\" + property + \"): \" + JSON.stringify(tweensContainer[property]), element);\n                    }\n\n                    /* Along with its property data, store a reference to the element itself onto tweensContainer. */\n                    tweensContainer.element = element;\n                }\n\n                /*****************\n                    Call Push\n                *****************/\n\n                /* Note: tweensContainer can be empty if all of the properties in this call's property map were skipped due to not\n                   being supported by the browser. The element property is used for checking that the tweensContainer has been appended to. */\n                if (tweensContainer.element) {\n                    /* Apply the \"velocity-animating\" indicator class. */\n                    CSS.Values.addClass(element, \"velocity-animating\");\n\n                    /* The call array houses the tweensContainers for each element being animated in the current call. */\n                    call.push(tweensContainer);\n\n                    /* Store the tweensContainer and options if we're working on the default effects queue, so that they can be used by the reverse command. */\n                    if (opts.queue === \"\") {\n                        Data(element).tweensContainer = tweensContainer;\n                        Data(element).opts = opts;\n                    }\n\n                    /* Switch on the element's animating flag. */\n                    Data(element).isAnimating = true;\n\n                    /* Once the final element in this call's element set has been processed, push the call array onto\n                       Velocity.State.calls for the animation tick to immediately begin processing. */\n                    if (elementsIndex === elementsLength - 1) {\n                        /* Add the current call plus its associated metadata (the element set and the call's options) onto the global call container.\n                           Anything on this call container is subjected to tick() processing. */\n                        Velocity.State.calls.push([ call, elements, opts, null, promiseData.resolver ]);\n\n                        /* If the animation tick isn't running, start it. (Velocity shuts it off when there are no active calls to process.) */\n                        if (Velocity.State.isTicking === false) {\n                            Velocity.State.isTicking = true;\n\n                            /* Start the tick loop. */\n                            tick();\n                        }\n                    } else {\n                        elementsIndex++;\n                    }\n                }\n            }\n\n            /* When the queue option is set to false, the call skips the element's queue and fires immediately. */\n            if (opts.queue === false) {\n                /* Since this buildQueue call doesn't respect the element's existing queue (which is where a delay option would have been appended),\n                   we manually inject the delay property here with an explicit setTimeout. */\n                if (opts.delay) {\n                    setTimeout(buildQueue, opts.delay);\n                } else {\n                    buildQueue();\n                }\n            /* Otherwise, the call undergoes element queueing as normal. */\n            /* Note: To interoperate with jQuery, Velocity uses jQuery's own $.queue() stack for queuing logic. */\n            } else {\n                $.queue(element, opts.queue, function(next, clearQueue) {\n                    /* If the clearQueue flag was passed in by the stop command, resolve this call's promise. (Promises can only be resolved once,\n                       so it's fine if this is repeatedly triggered for each element in the associated call.) */\n                    if (clearQueue === true) {\n                        if (promiseData.promise) {\n                            promiseData.resolver(elements);\n                        }\n\n                        /* Do not continue with animation queueing. */\n                        return true;\n                    }\n\n                    /* This flag indicates to the upcoming completeCall() function that this queue entry was initiated by Velocity.\n                       See completeCall() for further details. */\n                    Velocity.velocityQueueEntryFlag = true;\n\n                    buildQueue(next);\n                });\n            }\n\n            /*********************\n                Auto-Dequeuing\n            *********************/\n\n            /* As per jQuery's $.queue() behavior, to fire the first non-custom-queue entry on an element, the element\n               must be dequeued if its queue stack consists *solely* of the current call. (This can be determined by checking\n               for the \"inprogress\" item that jQuery prepends to active queue stack arrays.) Regardless, whenever the element's\n               queue is further appended with additional items -- including $.delay()'s or even $.animate() calls, the queue's\n               first entry is automatically fired. This behavior contrasts that of custom queues, which never auto-fire. */\n            /* Note: When an element set is being subjected to a non-parallel Velocity call, the animation will not begin until\n               each one of the elements in the set has reached the end of its individually pre-existing queue chain. */\n            /* Note: Unfortunately, most people don't fully grasp jQuery's powerful, yet quirky, $.queue() function.\n               Lean more here: http://stackoverflow.com/questions/1058158/can-somebody-explain-jquery-queue-to-me */\n            if ((opts.queue === \"\" || opts.queue === \"fx\") && $.queue(element)[0] !== \"inprogress\") {\n                $.dequeue(element);\n            }\n        }\n\n        /**************************\n           Element Set Iteration\n        **************************/\n\n        /* If the \"nodeType\" property exists on the elements variable, we're animating a single element.\n           Place it in an array so that $.each() can iterate over it. */\n        $.each(elements, function(i, element) {\n            /* Ensure each element in a set has a nodeType (is a real element) to avoid throwing errors. */\n            if (Type.isNode(element)) {\n                processElement.call(element);\n            }\n        });\n\n        /******************\n           Option: Loop\n        ******************/\n\n        /* The loop option accepts an integer indicating how many times the element should loop between the values in the\n           current call's properties map and the element's property values prior to this call. */\n        /* Note: The loop option's logic is performed here -- after element processing -- because the current call needs\n           to undergo its queue insertion prior to the loop option generating its series of constituent \"reverse\" calls,\n           which chain after the current call. Two reverse calls (two \"alternations\") constitute one loop. */\n        var opts = $.extend({}, Velocity.defaults, options),\n            reverseCallsCount;\n\n        opts.loop = parseInt(opts.loop);\n        reverseCallsCount = (opts.loop * 2) - 1;\n\n        if (opts.loop) {\n            /* Double the loop count to convert it into its appropriate number of \"reverse\" calls.\n               Subtract 1 from the resulting value since the current call is included in the total alternation count. */\n            for (var x = 0; x < reverseCallsCount; x++) {\n                /* Since the logic for the reverse action occurs inside Queueing and therefore this call's options object\n                   isn't parsed until then as well, the current call's delay option must be explicitly passed into the reverse\n                   call so that the delay logic that occurs inside *Pre-Queueing* can process it. */\n                var reverseOptions = {\n                    delay: opts.delay,\n                    progress: opts.progress\n                };\n\n                /* If a complete callback was passed into this call, transfer it to the loop redirect's final \"reverse\" call\n                   so that it's triggered when the entire redirect is complete (and not when the very first animation is complete). */\n                if (x === reverseCallsCount - 1) {\n                    reverseOptions.display = opts.display;\n                    reverseOptions.visibility = opts.visibility;\n                    reverseOptions.complete = opts.complete;\n                }\n\n                animate(elements, \"reverse\", reverseOptions);\n            }\n        }\n\n        /***************\n            Chaining\n        ***************/\n\n        /* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */\n        return getChain();\n    };\n\n    /* Turn Velocity into the animation function, extended with the pre-existing Velocity object. */\n    Velocity = $.extend(animate, Velocity);\n    /* For legacy support, also expose the literal animate method. */\n    Velocity.animate = animate;\n\n    /**************\n        Timing\n    **************/\n\n    /* Ticker function. */\n    var ticker = window.requestAnimationFrame || rAFShim;\n\n    /* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses.\n       To get around this, we dynamically switch rAF to setTimeout (which the browser *doesn't* pause) when the tab loses focus. We skip this for mobile\n       devices to avoid wasting battery power on inactive tabs. */\n    /* Note: Tab focus detection doesn't work on older versions of IE, but that's okay since they don't support rAF to begin with. */\n    if (!Velocity.State.isMobile && document.hidden !== undefined) {\n        document.addEventListener(\"visibilitychange\", function() {\n            /* Reassign the rAF function (which the global tick() function uses) based on the tab's focus state. */\n            if (document.hidden) {\n                ticker = function(callback) {\n                    /* The tick function needs a truthy first argument in order to pass its internal timestamp check. */\n                    return setTimeout(function() { callback(true) }, 16);\n                };\n\n                /* The rAF loop has been paused by the browser, so we manually restart the tick. */\n                tick();\n            } else {\n                ticker = window.requestAnimationFrame || rAFShim;\n            }\n        });\n    }\n\n    /************\n        Tick\n    ************/\n\n    /* Note: All calls to Velocity are pushed to the Velocity.State.calls array, which is fully iterated through upon each tick. */\n    function tick (timestamp) {\n        /* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on.\n           We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever\n           the browser's next tick sync time occurs, which results in the first elements subjected to Velocity\n           calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore\n           the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated\n           by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */\n        if (timestamp) {\n            /* We ignore RAF's high resolution timestamp since it can be significantly offset when the browser is\n               under high stress; we opt for choppiness over allowing the browser to drop huge chunks of frames. */\n            var timeCurrent = (new Date).getTime();\n\n            /********************\n               Call Iteration\n            ********************/\n\n            var callsLength = Velocity.State.calls.length;\n\n            /* To speed up iterating over this array, it is compacted (falsey items -- calls that have completed -- are removed)\n               when its length has ballooned to a point that can impact tick performance. This only becomes necessary when animation\n               has been continuous with many elements over a long period of time; whenever all active calls are completed, completeCall() clears Velocity.State.calls. */\n            if (callsLength > 10000) {\n                Velocity.State.calls = compactSparseArray(Velocity.State.calls);\n            }\n\n            /* Iterate through each active call. */\n            for (var i = 0; i < callsLength; i++) {\n                /* When a Velocity call is completed, its Velocity.State.calls entry is set to false. Continue on to the next call. */\n                if (!Velocity.State.calls[i]) {\n                    continue;\n                }\n\n                /************************\n                   Call-Wide Variables\n                ************************/\n\n                var callContainer = Velocity.State.calls[i],\n                    call = callContainer[0],\n                    opts = callContainer[2],\n                    timeStart = callContainer[3],\n                    firstTick = !!timeStart,\n                    tweenDummyValue = null;\n\n                /* If timeStart is undefined, then this is the first time that this call has been processed by tick().\n                   We assign timeStart now so that its value is as close to the real animation start time as possible.\n                   (Conversely, had timeStart been defined when this call was added to Velocity.State.calls, the delay\n                   between that time and now would cause the first few frames of the tween to be skipped since\n                   percentComplete is calculated relative to timeStart.) */\n                /* Further, subtract 16ms (the approximate resolution of RAF) from the current time value so that the\n                   first tick iteration isn't wasted by animating at 0% tween completion, which would produce the\n                   same style value as the element's current value. */\n                if (!timeStart) {\n                    timeStart = Velocity.State.calls[i][3] = timeCurrent - 16;\n                }\n\n                /* The tween's completion percentage is relative to the tween's start time, not the tween's start value\n                   (which would result in unpredictable tween durations since JavaScript's timers are not particularly accurate).\n                   Accordingly, we ensure that percentComplete does not exceed 1. */\n                var percentComplete = Math.min((timeCurrent - timeStart) / opts.duration, 1);\n\n                /**********************\n                   Element Iteration\n                **********************/\n\n                /* For every call, iterate through each of the elements in its set. */\n                for (var j = 0, callLength = call.length; j < callLength; j++) {\n                    var tweensContainer = call[j],\n                        element = tweensContainer.element;\n\n                    /* Check to see if this element has been deleted midway through the animation by checking for the\n                       continued existence of its data cache. If it's gone, skip animating this element. */\n                    if (!Data(element)) {\n                        continue;\n                    }\n\n                    var transformPropertyExists = false;\n\n                    /**********************************\n                       Display & Visibility Toggling\n                    **********************************/\n\n                    /* If the display option is set to non-\"none\", set it upfront so that the element can become visible before tweening begins.\n                       (Otherwise, display's \"none\" value is set in completeCall() once the animation has completed.) */\n                    if (opts.display !== undefined && opts.display !== null && opts.display !== \"none\") {\n                        if (opts.display === \"flex\") {\n                            var flexValues = [ \"-webkit-box\", \"-moz-box\", \"-ms-flexbox\", \"-webkit-flex\" ];\n\n                            $.each(flexValues, function(i, flexValue) {\n                                CSS.setPropertyValue(element, \"display\", flexValue);\n                            });\n                        }\n\n                        CSS.setPropertyValue(element, \"display\", opts.display);\n                    }\n\n                    /* Same goes with the visibility option, but its \"none\" equivalent is \"hidden\". */\n                    if (opts.visibility !== undefined && opts.visibility !== \"hidden\") {\n                        CSS.setPropertyValue(element, \"visibility\", opts.visibility);\n                    }\n\n                    /************************\n                       Property Iteration\n                    ************************/\n\n                    /* For every element, iterate through each property. */\n                    for (var property in tweensContainer) {\n                        /* Note: In addition to property tween data, tweensContainer contains a reference to its associated element. */\n                        if (property !== \"element\") {\n                            var tween = tweensContainer[property],\n                                currentValue,\n                                /* Easing can either be a pre-genereated function or a string that references a pre-registered easing\n                                   on the Velocity.Easings object. In either case, return the appropriate easing *function*. */\n                                easing = Type.isString(tween.easing) ? Velocity.Easings[tween.easing] : tween.easing;\n\n                            /******************************\n                               Current Value Calculation\n                            ******************************/\n\n                            /* If this is the last tick pass (if we've reached 100% completion for this tween),\n                               ensure that currentValue is explicitly set to its target endValue so that it's not subjected to any rounding. */\n                            if (percentComplete === 1) {\n                                currentValue = tween.endValue;\n                            /* Otherwise, calculate currentValue based on the current delta from startValue. */\n                            } else {\n                                var tweenDelta = tween.endValue - tween.startValue;\n                                currentValue = tween.startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));\n\n                                /* If no value change is occurring, don't proceed with DOM updating. */\n                                if (!firstTick && (currentValue === tween.currentValue)) {\n                                    continue;\n                                }\n                            }\n\n                            tween.currentValue = currentValue;\n\n                            /* If we're tweening a fake 'tween' property in order to log transition values, update the one-per-call variable so that\n                               it can be passed into the progress callback. */ \n                            if (property === \"tween\") {\n                                tweenDummyValue = currentValue;\n                            } else {\n                                /******************\n                                   Hooks: Part I\n                                ******************/\n\n                                /* For hooked properties, the newly-updated rootPropertyValueCache is cached onto the element so that it can be used\n                                   for subsequent hooks in this call that are associated with the same root property. If we didn't cache the updated\n                                   rootPropertyValue, each subsequent update to the root property in this tick pass would reset the previous hook's\n                                   updates to rootPropertyValue prior to injection. A nice performance byproduct of rootPropertyValue caching is that\n                                   subsequently chained animations using the same hookRoot but a different hook can use this cached rootPropertyValue. */\n                                if (CSS.Hooks.registered[property]) {\n                                    var hookRoot = CSS.Hooks.getRoot(property),\n                                        rootPropertyValueCache = Data(element).rootPropertyValueCache[hookRoot];\n\n                                    if (rootPropertyValueCache) {\n                                        tween.rootPropertyValue = rootPropertyValueCache;\n                                    }\n                                }\n\n                                /*****************\n                                    DOM Update\n                                *****************/\n\n                                /* setPropertyValue() returns an array of the property name and property value post any normalization that may have been performed. */\n                                /* Note: To solve an IE<=8 positioning bug, the unit type is dropped when setting a property value of 0. */\n                                var adjustedSetData = CSS.setPropertyValue(element, /* SET */\n                                                                           property,\n                                                                           tween.currentValue + (parseFloat(currentValue) === 0 ? \"\" : tween.unitType),\n                                                                           tween.rootPropertyValue,\n                                                                           tween.scrollData);\n\n                                /*******************\n                                   Hooks: Part II\n                                *******************/\n\n                                /* Now that we have the hook's updated rootPropertyValue (the post-processed value provided by adjustedSetData), cache it onto the element. */\n                                if (CSS.Hooks.registered[property]) {\n                                    /* Since adjustedSetData contains normalized data ready for DOM updating, the rootPropertyValue needs to be re-extracted from its normalized form. ?? */\n                                    if (CSS.Normalizations.registered[hookRoot]) {\n                                        Data(element).rootPropertyValueCache[hookRoot] = CSS.Normalizations.registered[hookRoot](\"extract\", null, adjustedSetData[1]);\n                                    } else {\n                                        Data(element).rootPropertyValueCache[hookRoot] = adjustedSetData[1];\n                                    }\n                                }\n\n                                /***************\n                                   Transforms\n                                ***************/\n\n                                /* Flag whether a transform property is being animated so that flushTransformCache() can be triggered once this tick pass is complete. */\n                                if (adjustedSetData[0] === \"transform\") {\n                                    transformPropertyExists = true;\n                                }\n\n                            }\n                        }\n                    }\n\n                    /****************\n                        mobileHA\n                    ****************/\n\n                    /* If mobileHA is enabled, set the translate3d transform to null to force hardware acceleration.\n                       It's safe to override this property since Velocity doesn't actually support its animation (hooks are used in its place). */\n                    if (opts.mobileHA) {\n                        /* Don't set the null transform hack if we've already done so. */\n                        if (Data(element).transformCache.translate3d === undefined) {\n                            /* All entries on the transformCache object are later concatenated into a single transform string via flushTransformCache(). */\n                            Data(element).transformCache.translate3d = \"(0px, 0px, 0px)\";\n\n                            transformPropertyExists = true;\n                        }\n                    }\n\n                    if (transformPropertyExists) {\n                        CSS.flushTransformCache(element);\n                    }\n                }\n\n                /* The non-\"none\" display value is only applied to an element once -- when its associated call is first ticked through.\n                   Accordingly, it's set to false so that it isn't re-processed by this call in the next tick. */\n                if (opts.display !== undefined && opts.display !== \"none\") {\n                    Velocity.State.calls[i][2].display = false;\n                }\n                if (opts.visibility !== undefined && opts.visibility !== \"hidden\") {\n                    Velocity.State.calls[i][2].visibility = false;\n                }\n\n                /* Pass the elements and the timing data (percentComplete, msRemaining, timeStart, tweenDummyValue) into the progress callback. */\n                if (opts.progress) {\n                    opts.progress.call(callContainer[1],\n                                       callContainer[1],\n                                       percentComplete,\n                                       Math.max(0, (timeStart + opts.duration) - timeCurrent),\n                                       timeStart,\n                                       tweenDummyValue);\n                }\n\n                /* If this call has finished tweening, pass its index to completeCall() to handle call cleanup. */\n                if (percentComplete === 1) {\n                    completeCall(i);\n                }\n            }\n        }\n\n        /* Note: completeCall() sets the isTicking flag to false when the last call on Velocity.State.calls has completed. */\n        if (Velocity.State.isTicking) {\n            ticker(tick);\n        }\n    }\n\n    /**********************\n        Call Completion\n    **********************/\n\n    /* Note: Unlike tick(), which processes all active calls at once, call completion is handled on a per-call basis. */\n    function completeCall (callIndex, isStopped) {\n        /* Ensure the call exists. */\n        if (!Velocity.State.calls[callIndex]) {\n            return false;\n        }\n\n        /* Pull the metadata from the call. */\n        var call = Velocity.State.calls[callIndex][0],\n            elements = Velocity.State.calls[callIndex][1],\n            opts = Velocity.State.calls[callIndex][2],\n            resolver = Velocity.State.calls[callIndex][4];\n\n        var remainingCallsExist = false;\n\n        /*************************\n           Element Finalization\n        *************************/\n\n        for (var i = 0, callLength = call.length; i < callLength; i++) {\n            var element = call[i].element;\n\n            /* If the user set display to \"none\" (intending to hide the element), set it now that the animation has completed. */\n            /* Note: display:none isn't set when calls are manually stopped (via Velocity(\"stop\"). */\n            /* Note: Display gets ignored with \"reverse\" calls and infinite loops, since this behavior would be undesirable. */\n            if (!isStopped && !opts.loop) {\n                if (opts.display === \"none\") {\n                    CSS.setPropertyValue(element, \"display\", opts.display);\n                }\n\n                if (opts.visibility === \"hidden\") {\n                    CSS.setPropertyValue(element, \"visibility\", opts.visibility);\n                }\n            }\n\n            /* If the element's queue is empty (if only the \"inprogress\" item is left at position 0) or if its queue is about to run\n               a non-Velocity-initiated entry, turn off the isAnimating flag. A non-Velocity-initiatied queue entry's logic might alter\n               an element's CSS values and thereby cause Velocity's cached value data to go stale. To detect if a queue entry was initiated by Velocity,\n               we check for the existence of our special Velocity.queueEntryFlag declaration, which minifiers won't rename since the flag\n               is assigned to jQuery's global $ object and thus exists out of Velocity's own scope. */\n            if (opts.loop !== true && ($.queue(element)[1] === undefined || !/\\.velocityQueueEntryFlag/i.test($.queue(element)[1]))) {\n                /* The element may have been deleted. Ensure that its data cache still exists before acting on it. */\n                if (Data(element)) {\n                    Data(element).isAnimating = false;\n                    /* Clear the element's rootPropertyValueCache, which will become stale. */\n                    Data(element).rootPropertyValueCache = {};\n\n                    var transformHAPropertyExists = false;\n                    /* If any 3D transform subproperty is at its default value (regardless of unit type), remove it. */\n                    $.each(CSS.Lists.transforms3D, function(i, transformName) {\n                        var defaultValue = /^scale/.test(transformName) ? 1 : 0,\n                            currentValue = Data(element).transformCache[transformName];\n\n                        if (Data(element).transformCache[transformName] !== undefined && new RegExp(\"^\\\\(\" + defaultValue + \"[^.]\").test(currentValue)) {\n                            transformHAPropertyExists = true;\n\n                            delete Data(element).transformCache[transformName];\n                        }\n                    });\n\n                    /* Mobile devices have hardware acceleration removed at the end of the animation in order to avoid hogging the GPU's memory. */\n                    if (opts.mobileHA) {\n                        transformHAPropertyExists = true;\n                        delete Data(element).transformCache.translate3d;\n                    }\n\n                    /* Flush the subproperty removals to the DOM. */\n                    if (transformHAPropertyExists) {\n                        CSS.flushTransformCache(element);\n                    }\n\n                    /* Remove the \"velocity-animating\" indicator class. */\n                    CSS.Values.removeClass(element, \"velocity-animating\");\n                }\n            }\n\n            /*********************\n               Option: Complete\n            *********************/\n\n            /* Complete is fired once per call (not once per element) and is passed the full raw DOM element set as both its context and its first argument. */\n            /* Note: Callbacks aren't fired when calls are manually stopped (via Velocity(\"stop\"). */\n            if (!isStopped && opts.complete && !opts.loop && (i === callLength - 1)) {\n                /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */\n                try {\n                    opts.complete.call(elements, elements);\n                } catch (error) {\n                    setTimeout(function() { throw error; }, 1);\n                }\n            }\n\n            /**********************\n               Promise Resolving\n            **********************/\n\n            /* Note: Infinite loops don't return promises. */\n            if (resolver && opts.loop !== true) {\n                resolver(elements);\n            }\n\n            /****************************\n               Option: Loop (Infinite)\n            ****************************/\n\n            if (Data(element) && opts.loop === true && !isStopped) {\n                /* If a rotateX/Y/Z property is being animated to 360 deg with loop:true, swap tween start/end values to enable\n                   continuous iterative rotation looping. (Otherise, the element would just rotate back and forth.) */\n                $.each(Data(element).tweensContainer, function(propertyName, tweenContainer) {\n                    if (/^rotate/.test(propertyName) && parseFloat(tweenContainer.endValue) === 360) {\n                        tweenContainer.endValue = 0;\n                        tweenContainer.startValue = 360;\n                    }\n\n                    if (/^backgroundPosition/.test(propertyName) && parseFloat(tweenContainer.endValue) === 100 && tweenContainer.unitType === \"%\") {\n                        tweenContainer.endValue = 0;\n                        tweenContainer.startValue = 100;\n                    }\n                });\n\n                Velocity(element, \"reverse\", { loop: true, delay: opts.delay });\n            }\n\n            /***************\n               Dequeueing\n            ***************/\n\n            /* Fire the next call in the queue so long as this call's queue wasn't set to false (to trigger a parallel animation),\n               which would have already caused the next call to fire. Note: Even if the end of the animation queue has been reached,\n               $.dequeue() must still be called in order to completely clear jQuery's animation queue. */\n            if (opts.queue !== false) {\n                $.dequeue(element, opts.queue);\n            }\n        }\n\n        /************************\n           Calls Array Cleanup\n        ************************/\n\n        /* Since this call is complete, set it to false so that the rAF tick skips it. This array is later compacted via compactSparseArray().\n          (For performance reasons, the call is set to false instead of being deleted from the array: http://www.html5rocks.com/en/tutorials/speed/v8/) */\n        Velocity.State.calls[callIndex] = false;\n\n        /* Iterate through the calls array to determine if this was the final in-progress animation.\n           If so, set a flag to end ticking and clear the calls array. */\n        for (var j = 0, callsLength = Velocity.State.calls.length; j < callsLength; j++) {\n            if (Velocity.State.calls[j] !== false) {\n                remainingCallsExist = true;\n\n                break;\n            }\n        }\n\n        if (remainingCallsExist === false) {\n            /* tick() will detect this flag upon its next iteration and subsequently turn itself off. */\n            Velocity.State.isTicking = false;\n\n            /* Clear the calls array so that its length is reset. */\n            delete Velocity.State.calls;\n            Velocity.State.calls = [];\n        }\n    }\n\n    /******************\n        Frameworks\n    ******************/\n\n    /* Both jQuery and Zepto allow their $.fn object to be extended to allow wrapped elements to be subjected to plugin calls.\n       If either framework is loaded, register a \"velocity\" extension pointing to Velocity's core animate() method.  Velocity\n       also registers itself onto a global container (window.jQuery || window.Zepto || window) so that certain features are\n       accessible beyond just a per-element scope. This master object contains an .animate() method, which is later assigned to $.fn\n       (if jQuery or Zepto are present). Accordingly, Velocity can both act on wrapped DOM elements and stand alone for targeting raw DOM elements. */\n    global.Velocity = Velocity;\n\n    if (global !== window) {\n        /* Assign the element function to Velocity's core animate() method. */\n        global.fn.velocity = animate;\n        /* Assign the object function's defaults to Velocity's global defaults object. */\n        global.fn.velocity.defaults = Velocity.defaults;\n    }\n\n    /***********************\n       Packaged Redirects\n    ***********************/\n\n    /* slideUp, slideDown */\n    $.each([ \"Down\", \"Up\" ], function(i, direction) {\n        Velocity.Redirects[\"slide\" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {\n            var opts = $.extend({}, options),\n                begin = opts.begin,\n                complete = opts.complete,\n                computedValues = { height: \"\", marginTop: \"\", marginBottom: \"\", paddingTop: \"\", paddingBottom: \"\" },\n                inlineValues = {};\n\n            if (opts.display === undefined) {\n                /* Show the element before slideDown begins and hide the element after slideUp completes. */\n                /* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */\n                opts.display = (direction === \"Down\" ? (Velocity.CSS.Values.getDisplayType(element) === \"inline\" ? \"inline-block\" : \"block\") : \"none\");\n            }\n\n            opts.begin = function() {\n                var style = element.renderer === \"webgl\" ? element.styleGL : element.style;\n                /* If the user passed in a begin callback, fire it now. */\n                begin && begin.call(elements, elements);\n\n                /* Cache the elements' original vertical dimensional property values so that we can animate back to them. */\n                for (var property in computedValues) {\n                    inlineValues[property] = style[property];\n\n                    /* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp,\n                       use forcefeeding to start from computed values and animate down to 0. */\n                    var propertyValue = Velocity.CSS.getPropertyValue(element, property);\n                    computedValues[property] = (direction === \"Down\") ? [ propertyValue, 0 ] : [ 0, propertyValue ];\n                }\n\n                /* Force vertical overflow content to clip so that sliding works as expected. */\n                inlineValues.overflow = style.overflow;\n                style.overflow = \"hidden\";\n            }\n\n            opts.complete = function() {\n                /* Reset element to its pre-slide inline values once its slide animation is complete. */\n                for (var property in inlineValues) {\n                    style[property] = inlineValues[property];\n                }\n\n                /* If the user passed in a complete callback, fire it now. */\n                complete && complete.call(elements, elements);\n                promiseData && promiseData.resolver(elements);\n            };\n\n            Velocity(element, computedValues, opts);\n        };\n    });\n\n    /* fadeIn, fadeOut */\n    $.each([ \"In\", \"Out\" ], function(i, direction) {\n        Velocity.Redirects[\"fade\" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {\n            var opts = $.extend({}, options),\n                propertiesMap = { opacity: (direction === \"In\") ? 1 : 0 },\n                originalComplete = opts.complete;\n\n            /* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering\n               callbacks by firing them only when the final element has been reached. */\n            if (elementsIndex !== elementsSize - 1) {\n                opts.complete = opts.begin = null;\n            } else {\n                opts.complete = function() {\n                    if (originalComplete) {\n                        originalComplete.call(elements, elements);\n                    }\n\n                    promiseData && promiseData.resolver(elements);\n                }\n            }\n\n            /* If a display was passed in, use it. Otherwise, default to \"none\" for fadeOut or the element-specific default for fadeIn. */\n            /* Note: We allow users to pass in \"null\" to skip display setting altogether. */\n            if (opts.display === undefined) {\n                opts.display = (direction === \"In\" ? \"auto\" : \"none\");\n            }\n\n            Velocity(this, propertiesMap, opts);\n        };\n    });\n\n    return Velocity;\n}((window.jQuery || window.Zepto || window), window, document);\n}));\n\n/******************\n   Known Issues\n******************/\n\n/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.\nVelocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties\nwill produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */"
  },
  {
    "path": "demo/nested-content-webgl.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"./assets/css/style.css\">\n    <title>HTML GL nested content</title>\n    <meta name=\"viewport\" content=\"width=1024 maximum-scale=1.0 minimum-scale=1.0 initial-scale=1.0, user-scalable=no\" />\n</head>\n<body>\n<div class=\"content_wrapper\">\n    <h1>MENU RENDERED IN DOM</h1>\n    <nav class=\"top_nav\">\n        <ul class=\"menu expanded\">\n            <li><a target=\"_blank\" href=\"http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/\">ABOUT HTML-GL</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL\">GITHUB REPO</a></li>\n            <li><a target=\"_blank\" href=\"https://github.com/PixelsCommander/HTML-GL/archive/master.zip\">DOWNLOAD</a></li>\n        </ul>\n        <ul class=\"submenu\">\n            <li>MOVIES</li>\n            <li>TV</li>\n            <li>KIDS</li>\n            <li>\n                <!-- AddThis Button BEGIN -->\n                <div class=\"addthis_toolbox addthis_default_style\">\n                    <iframe style=\"display: inline-block;\"\n                            src=\"http://ghbtns.com/github-btn.html?user=PixelsCommander&repo=HTML-GL&type=watch\"\n                            allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"62\" height=\"20\"></iframe>\n                    <a class=\"addthis_button_tweet\"></a>\n                    <a class=\"addthis_button_google_plusone\" g:plusone:size=\"medium\"></a>\n                </div>\n                <script type=\"text/javascript\">var addthis_config = {\"data_track_addressbar\":true};</script>\n                <script type=\"text/javascript\" src=\"//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4ea2f9164143bcfb\"></script>\n                <!-- AddThis Button END -->\n            </li>\n        </ul>\n    </nav>\n    <section class=\"broadcasts_list\">\n        <h1>SLIDER BELOW IS RENDERED IN WEBGL, DRAG IT</h1>\n        <html-gl class=\"horizontal_carusel\">\n            <html-gl>\n                <li class=\"broadcast\" onclick=\"alert('Clicked Argo')\">\n                    <div class=\"image_background\"></div>\n                    <img src=\"./pic/boxes/box_argo.png\" width=\"186px\" height=\"270px\">\n\n                    <p>\n                        Select me with DevTools\n                    </p>\n\n                    <p>\n                        <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                        <span>7.8<span>/10</span></span>\n                    </p>\n                </li>\n            </html-gl>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Avatar')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_avatar.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Change me in DevTools\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>8.0<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Clicked Breaking Bad')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_breaking_bad.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Breaking bad\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>9.6<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>6.7<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <li class=\"broadcast\" onclick=\"alert('Quantum of solace')\">\n                <div class=\"image_background\"></div>\n                <img src=\"./pic/boxes/box_quantum_of_solace.png\" width=\"186px\" height=\"270px\">\n\n                <p>\n                    Quantum of solace\n                </p>\n\n                <p>\n                    <img src=\"./assets/img/imdb.png\" width=\"52px\" height=\"24px\">\n                    <span>7.4<span>/10</span></span>\n                </p>\n            </li>\n            <div class=\"\">\n\n            </div>\n        </html-gl>\n    </section>\n</div>\n\n<script src=\"../bower_components/promise-polyfill/Promise.min.js\"></script>\n<script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n<script src=\"./js/vendor/velocity.js\"></script>\n<script src=\"./js/vendor/html2canvas.js\"></script>\n<script src=\"../bower_components/pixi/bin/pixi.js\"></script>\n<script src=\"../src/util.js\"></script>\n<script src=\"../src/gl-element-resolver.js\"></script>\n<script src=\"../src/gl-context.js\"></script>\n<script src=\"../src/images-loaded.js\"></script>\n<script src=\"../src/gl-element.js\"></script>\n<script src=\"./js/slider.js\"></script>\n<script>\n    window.addEventListener('load', function () {\n        setTimeout(function () {\n            Velocity(document.getElementsByTagName('html-gl')[0], {translateX: 408}, {duration: 500});\n        }, 500);\n    });\n\n    document.getElementsByTagName('html-gl')[0].addEventListener('htmlglReady', function(e){\n        alert('We got htmlglReady event');\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "demo/ripples.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"./assets/css/appstyle.css\">\n    <title>HTML GL filters demo</title>\n    <meta name=\"viewport\" content=\"width=1024 maximum-scale=1.0 minimum-scale=1.0 initial-scale=1.0, user-scalable=no\" />\n</head>\n<body>\n//Try add invert noise twist or bloom effects by editing attirubte a-la effects=\"ripples bloom twist\"\n<html-gl effects=\"ripples\">\n    <ul>\n        <li>\n            <img src=\"./assets/img/icons/bitcoin.png\">\n            <p>Bitcoin</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/2checkout.png\">\n            <p>2checkout</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/calendar.png\">\n            <p>Calendar</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/calculator.png\">\n            <p>Calculator</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/clock.png\">\n            <p>Clock</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/discover.png\">\n            <p>Discover</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/ebay.png\">\n            <p>Ebay</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/google-wallet.png\">\n            <p>Google wallet</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/maestro.png\">\n            <p>Maestro</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/mastercard.png\">\n            <p>MasterCard</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/paypal.png\">\n            <p>PayPal</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/locker.png\">\n            <p>Locker</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/visa.png\">\n            <p>Visa</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/wire-transfer.png\">\n            <p>Wire transfer</p>\n        </li>\n        <li>\n            <img src=\"./assets/img/icons/wu.png\">\n            <p>Western Union</p>\n        </li>\n    </ul>\n</html-gl>\n\n\n\n\n<script>\n    var listItems = document.getElementsByTagName('li');\n\n    for (var i = 0; i < listItems.length; i++) {\n        var item = listItems[i];\n\n        item.addEventListener('mouseup', function(e){\n            console.log(e.currentTarget.innerText);\n        });\n    }\n</script>\n<script src=\"../bower_components/promise-polyfill/Promise.min.js\"></script>\n<script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n<script src=\"./js/vendor/velocity.js\"></script>\n<script src=\"./js/vendor/html2canvas.js\"></script>\n<script src=\"../bower_components/pixi/bin/pixi.js\"></script>\n<script src=\"../src/util.js\"></script>\n<script src=\"../src/gl-element-resolver.js\"></script>\n<script src=\"../src/gl-context.js\"></script>\n<script src=\"../src/images-loaded.js\"></script>\n<script src=\"../src/gl-element.js\"></script>\n<script src=\"../dist/htmlgl-effects.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "dist/htmlgl-effects.js",
    "content": "(function (w) {\n\n    var Ascii = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.AsciiFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Ascii.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.ascii = Ascii;\n})(window);\n(function (w) {\n\n    var Bloom = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.BloomFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Bloom.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.bloom = Bloom;\n})(window);\n(function (w) {\n\n    var DiagonalBlur = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.BlurDirFilter(2, 2);\n        this.filter.passes = 2;\n        this.filter.blur = 3;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = DiagonalBlur.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.diagonalblur = DiagonalBlur;\n})(window);\n(function (w) {\n\n    var DotScreen = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.DotScreenFilter();\n        this.filter.scale = parseInt(this.element.getAttribute('dotScreenScale')) || 1;\n        this.filter.angle = parseInt(this.element.getAttribute('dotScreenAngle')) || 1;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = DotScreen.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.dotscreen = DotScreen;\n})(window);\n(function (w) {\n\n    var Invert = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.InvertFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Invert.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.invert = Invert;\n})(window);\n(function (w) {\n\n    var Noise = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.NoiseFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Noise.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.noise = Noise;\n})(window);\n(function (w) {\n\n    var Pixelate = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.PixelateFilter();\n        this.filter.size.x = parseInt(this.element.getAttribute('pixelSizeX')) || 2;\n        this.filter.size.y = parseInt(this.element.getAttribute('pixelSizeY')) || 2;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Pixelate.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.pixelate = Pixelate;\n})(window);\n(function (w) {\n\n    var RGBSplit = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.RGBSplitFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = RGBSplit.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.rgbsplit = RGBSplit;\n})(window);\n(function (w) {\n\n    var Ripples = function (element) {\n        this.element = element;\n        this.ripple = this.ripple.bind(this);\n        this.element.addEventListener('mousedown', this.ripple);\n\n        var displacementMapImage = new Image();\n        displacementMapImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgEAAAIBCAIAAABfhPs2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2tpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo1MjZkMzQyYS1kMzZjLTRkOTYtOGU4My1kNjYyNTkxZTIxMGQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTEwRUI3MDRGNEMxMTFFNDg1RDBBMEJCQ0UzMDExRkIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTEwRUI3MDNGNEMxMTFFNDg1RDBBMEJCQ0UzMDExRkIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OEI3NEM0QTE2MUM1MTFFMzgzM0FGOEVFNDc1RkUxMEYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OEI3NEM0QTI2MUM1MTFFMzgzM0FGOEVFNDc1RkUxMEYiLz4gPC9yZGY6RGVz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';\n\n        this.displacementSprite = PIXI.Sprite.fromImage('assets/img/ripple_displacement.png');\n        this.displacementFilter = new PIXI.filters.DisplacementFilter(this.displacementSprite);\n\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.displacementFilter);\n\n        this.displacementSprite.scale.x = 0.05;\n        this.displacementSprite.scale.y = 0.05;\n\n        this.displacementSprite.pivot.x = 513 / 2;\n        this.displacementSprite.pivot.y = 513 / 2;\n\n        window.HTMLGL.document.addChild(this.displacementSprite);\n\n        function redraw() {\n            TWEEN.update();\n            window.HTMLGL.renderer.render(window.HTMLGL.stage);\n            requestAnimationFrame(redraw);\n        }\n\n        requestAnimationFrame(redraw);\n    }\n\n    var p = Ripples.prototype;\n\n    p.ripple = function (e) {\n        this.displacementSprite.x = e.pageX * w.HTMLGL.pixelRatio;\n        this.displacementSprite.y = e.pageY * w.HTMLGL.pixelRatio;\n\n        this.displacementSprite.scale.x = 0.05;\n        this.displacementSprite.scale.y = 0.05;\n\n        this.displacementFilter.scale.x = 100;\n        this.displacementFilter.scale.y = 100;\n\n        new TWEEN.Tween(this.displacementSprite.scale)\n            .to({x: 1.5, y: 1.5}, 1000)\n            .easing(TWEEN.Easing.Cubic.Out)\n            .start();\n\n        new TWEEN.Tween(this.displacementFilter.scale)\n            .to({x: 0, y: 0}, 1000)\n            .easing(TWEEN.Easing.Cubic.Out)\n            .start();\n    }\n\n    p.destroy = function () {\n        ///var filterIndex = this.element.sprite.filters.indexOf(this.displacementFilter);\n\n        //window.HTMLGL.document.removeChild(this.displacementSprite);\n        this.element.removeEventListener('mousedown', this.ripple);\n        //this.element.sprite.removeFilter([this.displacementFilter]);\n\n        //this.element.sprite.filters.splice(filterIndex, 1);\n        //this.displacementSprite.texture.destroy();\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.ripples = Ripples;\n})(window);\n(function (w) {\n\n    var Twist = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.TwistFilter();\n        this.filter.radius = parseInt(this.element.getAttribute('twistRadius')) || 0.5;\n        this.filter.angle = parseInt(this.element.getAttribute('twistAngle')) || 5;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Twist.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.twist = Twist;\n})(window);\n/*\n * GLEffectsManager is a part of HTML GL library for applying effects based on tag attributes\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var GLEffectsManager = function (element) {\n        this.element = element;\n        this.filters = {};\n        this.initObserver();\n        this.updateFilters();\n    }\n\n    var p = GLEffectsManager.prototype;\n\n    p.initObserver = function () {\n        var self = this,\n            config = {\n                attributes: true,\n                attributeFilter: ['effects']\n            };\n\n        this.observer = this.observer || new MutationObserver(self.updateFilters.bind(this));\n\n        this.observer.observe(this.element, config);\n    }\n\n    p.updateFilters = function () {\n        var attributeValue = this.element.getAttribute('effects') || '',\n            effectsNamesArray = attributeValue.split(' ');\n\n        this.addFiltersFromAttributes(effectsNamesArray);\n        this.cleanFiltersFromAttributes(effectsNamesArray);\n    }\n\n    p.addFiltersFromAttributes = function (effectsNamesArray) {\n        var self = this;\n        effectsNamesArray.forEach(function (effectName) {\n            if (HTMLGL.effects[effectName]) {\n                self.filters[effectName] = self.filters[effectName] || new HTMLGL.effects[effectName](self.element);\n            }\n        });\n    }\n\n    p.cleanFiltersFromAttributes = function (effectsNamesArray) {\n        var self = this;\n        Object.keys(this.filters).forEach(function (effectName) {\n            if (effectsNamesArray.indexOf(effectName) === -1 && self.filters[effectName]) {\n                self.filters[effectName].destroy();\n                self.filters[effectName] = null;\n            }\n        });\n    }\n\n    w.HTMLGL.GLEffectsManager = GLEffectsManager;\n\n    //Reinitialize effects on elements\n    w.HTMLGL.elements.forEach(function (element) {\n        element.initEffects();\n    });\n})(window);"
  },
  {
    "path": "dist/htmlgl.js",
    "content": "/*! promise-polyfill 2.0.1 */\n!function(a){function b(a,b){return function(){a.apply(b,arguments)}}function c(a){if(\"object\"!=typeof this)throw new TypeError(\"Promises must be constructed via new\");if(\"function\"!=typeof a)throw new TypeError(\"not a function\");this._state=null,this._value=null,this._deferreds=[],i(a,b(e,this),b(f,this))}function d(a){var b=this;return null===this._state?void this._deferreds.push(a):void j(function(){var c=b._state?a.onFulfilled:a.onRejected;if(null===c)return void(b._state?a.resolve:a.reject)(b._value);var d;try{d=c(b._value)}catch(e){return void a.reject(e)}a.resolve(d)})}function e(a){try{if(a===this)throw new TypeError(\"A promise cannot be resolved with itself.\");if(a&&(\"object\"==typeof a||\"function\"==typeof a)){var c=a.then;if(\"function\"==typeof c)return void i(b(c,a),b(e,this),b(f,this))}this._state=!0,this._value=a,g.call(this)}catch(d){f.call(this,d)}}function f(a){this._state=!1,this._value=a,g.call(this)}function g(){for(var a=0,b=this._deferreds.length;b>a;a++)d.call(this,this._deferreds[a]);this._deferreds=null}function h(a,b,c,d){this.onFulfilled=\"function\"==typeof a?a:null,this.onRejected=\"function\"==typeof b?b:null,this.resolve=c,this.reject=d}function i(a,b,c){var d=!1;try{a(function(a){d||(d=!0,b(a))},function(a){d||(d=!0,c(a))})}catch(e){if(d)return;d=!0,c(e)}}var j=c.immediateFn||\"function\"==typeof setImmediate&&setImmediate||function(a){setTimeout(a,1)},k=Array.isArray||function(a){return\"[object Array]\"===Object.prototype.toString.call(a)};c.prototype[\"catch\"]=function(a){return this.then(null,a)},c.prototype.then=function(a,b){var e=this;return new c(function(c,f){d.call(e,new h(a,b,c,f))})},c.all=function(){var a=Array.prototype.slice.call(1===arguments.length&&k(arguments[0])?arguments[0]:arguments);return new c(function(b,c){function d(f,g){try{if(g&&(\"object\"==typeof g||\"function\"==typeof g)){var h=g.then;if(\"function\"==typeof h)return void h.call(g,function(a){d(f,a)},c)}a[f]=g,0===--e&&b(a)}catch(i){c(i)}}if(0===a.length)return b([]);for(var e=a.length,f=0;f<a.length;f++)d(f,a[f])})},c.resolve=function(a){return a&&\"object\"==typeof a&&a.constructor===c?a:new c(function(b){b(a)})},c.reject=function(a){return new c(function(b,c){c(a)})},c.race=function(a){return new c(function(b,c){for(var d=0,e=a.length;e>d;d++)a[d].then(b,c)})},\"undefined\"!=typeof module&&module.exports?module.exports=c:a.Promise||(a.Promise=c)}(this);\n/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.5.5\n\"undefined\"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,o=function(){this.name=\"__st\"+(1e9*Math.random()>>>0)+(t++ +\"__\")};o.prototype={set:function(t,o){var n=t[this.name];return n&&n[0]===t?n[1]=o:e(t,this.name,{value:[t,o],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},\"delete\":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=o}(),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,o=[],n=function(e){o.push(e)},r=function(){o.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){o(e,function(e){return t(e)?!0:void n(e,t)}),n(e,t)}function o(e,t,n){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,n)!==!0&&o(r,t,n),r=r.nextElementSibling;return null}function n(e,o){for(var n=e.shadowRoot;n;)t(n,o),n=n.olderShadowRoot}function r(e,t){i=[],a(e,t),i=null}function a(e,t){if(e=wrap(e),!(i.indexOf(e)>=0)){i.push(e);for(var o,n=e.querySelectorAll(\"link[rel=\"+u+\"]\"),r=0,d=n.length;d>r&&(o=n[r]);r++)o[\"import\"]&&a(o[\"import\"],t);t(e)}}var i,u=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:\"none\";e.forDocumentTree=r,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return o(e)||n(e)}function o(t){return e.upgrade(t)?!0:void u(t)}function n(e){y(e,function(e){return o(e)?!0:void 0})}function r(e){u(e),f(e)&&y(e,function(e){u(e)})}function a(e){M.push(e),C||(C=!0,setTimeout(i))}function i(){C=!1;for(var e,t=M,o=0,n=t.length;n>o&&(e=t[o]);o++)e();M=[]}function u(e){E?a(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){s(e),y(e,function(e){s(e)})}function s(e){E?a(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,o=wrap(document);t;){if(t==o)return!0;t=t.parentNode||t.host}}function p(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&console.log(\"watching shadow-root for: \",e.localName);for(var t=e.shadowRoot;t;)h(t),t=t.olderShadowRoot}}function m(e){if(_.dom){var o=e[0];if(o&&\"childList\"===o.type&&o.addedNodes&&o.addedNodes){for(var n=o.addedNodes[0];n&&n!==document&&!n.host;)n=n.parentNode;var r=n&&(n.URL||n._URL||n.host&&n.host.localName)||\"\";r=r.split(\"/?\").shift().split(\"/\").pop()}console.group(\"mutations (%d) [%s]\",e.length,r||\"\")}e.forEach(function(e){\"childList\"===e.type&&(N(e.addedNodes,function(e){e.localName&&t(e)}),N(e.removedNodes,function(e){e.localName&&c(e)}))}),_.dom&&console.groupEnd()}function w(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(m(t.takeRecords()),i())}function h(e){if(!e.__observer){var t=new MutationObserver(m);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function g(e){e=wrap(e),_.dom&&console.group(\"upgradeDocument: \",e.baseURI.split(\"/\").pop()),t(e),h(e),_.dom&&console.groupEnd()}function v(e){b(e,g)}var _=e.flags,y=e.forSubtree,b=e.forDocumentTree,E=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=E;var C=!1,M=[],N=Array.prototype.forEach.call.bind(Array.prototype.forEach),T=Element.prototype.createShadowRoot;T&&(Element.prototype.createShadowRoot=function(){var e=T.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=p,e.upgradeDocumentTree=v,e.upgradeSubtree=n,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=w}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var n=t.getAttribute(\"is\"),r=e.getRegisteredDefinition(n||t.localName);if(r){if(n&&r.tag==t.localName)return o(t,r);if(!n&&!r[\"extends\"])return o(t,r)}}}function o(t,o){return i.upgrade&&console.group(\"upgrade:\",t.localName),o.is&&t.setAttribute(\"is\",o.is),n(t,o),t.__upgraded__=!0,a(t),e.attachedNode(t),e.upgradeSubtree(t),i.upgrade&&console.groupEnd(),t}function n(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t[\"native\"]),e.__proto__=t.prototype)}function r(e,t,o){for(var n={},r=t;r!==o&&r!==HTMLElement.prototype;){for(var a,i=Object.getOwnPropertyNames(r),u=0;a=i[u];u++)n[a]||(Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(r,a)),n[a]=1);r=Object.getPrototypeOf(r)}}function a(e){e.createdCallback&&e.createdCallback()}var i=e.flags;e.upgrade=t,e.upgradeWithDefinition=o,e.implementPrototype=n}),CustomElements.addModule(function(e){function t(t,n){var d=n||{};if(!t)throw new Error(\"document.registerElement: first argument `name` must not be empty\");if(t.indexOf(\"-\")<0)throw new Error(\"document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '\"+String(t)+\"'.\");if(r(t))throw new Error(\"Failed to execute 'registerElement' on 'Document': Registration failed for type '\"+String(t)+\"'. The type name is invalid.\");if(c(t))throw new Error(\"DuplicateDefinitionError: a type with name '\"+String(t)+\"' is already registered\");return d.prototype||(d.prototype=Object.create(HTMLElement.prototype)),d.__name=t.toLowerCase(),d.lifecycle=d.lifecycle||{},d.ancestry=a(d[\"extends\"]),i(d),u(d),o(d.prototype),s(d.__name,d),d.ctor=l(d),d.ctor.prototype=d.prototype,d.prototype.constructor=d.ctor,e.ready&&h(document),d.ctor}function o(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,o){n.call(this,e,o,t)};var o=e.removeAttribute;e.removeAttribute=function(e){n.call(this,e,null,o)},e.setAttribute._polyfilled=!0}}function n(e,t,o){e=e.toLowerCase();var n=this.getAttribute(e);o.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==n&&this.attributeChangedCallback(e,n,r)}function r(e){for(var t=0;t<b.length;t++)if(e===b[t])return!0}function a(e){var t=c(e);return t?a(t[\"extends\"]).concat([t]):[]}function i(e){for(var t,o=e[\"extends\"],n=0;t=e.ancestry[n];n++)o=t.is&&t.tag;e.tag=o||e.__name,o&&(e.is=e.__name)}function u(e){if(!Object.__proto__){var t=HTMLElement.prototype;if(e.is){var o=document.createElement(e.tag),n=Object.getPrototypeOf(o);n===e.prototype&&(t=n)}for(var r,a=e.prototype;a&&a!==t;)r=Object.getPrototypeOf(a),a.__proto__=r,a=r;e[\"native\"]=t}}function d(e){return v(M(e.tag),e)}function c(e){return e?E[e.toLowerCase()]:void 0}function s(e,t){E[e]=t}function l(e){return function(){return d(e)}}function f(e,t,o){return e===C?p(t,o):N(e,t)}function p(e,t){var o=c(t||e);if(o){if(e==o.tag&&t==o.is)return new o.ctor;if(!t&&!o.is)return new o.ctor}var n;return t?(n=p(e),n.setAttribute(\"is\",t),n):(n=M(e),e.indexOf(\"-\")>=0&&_(n,HTMLElement),n)}function m(e){var t=T.call(this,e);return g(t),t}var w,h=e.upgradeDocumentTree,g=e.upgrade,v=e.upgradeWithDefinition,_=e.implementPrototype,y=e.useNative,b=[\"annotation-xml\",\"color-profile\",\"font-face\",\"font-face-src\",\"font-face-uri\",\"font-face-format\",\"font-face-name\",\"missing-glyph\"],E={},C=\"http://www.w3.org/1999/xhtml\",M=document.createElement.bind(document),N=document.createElementNS.bind(document),T=Node.prototype.cloneNode;w=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var o=e;o;){if(o===t.prototype)return!0;o=o.__proto__}return!1},document.registerElement=t,document.createElement=p,document.createElementNS=f,Node.prototype.cloneNode=m,e.registry=E,e[\"instanceof\"]=w,e.reservedTagList=b,e.getRegisteredDefinition=c,document.register=document.registerElement}),function(e){function t(){i(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){i(wrap(e[\"import\"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent(\"WebComponentsReady\",{bubbles:!0}))})}var o=e.useNative,n=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(o){var a=function(){};e.watchShadow=a,e.upgrade=a,e.upgradeAll=a,e.upgradeDocumentTree=a,e.upgradeSubtree=a,e.takeRecords=a,e[\"instanceof\"]=function(e,t){return e instanceof t}}else n();var i=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&\"function\"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var o=document.createEvent(\"CustomEvent\");return o.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),o},window.CustomEvent.prototype=window.Event.prototype),\"complete\"===document.readyState||e.flags.eager)t();else if(\"interactive\"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var u=window.HTMLImports&&!HTMLImports.ready?\"HTMLImportsLoaded\":\"DOMContentLoaded\";window.addEventListener(u,t)}else t()}(window.CustomElements);\n/**\n * @license\n * pixi.js - v3.0.10\n * Compiled 2016-03-31T20:39:38.722Z\n *\n * pixi.js is licensed under the MIT License.\n * http://www.opensource.org/licenses/mit-license.php\n *\n *\n * The MIT License\n * \n * Copyright (c) 2013-2015 Mathew Groves\n * \n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * \n * \n */\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.PIXI = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n(function () {\n\n    var async = {};\n    function noop() {}\n    function identity(v) {\n        return v;\n    }\n    function toBool(v) {\n        return !!v;\n    }\n    function notId(v) {\n        return !v;\n    }\n\n    // global on the server, window in the browser\n    var previous_async;\n\n    // Establish the root object, `window` (`self`) in the browser, `global`\n    // on the server, or `this` in some virtual machines. We use `self`\n    // instead of `window` for `WebWorker` support.\n    var root = typeof self === 'object' && self.self === self && self ||\n            typeof global === 'object' && global.global === global && global ||\n            this;\n\n    if (root != null) {\n        previous_async = root.async;\n    }\n\n    async.noConflict = function () {\n        root.async = previous_async;\n        return async;\n    };\n\n    function only_once(fn) {\n        return function() {\n            if (fn === null) throw new Error(\"Callback was already called.\");\n            fn.apply(this, arguments);\n            fn = null;\n        };\n    }\n\n    function _once(fn) {\n        return function() {\n            if (fn === null) return;\n            fn.apply(this, arguments);\n            fn = null;\n        };\n    }\n\n    //// cross-browser compatiblity functions ////\n\n    var _toString = Object.prototype.toString;\n\n    var _isArray = Array.isArray || function (obj) {\n        return _toString.call(obj) === '[object Array]';\n    };\n\n    // Ported from underscore.js isObject\n    var _isObject = function(obj) {\n        var type = typeof obj;\n        return type === 'function' || type === 'object' && !!obj;\n    };\n\n    function _isArrayLike(arr) {\n        return _isArray(arr) || (\n            // has a positive integer length property\n            typeof arr.length === \"number\" &&\n            arr.length >= 0 &&\n            arr.length % 1 === 0\n        );\n    }\n\n    function _arrayEach(arr, iterator) {\n        var index = -1,\n            length = arr.length;\n\n        while (++index < length) {\n            iterator(arr[index], index, arr);\n        }\n    }\n\n    function _map(arr, iterator) {\n        var index = -1,\n            length = arr.length,\n            result = Array(length);\n\n        while (++index < length) {\n            result[index] = iterator(arr[index], index, arr);\n        }\n        return result;\n    }\n\n    function _range(count) {\n        return _map(Array(count), function (v, i) { return i; });\n    }\n\n    function _reduce(arr, iterator, memo) {\n        _arrayEach(arr, function (x, i, a) {\n            memo = iterator(memo, x, i, a);\n        });\n        return memo;\n    }\n\n    function _forEachOf(object, iterator) {\n        _arrayEach(_keys(object), function (key) {\n            iterator(object[key], key);\n        });\n    }\n\n    function _indexOf(arr, item) {\n        for (var i = 0; i < arr.length; i++) {\n            if (arr[i] === item) return i;\n        }\n        return -1;\n    }\n\n    var _keys = Object.keys || function (obj) {\n        var keys = [];\n        for (var k in obj) {\n            if (obj.hasOwnProperty(k)) {\n                keys.push(k);\n            }\n        }\n        return keys;\n    };\n\n    function _keyIterator(coll) {\n        var i = -1;\n        var len;\n        var keys;\n        if (_isArrayLike(coll)) {\n            len = coll.length;\n            return function next() {\n                i++;\n                return i < len ? i : null;\n            };\n        } else {\n            keys = _keys(coll);\n            len = keys.length;\n            return function next() {\n                i++;\n                return i < len ? keys[i] : null;\n            };\n        }\n    }\n\n    // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)\n    // This accumulates the arguments passed into an array, after a given index.\n    // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).\n    function _restParam(func, startIndex) {\n        startIndex = startIndex == null ? func.length - 1 : +startIndex;\n        return function() {\n            var length = Math.max(arguments.length - startIndex, 0);\n            var rest = Array(length);\n            for (var index = 0; index < length; index++) {\n                rest[index] = arguments[index + startIndex];\n            }\n            switch (startIndex) {\n                case 0: return func.call(this, rest);\n                case 1: return func.call(this, arguments[0], rest);\n            }\n            // Currently unused but handle cases outside of the switch statement:\n            // var args = Array(startIndex + 1);\n            // for (index = 0; index < startIndex; index++) {\n            //     args[index] = arguments[index];\n            // }\n            // args[startIndex] = rest;\n            // return func.apply(this, args);\n        };\n    }\n\n    function _withoutIndex(iterator) {\n        return function (value, index, callback) {\n            return iterator(value, callback);\n        };\n    }\n\n    //// exported async module functions ////\n\n    //// nextTick implementation with browser-compatible fallback ////\n\n    // capture the global reference to guard against fakeTimer mocks\n    var _setImmediate = typeof setImmediate === 'function' && setImmediate;\n\n    var _delay = _setImmediate ? function(fn) {\n        // not a direct alias for IE10 compatibility\n        _setImmediate(fn);\n    } : function(fn) {\n        setTimeout(fn, 0);\n    };\n\n    if (typeof process === 'object' && typeof process.nextTick === 'function') {\n        async.nextTick = process.nextTick;\n    } else {\n        async.nextTick = _delay;\n    }\n    async.setImmediate = _setImmediate ? _delay : async.nextTick;\n\n\n    async.forEach =\n    async.each = function (arr, iterator, callback) {\n        return async.eachOf(arr, _withoutIndex(iterator), callback);\n    };\n\n    async.forEachSeries =\n    async.eachSeries = function (arr, iterator, callback) {\n        return async.eachOfSeries(arr, _withoutIndex(iterator), callback);\n    };\n\n\n    async.forEachLimit =\n    async.eachLimit = function (arr, limit, iterator, callback) {\n        return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);\n    };\n\n    async.forEachOf =\n    async.eachOf = function (object, iterator, callback) {\n        callback = _once(callback || noop);\n        object = object || [];\n\n        var iter = _keyIterator(object);\n        var key, completed = 0;\n\n        while ((key = iter()) != null) {\n            completed += 1;\n            iterator(object[key], key, only_once(done));\n        }\n\n        if (completed === 0) callback(null);\n\n        function done(err) {\n            completed--;\n            if (err) {\n                callback(err);\n            }\n            // Check key is null in case iterator isn't exhausted\n            // and done resolved synchronously.\n            else if (key === null && completed <= 0) {\n                callback(null);\n            }\n        }\n    };\n\n    async.forEachOfSeries =\n    async.eachOfSeries = function (obj, iterator, callback) {\n        callback = _once(callback || noop);\n        obj = obj || [];\n        var nextKey = _keyIterator(obj);\n        var key = nextKey();\n        function iterate() {\n            var sync = true;\n            if (key === null) {\n                return callback(null);\n            }\n            iterator(obj[key], key, only_once(function (err) {\n                if (err) {\n                    callback(err);\n                }\n                else {\n                    key = nextKey();\n                    if (key === null) {\n                        return callback(null);\n                    } else {\n                        if (sync) {\n                            async.setImmediate(iterate);\n                        } else {\n                            iterate();\n                        }\n                    }\n                }\n            }));\n            sync = false;\n        }\n        iterate();\n    };\n\n\n\n    async.forEachOfLimit =\n    async.eachOfLimit = function (obj, limit, iterator, callback) {\n        _eachOfLimit(limit)(obj, iterator, callback);\n    };\n\n    function _eachOfLimit(limit) {\n\n        return function (obj, iterator, callback) {\n            callback = _once(callback || noop);\n            obj = obj || [];\n            var nextKey = _keyIterator(obj);\n            if (limit <= 0) {\n                return callback(null);\n            }\n            var done = false;\n            var running = 0;\n            var errored = false;\n\n            (function replenish () {\n                if (done && running <= 0) {\n                    return callback(null);\n                }\n\n                while (running < limit && !errored) {\n                    var key = nextKey();\n                    if (key === null) {\n                        done = true;\n                        if (running <= 0) {\n                            callback(null);\n                        }\n                        return;\n                    }\n                    running += 1;\n                    iterator(obj[key], key, only_once(function (err) {\n                        running -= 1;\n                        if (err) {\n                            callback(err);\n                            errored = true;\n                        }\n                        else {\n                            replenish();\n                        }\n                    }));\n                }\n            })();\n        };\n    }\n\n\n    function doParallel(fn) {\n        return function (obj, iterator, callback) {\n            return fn(async.eachOf, obj, iterator, callback);\n        };\n    }\n    function doParallelLimit(fn) {\n        return function (obj, limit, iterator, callback) {\n            return fn(_eachOfLimit(limit), obj, iterator, callback);\n        };\n    }\n    function doSeries(fn) {\n        return function (obj, iterator, callback) {\n            return fn(async.eachOfSeries, obj, iterator, callback);\n        };\n    }\n\n    function _asyncMap(eachfn, arr, iterator, callback) {\n        callback = _once(callback || noop);\n        arr = arr || [];\n        var results = _isArrayLike(arr) ? [] : {};\n        eachfn(arr, function (value, index, callback) {\n            iterator(value, function (err, v) {\n                results[index] = v;\n                callback(err);\n            });\n        }, function (err) {\n            callback(err, results);\n        });\n    }\n\n    async.map = doParallel(_asyncMap);\n    async.mapSeries = doSeries(_asyncMap);\n    async.mapLimit = doParallelLimit(_asyncMap);\n\n    // reduce only has a series version, as doing reduce in parallel won't\n    // work in many situations.\n    async.inject =\n    async.foldl =\n    async.reduce = function (arr, memo, iterator, callback) {\n        async.eachOfSeries(arr, function (x, i, callback) {\n            iterator(memo, x, function (err, v) {\n                memo = v;\n                callback(err);\n            });\n        }, function (err) {\n            callback(err, memo);\n        });\n    };\n\n    async.foldr =\n    async.reduceRight = function (arr, memo, iterator, callback) {\n        var reversed = _map(arr, identity).reverse();\n        async.reduce(reversed, memo, iterator, callback);\n    };\n\n    async.transform = function (arr, memo, iterator, callback) {\n        if (arguments.length === 3) {\n            callback = iterator;\n            iterator = memo;\n            memo = _isArray(arr) ? [] : {};\n        }\n\n        async.eachOf(arr, function(v, k, cb) {\n            iterator(memo, v, k, cb);\n        }, function(err) {\n            callback(err, memo);\n        });\n    };\n\n    function _filter(eachfn, arr, iterator, callback) {\n        var results = [];\n        eachfn(arr, function (x, index, callback) {\n            iterator(x, function (v) {\n                if (v) {\n                    results.push({index: index, value: x});\n                }\n                callback();\n            });\n        }, function () {\n            callback(_map(results.sort(function (a, b) {\n                return a.index - b.index;\n            }), function (x) {\n                return x.value;\n            }));\n        });\n    }\n\n    async.select =\n    async.filter = doParallel(_filter);\n\n    async.selectLimit =\n    async.filterLimit = doParallelLimit(_filter);\n\n    async.selectSeries =\n    async.filterSeries = doSeries(_filter);\n\n    function _reject(eachfn, arr, iterator, callback) {\n        _filter(eachfn, arr, function(value, cb) {\n            iterator(value, function(v) {\n                cb(!v);\n            });\n        }, callback);\n    }\n    async.reject = doParallel(_reject);\n    async.rejectLimit = doParallelLimit(_reject);\n    async.rejectSeries = doSeries(_reject);\n\n    function _createTester(eachfn, check, getResult) {\n        return function(arr, limit, iterator, cb) {\n            function done() {\n                if (cb) cb(getResult(false, void 0));\n            }\n            function iteratee(x, _, callback) {\n                if (!cb) return callback();\n                iterator(x, function (v) {\n                    if (cb && check(v)) {\n                        cb(getResult(true, x));\n                        cb = iterator = false;\n                    }\n                    callback();\n                });\n            }\n            if (arguments.length > 3) {\n                eachfn(arr, limit, iteratee, done);\n            } else {\n                cb = iterator;\n                iterator = limit;\n                eachfn(arr, iteratee, done);\n            }\n        };\n    }\n\n    async.any =\n    async.some = _createTester(async.eachOf, toBool, identity);\n\n    async.someLimit = _createTester(async.eachOfLimit, toBool, identity);\n\n    async.all =\n    async.every = _createTester(async.eachOf, notId, notId);\n\n    async.everyLimit = _createTester(async.eachOfLimit, notId, notId);\n\n    function _findGetResult(v, x) {\n        return x;\n    }\n    async.detect = _createTester(async.eachOf, identity, _findGetResult);\n    async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);\n    async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);\n\n    async.sortBy = function (arr, iterator, callback) {\n        async.map(arr, function (x, callback) {\n            iterator(x, function (err, criteria) {\n                if (err) {\n                    callback(err);\n                }\n                else {\n                    callback(null, {value: x, criteria: criteria});\n                }\n            });\n        }, function (err, results) {\n            if (err) {\n                return callback(err);\n            }\n            else {\n                callback(null, _map(results.sort(comparator), function (x) {\n                    return x.value;\n                }));\n            }\n\n        });\n\n        function comparator(left, right) {\n            var a = left.criteria, b = right.criteria;\n            return a < b ? -1 : a > b ? 1 : 0;\n        }\n    };\n\n    async.auto = function (tasks, concurrency, callback) {\n        if (typeof arguments[1] === 'function') {\n            // concurrency is optional, shift the args.\n            callback = concurrency;\n            concurrency = null;\n        }\n        callback = _once(callback || noop);\n        var keys = _keys(tasks);\n        var remainingTasks = keys.length;\n        if (!remainingTasks) {\n            return callback(null);\n        }\n        if (!concurrency) {\n            concurrency = remainingTasks;\n        }\n\n        var results = {};\n        var runningTasks = 0;\n\n        var hasError = false;\n\n        var listeners = [];\n        function addListener(fn) {\n            listeners.unshift(fn);\n        }\n        function removeListener(fn) {\n            var idx = _indexOf(listeners, fn);\n            if (idx >= 0) listeners.splice(idx, 1);\n        }\n        function taskComplete() {\n            remainingTasks--;\n            _arrayEach(listeners.slice(0), function (fn) {\n                fn();\n            });\n        }\n\n        addListener(function () {\n            if (!remainingTasks) {\n                callback(null, results);\n            }\n        });\n\n        _arrayEach(keys, function (k) {\n            if (hasError) return;\n            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n            var taskCallback = _restParam(function(err, args) {\n                runningTasks--;\n                if (args.length <= 1) {\n                    args = args[0];\n                }\n                if (err) {\n                    var safeResults = {};\n                    _forEachOf(results, function(val, rkey) {\n                        safeResults[rkey] = val;\n                    });\n                    safeResults[k] = args;\n                    hasError = true;\n\n                    callback(err, safeResults);\n                }\n                else {\n                    results[k] = args;\n                    async.setImmediate(taskComplete);\n                }\n            });\n            var requires = task.slice(0, task.length - 1);\n            // prevent dead-locks\n            var len = requires.length;\n            var dep;\n            while (len--) {\n                if (!(dep = tasks[requires[len]])) {\n                    throw new Error('Has nonexistent dependency in ' + requires.join(', '));\n                }\n                if (_isArray(dep) && _indexOf(dep, k) >= 0) {\n                    throw new Error('Has cyclic dependencies');\n                }\n            }\n            function ready() {\n                return runningTasks < concurrency && _reduce(requires, function (a, x) {\n                    return (a && results.hasOwnProperty(x));\n                }, true) && !results.hasOwnProperty(k);\n            }\n            if (ready()) {\n                runningTasks++;\n                task[task.length - 1](taskCallback, results);\n            }\n            else {\n                addListener(listener);\n            }\n            function listener() {\n                if (ready()) {\n                    runningTasks++;\n                    removeListener(listener);\n                    task[task.length - 1](taskCallback, results);\n                }\n            }\n        });\n    };\n\n\n\n    async.retry = function(times, task, callback) {\n        var DEFAULT_TIMES = 5;\n        var DEFAULT_INTERVAL = 0;\n\n        var attempts = [];\n\n        var opts = {\n            times: DEFAULT_TIMES,\n            interval: DEFAULT_INTERVAL\n        };\n\n        function parseTimes(acc, t){\n            if(typeof t === 'number'){\n                acc.times = parseInt(t, 10) || DEFAULT_TIMES;\n            } else if(typeof t === 'object'){\n                acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;\n                acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;\n            } else {\n                throw new Error('Unsupported argument type for \\'times\\': ' + typeof t);\n            }\n        }\n\n        var length = arguments.length;\n        if (length < 1 || length > 3) {\n            throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');\n        } else if (length <= 2 && typeof times === 'function') {\n            callback = task;\n            task = times;\n        }\n        if (typeof times !== 'function') {\n            parseTimes(opts, times);\n        }\n        opts.callback = callback;\n        opts.task = task;\n\n        function wrappedTask(wrappedCallback, wrappedResults) {\n            function retryAttempt(task, finalAttempt) {\n                return function(seriesCallback) {\n                    task(function(err, result){\n                        seriesCallback(!err || finalAttempt, {err: err, result: result});\n                    }, wrappedResults);\n                };\n            }\n\n            function retryInterval(interval){\n                return function(seriesCallback){\n                    setTimeout(function(){\n                        seriesCallback(null);\n                    }, interval);\n                };\n            }\n\n            while (opts.times) {\n\n                var finalAttempt = !(opts.times-=1);\n                attempts.push(retryAttempt(opts.task, finalAttempt));\n                if(!finalAttempt && opts.interval > 0){\n                    attempts.push(retryInterval(opts.interval));\n                }\n            }\n\n            async.series(attempts, function(done, data){\n                data = data[data.length - 1];\n                (wrappedCallback || opts.callback)(data.err, data.result);\n            });\n        }\n\n        // If a callback is passed, run this as a controll flow\n        return opts.callback ? wrappedTask() : wrappedTask;\n    };\n\n    async.waterfall = function (tasks, callback) {\n        callback = _once(callback || noop);\n        if (!_isArray(tasks)) {\n            var err = new Error('First argument to waterfall must be an array of functions');\n            return callback(err);\n        }\n        if (!tasks.length) {\n            return callback();\n        }\n        function wrapIterator(iterator) {\n            return _restParam(function (err, args) {\n                if (err) {\n                    callback.apply(null, [err].concat(args));\n                }\n                else {\n                    var next = iterator.next();\n                    if (next) {\n                        args.push(wrapIterator(next));\n                    }\n                    else {\n                        args.push(callback);\n                    }\n                    ensureAsync(iterator).apply(null, args);\n                }\n            });\n        }\n        wrapIterator(async.iterator(tasks))();\n    };\n\n    function _parallel(eachfn, tasks, callback) {\n        callback = callback || noop;\n        var results = _isArrayLike(tasks) ? [] : {};\n\n        eachfn(tasks, function (task, key, callback) {\n            task(_restParam(function (err, args) {\n                if (args.length <= 1) {\n                    args = args[0];\n                }\n                results[key] = args;\n                callback(err);\n            }));\n        }, function (err) {\n            callback(err, results);\n        });\n    }\n\n    async.parallel = function (tasks, callback) {\n        _parallel(async.eachOf, tasks, callback);\n    };\n\n    async.parallelLimit = function(tasks, limit, callback) {\n        _parallel(_eachOfLimit(limit), tasks, callback);\n    };\n\n    async.series = function(tasks, callback) {\n        _parallel(async.eachOfSeries, tasks, callback);\n    };\n\n    async.iterator = function (tasks) {\n        function makeCallback(index) {\n            function fn() {\n                if (tasks.length) {\n                    tasks[index].apply(null, arguments);\n                }\n                return fn.next();\n            }\n            fn.next = function () {\n                return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n            };\n            return fn;\n        }\n        return makeCallback(0);\n    };\n\n    async.apply = _restParam(function (fn, args) {\n        return _restParam(function (callArgs) {\n            return fn.apply(\n                null, args.concat(callArgs)\n            );\n        });\n    });\n\n    function _concat(eachfn, arr, fn, callback) {\n        var result = [];\n        eachfn(arr, function (x, index, cb) {\n            fn(x, function (err, y) {\n                result = result.concat(y || []);\n                cb(err);\n            });\n        }, function (err) {\n            callback(err, result);\n        });\n    }\n    async.concat = doParallel(_concat);\n    async.concatSeries = doSeries(_concat);\n\n    async.whilst = function (test, iterator, callback) {\n        callback = callback || noop;\n        if (test()) {\n            var next = _restParam(function(err, args) {\n                if (err) {\n                    callback(err);\n                } else if (test.apply(this, args)) {\n                    iterator(next);\n                } else {\n                    callback.apply(null, [null].concat(args));\n                }\n            });\n            iterator(next);\n        } else {\n            callback(null);\n        }\n    };\n\n    async.doWhilst = function (iterator, test, callback) {\n        var calls = 0;\n        return async.whilst(function() {\n            return ++calls <= 1 || test.apply(this, arguments);\n        }, iterator, callback);\n    };\n\n    async.until = function (test, iterator, callback) {\n        return async.whilst(function() {\n            return !test.apply(this, arguments);\n        }, iterator, callback);\n    };\n\n    async.doUntil = function (iterator, test, callback) {\n        return async.doWhilst(iterator, function() {\n            return !test.apply(this, arguments);\n        }, callback);\n    };\n\n    async.during = function (test, iterator, callback) {\n        callback = callback || noop;\n\n        var next = _restParam(function(err, args) {\n            if (err) {\n                callback(err);\n            } else {\n                args.push(check);\n                test.apply(this, args);\n            }\n        });\n\n        var check = function(err, truth) {\n            if (err) {\n                callback(err);\n            } else if (truth) {\n                iterator(next);\n            } else {\n                callback(null);\n            }\n        };\n\n        test(check);\n    };\n\n    async.doDuring = function (iterator, test, callback) {\n        var calls = 0;\n        async.during(function(next) {\n            if (calls++ < 1) {\n                next(null, true);\n            } else {\n                test.apply(this, arguments);\n            }\n        }, iterator, callback);\n    };\n\n    function _queue(worker, concurrency, payload) {\n        if (concurrency == null) {\n            concurrency = 1;\n        }\n        else if(concurrency === 0) {\n            throw new Error('Concurrency must not be zero');\n        }\n        function _insert(q, data, pos, callback) {\n            if (callback != null && typeof callback !== \"function\") {\n                throw new Error(\"task callback must be a function\");\n            }\n            q.started = true;\n            if (!_isArray(data)) {\n                data = [data];\n            }\n            if(data.length === 0 && q.idle()) {\n                // call drain immediately if there are no tasks\n                return async.setImmediate(function() {\n                    q.drain();\n                });\n            }\n            _arrayEach(data, function(task) {\n                var item = {\n                    data: task,\n                    callback: callback || noop\n                };\n\n                if (pos) {\n                    q.tasks.unshift(item);\n                } else {\n                    q.tasks.push(item);\n                }\n\n                if (q.tasks.length === q.concurrency) {\n                    q.saturated();\n                }\n            });\n            async.setImmediate(q.process);\n        }\n        function _next(q, tasks) {\n            return function(){\n                workers -= 1;\n\n                var removed = false;\n                var args = arguments;\n                _arrayEach(tasks, function (task) {\n                    _arrayEach(workersList, function (worker, index) {\n                        if (worker === task && !removed) {\n                            workersList.splice(index, 1);\n                            removed = true;\n                        }\n                    });\n\n                    task.callback.apply(task, args);\n                });\n                if (q.tasks.length + workers === 0) {\n                    q.drain();\n                }\n                q.process();\n            };\n        }\n\n        var workers = 0;\n        var workersList = [];\n        var q = {\n            tasks: [],\n            concurrency: concurrency,\n            payload: payload,\n            saturated: noop,\n            empty: noop,\n            drain: noop,\n            started: false,\n            paused: false,\n            push: function (data, callback) {\n                _insert(q, data, false, callback);\n            },\n            kill: function () {\n                q.drain = noop;\n                q.tasks = [];\n            },\n            unshift: function (data, callback) {\n                _insert(q, data, true, callback);\n            },\n            process: function () {\n                while(!q.paused && workers < q.concurrency && q.tasks.length){\n\n                    var tasks = q.payload ?\n                        q.tasks.splice(0, q.payload) :\n                        q.tasks.splice(0, q.tasks.length);\n\n                    var data = _map(tasks, function (task) {\n                        return task.data;\n                    });\n\n                    if (q.tasks.length === 0) {\n                        q.empty();\n                    }\n                    workers += 1;\n                    workersList.push(tasks[0]);\n                    var cb = only_once(_next(q, tasks));\n                    worker(data, cb);\n                }\n            },\n            length: function () {\n                return q.tasks.length;\n            },\n            running: function () {\n                return workers;\n            },\n            workersList: function () {\n                return workersList;\n            },\n            idle: function() {\n                return q.tasks.length + workers === 0;\n            },\n            pause: function () {\n                q.paused = true;\n            },\n            resume: function () {\n                if (q.paused === false) { return; }\n                q.paused = false;\n                var resumeCount = Math.min(q.concurrency, q.tasks.length);\n                // Need to call q.process once per concurrent\n                // worker to preserve full concurrency after pause\n                for (var w = 1; w <= resumeCount; w++) {\n                    async.setImmediate(q.process);\n                }\n            }\n        };\n        return q;\n    }\n\n    async.queue = function (worker, concurrency) {\n        var q = _queue(function (items, cb) {\n            worker(items[0], cb);\n        }, concurrency, 1);\n\n        return q;\n    };\n\n    async.priorityQueue = function (worker, concurrency) {\n\n        function _compareTasks(a, b){\n            return a.priority - b.priority;\n        }\n\n        function _binarySearch(sequence, item, compare) {\n            var beg = -1,\n                end = sequence.length - 1;\n            while (beg < end) {\n                var mid = beg + ((end - beg + 1) >>> 1);\n                if (compare(item, sequence[mid]) >= 0) {\n                    beg = mid;\n                } else {\n                    end = mid - 1;\n                }\n            }\n            return beg;\n        }\n\n        function _insert(q, data, priority, callback) {\n            if (callback != null && typeof callback !== \"function\") {\n                throw new Error(\"task callback must be a function\");\n            }\n            q.started = true;\n            if (!_isArray(data)) {\n                data = [data];\n            }\n            if(data.length === 0) {\n                // call drain immediately if there are no tasks\n                return async.setImmediate(function() {\n                    q.drain();\n                });\n            }\n            _arrayEach(data, function(task) {\n                var item = {\n                    data: task,\n                    priority: priority,\n                    callback: typeof callback === 'function' ? callback : noop\n                };\n\n                q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n                if (q.tasks.length === q.concurrency) {\n                    q.saturated();\n                }\n                async.setImmediate(q.process);\n            });\n        }\n\n        // Start with a normal queue\n        var q = async.queue(worker, concurrency);\n\n        // Override push to accept second parameter representing priority\n        q.push = function (data, priority, callback) {\n            _insert(q, data, priority, callback);\n        };\n\n        // Remove unshift function\n        delete q.unshift;\n\n        return q;\n    };\n\n    async.cargo = function (worker, payload) {\n        return _queue(worker, 1, payload);\n    };\n\n    function _console_fn(name) {\n        return _restParam(function (fn, args) {\n            fn.apply(null, args.concat([_restParam(function (err, args) {\n                if (typeof console === 'object') {\n                    if (err) {\n                        if (console.error) {\n                            console.error(err);\n                        }\n                    }\n                    else if (console[name]) {\n                        _arrayEach(args, function (x) {\n                            console[name](x);\n                        });\n                    }\n                }\n            })]));\n        });\n    }\n    async.log = _console_fn('log');\n    async.dir = _console_fn('dir');\n    /*async.info = _console_fn('info');\n    async.warn = _console_fn('warn');\n    async.error = _console_fn('error');*/\n\n    async.memoize = function (fn, hasher) {\n        var memo = {};\n        var queues = {};\n        var has = Object.prototype.hasOwnProperty;\n        hasher = hasher || identity;\n        var memoized = _restParam(function memoized(args) {\n            var callback = args.pop();\n            var key = hasher.apply(null, args);\n            if (has.call(memo, key)) {   \n                async.setImmediate(function () {\n                    callback.apply(null, memo[key]);\n                });\n            }\n            else if (has.call(queues, key)) {\n                queues[key].push(callback);\n            }\n            else {\n                queues[key] = [callback];\n                fn.apply(null, args.concat([_restParam(function (args) {\n                    memo[key] = args;\n                    var q = queues[key];\n                    delete queues[key];\n                    for (var i = 0, l = q.length; i < l; i++) {\n                        q[i].apply(null, args);\n                    }\n                })]));\n            }\n        });\n        memoized.memo = memo;\n        memoized.unmemoized = fn;\n        return memoized;\n    };\n\n    async.unmemoize = function (fn) {\n        return function () {\n            return (fn.unmemoized || fn).apply(null, arguments);\n        };\n    };\n\n    function _times(mapper) {\n        return function (count, iterator, callback) {\n            mapper(_range(count), iterator, callback);\n        };\n    }\n\n    async.times = _times(async.map);\n    async.timesSeries = _times(async.mapSeries);\n    async.timesLimit = function (count, limit, iterator, callback) {\n        return async.mapLimit(_range(count), limit, iterator, callback);\n    };\n\n    async.seq = function (/* functions... */) {\n        var fns = arguments;\n        return _restParam(function (args) {\n            var that = this;\n\n            var callback = args[args.length - 1];\n            if (typeof callback == 'function') {\n                args.pop();\n            } else {\n                callback = noop;\n            }\n\n            async.reduce(fns, args, function (newargs, fn, cb) {\n                fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {\n                    cb(err, nextargs);\n                })]));\n            },\n            function (err, results) {\n                callback.apply(that, [err].concat(results));\n            });\n        });\n    };\n\n    async.compose = function (/* functions... */) {\n        return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n    };\n\n\n    function _applyEach(eachfn) {\n        return _restParam(function(fns, args) {\n            var go = _restParam(function(args) {\n                var that = this;\n                var callback = args.pop();\n                return eachfn(fns, function (fn, _, cb) {\n                    fn.apply(that, args.concat([cb]));\n                },\n                callback);\n            });\n            if (args.length) {\n                return go.apply(this, args);\n            }\n            else {\n                return go;\n            }\n        });\n    }\n\n    async.applyEach = _applyEach(async.eachOf);\n    async.applyEachSeries = _applyEach(async.eachOfSeries);\n\n\n    async.forever = function (fn, callback) {\n        var done = only_once(callback || noop);\n        var task = ensureAsync(fn);\n        function next(err) {\n            if (err) {\n                return done(err);\n            }\n            task(next);\n        }\n        next();\n    };\n\n    function ensureAsync(fn) {\n        return _restParam(function (args) {\n            var callback = args.pop();\n            args.push(function () {\n                var innerArgs = arguments;\n                if (sync) {\n                    async.setImmediate(function () {\n                        callback.apply(null, innerArgs);\n                    });\n                } else {\n                    callback.apply(null, innerArgs);\n                }\n            });\n            var sync = true;\n            fn.apply(this, args);\n            sync = false;\n        });\n    }\n\n    async.ensureAsync = ensureAsync;\n\n    async.constant = _restParam(function(values) {\n        var args = [null].concat(values);\n        return function (callback) {\n            return callback.apply(this, args);\n        };\n    });\n\n    async.wrapSync =\n    async.asyncify = function asyncify(func) {\n        return _restParam(function (args) {\n            var callback = args.pop();\n            var result;\n            try {\n                result = func.apply(this, args);\n            } catch (e) {\n                return callback(e);\n            }\n            // if result is Promise object\n            if (_isObject(result) && typeof result.then === \"function\") {\n                result.then(function(value) {\n                    callback(null, value);\n                })[\"catch\"](function(err) {\n                    callback(err.message ? err : new Error(err));\n                });\n            } else {\n                callback(null, result);\n            }\n        });\n    };\n\n    // Node.js\n    if (typeof module === 'object' && module.exports) {\n        module.exports = async;\n    }\n    // AMD / RequireJS\n    else if (typeof define === 'function' && define.amd) {\n        define([], function () {\n            return async;\n        });\n    }\n    // included directly via <script> tag\n    else {\n        root.async = async;\n    }\n\n}());\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"_process\":3}],2:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = parts.length - 1; i >= 0; i--) {\n    var last = parts[i];\n    if (last === '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nvar splitPathRe =\n    /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/;\nvar splitPath = function(filename) {\n  return splitPathRe.exec(filename).slice(1);\n};\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\n  var resolvedPath = '',\n      resolvedAbsolute = false;\n\n  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n    var path = (i >= 0) ? arguments[i] : process.cwd();\n\n    // Skip empty and invalid entries\n    if (typeof path !== 'string') {\n      throw new TypeError('Arguments to path.resolve must be strings');\n    } else if (!path) {\n      continue;\n    }\n\n    resolvedPath = path + '/' + resolvedPath;\n    resolvedAbsolute = path.charAt(0) === '/';\n  }\n\n  // At this point the path should be resolved to a full absolute path, but\n  // handle relative paths to be safe (might happen when process.cwd() fails)\n\n  // Normalize the path\n  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n    return !!p;\n  }), !resolvedAbsolute).join('/');\n\n  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\n  var isAbsolute = exports.isAbsolute(path),\n      trailingSlash = substr(path, -1) === '/';\n\n  // Normalize the path\n  path = normalizeArray(filter(path.split('/'), function(p) {\n    return !!p;\n  }), !isAbsolute).join('/');\n\n  if (!path && !isAbsolute) {\n    path = '.';\n  }\n  if (path && trailingSlash) {\n    path += '/';\n  }\n\n  return (isAbsolute ? '/' : '') + path;\n};\n\n// posix version\nexports.isAbsolute = function(path) {\n  return path.charAt(0) === '/';\n};\n\n// posix version\nexports.join = function() {\n  var paths = Array.prototype.slice.call(arguments, 0);\n  return exports.normalize(filter(paths, function(p, index) {\n    if (typeof p !== 'string') {\n      throw new TypeError('Arguments to path.join must be strings');\n    }\n    return p;\n  }).join('/'));\n};\n\n\n// path.relative(from, to)\n// posix version\nexports.relative = function(from, to) {\n  from = exports.resolve(from).substr(1);\n  to = exports.resolve(to).substr(1);\n\n  function trim(arr) {\n    var start = 0;\n    for (; start < arr.length; start++) {\n      if (arr[start] !== '') break;\n    }\n\n    var end = arr.length - 1;\n    for (; end >= 0; end--) {\n      if (arr[end] !== '') break;\n    }\n\n    if (start > end) return [];\n    return arr.slice(start, end - start + 1);\n  }\n\n  var fromParts = trim(from.split('/'));\n  var toParts = trim(to.split('/'));\n\n  var length = Math.min(fromParts.length, toParts.length);\n  var samePartsLength = length;\n  for (var i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  var outputParts = [];\n  for (var i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n};\n\nexports.sep = '/';\nexports.delimiter = ':';\n\nexports.dirname = function(path) {\n  var result = splitPath(path),\n      root = result[0],\n      dir = result[1];\n\n  if (!root && !dir) {\n    // No dirname whatsoever\n    return '.';\n  }\n\n  if (dir) {\n    // It has a dirname, strip trailing slash\n    dir = dir.substr(0, dir.length - 1);\n  }\n\n  return root + dir;\n};\n\n\nexports.basename = function(path, ext) {\n  var f = splitPath(path)[2];\n  // TODO: make this comparison case-insensitive on windows?\n  if (ext && f.substr(-1 * ext.length) === ext) {\n    f = f.substr(0, f.length - ext.length);\n  }\n  return f;\n};\n\n\nexports.extname = function(path) {\n  return splitPath(path)[3];\n};\n\nfunction filter (xs, f) {\n    if (xs.filter) return xs.filter(f);\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        if (f(xs[i], i, xs)) res.push(xs[i]);\n    }\n    return res;\n}\n\n// String.prototype.substr - negative index don't work in IE8\nvar substr = 'ab'.substr(-1) === 'b'\n    ? function (str, start, len) { return str.substr(start, len) }\n    : function (str, start, len) {\n        if (start < 0) start = str.length + start;\n        return str.substr(start, len);\n    }\n;\n\n}).call(this,require('_process'))\n},{\"_process\":3}],3:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],4:[function(require,module,exports){\n(function (global){\n/*! https://mths.be/punycode v1.4.0 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow new RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t    counter = 0,\n\t\t    length = string.length,\n\t\t    value,\n\t\t    extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t//  0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * https://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t    inputLength = input.length,\n\t\t    out,\n\t\t    i = 0,\n\t\t    n = initialN,\n\t\t    bias = initialBias,\n\t\t    basic,\n\t\t    j,\n\t\t    index,\n\t\t    oldi,\n\t\t    w,\n\t\t    k,\n\t\t    digit,\n\t\t    t,\n\t\t    /** Cached calculation results */\n\t\t    baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols (e.g. a domain name label) to a\n\t * Punycode string of ASCII-only symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t    delta,\n\t\t    handledCPCount,\n\t\t    basicLength,\n\t\t    bias,\n\t\t    j,\n\t\t    m,\n\t\t    q,\n\t\t    k,\n\t\t    t,\n\t\t    currentValue,\n\t\t    output = [],\n\t\t    /** `inputLength` will hold the number of code points in `input`. */\n\t\t    inputLength,\n\t\t    /** Cached calculation results */\n\t\t    handledCPCountPlusOne,\n\t\t    baseMinusT,\n\t\t    qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name or an email address\n\t * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n\t * it doesn't matter if you call it on a string that has already been\n\t * converted to Unicode.\n\t * @memberOf punycode\n\t * @param {String} input The Punycoded domain name or email address to\n\t * convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name or an email address to\n\t * Punycode. Only the non-ASCII parts of the domain name will be converted,\n\t * i.e. it doesn't matter if you call it with a domain that's already in\n\t * ASCII.\n\t * @memberOf punycode\n\t * @param {String} input The domain name or email address to convert, as a\n\t * Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name or\n\t * email address.\n\t */\n\tfunction toASCII(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.3.2',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine('punycode', function() {\n\t\t\treturn punycode;\n\t\t});\n\t} else if (freeExports && freeModule) {\n\t\tif (module.exports == freeExports) {\n\t\t\t// in Node.js, io.js, or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = punycode;\n\t\t} else {\n\t\t\t// in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (key in punycode) {\n\t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// in Rhino or a web browser\n\t\troot.punycode = punycode;\n\t}\n\n}(this));\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],5:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n  sep = sep || '&';\n  eq = eq || '=';\n  var obj = {};\n\n  if (typeof qs !== 'string' || qs.length === 0) {\n    return obj;\n  }\n\n  var regexp = /\\+/g;\n  qs = qs.split(sep);\n\n  var maxKeys = 1000;\n  if (options && typeof options.maxKeys === 'number') {\n    maxKeys = options.maxKeys;\n  }\n\n  var len = qs.length;\n  // maxKeys <= 0 means that we should not limit keys count\n  if (maxKeys > 0 && len > maxKeys) {\n    len = maxKeys;\n  }\n\n  for (var i = 0; i < len; ++i) {\n    var x = qs[i].replace(regexp, '%20'),\n        idx = x.indexOf(eq),\n        kstr, vstr, k, v;\n\n    if (idx >= 0) {\n      kstr = x.substr(0, idx);\n      vstr = x.substr(idx + 1);\n    } else {\n      kstr = x;\n      vstr = '';\n    }\n\n    k = decodeURIComponent(kstr);\n    v = decodeURIComponent(vstr);\n\n    if (!hasOwnProperty(obj, k)) {\n      obj[k] = v;\n    } else if (isArray(obj[k])) {\n      obj[k].push(v);\n    } else {\n      obj[k] = [obj[k], v];\n    }\n  }\n\n  return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n},{}],6:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar stringifyPrimitive = function(v) {\n  switch (typeof v) {\n    case 'string':\n      return v;\n\n    case 'boolean':\n      return v ? 'true' : 'false';\n\n    case 'number':\n      return isFinite(v) ? v : '';\n\n    default:\n      return '';\n  }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n  sep = sep || '&';\n  eq = eq || '=';\n  if (obj === null) {\n    obj = undefined;\n  }\n\n  if (typeof obj === 'object') {\n    return map(objectKeys(obj), function(k) {\n      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n      if (isArray(obj[k])) {\n        return map(obj[k], function(v) {\n          return ks + encodeURIComponent(stringifyPrimitive(v));\n        }).join(sep);\n      } else {\n        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n      }\n    }).join(sep);\n\n  }\n\n  if (!name) return '';\n  return encodeURIComponent(stringifyPrimitive(name)) + eq +\n         encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n  if (xs.map) return xs.map(f);\n  var res = [];\n  for (var i = 0; i < xs.length; i++) {\n    res.push(f(xs[i], i));\n  }\n  return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n  var res = [];\n  for (var key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n  }\n  return res;\n};\n\n},{}],7:[function(require,module,exports){\n'use strict';\n\nexports.decode = exports.parse = require('./decode');\nexports.encode = exports.stringify = require('./encode');\n\n},{\"./decode\":5,\"./encode\":6}],8:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar punycode = require('punycode');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.host = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.query = null;\n  this.pathname = null;\n  this.path = null;\n  this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n    portPattern = /:[0-9]*$/,\n\n    // RFC 2396: characters reserved for delimiting URLs.\n    // We actually just auto-escape these.\n    delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n    // RFC 2396: characters not allowed for various reasons.\n    unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.\n    autoEscape = ['\\''].concat(unwise),\n    // Characters that are never ever allowed in a hostname.\n    // Note that any invalid chars are also handled, but these\n    // are the ones that are *expected* to be seen, so we fast-path\n    // them.\n    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n    hostEndingChars = ['/', '?', '#'],\n    hostnameMaxLen = 255,\n    hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,\n    hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,\n    // protocols that can allow \"unsafe\" and \"unwise\" chars.\n    unsafeProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that never have a hostname.\n    hostlessProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that always contain a // bit.\n    slashedProtocol = {\n      'http': true,\n      'https': true,\n      'ftp': true,\n      'gopher': true,\n      'file': true,\n      'http:': true,\n      'https:': true,\n      'ftp:': true,\n      'gopher:': true,\n      'file:': true\n    },\n    querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n  if (url && isObject(url) && url instanceof Url) return url;\n\n  var u = new Url;\n  u.parse(url, parseQueryString, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n  if (!isString(url)) {\n    throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n  }\n\n  var rest = url;\n\n  // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n  rest = rest.trim();\n\n  var proto = protocolPattern.exec(rest);\n  if (proto) {\n    proto = proto[0];\n    var lowerProto = proto.toLowerCase();\n    this.protocol = lowerProto;\n    rest = rest.substr(proto.length);\n  }\n\n  // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    var slashes = rest.substr(0, 2) === '//';\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n\n  if (!hostlessProtocol[proto] &&\n      (slashes || (proto && !slashedProtocol[proto]))) {\n\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    //\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    //\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n\n    // find the first instance of any hostEndingChars\n    var hostEnd = -1;\n    for (var i = 0; i < hostEndingChars.length; i++) {\n      var hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n\n    // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n    var auth, atSign;\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf('@');\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf('@', hostEnd);\n    }\n\n    // Now we have a portion which is definitely the auth.\n    // Pull that off.\n    if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = decodeURIComponent(auth);\n    }\n\n    // the host is the remaining to the left of the first non-host char\n    hostEnd = -1;\n    for (var i = 0; i < nonHostChars.length; i++) {\n      var hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n    // if we still have not hit it, then the entire thing is a host.\n    if (hostEnd === -1)\n      hostEnd = rest.length;\n\n    this.host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd);\n\n    // pull out port.\n    this.parseHost();\n\n    // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n    this.hostname = this.hostname || '';\n\n    // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n    var ipv6Hostname = this.hostname[0] === '[' &&\n        this.hostname[this.hostname.length - 1] === ']';\n\n    // validate a little.\n    if (!ipv6Hostname) {\n      var hostparts = this.hostname.split(/\\./);\n      for (var i = 0, l = hostparts.length; i < l; i++) {\n        var part = hostparts[i];\n        if (!part) continue;\n        if (!part.match(hostnamePartPattern)) {\n          var newpart = '';\n          for (var j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += 'x';\n            } else {\n              newpart += part[j];\n            }\n          }\n          // we test again with ASCII char only\n          if (!newpart.match(hostnamePartPattern)) {\n            var validParts = hostparts.slice(0, i);\n            var notHost = hostparts.slice(i + 1);\n            var bit = part.match(hostnamePartStart);\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n            if (notHost.length) {\n              rest = '/' + notHost.join('.') + rest;\n            }\n            this.hostname = validParts.join('.');\n            break;\n          }\n        }\n      }\n    }\n\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = '';\n    } else {\n      // hostnames are always lower case.\n      this.hostname = this.hostname.toLowerCase();\n    }\n\n    if (!ipv6Hostname) {\n      // IDNA Support: Returns a puny coded representation of \"domain\".\n      // It only converts the part of the domain name that\n      // has non ASCII characters. I.e. it dosent matter if\n      // you call it with a domain that already is in ASCII.\n      var domainArray = this.hostname.split('.');\n      var newOut = [];\n      for (var i = 0; i < domainArray.length; ++i) {\n        var s = domainArray[i];\n        newOut.push(s.match(/[^A-Za-z0-9_-]/) ?\n            'xn--' + punycode.encode(s) : s);\n      }\n      this.hostname = newOut.join('.');\n    }\n\n    var p = this.port ? ':' + this.port : '';\n    var h = this.hostname || '';\n    this.host = h + p;\n    this.href += this.host;\n\n    // strip [ and ] from the hostname\n    // the host field still retains them, though\n    if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n      if (rest[0] !== '/') {\n        rest = '/' + rest;\n      }\n    }\n  }\n\n  // now rest is set to the post-host stuff.\n  // chop off any delim chars.\n  if (!unsafeProtocol[lowerProto]) {\n\n    // First, make 100% sure that any \"autoEscape\" chars get\n    // escaped, even if encodeURIComponent doesn't think they\n    // need to be.\n    for (var i = 0, l = autoEscape.length; i < l; i++) {\n      var ae = autoEscape[i];\n      var esc = encodeURIComponent(ae);\n      if (esc === ae) {\n        esc = escape(ae);\n      }\n      rest = rest.split(ae).join(esc);\n    }\n  }\n\n\n  // chop off from the tail first.\n  var hash = rest.indexOf('#');\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n  var qm = rest.indexOf('?');\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    this.query = rest.substr(qm + 1);\n    if (parseQueryString) {\n      this.query = querystring.parse(this.query);\n    }\n    rest = rest.slice(0, qm);\n  } else if (parseQueryString) {\n    // no query string, but parseQueryString still requested\n    this.search = '';\n    this.query = {};\n  }\n  if (rest) this.pathname = rest;\n  if (slashedProtocol[lowerProto] &&\n      this.hostname && !this.pathname) {\n    this.pathname = '/';\n  }\n\n  //to support http.request\n  if (this.pathname || this.search) {\n    var p = this.pathname || '';\n    var s = this.search || '';\n    this.path = p + s;\n  }\n\n  // finally, reconstruct the href based on what has been validated.\n  this.href = this.format();\n  return this;\n};\n\n// format a parsed object into a url string\nfunction urlFormat(obj) {\n  // ensure it's an object, and not a string url.\n  // If it's an obj, this is a no-op.\n  // this way, you can call url_format() on strings\n  // to clean up potentially wonky urls.\n  if (isString(obj)) obj = urlParse(obj);\n  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n  return obj.format();\n}\n\nUrl.prototype.format = function() {\n  var auth = this.auth || '';\n  if (auth) {\n    auth = encodeURIComponent(auth);\n    auth = auth.replace(/%3A/i, ':');\n    auth += '@';\n  }\n\n  var protocol = this.protocol || '',\n      pathname = this.pathname || '',\n      hash = this.hash || '',\n      host = false,\n      query = '';\n\n  if (this.host) {\n    host = auth + this.host;\n  } else if (this.hostname) {\n    host = auth + (this.hostname.indexOf(':') === -1 ?\n        this.hostname :\n        '[' + this.hostname + ']');\n    if (this.port) {\n      host += ':' + this.port;\n    }\n  }\n\n  if (this.query &&\n      isObject(this.query) &&\n      Object.keys(this.query).length) {\n    query = querystring.stringify(this.query);\n  }\n\n  var search = this.search || (query && ('?' + query)) || '';\n\n  if (protocol && protocol.substr(-1) !== ':') protocol += ':';\n\n  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.\n  // unless they had them to begin with.\n  if (this.slashes ||\n      (!protocol || slashedProtocol[protocol]) && host !== false) {\n    host = '//' + (host || '');\n    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n  } else if (!host) {\n    host = '';\n  }\n\n  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n  if (search && search.charAt(0) !== '?') search = '?' + search;\n\n  pathname = pathname.replace(/[?#]/g, function(match) {\n    return encodeURIComponent(match);\n  });\n  search = search.replace('#', '%23');\n\n  return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n  return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function(relative) {\n  return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n  if (!source) return relative;\n  return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function(relative) {\n  if (isString(relative)) {\n    var rel = new Url();\n    rel.parse(relative, false, true);\n    relative = rel;\n  }\n\n  var result = new Url();\n  Object.keys(this).forEach(function(k) {\n    result[k] = this[k];\n  }, this);\n\n  // hash is always overridden, no matter what.\n  // even href=\"\" will remove it.\n  result.hash = relative.hash;\n\n  // if the relative url is empty, then there's nothing left to do here.\n  if (relative.href === '') {\n    result.href = result.format();\n    return result;\n  }\n\n  // hrefs like //foo/bar always cut to the protocol.\n  if (relative.slashes && !relative.protocol) {\n    // take everything except the protocol from relative\n    Object.keys(relative).forEach(function(k) {\n      if (k !== 'protocol')\n        result[k] = relative[k];\n    });\n\n    //urlParse appends trailing / to urls like http://www.example.com\n    if (slashedProtocol[result.protocol] &&\n        result.hostname && !result.pathname) {\n      result.path = result.pathname = '/';\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (relative.protocol && relative.protocol !== result.protocol) {\n    // if it's a known url protocol, then changing\n    // the protocol does weird things\n    // first, if it's not file:, then we MUST have a host,\n    // and if there was a path\n    // to begin with, then we MUST have a path.\n    // if it is file:, then the host is dropped,\n    // because that's known to be hostless.\n    // anything else is assumed to be absolute.\n    if (!slashedProtocol[relative.protocol]) {\n      Object.keys(relative).forEach(function(k) {\n        result[k] = relative[k];\n      });\n      result.href = result.format();\n      return result;\n    }\n\n    result.protocol = relative.protocol;\n    if (!relative.host && !hostlessProtocol[relative.protocol]) {\n      var relPath = (relative.pathname || '').split('/');\n      while (relPath.length && !(relative.host = relPath.shift()));\n      if (!relative.host) relative.host = '';\n      if (!relative.hostname) relative.hostname = '';\n      if (relPath[0] !== '') relPath.unshift('');\n      if (relPath.length < 2) relPath.unshift('');\n      result.pathname = relPath.join('/');\n    } else {\n      result.pathname = relative.pathname;\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    result.host = relative.host || '';\n    result.auth = relative.auth;\n    result.hostname = relative.hostname || relative.host;\n    result.port = relative.port;\n    // to support http.request\n    if (result.pathname || result.search) {\n      var p = result.pathname || '';\n      var s = result.search || '';\n      result.path = p + s;\n    }\n    result.slashes = result.slashes || relative.slashes;\n    result.href = result.format();\n    return result;\n  }\n\n  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),\n      isRelAbs = (\n          relative.host ||\n          relative.pathname && relative.pathname.charAt(0) === '/'\n      ),\n      mustEndAbs = (isRelAbs || isSourceAbs ||\n                    (result.host && relative.pathname)),\n      removeAllDots = mustEndAbs,\n      srcPath = result.pathname && result.pathname.split('/') || [],\n      relPath = relative.pathname && relative.pathname.split('/') || [],\n      psychotic = result.protocol && !slashedProtocol[result.protocol];\n\n  // if the url is a non-slashed url, then relative\n  // links like ../.. should be able\n  // to crawl up to the hostname, as well.  This is strange.\n  // result.protocol has already been set by now.\n  // Later on, put the first path part into the host field.\n  if (psychotic) {\n    result.hostname = '';\n    result.port = null;\n    if (result.host) {\n      if (srcPath[0] === '') srcPath[0] = result.host;\n      else srcPath.unshift(result.host);\n    }\n    result.host = '';\n    if (relative.protocol) {\n      relative.hostname = null;\n      relative.port = null;\n      if (relative.host) {\n        if (relPath[0] === '') relPath[0] = relative.host;\n        else relPath.unshift(relative.host);\n      }\n      relative.host = null;\n    }\n    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n  }\n\n  if (isRelAbs) {\n    // it's absolute.\n    result.host = (relative.host || relative.host === '') ?\n                  relative.host : result.host;\n    result.hostname = (relative.hostname || relative.hostname === '') ?\n                      relative.hostname : result.hostname;\n    result.search = relative.search;\n    result.query = relative.query;\n    srcPath = relPath;\n    // fall through to the dot-handling below.\n  } else if (relPath.length) {\n    // it's relative\n    // throw away the existing file, and take the new path instead.\n    if (!srcPath) srcPath = [];\n    srcPath.pop();\n    srcPath = srcPath.concat(relPath);\n    result.search = relative.search;\n    result.query = relative.query;\n  } else if (!isNullOrUndefined(relative.search)) {\n    // just pull out the search.\n    // like href='?foo'.\n    // Put this after the other two cases because it simplifies the booleans\n    if (psychotic) {\n      result.hostname = result.host = srcPath.shift();\n      //occationaly the auth can get stuck only in host\n      //this especialy happens in cases like\n      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n      var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                       result.host.split('@') : false;\n      if (authInHost) {\n        result.auth = authInHost.shift();\n        result.host = result.hostname = authInHost.shift();\n      }\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    //to support http.request\n    if (!isNull(result.pathname) || !isNull(result.search)) {\n      result.path = (result.pathname ? result.pathname : '') +\n                    (result.search ? result.search : '');\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  if (!srcPath.length) {\n    // no path at all.  easy.\n    // we've already handled the other stuff above.\n    result.pathname = null;\n    //to support http.request\n    if (result.search) {\n      result.path = '/' + result.search;\n    } else {\n      result.path = null;\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  // if a url ENDs in . or .., then it must get a trailing slash.\n  // however, if it ends in anything else non-slashy,\n  // then it must NOT get a trailing slash.\n  var last = srcPath.slice(-1)[0];\n  var hasTrailingSlash = (\n      (result.host || relative.host) && (last === '.' || last === '..') ||\n      last === '');\n\n  // strip single dots, resolve double dots to parent dir\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = srcPath.length; i >= 0; i--) {\n    last = srcPath[i];\n    if (last == '.') {\n      srcPath.splice(i, 1);\n    } else if (last === '..') {\n      srcPath.splice(i, 1);\n      up++;\n    } else if (up) {\n      srcPath.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (!mustEndAbs && !removeAllDots) {\n    for (; up--; up) {\n      srcPath.unshift('..');\n    }\n  }\n\n  if (mustEndAbs && srcPath[0] !== '' &&\n      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n    srcPath.unshift('');\n  }\n\n  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {\n    srcPath.push('');\n  }\n\n  var isAbsolute = srcPath[0] === '' ||\n      (srcPath[0] && srcPath[0].charAt(0) === '/');\n\n  // put the host back\n  if (psychotic) {\n    result.hostname = result.host = isAbsolute ? '' :\n                                    srcPath.length ? srcPath.shift() : '';\n    //occationaly the auth can get stuck only in host\n    //this especialy happens in cases like\n    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n    var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                     result.host.split('@') : false;\n    if (authInHost) {\n      result.auth = authInHost.shift();\n      result.host = result.hostname = authInHost.shift();\n    }\n  }\n\n  mustEndAbs = mustEndAbs || (result.host && srcPath.length);\n\n  if (mustEndAbs && !isAbsolute) {\n    srcPath.unshift('');\n  }\n\n  if (!srcPath.length) {\n    result.pathname = null;\n    result.path = null;\n  } else {\n    result.pathname = srcPath.join('/');\n  }\n\n  //to support request.http\n  if (!isNull(result.pathname) || !isNull(result.search)) {\n    result.path = (result.pathname ? result.pathname : '') +\n                  (result.search ? result.search : '');\n  }\n  result.auth = relative.auth || result.auth;\n  result.slashes = result.slashes || relative.slashes;\n  result.href = result.format();\n  return result;\n};\n\nUrl.prototype.parseHost = function() {\n  var host = this.host;\n  var port = portPattern.exec(host);\n  if (port) {\n    port = port[0];\n    if (port !== ':') {\n      this.port = port.substr(1);\n    }\n    host = host.substr(0, host.length - port.length);\n  }\n  if (host) this.hostname = host;\n};\n\nfunction isString(arg) {\n  return typeof arg === \"string\";\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isNull(arg) {\n  return arg === null;\n}\nfunction isNullOrUndefined(arg) {\n  return  arg == null;\n}\n\n},{\"punycode\":4,\"querystring\":7}],9:[function(require,module,exports){\n'use strict';\n\nmodule.exports = earcut;\n\nfunction earcut(data, holeIndices, dim) {\n\n    dim = dim || 2;\n\n    var hasHoles = holeIndices && holeIndices.length,\n        outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n        outerNode = linkedList(data, 0, outerLen, dim, true),\n        triangles = [];\n\n    if (!outerNode) return triangles;\n\n    var minX, minY, maxX, maxY, x, y, size;\n\n    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n    if (data.length > 80 * dim) {\n        minX = maxX = data[0];\n        minY = maxY = data[1];\n\n        for (var i = dim; i < outerLen; i += dim) {\n            x = data[i];\n            y = data[i + 1];\n            if (x < minX) minX = x;\n            if (y < minY) minY = y;\n            if (x > maxX) maxX = x;\n            if (y > maxY) maxY = y;\n        }\n\n        // minX, minY and size are later used to transform coords into integers for z-order calculation\n        size = Math.max(maxX - minX, maxY - minY);\n    }\n\n    earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\n    return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n    var sum = 0,\n        i, j, last;\n\n    // calculate original winding order of a polygon ring\n    for (i = start, j = end - dim; i < end; i += dim) {\n        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n        j = i;\n    }\n\n    // link points into circular doubly-linked list in the specified winding order\n    if (clockwise === (sum > 0)) {\n        for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n    } else {\n        for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n    }\n\n    return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n    if (!start) return start;\n    if (!end) end = start;\n\n    var p = start,\n        again;\n    do {\n        again = false;\n\n        if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n            removeNode(p);\n            p = end = p.prev;\n            if (p === p.next) return null;\n            again = true;\n\n        } else {\n            p = p.next;\n        }\n    } while (again || p !== end);\n\n    return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n    if (!ear) return;\n\n    // interlink polygon nodes in z-order\n    if (!pass && size) indexCurve(ear, minX, minY, size);\n\n    var stop = ear,\n        prev, next;\n\n    // iterate through ears, slicing them one by one\n    while (ear.prev !== ear.next) {\n        prev = ear.prev;\n        next = ear.next;\n\n        if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n            // cut off the triangle\n            triangles.push(prev.i / dim);\n            triangles.push(ear.i / dim);\n            triangles.push(next.i / dim);\n\n            removeNode(ear);\n\n            // skipping the next vertice leads to less sliver triangles\n            ear = next.next;\n            stop = next.next;\n\n            continue;\n        }\n\n        ear = next;\n\n        // if we looped through the whole remaining polygon and can't find any more ears\n        if (ear === stop) {\n            // try filtering points and slicing again\n            if (!pass) {\n                earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\n            // if this didn't work, try curing all small self-intersections locally\n            } else if (pass === 1) {\n                ear = cureLocalIntersections(ear, triangles, dim);\n                earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\n            // as a last resort, try splitting the remaining polygon into two\n            } else if (pass === 2) {\n                splitEarcut(ear, triangles, dim, minX, minY, size);\n            }\n\n            break;\n        }\n    }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n    var a = ear.prev,\n        b = ear,\n        c = ear.next;\n\n    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n    // now make sure we don't have other points inside the potential ear\n    var p = ear.next.next;\n\n    while (p !== ear.prev) {\n        if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n            area(p.prev, p, p.next) >= 0) return false;\n        p = p.next;\n    }\n\n    return true;\n}\n\nfunction isEarHashed(ear, minX, minY, size) {\n    var a = ear.prev,\n        b = ear,\n        c = ear.next;\n\n    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n    // triangle bbox; min & max are calculated like this for speed\n    var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n        minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n        maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n        maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n    // z-order range for the current triangle bbox;\n    var minZ = zOrder(minTX, minTY, minX, minY, size),\n        maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\n    // first look for points inside the triangle in increasing z-order\n    var p = ear.nextZ;\n\n    while (p && p.z <= maxZ) {\n        if (p !== ear.prev && p !== ear.next &&\n            pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n            area(p.prev, p, p.next) >= 0) return false;\n        p = p.nextZ;\n    }\n\n    // then look for points in decreasing z-order\n    p = ear.prevZ;\n\n    while (p && p.z >= minZ) {\n        if (p !== ear.prev && p !== ear.next &&\n            pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n            area(p.prev, p, p.next) >= 0) return false;\n        p = p.prevZ;\n    }\n\n    return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n    var p = start;\n    do {\n        var a = p.prev,\n            b = p.next.next;\n\n        // a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2])\n        if (intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n            triangles.push(a.i / dim);\n            triangles.push(p.i / dim);\n            triangles.push(b.i / dim);\n\n            // remove two nodes involved\n            removeNode(p);\n            removeNode(p.next);\n\n            p = start = b;\n        }\n        p = p.next;\n    } while (p !== start);\n\n    return p;\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n    // look for a valid diagonal that divides the polygon into two\n    var a = start;\n    do {\n        var b = a.next.next;\n        while (b !== a.prev) {\n            if (a.i !== b.i && isValidDiagonal(a, b)) {\n                // split the polygon in two by the diagonal\n                var c = splitPolygon(a, b);\n\n                // filter colinear points around the cuts\n                a = filterPoints(a, a.next);\n                c = filterPoints(c, c.next);\n\n                // run earcut on each half\n                earcutLinked(a, triangles, dim, minX, minY, size);\n                earcutLinked(c, triangles, dim, minX, minY, size);\n                return;\n            }\n            b = b.next;\n        }\n        a = a.next;\n    } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n    var queue = [],\n        i, len, start, end, list;\n\n    for (i = 0, len = holeIndices.length; i < len; i++) {\n        start = holeIndices[i] * dim;\n        end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n        list = linkedList(data, start, end, dim, false);\n        if (list === list.next) list.steiner = true;\n        queue.push(getLeftmost(list));\n    }\n\n    queue.sort(compareX);\n\n    // process holes from left to right\n    for (i = 0; i < queue.length; i++) {\n        eliminateHole(queue[i], outerNode);\n        outerNode = filterPoints(outerNode, outerNode.next);\n    }\n\n    return outerNode;\n}\n\nfunction compareX(a, b) {\n    return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n    outerNode = findHoleBridge(hole, outerNode);\n    if (outerNode) {\n        var b = splitPolygon(outerNode, hole);\n        filterPoints(b, b.next);\n    }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n    var p = outerNode,\n        hx = hole.x,\n        hy = hole.y,\n        qx = -Infinity,\n        m;\n\n    // find a segment intersected by a ray from the hole's leftmost point to the left;\n    // segment's endpoint with lesser x will be potential connection point\n    do {\n        if (hy <= p.y && hy >= p.next.y) {\n            var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n            if (x <= hx && x > qx) {\n                qx = x;\n                m = p.x < p.next.x ? p : p.next;\n            }\n        }\n        p = p.next;\n    } while (p !== outerNode);\n\n    if (!m) return null;\n\n    if (hole.x === m.x) return m.prev; // hole touches outer segment; pick lower endpoint\n\n    // look for points inside the triangle of hole point, segment intersection and endpoint;\n    // if there are no points found, we have a valid connection;\n    // otherwise choose the point of the minimum angle with the ray as connection point\n\n    var stop = m,\n        tanMin = Infinity,\n        tan;\n\n    p = m.next;\n\n    while (p !== stop) {\n        if (hx >= p.x && p.x >= m.x &&\n                pointInTriangle(hy < m.y ? hx : qx, hy, m.x, m.y, hy < m.y ? qx : hx, hy, p.x, p.y)) {\n\n            tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n            if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n                m = p;\n                tanMin = tan;\n            }\n        }\n\n        p = p.next;\n    }\n\n    return m;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, size) {\n    var p = start;\n    do {\n        if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n        p.prevZ = p.prev;\n        p.nextZ = p.next;\n        p = p.next;\n    } while (p !== start);\n\n    p.prevZ.nextZ = null;\n    p.prevZ = null;\n\n    sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n    var i, p, q, e, tail, numMerges, pSize, qSize,\n        inSize = 1;\n\n    do {\n        p = list;\n        list = null;\n        tail = null;\n        numMerges = 0;\n\n        while (p) {\n            numMerges++;\n            q = p;\n            pSize = 0;\n            for (i = 0; i < inSize; i++) {\n                pSize++;\n                q = q.nextZ;\n                if (!q) break;\n            }\n\n            qSize = inSize;\n\n            while (pSize > 0 || (qSize > 0 && q)) {\n\n                if (pSize === 0) {\n                    e = q;\n                    q = q.nextZ;\n                    qSize--;\n                } else if (qSize === 0 || !q) {\n                    e = p;\n                    p = p.nextZ;\n                    pSize--;\n                } else if (p.z <= q.z) {\n                    e = p;\n                    p = p.nextZ;\n                    pSize--;\n                } else {\n                    e = q;\n                    q = q.nextZ;\n                    qSize--;\n                }\n\n                if (tail) tail.nextZ = e;\n                else list = e;\n\n                e.prevZ = tail;\n                tail = e;\n            }\n\n            p = q;\n        }\n\n        tail.nextZ = null;\n        inSize *= 2;\n\n    } while (numMerges > 1);\n\n    return list;\n}\n\n// z-order of a point given coords and size of the data bounding box\nfunction zOrder(x, y, minX, minY, size) {\n    // coords are transformed into non-negative 15-bit integer range\n    x = 32767 * (x - minX) / size;\n    y = 32767 * (y - minY) / size;\n\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n\n    y = (y | (y << 8)) & 0x00FF00FF;\n    y = (y | (y << 4)) & 0x0F0F0F0F;\n    y = (y | (y << 2)) & 0x33333333;\n    y = (y | (y << 1)) & 0x55555555;\n\n    return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n    var p = start,\n        leftmost = start;\n    do {\n        if (p.x < leftmost.x) leftmost = p;\n        p = p.next;\n    } while (p !== start);\n\n    return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n    return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n           (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n           (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n    return equals(a, b) || a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n           locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n    return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n    return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n    return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n           area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n    var p = a;\n    do {\n        if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n                intersects(p, p.next, a, b)) return true;\n        p = p.next;\n    } while (p !== a);\n\n    return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n    return area(a.prev, a, a.next) < 0 ?\n        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n    var p = a,\n        inside = false,\n        px = (a.x + b.x) / 2,\n        py = (a.y + b.y) / 2;\n    do {\n        if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n            inside = !inside;\n        p = p.next;\n    } while (p !== a);\n\n    return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n    var a2 = new Node(a.i, a.x, a.y),\n        b2 = new Node(b.i, b.x, b.y),\n        an = a.next,\n        bp = b.prev;\n\n    a.next = b;\n    b.prev = a;\n\n    a2.next = an;\n    an.prev = a2;\n\n    b2.next = a2;\n    a2.prev = b2;\n\n    bp.next = b2;\n    b2.prev = bp;\n\n    return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n    var p = new Node(i, x, y);\n\n    if (!last) {\n        p.prev = p;\n        p.next = p;\n\n    } else {\n        p.next = last.next;\n        p.prev = last;\n        last.next.prev = p;\n        last.next = p;\n    }\n    return p;\n}\n\nfunction removeNode(p) {\n    p.next.prev = p.prev;\n    p.prev.next = p.next;\n\n    if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n    if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n    // vertice index in coordinates array\n    this.i = i;\n\n    // vertex coordinates\n    this.x = x;\n    this.y = y;\n\n    // previous and next vertice nodes in a polygon ring\n    this.prev = null;\n    this.next = null;\n\n    // z-order curve value\n    this.z = null;\n\n    // previous and next nodes in z-order\n    this.prevZ = null;\n    this.nextZ = null;\n\n    // indicates whether this is a steiner point\n    this.steiner = false;\n}\n\n},{}],10:[function(require,module,exports){\n'use strict';\n\n//\n// We store our EE objects in a plain object whose properties are event names.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// `~` to make sure that the built-in object properties are not overridden or\n// used as an attack vector.\n// We also assume that `Object.create(null)` is available when the event name\n// is an ES6 Symbol.\n//\nvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\n/**\n * Representation of a single EventEmitter function.\n *\n * @param {Function} fn Event handler to be called.\n * @param {Mixed} context Context for function execution.\n * @param {Boolean} once Only emit once\n * @api private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Minimal EventEmitter interface that is molded against the Node.js\n * EventEmitter interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() { /* Nothing to set */ }\n\n/**\n * Holds the assigned EventEmitters by name.\n *\n * @type {Object}\n * @private\n */\nEventEmitter.prototype._events = undefined;\n\n/**\n * Return a list of assigned event listeners.\n *\n * @param {String} event The events that should be listed.\n * @param {Boolean} exists We only need to know if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n  var evt = prefix ? prefix + event : event\n    , available = this._events && this._events[evt];\n\n  if (exists) return !!available;\n  if (!available) return [];\n  if (available.fn) return [available.fn];\n\n  for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n    ee[i] = available[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Emit an event to all registered event listeners.\n *\n * @param {String} event The name of the event.\n * @returns {Boolean} Indication if we've emitted an event.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events || !this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if ('function' === typeof listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Register a new EventListener for the given event.\n *\n * @param {String} event Name of the event.\n * @param {Functon} fn Callback function.\n * @param {Mixed} context The context of the function.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  var listener = new EE(fn, context || this)\n    , evt = prefix ? prefix + event : event;\n\n  if (!this._events) this._events = prefix ? {} : Object.create(null);\n  if (!this._events[evt]) this._events[evt] = listener;\n  else {\n    if (!this._events[evt].fn) this._events[evt].push(listener);\n    else this._events[evt] = [\n      this._events[evt], listener\n    ];\n  }\n\n  return this;\n};\n\n/**\n * Add an EventListener that's only called once.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} context The context of the function.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  var listener = new EE(fn, context || this, true)\n    , evt = prefix ? prefix + event : event;\n\n  if (!this._events) this._events = prefix ? {} : Object.create(null);\n  if (!this._events[evt]) this._events[evt] = listener;\n  else {\n    if (!this._events[evt].fn) this._events[evt].push(listener);\n    else this._events[evt] = [\n      this._events[evt], listener\n    ];\n  }\n\n  return this;\n};\n\n/**\n * Remove event listeners.\n *\n * @param {String} event The event we want to remove.\n * @param {Function} fn The listener that we need to find.\n * @param {Mixed} context Only remove listeners matching this context.\n * @param {Boolean} once Only remove once listeners.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events || !this._events[evt]) return this;\n\n  var listeners = this._events[evt]\n    , events = [];\n\n  if (fn) {\n    if (listeners.fn) {\n      if (\n           listeners.fn !== fn\n        || (once && !listeners.once)\n        || (context && listeners.context !== context)\n      ) {\n        events.push(listeners);\n      }\n    } else {\n      for (var i = 0, length = listeners.length; i < length; i++) {\n        if (\n             listeners[i].fn !== fn\n          || (once && !listeners[i].once)\n          || (context && listeners[i].context !== context)\n        ) {\n          events.push(listeners[i]);\n        }\n      }\n    }\n  }\n\n  //\n  // Reset the array, or remove it completely if we have no more listeners.\n  //\n  if (events.length) {\n    this._events[evt] = events.length === 1 ? events[0] : events;\n  } else {\n    delete this._events[evt];\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners or only the listeners for the specified event.\n *\n * @param {String} event The event want to remove all listeners for.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  if (!this._events) return this;\n\n  if (event) delete this._events[prefix ? prefix + event : event];\n  else this._events = prefix ? {} : Object.create(null);\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n  return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n\n},{}],11:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\n'use strict';\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nmodule.exports = Object.assign || function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (Object.getOwnPropertySymbols) {\n\t\t\tsymbols = Object.getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],12:[function(require,module,exports){\n(function (process){\n/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n/*jshint onevar: false, indent:4 */\n/*global setImmediate: false, setTimeout: false, console: false */\n(function () {\n\n    var async = {};\n\n    // global on the server, window in the browser\n    var root, previous_async;\n\n    root = this;\n    if (root != null) {\n      previous_async = root.async;\n    }\n\n    async.noConflict = function () {\n        root.async = previous_async;\n        return async;\n    };\n\n    function only_once(fn) {\n        var called = false;\n        return function() {\n            if (called) throw new Error(\"Callback was already called.\");\n            called = true;\n            fn.apply(root, arguments);\n        }\n    }\n\n    //// cross-browser compatiblity functions ////\n\n    var _toString = Object.prototype.toString;\n\n    var _isArray = Array.isArray || function (obj) {\n        return _toString.call(obj) === '[object Array]';\n    };\n\n    var _each = function (arr, iterator) {\n        for (var i = 0; i < arr.length; i += 1) {\n            iterator(arr[i], i, arr);\n        }\n    };\n\n    var _map = function (arr, iterator) {\n        if (arr.map) {\n            return arr.map(iterator);\n        }\n        var results = [];\n        _each(arr, function (x, i, a) {\n            results.push(iterator(x, i, a));\n        });\n        return results;\n    };\n\n    var _reduce = function (arr, iterator, memo) {\n        if (arr.reduce) {\n            return arr.reduce(iterator, memo);\n        }\n        _each(arr, function (x, i, a) {\n            memo = iterator(memo, x, i, a);\n        });\n        return memo;\n    };\n\n    var _keys = function (obj) {\n        if (Object.keys) {\n            return Object.keys(obj);\n        }\n        var keys = [];\n        for (var k in obj) {\n            if (obj.hasOwnProperty(k)) {\n                keys.push(k);\n            }\n        }\n        return keys;\n    };\n\n    //// exported async module functions ////\n\n    //// nextTick implementation with browser-compatible fallback ////\n    if (typeof process === 'undefined' || !(process.nextTick)) {\n        if (typeof setImmediate === 'function') {\n            async.nextTick = function (fn) {\n                // not a direct alias for IE10 compatibility\n                setImmediate(fn);\n            };\n            async.setImmediate = async.nextTick;\n        }\n        else {\n            async.nextTick = function (fn) {\n                setTimeout(fn, 0);\n            };\n            async.setImmediate = async.nextTick;\n        }\n    }\n    else {\n        async.nextTick = process.nextTick;\n        if (typeof setImmediate !== 'undefined') {\n            async.setImmediate = function (fn) {\n              // not a direct alias for IE10 compatibility\n              setImmediate(fn);\n            };\n        }\n        else {\n            async.setImmediate = async.nextTick;\n        }\n    }\n\n    async.each = function (arr, iterator, callback) {\n        callback = callback || function () {};\n        if (!arr.length) {\n            return callback();\n        }\n        var completed = 0;\n        _each(arr, function (x) {\n            iterator(x, only_once(done) );\n        });\n        function done(err) {\n          if (err) {\n              callback(err);\n              callback = function () {};\n          }\n          else {\n              completed += 1;\n              if (completed >= arr.length) {\n                  callback();\n              }\n          }\n        }\n    };\n    async.forEach = async.each;\n\n    async.eachSeries = function (arr, iterator, callback) {\n        callback = callback || function () {};\n        if (!arr.length) {\n            return callback();\n        }\n        var completed = 0;\n        var iterate = function () {\n            iterator(arr[completed], function (err) {\n                if (err) {\n                    callback(err);\n                    callback = function () {};\n                }\n                else {\n                    completed += 1;\n                    if (completed >= arr.length) {\n                        callback();\n                    }\n                    else {\n                        iterate();\n                    }\n                }\n            });\n        };\n        iterate();\n    };\n    async.forEachSeries = async.eachSeries;\n\n    async.eachLimit = function (arr, limit, iterator, callback) {\n        var fn = _eachLimit(limit);\n        fn.apply(null, [arr, iterator, callback]);\n    };\n    async.forEachLimit = async.eachLimit;\n\n    var _eachLimit = function (limit) {\n\n        return function (arr, iterator, callback) {\n            callback = callback || function () {};\n            if (!arr.length || limit <= 0) {\n                return callback();\n            }\n            var completed = 0;\n            var started = 0;\n            var running = 0;\n\n            (function replenish () {\n                if (completed >= arr.length) {\n                    return callback();\n                }\n\n                while (running < limit && started < arr.length) {\n                    started += 1;\n                    running += 1;\n                    iterator(arr[started - 1], function (err) {\n                        if (err) {\n                            callback(err);\n                            callback = function () {};\n                        }\n                        else {\n                            completed += 1;\n                            running -= 1;\n                            if (completed >= arr.length) {\n                                callback();\n                            }\n                            else {\n                                replenish();\n                            }\n                        }\n                    });\n                }\n            })();\n        };\n    };\n\n\n    var doParallel = function (fn) {\n        return function () {\n            var args = Array.prototype.slice.call(arguments);\n            return fn.apply(null, [async.each].concat(args));\n        };\n    };\n    var doParallelLimit = function(limit, fn) {\n        return function () {\n            var args = Array.prototype.slice.call(arguments);\n            return fn.apply(null, [_eachLimit(limit)].concat(args));\n        };\n    };\n    var doSeries = function (fn) {\n        return function () {\n            var args = Array.prototype.slice.call(arguments);\n            return fn.apply(null, [async.eachSeries].concat(args));\n        };\n    };\n\n\n    var _asyncMap = function (eachfn, arr, iterator, callback) {\n        arr = _map(arr, function (x, i) {\n            return {index: i, value: x};\n        });\n        if (!callback) {\n            eachfn(arr, function (x, callback) {\n                iterator(x.value, function (err) {\n                    callback(err);\n                });\n            });\n        } else {\n            var results = [];\n            eachfn(arr, function (x, callback) {\n                iterator(x.value, function (err, v) {\n                    results[x.index] = v;\n                    callback(err);\n                });\n            }, function (err) {\n                callback(err, results);\n            });\n        }\n    };\n    async.map = doParallel(_asyncMap);\n    async.mapSeries = doSeries(_asyncMap);\n    async.mapLimit = function (arr, limit, iterator, callback) {\n        return _mapLimit(limit)(arr, iterator, callback);\n    };\n\n    var _mapLimit = function(limit) {\n        return doParallelLimit(limit, _asyncMap);\n    };\n\n    // reduce only has a series version, as doing reduce in parallel won't\n    // work in many situations.\n    async.reduce = function (arr, memo, iterator, callback) {\n        async.eachSeries(arr, function (x, callback) {\n            iterator(memo, x, function (err, v) {\n                memo = v;\n                callback(err);\n            });\n        }, function (err) {\n            callback(err, memo);\n        });\n    };\n    // inject alias\n    async.inject = async.reduce;\n    // foldl alias\n    async.foldl = async.reduce;\n\n    async.reduceRight = function (arr, memo, iterator, callback) {\n        var reversed = _map(arr, function (x) {\n            return x;\n        }).reverse();\n        async.reduce(reversed, memo, iterator, callback);\n    };\n    // foldr alias\n    async.foldr = async.reduceRight;\n\n    var _filter = function (eachfn, arr, iterator, callback) {\n        var results = [];\n        arr = _map(arr, function (x, i) {\n            return {index: i, value: x};\n        });\n        eachfn(arr, function (x, callback) {\n            iterator(x.value, function (v) {\n                if (v) {\n                    results.push(x);\n                }\n                callback();\n            });\n        }, function (err) {\n            callback(_map(results.sort(function (a, b) {\n                return a.index - b.index;\n            }), function (x) {\n                return x.value;\n            }));\n        });\n    };\n    async.filter = doParallel(_filter);\n    async.filterSeries = doSeries(_filter);\n    // select alias\n    async.select = async.filter;\n    async.selectSeries = async.filterSeries;\n\n    var _reject = function (eachfn, arr, iterator, callback) {\n        var results = [];\n        arr = _map(arr, function (x, i) {\n            return {index: i, value: x};\n        });\n        eachfn(arr, function (x, callback) {\n            iterator(x.value, function (v) {\n                if (!v) {\n                    results.push(x);\n                }\n                callback();\n            });\n        }, function (err) {\n            callback(_map(results.sort(function (a, b) {\n                return a.index - b.index;\n            }), function (x) {\n                return x.value;\n            }));\n        });\n    };\n    async.reject = doParallel(_reject);\n    async.rejectSeries = doSeries(_reject);\n\n    var _detect = function (eachfn, arr, iterator, main_callback) {\n        eachfn(arr, function (x, callback) {\n            iterator(x, function (result) {\n                if (result) {\n                    main_callback(x);\n                    main_callback = function () {};\n                }\n                else {\n                    callback();\n                }\n            });\n        }, function (err) {\n            main_callback();\n        });\n    };\n    async.detect = doParallel(_detect);\n    async.detectSeries = doSeries(_detect);\n\n    async.some = function (arr, iterator, main_callback) {\n        async.each(arr, function (x, callback) {\n            iterator(x, function (v) {\n                if (v) {\n                    main_callback(true);\n                    main_callback = function () {};\n                }\n                callback();\n            });\n        }, function (err) {\n            main_callback(false);\n        });\n    };\n    // any alias\n    async.any = async.some;\n\n    async.every = function (arr, iterator, main_callback) {\n        async.each(arr, function (x, callback) {\n            iterator(x, function (v) {\n                if (!v) {\n                    main_callback(false);\n                    main_callback = function () {};\n                }\n                callback();\n            });\n        }, function (err) {\n            main_callback(true);\n        });\n    };\n    // all alias\n    async.all = async.every;\n\n    async.sortBy = function (arr, iterator, callback) {\n        async.map(arr, function (x, callback) {\n            iterator(x, function (err, criteria) {\n                if (err) {\n                    callback(err);\n                }\n                else {\n                    callback(null, {value: x, criteria: criteria});\n                }\n            });\n        }, function (err, results) {\n            if (err) {\n                return callback(err);\n            }\n            else {\n                var fn = function (left, right) {\n                    var a = left.criteria, b = right.criteria;\n                    return a < b ? -1 : a > b ? 1 : 0;\n                };\n                callback(null, _map(results.sort(fn), function (x) {\n                    return x.value;\n                }));\n            }\n        });\n    };\n\n    async.auto = function (tasks, callback) {\n        callback = callback || function () {};\n        var keys = _keys(tasks);\n        var remainingTasks = keys.length\n        if (!remainingTasks) {\n            return callback();\n        }\n\n        var results = {};\n\n        var listeners = [];\n        var addListener = function (fn) {\n            listeners.unshift(fn);\n        };\n        var removeListener = function (fn) {\n            for (var i = 0; i < listeners.length; i += 1) {\n                if (listeners[i] === fn) {\n                    listeners.splice(i, 1);\n                    return;\n                }\n            }\n        };\n        var taskComplete = function () {\n            remainingTasks--\n            _each(listeners.slice(0), function (fn) {\n                fn();\n            });\n        };\n\n        addListener(function () {\n            if (!remainingTasks) {\n                var theCallback = callback;\n                // prevent final callback from calling itself if it errors\n                callback = function () {};\n\n                theCallback(null, results);\n            }\n        });\n\n        _each(keys, function (k) {\n            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n            var taskCallback = function (err) {\n                var args = Array.prototype.slice.call(arguments, 1);\n                if (args.length <= 1) {\n                    args = args[0];\n                }\n                if (err) {\n                    var safeResults = {};\n                    _each(_keys(results), function(rkey) {\n                        safeResults[rkey] = results[rkey];\n                    });\n                    safeResults[k] = args;\n                    callback(err, safeResults);\n                    // stop subsequent errors hitting callback multiple times\n                    callback = function () {};\n                }\n                else {\n                    results[k] = args;\n                    async.setImmediate(taskComplete);\n                }\n            };\n            var requires = task.slice(0, Math.abs(task.length - 1)) || [];\n            var ready = function () {\n                return _reduce(requires, function (a, x) {\n                    return (a && results.hasOwnProperty(x));\n                }, true) && !results.hasOwnProperty(k);\n            };\n            if (ready()) {\n                task[task.length - 1](taskCallback, results);\n            }\n            else {\n                var listener = function () {\n                    if (ready()) {\n                        removeListener(listener);\n                        task[task.length - 1](taskCallback, results);\n                    }\n                };\n                addListener(listener);\n            }\n        });\n    };\n\n    async.retry = function(times, task, callback) {\n        var DEFAULT_TIMES = 5;\n        var attempts = [];\n        // Use defaults if times not passed\n        if (typeof times === 'function') {\n            callback = task;\n            task = times;\n            times = DEFAULT_TIMES;\n        }\n        // Make sure times is a number\n        times = parseInt(times, 10) || DEFAULT_TIMES;\n        var wrappedTask = function(wrappedCallback, wrappedResults) {\n            var retryAttempt = function(task, finalAttempt) {\n                return function(seriesCallback) {\n                    task(function(err, result){\n                        seriesCallback(!err || finalAttempt, {err: err, result: result});\n                    }, wrappedResults);\n                };\n            };\n            while (times) {\n                attempts.push(retryAttempt(task, !(times-=1)));\n            }\n            async.series(attempts, function(done, data){\n                data = data[data.length - 1];\n                (wrappedCallback || callback)(data.err, data.result);\n            });\n        }\n        // If a callback is passed, run this as a controll flow\n        return callback ? wrappedTask() : wrappedTask\n    };\n\n    async.waterfall = function (tasks, callback) {\n        callback = callback || function () {};\n        if (!_isArray(tasks)) {\n          var err = new Error('First argument to waterfall must be an array of functions');\n          return callback(err);\n        }\n        if (!tasks.length) {\n            return callback();\n        }\n        var wrapIterator = function (iterator) {\n            return function (err) {\n                if (err) {\n                    callback.apply(null, arguments);\n                    callback = function () {};\n                }\n                else {\n                    var args = Array.prototype.slice.call(arguments, 1);\n                    var next = iterator.next();\n                    if (next) {\n                        args.push(wrapIterator(next));\n                    }\n                    else {\n                        args.push(callback);\n                    }\n                    async.setImmediate(function () {\n                        iterator.apply(null, args);\n                    });\n                }\n            };\n        };\n        wrapIterator(async.iterator(tasks))();\n    };\n\n    var _parallel = function(eachfn, tasks, callback) {\n        callback = callback || function () {};\n        if (_isArray(tasks)) {\n            eachfn.map(tasks, function (fn, callback) {\n                if (fn) {\n                    fn(function (err) {\n                        var args = Array.prototype.slice.call(arguments, 1);\n                        if (args.length <= 1) {\n                            args = args[0];\n                        }\n                        callback.call(null, err, args);\n                    });\n                }\n            }, callback);\n        }\n        else {\n            var results = {};\n            eachfn.each(_keys(tasks), function (k, callback) {\n                tasks[k](function (err) {\n                    var args = Array.prototype.slice.call(arguments, 1);\n                    if (args.length <= 1) {\n                        args = args[0];\n                    }\n                    results[k] = args;\n                    callback(err);\n                });\n            }, function (err) {\n                callback(err, results);\n            });\n        }\n    };\n\n    async.parallel = function (tasks, callback) {\n        _parallel({ map: async.map, each: async.each }, tasks, callback);\n    };\n\n    async.parallelLimit = function(tasks, limit, callback) {\n        _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);\n    };\n\n    async.series = function (tasks, callback) {\n        callback = callback || function () {};\n        if (_isArray(tasks)) {\n            async.mapSeries(tasks, function (fn, callback) {\n                if (fn) {\n                    fn(function (err) {\n                        var args = Array.prototype.slice.call(arguments, 1);\n                        if (args.length <= 1) {\n                            args = args[0];\n                        }\n                        callback.call(null, err, args);\n                    });\n                }\n            }, callback);\n        }\n        else {\n            var results = {};\n            async.eachSeries(_keys(tasks), function (k, callback) {\n                tasks[k](function (err) {\n                    var args = Array.prototype.slice.call(arguments, 1);\n                    if (args.length <= 1) {\n                        args = args[0];\n                    }\n                    results[k] = args;\n                    callback(err);\n                });\n            }, function (err) {\n                callback(err, results);\n            });\n        }\n    };\n\n    async.iterator = function (tasks) {\n        var makeCallback = function (index) {\n            var fn = function () {\n                if (tasks.length) {\n                    tasks[index].apply(null, arguments);\n                }\n                return fn.next();\n            };\n            fn.next = function () {\n                return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n            };\n            return fn;\n        };\n        return makeCallback(0);\n    };\n\n    async.apply = function (fn) {\n        var args = Array.prototype.slice.call(arguments, 1);\n        return function () {\n            return fn.apply(\n                null, args.concat(Array.prototype.slice.call(arguments))\n            );\n        };\n    };\n\n    var _concat = function (eachfn, arr, fn, callback) {\n        var r = [];\n        eachfn(arr, function (x, cb) {\n            fn(x, function (err, y) {\n                r = r.concat(y || []);\n                cb(err);\n            });\n        }, function (err) {\n            callback(err, r);\n        });\n    };\n    async.concat = doParallel(_concat);\n    async.concatSeries = doSeries(_concat);\n\n    async.whilst = function (test, iterator, callback) {\n        if (test()) {\n            iterator(function (err) {\n                if (err) {\n                    return callback(err);\n                }\n                async.whilst(test, iterator, callback);\n            });\n        }\n        else {\n            callback();\n        }\n    };\n\n    async.doWhilst = function (iterator, test, callback) {\n        iterator(function (err) {\n            if (err) {\n                return callback(err);\n            }\n            var args = Array.prototype.slice.call(arguments, 1);\n            if (test.apply(null, args)) {\n                async.doWhilst(iterator, test, callback);\n            }\n            else {\n                callback();\n            }\n        });\n    };\n\n    async.until = function (test, iterator, callback) {\n        if (!test()) {\n            iterator(function (err) {\n                if (err) {\n                    return callback(err);\n                }\n                async.until(test, iterator, callback);\n            });\n        }\n        else {\n            callback();\n        }\n    };\n\n    async.doUntil = function (iterator, test, callback) {\n        iterator(function (err) {\n            if (err) {\n                return callback(err);\n            }\n            var args = Array.prototype.slice.call(arguments, 1);\n            if (!test.apply(null, args)) {\n                async.doUntil(iterator, test, callback);\n            }\n            else {\n                callback();\n            }\n        });\n    };\n\n    async.queue = function (worker, concurrency) {\n        if (concurrency === undefined) {\n            concurrency = 1;\n        }\n        function _insert(q, data, pos, callback) {\n          if (!q.started){\n            q.started = true;\n          }\n          if (!_isArray(data)) {\n              data = [data];\n          }\n          if(data.length == 0) {\n             // call drain immediately if there are no tasks\n             return async.setImmediate(function() {\n                 if (q.drain) {\n                     q.drain();\n                 }\n             });\n          }\n          _each(data, function(task) {\n              var item = {\n                  data: task,\n                  callback: typeof callback === 'function' ? callback : null\n              };\n\n              if (pos) {\n                q.tasks.unshift(item);\n              } else {\n                q.tasks.push(item);\n              }\n\n              if (q.saturated && q.tasks.length === q.concurrency) {\n                  q.saturated();\n              }\n              async.setImmediate(q.process);\n          });\n        }\n\n        var workers = 0;\n        var q = {\n            tasks: [],\n            concurrency: concurrency,\n            saturated: null,\n            empty: null,\n            drain: null,\n            started: false,\n            paused: false,\n            push: function (data, callback) {\n              _insert(q, data, false, callback);\n            },\n            kill: function () {\n              q.drain = null;\n              q.tasks = [];\n            },\n            unshift: function (data, callback) {\n              _insert(q, data, true, callback);\n            },\n            process: function () {\n                if (!q.paused && workers < q.concurrency && q.tasks.length) {\n                    var task = q.tasks.shift();\n                    if (q.empty && q.tasks.length === 0) {\n                        q.empty();\n                    }\n                    workers += 1;\n                    var next = function () {\n                        workers -= 1;\n                        if (task.callback) {\n                            task.callback.apply(task, arguments);\n                        }\n                        if (q.drain && q.tasks.length + workers === 0) {\n                            q.drain();\n                        }\n                        q.process();\n                    };\n                    var cb = only_once(next);\n                    worker(task.data, cb);\n                }\n            },\n            length: function () {\n                return q.tasks.length;\n            },\n            running: function () {\n                return workers;\n            },\n            idle: function() {\n                return q.tasks.length + workers === 0;\n            },\n            pause: function () {\n                if (q.paused === true) { return; }\n                q.paused = true;\n            },\n            resume: function () {\n                if (q.paused === false) { return; }\n                q.paused = false;\n                // Need to call q.process once per concurrent\n                // worker to preserve full concurrency after pause\n                for (var w = 1; w <= q.concurrency; w++) {\n                    async.setImmediate(q.process);\n                }\n            }\n        };\n        return q;\n    };\n\n    async.priorityQueue = function (worker, concurrency) {\n\n        function _compareTasks(a, b){\n          return a.priority - b.priority;\n        };\n\n        function _binarySearch(sequence, item, compare) {\n          var beg = -1,\n              end = sequence.length - 1;\n          while (beg < end) {\n            var mid = beg + ((end - beg + 1) >>> 1);\n            if (compare(item, sequence[mid]) >= 0) {\n              beg = mid;\n            } else {\n              end = mid - 1;\n            }\n          }\n          return beg;\n        }\n\n        function _insert(q, data, priority, callback) {\n          if (!q.started){\n            q.started = true;\n          }\n          if (!_isArray(data)) {\n              data = [data];\n          }\n          if(data.length == 0) {\n             // call drain immediately if there are no tasks\n             return async.setImmediate(function() {\n                 if (q.drain) {\n                     q.drain();\n                 }\n             });\n          }\n          _each(data, function(task) {\n              var item = {\n                  data: task,\n                  priority: priority,\n                  callback: typeof callback === 'function' ? callback : null\n              };\n\n              q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n              if (q.saturated && q.tasks.length === q.concurrency) {\n                  q.saturated();\n              }\n              async.setImmediate(q.process);\n          });\n        }\n\n        // Start with a normal queue\n        var q = async.queue(worker, concurrency);\n\n        // Override push to accept second parameter representing priority\n        q.push = function (data, priority, callback) {\n          _insert(q, data, priority, callback);\n        };\n\n        // Remove unshift function\n        delete q.unshift;\n\n        return q;\n    };\n\n    async.cargo = function (worker, payload) {\n        var working     = false,\n            tasks       = [];\n\n        var cargo = {\n            tasks: tasks,\n            payload: payload,\n            saturated: null,\n            empty: null,\n            drain: null,\n            drained: true,\n            push: function (data, callback) {\n                if (!_isArray(data)) {\n                    data = [data];\n                }\n                _each(data, function(task) {\n                    tasks.push({\n                        data: task,\n                        callback: typeof callback === 'function' ? callback : null\n                    });\n                    cargo.drained = false;\n                    if (cargo.saturated && tasks.length === payload) {\n                        cargo.saturated();\n                    }\n                });\n                async.setImmediate(cargo.process);\n            },\n            process: function process() {\n                if (working) return;\n                if (tasks.length === 0) {\n                    if(cargo.drain && !cargo.drained) cargo.drain();\n                    cargo.drained = true;\n                    return;\n                }\n\n                var ts = typeof payload === 'number'\n                            ? tasks.splice(0, payload)\n                            : tasks.splice(0, tasks.length);\n\n                var ds = _map(ts, function (task) {\n                    return task.data;\n                });\n\n                if(cargo.empty) cargo.empty();\n                working = true;\n                worker(ds, function () {\n                    working = false;\n\n                    var args = arguments;\n                    _each(ts, function (data) {\n                        if (data.callback) {\n                            data.callback.apply(null, args);\n                        }\n                    });\n\n                    process();\n                });\n            },\n            length: function () {\n                return tasks.length;\n            },\n            running: function () {\n                return working;\n            }\n        };\n        return cargo;\n    };\n\n    var _console_fn = function (name) {\n        return function (fn) {\n            var args = Array.prototype.slice.call(arguments, 1);\n            fn.apply(null, args.concat([function (err) {\n                var args = Array.prototype.slice.call(arguments, 1);\n                if (typeof console !== 'undefined') {\n                    if (err) {\n                        if (console.error) {\n                            console.error(err);\n                        }\n                    }\n                    else if (console[name]) {\n                        _each(args, function (x) {\n                            console[name](x);\n                        });\n                    }\n                }\n            }]));\n        };\n    };\n    async.log = _console_fn('log');\n    async.dir = _console_fn('dir');\n    /*async.info = _console_fn('info');\n    async.warn = _console_fn('warn');\n    async.error = _console_fn('error');*/\n\n    async.memoize = function (fn, hasher) {\n        var memo = {};\n        var queues = {};\n        hasher = hasher || function (x) {\n            return x;\n        };\n        var memoized = function () {\n            var args = Array.prototype.slice.call(arguments);\n            var callback = args.pop();\n            var key = hasher.apply(null, args);\n            if (key in memo) {\n                async.nextTick(function () {\n                    callback.apply(null, memo[key]);\n                });\n            }\n            else if (key in queues) {\n                queues[key].push(callback);\n            }\n            else {\n                queues[key] = [callback];\n                fn.apply(null, args.concat([function () {\n                    memo[key] = arguments;\n                    var q = queues[key];\n                    delete queues[key];\n                    for (var i = 0, l = q.length; i < l; i++) {\n                      q[i].apply(null, arguments);\n                    }\n                }]));\n            }\n        };\n        memoized.memo = memo;\n        memoized.unmemoized = fn;\n        return memoized;\n    };\n\n    async.unmemoize = function (fn) {\n      return function () {\n        return (fn.unmemoized || fn).apply(null, arguments);\n      };\n    };\n\n    async.times = function (count, iterator, callback) {\n        var counter = [];\n        for (var i = 0; i < count; i++) {\n            counter.push(i);\n        }\n        return async.map(counter, iterator, callback);\n    };\n\n    async.timesSeries = function (count, iterator, callback) {\n        var counter = [];\n        for (var i = 0; i < count; i++) {\n            counter.push(i);\n        }\n        return async.mapSeries(counter, iterator, callback);\n    };\n\n    async.seq = function (/* functions... */) {\n        var fns = arguments;\n        return function () {\n            var that = this;\n            var args = Array.prototype.slice.call(arguments);\n            var callback = args.pop();\n            async.reduce(fns, args, function (newargs, fn, cb) {\n                fn.apply(that, newargs.concat([function () {\n                    var err = arguments[0];\n                    var nextargs = Array.prototype.slice.call(arguments, 1);\n                    cb(err, nextargs);\n                }]))\n            },\n            function (err, results) {\n                callback.apply(that, [err].concat(results));\n            });\n        };\n    };\n\n    async.compose = function (/* functions... */) {\n      return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n    };\n\n    var _applyEach = function (eachfn, fns /*args...*/) {\n        var go = function () {\n            var that = this;\n            var args = Array.prototype.slice.call(arguments);\n            var callback = args.pop();\n            return eachfn(fns, function (fn, cb) {\n                fn.apply(that, args.concat([cb]));\n            },\n            callback);\n        };\n        if (arguments.length > 2) {\n            var args = Array.prototype.slice.call(arguments, 2);\n            return go.apply(this, args);\n        }\n        else {\n            return go;\n        }\n    };\n    async.applyEach = doParallel(_applyEach);\n    async.applyEachSeries = doSeries(_applyEach);\n\n    async.forever = function (fn, callback) {\n        function next(err) {\n            if (err) {\n                if (callback) {\n                    return callback(err);\n                }\n                throw err;\n            }\n            fn(next);\n        }\n        next();\n    };\n\n    // Node.js\n    if (typeof module !== 'undefined' && module.exports) {\n        module.exports = async;\n    }\n    // AMD / RequireJS\n    else if (typeof define !== 'undefined' && define.amd) {\n        define([], function () {\n            return async;\n        });\n    }\n    // included directly via <script> tag\n    else {\n        root.async = async;\n    }\n\n}());\n\n}).call(this,require('_process'))\n},{\"_process\":3}],13:[function(require,module,exports){\nvar async       = require('async'),\n    urlParser   = require('url'),\n    Resource    = require('./Resource'),\n    EventEmitter = require('eventemitter3');\n\n/**\n * Manages the state and loading of multiple resources to load.\n *\n * @class\n * @param [baseUrl=''] {string} The base url for all resources loaded by this loader.\n * @param [concurrency=10] {number} The number of resources to load concurrently.\n */\nfunction Loader(baseUrl, concurrency) {\n    EventEmitter.call(this);\n\n    concurrency = concurrency || 10;\n\n    /**\n     * The base url for all resources loaded by this loader.\n     *\n     * @member {string}\n     */\n    this.baseUrl = baseUrl || '';\n\n    /**\n     * The progress percent of the loader going through the queue.\n     *\n     * @member {number}\n     */\n    this.progress = 0;\n\n    /**\n     * Loading state of the loader, true if it is currently loading resources.\n     *\n     * @member {boolean}\n     */\n    this.loading = false;\n\n    /**\n     * The percentage of total progress that a single resource represents.\n     *\n     * @member {number}\n     */\n    this._progressChunk = 0;\n\n    /**\n     * The middleware to run before loading each resource.\n     *\n     * @member {function[]}\n     */\n    this._beforeMiddleware = [];\n\n    /**\n     * The middleware to run after loading each resource.\n     *\n     * @member {function[]}\n     */\n    this._afterMiddleware = [];\n\n    /**\n     * The `_loadResource` function bound with this object context.\n     *\n     * @private\n     * @member {function}\n     */\n    this._boundLoadResource = this._loadResource.bind(this);\n\n    /**\n     * The `_onLoad` function bound with this object context.\n     *\n     * @private\n     * @member {function}\n     */\n    this._boundOnLoad = this._onLoad.bind(this);\n\n    /**\n     * The resource buffer that fills until `load` is called to start loading resources.\n     *\n     * @private\n     * @member {Resource[]}\n     */\n    this._buffer = [];\n\n    /**\n     * Used to track load completion.\n     *\n     * @private\n     * @member {number}\n     */\n    this._numToLoad = 0;\n\n    /**\n     * The resources waiting to be loaded.\n     *\n     * @private\n     * @member {Resource[]}\n     */\n    this._queue = async.queue(this._boundLoadResource, concurrency);\n\n    /**\n     * All the resources for this loader keyed by name.\n     *\n     * @member {object<string, Resource>}\n     */\n    this.resources = {};\n\n    /**\n     * Emitted once per loaded or errored resource.\n     *\n     * @event progress\n     * @memberof Loader#\n     */\n\n    /**\n     * Emitted once per errored resource.\n     *\n     * @event error\n     * @memberof Loader#\n     */\n\n    /**\n     * Emitted once per loaded resource.\n     *\n     * @event load\n     * @memberof Loader#\n     */\n\n    /**\n     * Emitted when the loader begins to process the queue.\n     *\n     * @event start\n     * @memberof Loader#\n     */\n\n    /**\n     * Emitted when the queued resources all load.\n     *\n     * @event complete\n     * @memberof Loader#\n     */\n}\n\nLoader.prototype = Object.create(EventEmitter.prototype);\nLoader.prototype.constructor = Loader;\nmodule.exports = Loader;\n\n/**\n * Adds a resource (or multiple resources) to the loader queue.\n *\n * This function can take a wide variety of different parameters. The only thing that is always\n * required the url to load. All the following will work:\n *\n * ```js\n * loader\n *     // normal param syntax\n *     .add('key', 'http://...', function () {})\n *     .add('http://...', function () {})\n *     .add('http://...')\n *\n *     // object syntax\n *     .add({\n *         name: 'key2',\n *         url: 'http://...'\n *     }, function () {})\n *     .add({\n *         url: 'http://...'\n *     }, function () {})\n *     .add({\n *         name: 'key3',\n *         url: 'http://...'\n *         onComplete: function () {}\n *     })\n *     .add({\n *         url: 'https://...',\n *         onComplete: function () {},\n *         crossOrigin: true\n *     })\n *\n *     // you can also pass an array of objects or urls or both\n *     .add([\n *         { name: 'key4', url: 'http://...', onComplete: function () {} },\n *         { url: 'http://...', onComplete: function () {} },\n *         'http://...'\n *     ]);\n * ```\n *\n * @alias enqueue\n * @param [name] {string} The name of the resource to load, if not passed the url is used.\n * @param url {string} The url for this resource, relative to the baseUrl of this loader.\n * @param [options] {object} The options for the load.\n * @param [options.crossOrigin] {boolean} Is this request cross-origin? Default is to determine automatically.\n * @param [options.loadType=Resource.LOAD_TYPE.XHR] {Resource.XHR_LOAD_TYPE} How should this resource be loaded?\n * @param [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] {Resource.XHR_RESPONSE_TYPE} How should the data being\n *      loaded be interpreted when using XHR?\n * @param [callback] {function} Function to call when this specific resource completes loading.\n * @return {Loader}\n */\nLoader.prototype.add = Loader.prototype.enqueue = function (name, url, options, cb) {\n    // special case of an array of objects or urls\n    if (Array.isArray(name)) {\n        for (var i = 0; i < name.length; ++i) {\n            this.add(name[i]);\n        }\n\n        return this;\n    }\n\n    // if an object is passed instead of params\n    if (typeof name === 'object') {\n        cb = url || name.callback || name.onComplete;\n        options = name;\n        url = name.url;\n        name = name.name || name.key || name.url;\n    }\n\n    // case where no name is passed shift all args over by one.\n    if (typeof url !== 'string') {\n        cb = options;\n        options = url;\n        url = name;\n    }\n\n    // now that we shifted make sure we have a proper url.\n    if (typeof url !== 'string') {\n        throw new Error('No url passed to add resource to loader.');\n    }\n\n    // options are optional so people might pass a function and no options\n    if (typeof options === 'function') {\n        cb = options;\n        options = null;\n    }\n\n    // check if resource already exists.\n    if (this.resources[name]) {\n        throw new Error('Resource with name \"' + name + '\" already exists.');\n    }\n\n    // add base url if this isn't an absolute url\n    url = this._handleBaseUrl(url);\n\n    // create the store the resource\n    this.resources[name] = new Resource(name, url, options);\n\n    if (typeof cb === 'function') {\n        this.resources[name].once('afterMiddleware', cb);\n    }\n\n    this._numToLoad++;\n\n    // if already loading add it to the worker queue\n    if (this._queue.started) {\n        this._queue.push(this.resources[name]);\n        this._progressChunk = (100 - this.progress) / (this._queue.length() + this._queue.running());\n    }\n    // otherwise buffer it to be added to the queue later\n    else {\n        this._buffer.push(this.resources[name]);\n        this._progressChunk = 100 / this._buffer.length;\n    }\n\n    return this;\n};\n\nLoader.prototype._handleBaseUrl = function (url) {\n    var parsedUrl = urlParser.parse(url);\n\n    // absolute url, just use it as is.\n    if (parsedUrl.protocol || parsedUrl.pathname.indexOf('//') === 0) {\n        return url;\n    }\n\n    // if baseUrl doesn't end in slash and url doesn't start with slash, then add a slash inbetween\n    if (\n        this.baseUrl.length &&\n        this.baseUrl.lastIndexOf('/') !== this.baseUrl.length - 1 &&\n        url.charAt(0) !== '/'\n    ) {\n        return this.baseUrl + '/' + url;\n    }\n    else {\n        return this.baseUrl + url;\n    }\n};\n\n\n/**\n * Sets up a middleware function that will run *before* the\n * resource is loaded.\n *\n * @alias pre\n * @param middleware {function} The middleware function to register.\n * @return {Loader}\n */\nLoader.prototype.before = Loader.prototype.pre = function (fn) {\n    this._beforeMiddleware.push(fn);\n\n    return this;\n};\n\n/**\n * Sets up a middleware function that will run *after* the\n * resource is loaded.\n *\n * @alias use\n * @param middleware {function} The middleware function to register.\n * @return {Loader}\n */\nLoader.prototype.after = Loader.prototype.use = function (fn) {\n    this._afterMiddleware.push(fn);\n\n    return this;\n};\n\n/**\n * Resets the queue of the loader to prepare for a new load.\n *\n * @return {Loader}\n */\nLoader.prototype.reset = function () {\n    // this.baseUrl = baseUrl || '';\n\n    this.progress = 0;\n\n    this.loading = false;\n\n    this._progressChunk = 0;\n\n    // this._beforeMiddleware.length = 0;\n    // this._afterMiddleware.length = 0;\n\n    this._buffer.length = 0;\n\n    this._numToLoad = 0;\n\n    this._queue.kill();\n    this._queue.started = false;\n\n    this.resources = {};\n};\n\n/**\n * Starts loading the queued resources.\n *\n * @fires start\n * @param [callback] {function} Optional callback that will be bound to the `complete` event.\n * @return {Loader}\n */\nLoader.prototype.load = function (cb) {\n    // register complete callback if they pass one\n    if (typeof cb === 'function') {\n        this.once('complete', cb);\n    }\n\n    // if the queue has already started we are done here\n    if (this._queue.started) {\n        return this;\n    }\n\n    // notify of start\n    this.emit('start', this);\n\n    // start the internal queue\n    for (var i = 0; i < this._buffer.length; ++i) {\n        this._queue.push(this._buffer[i]);\n    }\n\n    // empty the buffer\n    this._buffer.length = 0;\n\n    return this;\n};\n\n/**\n * Loads a single resource.\n *\n * @fires progress\n * @private\n */\nLoader.prototype._loadResource = function (resource, dequeue) {\n    var self = this;\n\n    resource._dequeue = dequeue;\n\n    this._runMiddleware(resource, this._beforeMiddleware, function () {\n        // resource.on('progress', self.emit.bind(self, 'progress'));\n\n        resource.load(self._boundOnLoad);\n    });\n};\n\n/**\n * Called once each resource has loaded.\n *\n * @fires complete\n * @private\n */\nLoader.prototype._onComplete = function () {\n    this.emit('complete', this, this.resources);\n};\n\n/**\n * Called each time a resources is loaded.\n *\n * @fires progress\n * @fires error\n * @fires load\n * @private\n */\nLoader.prototype._onLoad = function (resource) {\n    this.progress += this._progressChunk;\n\n    this.emit('progress', this, resource);\n\n    // run middleware, this *must* happen before dequeue so sub-assets get added properly\n    this._runMiddleware(resource, this._afterMiddleware, function () {\n        resource.emit('afterMiddleware', resource);\n\n        this._numToLoad--;\n\n        // do completion check\n        if (this._numToLoad === 0) {\n            this.progress = 100;\n            this._onComplete();\n        }\n        \n        if (resource.error) {\n            this.emit('error', resource.error, this, resource);\n        }\n        else {\n            this.emit('load', this, resource);\n        }\n    });\n    \n\n\n    // remove this resource from the async queue\n    resource._dequeue();\n};\n\n/**\n * Run middleware functions on a resource.\n *\n * @private\n */\nLoader.prototype._runMiddleware = function (resource, fns, cb) {\n    var self = this;\n\n    async.eachSeries(fns, function (fn, next) {\n        fn.call(self, resource, next);\n    }, cb.bind(this, resource));\n};\n\nLoader.LOAD_TYPE = Resource.LOAD_TYPE;\nLoader.XHR_READY_STATE = Resource.XHR_READY_STATE;\nLoader.XHR_RESPONSE_TYPE = Resource.XHR_RESPONSE_TYPE;\n\n},{\"./Resource\":14,\"async\":12,\"eventemitter3\":10,\"url\":8}],14:[function(require,module,exports){\nvar EventEmitter = require('eventemitter3'),\n    _url = require('url'),\n    // tests is CORS is supported in XHR, if not we need to use XDR\n    useXdr = !!(window.XDomainRequest && !('withCredentials' in (new XMLHttpRequest()))),\n    tempAnchor = null;\n\n/**\n * Manages the state and loading of a single resource represented by\n * a single URL.\n *\n * @class\n * @param name {string} The name of the resource to load.\n * @param url {string|string[]} The url for this resource, for audio/video loads you can pass an array of sources.\n * @param [options] {object} The options for the load.\n * @param [options.crossOrigin] {string|boolean} Is this request cross-origin? Default is to determine automatically.\n * @param [options.loadType=Resource.LOAD_TYPE.XHR] {Resource.LOAD_TYPE} How should this resource be loaded?\n * @param [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] {Resource.XHR_RESPONSE_TYPE} How should the data being\n *      loaded be interpreted when using XHR?\n * @param [options.metadata] {object} Extra info for middleware.\n */\nfunction Resource(name, url, options) {\n    EventEmitter.call(this);\n\n    options = options || {};\n\n    if (typeof name !== 'string' || typeof url !== 'string') {\n        throw new Error('Both name and url are required for constructing a resource.');\n    }\n\n    /**\n     * The name of this resource.\n     *\n     * @member {string}\n     * @readonly\n     */\n    this.name = name;\n\n    /**\n     * The url used to load this resource.\n     *\n     * @member {string}\n     * @readonly\n     */\n    this.url = url;\n\n    /**\n     * Stores whether or not this url is a data url.\n     *\n     * @member {boolean}\n     * @readonly\n     */\n    this.isDataUrl = this.url.indexOf('data:') === 0;\n\n    /**\n     * The data that was loaded by the resource.\n     *\n     * @member {any}\n     */\n    this.data = null;\n\n    /**\n     * Is this request cross-origin? If unset, determined automatically.\n     *\n     * @member {string}\n     */\n    this.crossOrigin = options.crossOrigin === true ? 'anonymous' : options.crossOrigin;\n\n    /**\n     * The method of loading to use for this resource.\n     *\n     * @member {Resource.LOAD_TYPE}\n     */\n    this.loadType = options.loadType || this._determineLoadType();\n\n    /**\n     * The type used to load the resource via XHR. If unset, determined automatically.\n     *\n     * @member {string}\n     */\n    this.xhrType = options.xhrType;\n\n    /**\n     * Extra info for middleware\n     *\n     * @member {object}\n     */\n    this.metadata = options.metadata || {};\n\n    /**\n     * The error that occurred while loading (if any).\n     *\n     * @member {Error}\n     * @readonly\n     */\n    this.error = null;\n\n    /**\n     * The XHR object that was used to load this resource. This is only set\n     * when `loadType` is `Resource.LOAD_TYPE.XHR`.\n     *\n     * @member {XMLHttpRequest}\n     */\n    this.xhr = null;\n\n    /**\n     * Describes if this resource was loaded as json. Only valid after the resource\n     * has completely loaded.\n     *\n     * @member {boolean}\n     */\n    this.isJson = false;\n\n    /**\n     * Describes if this resource was loaded as xml. Only valid after the resource\n     * has completely loaded.\n     *\n     * @member {boolean}\n     */\n    this.isXml = false;\n\n    /**\n     * Describes if this resource was loaded as an image tag. Only valid after the resource\n     * has completely loaded.\n     *\n     * @member {boolean}\n     */\n    this.isImage = false;\n\n    /**\n     * Describes if this resource was loaded as an audio tag. Only valid after the resource\n     * has completely loaded.\n     *\n     * @member {boolean}\n     */\n    this.isAudio = false;\n\n    /**\n     * Describes if this resource was loaded as a video tag. Only valid after the resource\n     * has completely loaded.\n     *\n     * @member {boolean}\n     */\n    this.isVideo = false;\n\n    /**\n     * The `dequeue` method that will be used a storage place for the async queue dequeue method\n     * used privately by the loader.\n     *\n     * @member {function}\n     * @private\n     */\n    this._dequeue = null;\n\n    /**\n     * The `complete` function bound to this resource's context.\n     *\n     * @member {function}\n     * @private\n     */\n    this._boundComplete = this.complete.bind(this);\n\n    /**\n     * The `_onError` function bound to this resource's context.\n     *\n     * @member {function}\n     * @private\n     */\n    this._boundOnError = this._onError.bind(this);\n\n    /**\n     * The `_onProgress` function bound to this resource's context.\n     *\n     * @member {function}\n     * @private\n     */\n    this._boundOnProgress = this._onProgress.bind(this);\n\n    // xhr callbacks\n    this._boundXhrOnError = this._xhrOnError.bind(this);\n    this._boundXhrOnAbort = this._xhrOnAbort.bind(this);\n    this._boundXhrOnLoad = this._xhrOnLoad.bind(this);\n    this._boundXdrOnTimeout = this._xdrOnTimeout.bind(this);\n\n    /**\n     * Emitted when the resource beings to load.\n     *\n     * @event start\n     * @memberof Resource#\n     */\n\n    /**\n     * Emitted each time progress of this resource load updates.\n     * Not all resources types and loader systems can support this event\n     * so sometimes it may not be available. If the resource\n     * is being loaded on a modern browser, using XHR, and the remote server\n     * properly sets Content-Length headers, then this will be available.\n     *\n     * @event progress\n     * @memberof Resource#\n     */\n\n    /**\n     * Emitted once this resource has loaded, if there was an error it will\n     * be in the `error` property.\n     *\n     * @event complete\n     * @memberof Resource#\n     */\n}\n\nResource.prototype = Object.create(EventEmitter.prototype);\nResource.prototype.constructor = Resource;\nmodule.exports = Resource;\n\n/**\n * Marks the resource as complete.\n *\n * @fires complete\n */\nResource.prototype.complete = function () {\n    // TODO: Clean this up in a wrapper or something...gross....\n    if (this.data && this.data.removeEventListener) {\n        this.data.removeEventListener('error', this._boundOnError);\n        this.data.removeEventListener('load', this._boundComplete);\n        this.data.removeEventListener('progress', this._boundOnProgress);\n        this.data.removeEventListener('canplaythrough', this._boundComplete);\n    }\n\n    if (this.xhr) {\n        if (this.xhr.removeEventListener) {\n            this.xhr.removeEventListener('error', this._boundXhrOnError);\n            this.xhr.removeEventListener('abort', this._boundXhrOnAbort);\n            this.xhr.removeEventListener('progress', this._boundOnProgress);\n            this.xhr.removeEventListener('load', this._boundXhrOnLoad);\n        }\n        else {\n            this.xhr.onerror = null;\n            this.xhr.ontimeout = null;\n            this.xhr.onprogress = null;\n            this.xhr.onload = null;\n        }\n    }\n\n    this.emit('complete', this);\n};\n\n/**\n * Kicks off loading of this resource.\n *\n * @fires start\n * @param [callback] {function} Optional callback to call once the resource is loaded.\n */\nResource.prototype.load = function (cb) {\n    this.emit('start', this);\n\n    // if a callback is set, listen for complete event\n    if (cb) {\n        this.once('complete', cb);\n    }\n\n    // if unset, determine the value\n    if (this.crossOrigin === false || typeof this.crossOrigin !== 'string') {\n        this.crossOrigin = this._determineCrossOrigin(this.url);\n    }\n\n    switch(this.loadType) {\n        case Resource.LOAD_TYPE.IMAGE:\n            this._loadImage();\n            break;\n\n        case Resource.LOAD_TYPE.AUDIO:\n            this._loadElement('audio');\n            break;\n\n        case Resource.LOAD_TYPE.VIDEO:\n            this._loadElement('video');\n            break;\n\n        case Resource.LOAD_TYPE.XHR:\n            /* falls through */\n        default:\n            if (useXdr && this.crossOrigin) {\n                this._loadXdr();\n            }\n            else {\n                this._loadXhr();\n            }\n            break;\n    }\n};\n\n/**\n * Loads this resources using an Image object.\n *\n * @private\n */\nResource.prototype._loadImage = function () {\n    this.data = new Image();\n\n    if (this.crossOrigin) {\n        this.data.crossOrigin = this.crossOrigin;\n    }\n\n    this.data.src = this.url;\n\n    this.isImage = true;\n\n    this.data.addEventListener('error', this._boundOnError, false);\n    this.data.addEventListener('load', this._boundComplete, false);\n    this.data.addEventListener('progress', this._boundOnProgress, false);\n};\n\n/**\n * Loads this resources using an HTMLAudioElement or HTMLVideoElement.\n *\n * @private\n */\nResource.prototype._loadElement = function (type) {\n    if (type === 'audio' && typeof Audio !== 'undefined') {\n        this.data = new Audio();\n    }\n    else {\n        this.data = document.createElement(type);\n    }\n\n    if (this.data === null) {\n        this.error = new Error('Unsupported element ' + type);\n        this.complete();\n        return;\n    }\n\n    // support for CocoonJS Canvas+ runtime, lacks document.createElement('source')\n    if (navigator.isCocoonJS) {\n        this.data.src = Array.isArray(this.url) ? this.url[0] : this.url;\n    }\n    else {\n        if (Array.isArray(this.url)) {\n            for (var i = 0; i < this.url.length; ++i) {\n                this.data.appendChild(this._createSource(type, this.url[i]));\n            }\n        }\n        else {\n            this.data.appendChild(this._createSource(type, this.url));\n        }\n    }\n\n    this['is' + type[0].toUpperCase() + type.substring(1)] = true;\n\n    this.data.addEventListener('error', this._boundOnError, false);\n    this.data.addEventListener('load', this._boundComplete, false);\n    this.data.addEventListener('progress', this._boundOnProgress, false);\n    this.data.addEventListener('canplaythrough', this._boundComplete, false);\n\n    this.data.load();\n};\n\n/**\n * Loads this resources using an XMLHttpRequest.\n *\n * @private\n */\nResource.prototype._loadXhr = function () {\n    // if unset, determine the value\n    if (typeof this.xhrType !== 'string') {\n        this.xhrType = this._determineXhrType();\n    }\n\n    var xhr = this.xhr = new XMLHttpRequest();\n\n    // set the request type and url\n    xhr.open('GET', this.url, true);\n\n    // load json as text and parse it ourselves. We do this because some browsers\n    // *cough* safari *cough* can't deal with it.\n    if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON || this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) {\n        xhr.responseType = Resource.XHR_RESPONSE_TYPE.TEXT;\n    }\n    else {\n        xhr.responseType = this.xhrType;\n    }\n\n    xhr.addEventListener('error', this._boundXhrOnError, false);\n    xhr.addEventListener('abort', this._boundXhrOnAbort, false);\n    xhr.addEventListener('progress', this._boundOnProgress, false);\n    xhr.addEventListener('load', this._boundXhrOnLoad, false);\n\n    xhr.send();\n};\n\n/**\n * Loads this resources using an XDomainRequest. This is here because we need to support IE9 (gross).\n *\n * @private\n */\nResource.prototype._loadXdr = function () {\n    // if unset, determine the value\n    if (typeof this.xhrType !== 'string') {\n        this.xhrType = this._determineXhrType();\n    }\n\n    var xdr = this.xhr = new XDomainRequest();\n\n    // XDomainRequest has a few quirks. Occasionally it will abort requests\n    // A way to avoid this is to make sure ALL callbacks are set even if not used\n    // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9\n    xdr.timeout = 5000;\n\n    xdr.onerror = this._boundXhrOnError;\n    xdr.ontimeout = this._boundXdrOnTimeout;\n    xdr.onprogress = this._boundOnProgress;\n    xdr.onload = this._boundXhrOnLoad;\n\n    xdr.open('GET', this.url, true);\n\n    //  Note: The xdr.send() call is wrapped in a timeout to prevent an issue with the interface where some requests are lost\n    //  if multiple XDomainRequests are being sent at the same time.\n    // Some info here: https://github.com/photonstorm/phaser/issues/1248\n    setTimeout(function () {\n        xdr.send();\n    }, 0);\n};\n\n/**\n * Creates a source used in loading via an element.\n *\n * @param type {string} The element type (video or audio).\n * @param url {string} The source URL to load from.\n * @param [mime] {string} The mime type of the video\n * @private\n */\nResource.prototype._createSource = function (type, url, mime) {\n    if (!mime) {\n        mime = type + '/' + url.substr(url.lastIndexOf('.') + 1);\n    }\n\n    var source = document.createElement('source');\n\n    source.src = url;\n    source.type = mime;\n\n    return source;\n};\n\n/**\n * Called if a load errors out.\n *\n * @param event {Event} The error event from the element that emits it.\n * @private\n */\nResource.prototype._onError = function (event) {\n    this.error = new Error('Failed to load element using ' + event.target.nodeName);\n    this.complete();\n};\n\n/**\n * Called if a load progress event fires for xhr/xdr.\n *\n * @fires progress\n * @param event {XMLHttpRequestProgressEvent|Event}\n * @private\n */\nResource.prototype._onProgress =  function (event) {\n    if (event && event.lengthComputable) {\n        this.emit('progress', this, event.loaded / event.total);\n    }\n};\n\n/**\n * Called if an error event fires for xhr/xdr.\n *\n * @param event {XMLHttpRequestErrorEvent|Event}\n * @private\n */\nResource.prototype._xhrOnError = function () {\n    this.error = new Error(\n        reqType(this.xhr) + ' Request failed. ' +\n        'Status: ' + this.xhr.status + ', text: \"' + this.xhr.statusText + '\"'\n    );\n\n    this.complete();\n};\n\n/**\n * Called if an abort event fires for xhr.\n *\n * @param event {XMLHttpRequestAbortEvent}\n * @private\n */\nResource.prototype._xhrOnAbort = function () {\n    this.error = new Error(reqType(this.xhr) + ' Request was aborted by the user.');\n    this.complete();\n};\n\n/**\n * Called if a timeout event fires for xdr.\n *\n * @param event {Event}\n * @private\n */\nResource.prototype._xdrOnTimeout = function () {\n    this.error = new Error(reqType(this.xhr) + ' Request timed out.');\n    this.complete();\n};\n\n/**\n * Called when data successfully loads from an xhr/xdr request.\n *\n * @param event {XMLHttpRequestLoadEvent|Event}\n * @private\n */\nResource.prototype._xhrOnLoad = function () {\n    var xhr = this.xhr,\n        status = xhr.status !== undefined ? xhr.status : 200; //XDR has no `.status`, assume 200.\n\n    // status can be 0 when using the file:// protocol, also check if a response was found\n    if (status === 200 || status === 204 || (status === 0 && xhr.responseText.length > 0)) {\n        // if text, just return it\n        if (this.xhrType === Resource.XHR_RESPONSE_TYPE.TEXT) {\n            this.data = xhr.responseText;\n        }\n        // if json, parse into json object\n        else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON) {\n            try {\n                this.data = JSON.parse(xhr.responseText);\n                this.isJson = true;\n            } catch(e) {\n                this.error = new Error('Error trying to parse loaded json:', e);\n            }\n        }\n        // if xml, parse into an xml document or div element\n        else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) {\n            try {\n                if (window.DOMParser) {\n                    var domparser = new DOMParser();\n                    this.data = domparser.parseFromString(xhr.responseText, 'text/xml');\n                }\n                else {\n                    var div = document.createElement('div');\n                    div.innerHTML = xhr.responseText;\n                    this.data = div;\n                }\n                this.isXml = true;\n            } catch (e) {\n                this.error = new Error('Error trying to parse loaded xml:', e);\n            }\n        }\n        // other types just return the response\n        else {\n            this.data = xhr.response || xhr.responseText;\n        }\n    }\n    else {\n        this.error = new Error('[' + xhr.status + ']' + xhr.statusText + ':' + xhr.responseURL);\n    }\n\n    this.complete();\n};\n\nfunction reqType(xhr) {\n    return xhr.toString().replace('object ', '');\n}\n\n/**\n * Sets the `crossOrigin` property for this resource based on if the url\n * for this resource is cross-origin. If crossOrigin was manually set, this\n * function does nothing.\n *\n * @private\n * @param url {string} The url to test.\n * @param [location=window.location] {object} The location object to test against.\n * @return {string} The crossOrigin value to use (or empty string for none).\n */\nResource.prototype._determineCrossOrigin = function (url, loc) {\n    // data: and javascript: urls are considered same-origin\n    if (url.indexOf('data:') === 0) {\n        return '';\n    }\n\n    // default is window.location\n    loc = loc || window.location;\n\n    if (!tempAnchor) {\n        tempAnchor = document.createElement('a');\n    }\n\n    // let the browser determine the full href for the url of this resource and then\n    // parse with the node url lib, we can't use the properties of the anchor element\n    // because they don't work in IE9 :(\n    tempAnchor.href = url;\n    url = _url.parse(tempAnchor.href);\n\n    var samePort = (!url.port && loc.port === '') || (url.port === loc.port);\n\n    // if cross origin\n    if (url.hostname !== loc.hostname || !samePort || url.protocol !== loc.protocol) {\n        return 'anonymous';\n    }\n\n    return '';\n};\n\n/**\n * Determines the responseType of an XHR request based on the extension of the\n * resource being loaded.\n *\n * @private\n * @return {Resource.XHR_RESPONSE_TYPE} The responseType to use.\n */\nResource.prototype._determineXhrType = function () {\n    return Resource._xhrTypeMap[this._getExtension()] || Resource.XHR_RESPONSE_TYPE.TEXT;\n};\n\nResource.prototype._determineLoadType = function () {\n    return Resource._loadTypeMap[this._getExtension()] || Resource.LOAD_TYPE.XHR;\n};\n\nResource.prototype._getExtension = function () {\n    var url = this.url,\n        ext;\n\n    if (this.isDataUrl) {\n        var slashIndex = url.indexOf('/');\n        ext = url.substring(slashIndex + 1, url.indexOf(';', slashIndex));\n    }\n    else {\n        var queryStart = url.indexOf('?');\n        if (queryStart !== -1) {\n            url = url.substring(0, queryStart);\n        }\n\n        ext = url.substring(url.lastIndexOf('.') + 1);\n    }\n\n    return ext;\n};\n\n/**\n * Determines the mime type of an XHR request based on the responseType of\n * resource being loaded.\n *\n * @private\n * @return {string} The mime type to use.\n */\nResource.prototype._getMimeFromXhrType = function (type) {\n    switch(type) {\n        case Resource.XHR_RESPONSE_TYPE.BUFFER:\n            return 'application/octet-binary';\n\n        case Resource.XHR_RESPONSE_TYPE.BLOB:\n            return 'application/blob';\n\n        case Resource.XHR_RESPONSE_TYPE.DOCUMENT:\n            return 'application/xml';\n\n        case Resource.XHR_RESPONSE_TYPE.JSON:\n            return 'application/json';\n\n        case Resource.XHR_RESPONSE_TYPE.DEFAULT:\n        case Resource.XHR_RESPONSE_TYPE.TEXT:\n            /* falls through */\n        default:\n            return 'text/plain';\n\n    }\n};\n\n/**\n * The types of loading a resource can use.\n *\n * @static\n * @constant\n * @property {object} LOAD_TYPE\n * @property {number} LOAD_TYPE.XHR - Uses XMLHttpRequest to load the resource.\n * @property {number} LOAD_TYPE.IMAGE - Uses an `Image` object to load the resource.\n * @property {number} LOAD_TYPE.AUDIO - Uses an `Audio` object to load the resource.\n * @property {number} LOAD_TYPE.VIDEO - Uses a `Video` object to load the resource.\n */\nResource.LOAD_TYPE = {\n    XHR:    1,\n    IMAGE:  2,\n    AUDIO:  3,\n    VIDEO:  4\n};\n\n/**\n * The XHR ready states, used internally.\n *\n * @static\n * @constant\n * @property {object} XHR_READY_STATE\n * @property {number} XHR_READY_STATE.UNSENT - open()has not been called yet.\n * @property {number} XHR_READY_STATE.OPENED - send()has not been called yet.\n * @property {number} XHR_READY_STATE.HEADERS_RECEIVED - send() has been called, and headers and status are available.\n * @property {number} XHR_READY_STATE.LOADING - Downloading; responseText holds partial data.\n * @property {number} XHR_READY_STATE.DONE - The operation is complete.\n */\nResource.XHR_READY_STATE = {\n    UNSENT: 0,\n    OPENED: 1,\n    HEADERS_RECEIVED: 2,\n    LOADING: 3,\n    DONE: 4\n};\n\n/**\n * The XHR ready states, used internally.\n *\n * @static\n * @constant\n * @property {object} XHR_RESPONSE_TYPE\n * @property {string} XHR_RESPONSE_TYPE.DEFAULT - defaults to text\n * @property {string} XHR_RESPONSE_TYPE.BUFFER - ArrayBuffer\n * @property {string} XHR_RESPONSE_TYPE.BLOB - Blob\n * @property {string} XHR_RESPONSE_TYPE.DOCUMENT - Document\n * @property {string} XHR_RESPONSE_TYPE.JSON - Object\n * @property {string} XHR_RESPONSE_TYPE.TEXT - String\n */\nResource.XHR_RESPONSE_TYPE = {\n    DEFAULT:    'text',\n    BUFFER:     'arraybuffer',\n    BLOB:       'blob',\n    DOCUMENT:   'document',\n    JSON:       'json',\n    TEXT:       'text'\n};\n\nResource._loadTypeMap = {\n    'gif':      Resource.LOAD_TYPE.IMAGE,\n    'png':      Resource.LOAD_TYPE.IMAGE,\n    'bmp':      Resource.LOAD_TYPE.IMAGE,\n    'jpg':      Resource.LOAD_TYPE.IMAGE,\n    'jpeg':     Resource.LOAD_TYPE.IMAGE,\n    'tif':      Resource.LOAD_TYPE.IMAGE,\n    'tiff':     Resource.LOAD_TYPE.IMAGE,\n    'webp':     Resource.LOAD_TYPE.IMAGE,\n    'tga':      Resource.LOAD_TYPE.IMAGE\n};\n\nResource._xhrTypeMap = {\n    // xml\n    'xhtml':    Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'html':     Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'htm':      Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'xml':      Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'tmx':      Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'tsx':      Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n    'svg':      Resource.XHR_RESPONSE_TYPE.DOCUMENT,\n\n    // images\n    'gif':      Resource.XHR_RESPONSE_TYPE.BLOB,\n    'png':      Resource.XHR_RESPONSE_TYPE.BLOB,\n    'bmp':      Resource.XHR_RESPONSE_TYPE.BLOB,\n    'jpg':      Resource.XHR_RESPONSE_TYPE.BLOB,\n    'jpeg':     Resource.XHR_RESPONSE_TYPE.BLOB,\n    'tif':      Resource.XHR_RESPONSE_TYPE.BLOB,\n    'tiff':     Resource.XHR_RESPONSE_TYPE.BLOB,\n    'webp':     Resource.XHR_RESPONSE_TYPE.BLOB,\n    'tga':      Resource.XHR_RESPONSE_TYPE.BLOB,\n\n    // json\n    'json':     Resource.XHR_RESPONSE_TYPE.JSON,\n\n    // text\n    'text':     Resource.XHR_RESPONSE_TYPE.TEXT,\n    'txt':      Resource.XHR_RESPONSE_TYPE.TEXT\n};\n\n/**\n * Sets the load type to be used for a specific extension.\n *\n * @static\n * @param extname {string} The extension to set the type for, e.g. \"png\" or \"fnt\"\n * @param loadType {Resource.LOAD_TYPE} The load type to set it to.\n */\nResource.setExtensionLoadType = function (extname, loadType) {\n    setExtMap(Resource._loadTypeMap, extname, loadType);\n};\n\n/**\n * Sets the load type to be used for a specific extension.\n *\n * @static\n * @param extname {string} The extension to set the type for, e.g. \"png\" or \"fnt\"\n * @param xhrType {Resource.XHR_RESPONSE_TYPE} The xhr type to set it to.\n */\nResource.setExtensionXhrType = function (extname, xhrType) {\n    setExtMap(Resource._xhrTypeMap, extname, xhrType);\n};\n\nfunction setExtMap(map, extname, val) {\n    if (extname && extname.indexOf('.') === 0) {\n        extname = extname.substring(1);\n    }\n\n    if (!extname) {\n        return;\n    }\n\n    map[extname] = val;\n}\n\n},{\"eventemitter3\":10,\"url\":8}],15:[function(require,module,exports){\nmodule.exports = {\n\n    // private property\n    _keyStr: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",\n\n    encodeBinary: function (input) {\n        var output = \"\";\n        var bytebuffer;\n        var encodedCharIndexes = new Array(4);\n        var inx = 0;\n        var jnx = 0;\n        var paddingBytes = 0;\n\n        while (inx < input.length) {\n            // Fill byte buffer array\n            bytebuffer = new Array(3);\n            for (jnx = 0; jnx < bytebuffer.length; jnx++) {\n                if (inx < input.length) {\n                    // throw away high-order byte, as documented at:\n                    // https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data\n                    bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff;\n                }\n                else {\n                    bytebuffer[jnx] = 0;\n                }\n            }\n\n            // Get each encoded character, 6 bits at a time\n            // index 1: first 6 bits\n            encodedCharIndexes[0] = bytebuffer[0] >> 2;\n            // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)\n            encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);\n            // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)\n            encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);\n            // index 3: forth 6 bits (6 least significant bits from input byte 3)\n            encodedCharIndexes[3] = bytebuffer[2] & 0x3f;\n\n            // Determine whether padding happened, and adjust accordingly\n            paddingBytes = inx - (input.length - 1);\n            switch (paddingBytes) {\n                case 2:\n                    // Set last 2 characters to padding char\n                    encodedCharIndexes[3] = 64;\n                    encodedCharIndexes[2] = 64;\n                    break;\n\n                case 1:\n                    // Set last character to padding char\n                    encodedCharIndexes[3] = 64;\n                    break;\n\n                default:\n                    break; // No padding - proceed\n            }\n\n            // Now we will grab each appropriate character out of our keystring\n            // based on our index array and append it to the output string\n            for (jnx = 0; jnx < encodedCharIndexes.length; jnx++) {\n                output += this._keyStr.charAt(encodedCharIndexes[jnx]);\n            }\n        }\n        return output;\n    }\n};\n\n},{}],16:[function(require,module,exports){\nmodule.exports = require('./Loader');\n\nmodule.exports.Resource = require('./Resource');\n\nmodule.exports.middleware = {\n    caching: {\n        memory: require('./middlewares/caching/memory')\n    },\n    parsing: {\n        blob: require('./middlewares/parsing/blob')\n    }\n};\n\n},{\"./Loader\":13,\"./Resource\":14,\"./middlewares/caching/memory\":17,\"./middlewares/parsing/blob\":18}],17:[function(require,module,exports){\n// a simple in-memory cache for resources\nvar cache = {};\n\nmodule.exports = function () {\n    return function (resource, next) {\n        // if cached, then set data and complete the resource\n        if (cache[resource.url]) {\n            resource.data = cache[resource.url];\n            resource.complete();\n        }\n        // if not cached, wait for complete and store it in the cache.\n        else {\n            resource.once('complete', function () {\n               cache[this.url] = this.data;\n            });\n        }\n        \n        next();\n    };\n};\n\n},{}],18:[function(require,module,exports){\nvar Resource = require('../../Resource'),\n    b64 = require('../../b64');\n\nwindow.URL = window.URL || window.webkitURL;\n\n// a middleware for transforming XHR loaded Blobs into more useful objects\n\nmodule.exports = function () {\n    return function (resource, next) {\n        if (!resource.data) {\n            return next();\n        }\n\n        // if this was an XHR load of a blob\n        if (resource.xhr && resource.xhrType === Resource.XHR_RESPONSE_TYPE.BLOB) {\n            // if there is no blob support we probably got a binary string back\n            if (!window.Blob || typeof resource.data === 'string') {\n                var type = resource.xhr.getResponseHeader('content-type');\n\n                // this is an image, convert the binary string into a data url\n                if (type && type.indexOf('image') === 0) {\n                    resource.data = new Image();\n                    resource.data.src = 'data:' + type + ';base64,' + b64.encodeBinary(resource.xhr.responseText);\n\n                    resource.isImage = true;\n\n                    // wait until the image loads and then callback\n                    resource.data.onload = function () {\n                        resource.data.onload = null;\n\n                        next();\n                    };\n                }\n            }\n            // if content type says this is an image, then we should transform the blob into an Image object\n            else if (resource.data.type.indexOf('image') === 0) {\n                var src = URL.createObjectURL(resource.data);\n\n                resource.blob = resource.data;\n                resource.data = new Image();\n                resource.data.src = src;\n\n                resource.isImage = true;\n\n                // cleanup the no longer used blob after the image loads\n                resource.data.onload = function () {\n                    URL.revokeObjectURL(src);\n                    resource.data.onload = null;\n\n                    next();\n                };\n            }\n        }\n        else {\n            next();\n        }\n    };\n};\n\n},{\"../../Resource\":14,\"../../b64\":15}],19:[function(require,module,exports){\nvar core = require('../core');\n\n// add some extra variables to the container..\nObject.assign(\n    core.DisplayObject.prototype,\n    require('./accessibleTarget')\n);\n\n\n/**\n * The Accessibility manager reacreates the ability to tab and and have content read by screen readers. This is very important as it can possibly help people with disabilities access pixi content.\n * Much like interaction any DisplayObject can be made accessible. This manager will map the events as if the mouse was being used, minimizing the efferot required to implement.\n *\n * @class\n * @memberof PIXI\n * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} A reference to the current renderer\n */\nfunction AccessibilityManager(renderer)\n{\n\t// first we create a div that will sit over the pixi element. This is where the div overlays will go.\n    var div = document.createElement('div');\n    \n    div.style.width = 100 + 'px';\n    div.style.height = 100 + 'px';\n    div.style.position = 'absolute';\n    div.style.top = 0;\n    div.style.left = 0;\n   //\n    div.style.zIndex = 2;\n   \t\n   \t/**\n   \t * This is the dom element that will sit over the pixi element. This is where the div overlays will go.\n   \t * \n   \t * @type {HTMLElement}\n   \t * @private\n   \t */\n   \tthis.div = div;\n\n   \t/**\n   \t * A simple pool for storing divs.\n   \t * \n   \t * @type {Array}\n   \t * @private\n   \t */\n \tthis.pool = [];\n\n \t/**\n \t * This is a tick used to check if an object is no longer being rendered.\n \t * \n \t * @type {Number}\n \t * @private\n \t */\n   \tthis.renderId = 0;\n\n   \t/**\n   \t * Setting this to true will visually show the divs\n   \t * \n   \t * @type {Boolean}\n   \t */\n   \tthis.debug = false;\n\n  \t/**\n     * The renderer this accessibility manager works for.\n     *\n     * @member {PIXI.SystemRenderer}\n     */\n   \tthis.renderer = renderer;\n\n   \t/**\n     * The array of currently active accessible items.\n     *\n     * @member {Array}\n     * @private\n     */\n   \tthis.children = [];\n   \t\n   \t/**\n     * pre bind the functions..\n     */\n   \tthis._onKeyDown = this._onKeyDown.bind(this);\n   \tthis._onMouseMove = this._onMouseMove.bind(this);\n   \t\n   \t/**\n     * stores the state of the manager. If there are no accessible objects or the mouse is moving the will be false.\n     *\n     * @member {Array}\n     * @private\n     */\n   \tthis.isActive = false;\n\n\n   \t// let listen for tab.. once pressed we can fire up and show the accessibility layer\n   \twindow.addEventListener('keydown', this._onKeyDown, false);\n}\n\n\nAccessibilityManager.prototype.constructor = AccessibilityManager;\nmodule.exports = AccessibilityManager;\n\n/**\n * Activating will cause the Accessibility layer to be shown. This is called when a user preses the tab key\n * @private\n */\nAccessibilityManager.prototype.activate = function()\n{\n\tif(this.isActive)\n\t{\n\t\treturn;\n\t}\n\n\tthis.isActive = true;\n\n\twindow.document.addEventListener('mousemove', this._onMouseMove, true);\n\twindow.removeEventListener('keydown', this._onKeyDown, false);\n\n\tthis.renderer.on('postrender', this.update, this);\n\n\tthis.renderer.view.parentNode.appendChild(this.div);\t\n};\n\n/**\n * Deactivating will cause the Accessibility layer to be hidden. This is called when a user moves the mouse\n * @private\n */\nAccessibilityManager.prototype.deactivate = function()\n{\n\tif(!this.isActive)\n\t{\n\t\treturn;\n\t}\n\n\tthis.isActive = false;\n\n\twindow.document.removeEventListener('mousemove', this._onMouseMove);\n\twindow.addEventListener('keydown', this._onKeyDown, false);\n\n\tthis.renderer.off('postrender', this.update);\n\n\tthis.div.parentNode.removeChild(this.div);\n\n};\n\n/**\n * This recursive function will run throught he scene graph and add any new accessible objects to the DOM layer.\n * @param element {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} the DisplayObject to check.\n * @private\n */\nAccessibilityManager.prototype.updateAccessibleObjects = function(displayObject)\n{\n\tif(!displayObject.visible)\n\t{\n\t\treturn;\n\t}\n\n\tif(displayObject.accessible && displayObject.interactive)\n\t{\n\t\tif(!displayObject._accessibleActive)\n\t\t{\n\t\t\tthis.addChild(displayObject);\n\t\t}\n\t   \t\n\t   \tdisplayObject.renderId = this.renderId;\n\t}\n\n\n\tif(displayObject.interactiveChildren)\n\t{\n\n\t\tvar children = displayObject.children;\n\n\t\tfor (var i = children.length - 1; i >= 0; i--) {\n\t\t\n\t\t\tthis.updateAccessibleObjects(children[i]);\n\t\t}\n\t}\n};\n\n\n/**\n * Before each render this function will ensure that all divs are mapped correctly to their DisplayObjects\n * @private\n */\nAccessibilityManager.prototype.update = function()\n{\n\n\t// update children...\n\tthis.updateAccessibleObjects(this.renderer._lastObjectRendered);\n\n\tvar rect = this.renderer.view.getBoundingClientRect();\n\tvar sx = rect.width  / this.renderer.width;\n\tvar sy = rect.height / this.renderer.height;\n\n\tvar div = this.div;\n\n\tdiv.style.left = rect.left + 'px';\n\tdiv.style.top = rect.top + 'px';\n\tdiv.style.width = this.renderer.width + 'px';\n\tdiv.style.height = this.renderer.height + 'px';\n\n\tfor (var i = 0; i < this.children.length; i++)\n\t{\n\n\t\tvar child = this.children[i];\n\n\t\tif(child.renderId !== this.renderId)\n\t\t{\n\t\t\tchild._accessibleActive = false;\n\n            core.utils.removeItems(this.children, i, 1);\n\t\t\tthis.div.removeChild( child._accessibleDiv );\n\t\t\tthis.pool.push(child._accessibleDiv);\n\t\t\tchild._accessibleDiv = null;\n\n\t\t\ti--;\n\n\t\t\tif(this.children.length === 0)\n\t\t\t{\n\t\t\t\tthis.deactivate();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// map div to display..\n\t\t\tdiv = child._accessibleDiv;\n\t\t\tvar hitArea = child.hitArea;\n\t\t\tvar wt = child.worldTransform;\n\n\t\t\tif(child.hitArea)\n\t\t\t{\n\t\t\t\tdiv.style.left = ((wt.tx + (hitArea.x * wt.a)) * sx) + 'px';\n\t\t\t\tdiv.style.top =  ((wt.ty + (hitArea.y * wt.d)) * sy) +  'px';\n\n\t\t\t\tdiv.style.width = (hitArea.width * wt.a * sx) + 'px';\n\t\t\t\tdiv.style.height = (hitArea.height * wt.d * sy) + 'px';\n\t\t\t\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\thitArea = child.getBounds();\n\n\t\t\t\tthis.capHitArea(hitArea);\n\n\t\t\t\tdiv.style.left = (hitArea.x * sx) + 'px';\n\t\t\t\tdiv.style.top =  (hitArea.y * sy) +  'px';\n\n\t\t\t\tdiv.style.width = (hitArea.width * sx) + 'px';\n\t\t\t\tdiv.style.height = (hitArea.height * sy) + 'px';\n\t\t\t}\t\t\n\t\t}\n\t}\n\n\t// increment the render id..\n\tthis.renderId++;\n};\n\nAccessibilityManager.prototype.capHitArea = function (hitArea)\n{\n    if (hitArea.x < 0)\n    {\n        hitArea.width += hitArea.x;\n        hitArea.x = 0;\n    }\n\n    if (hitArea.y < 0)\n    {\n        hitArea.height += hitArea.y;\n        hitArea.y = 0;\n    }\n\n    if ( hitArea.x + hitArea.width > this.renderer.width )\n    {\n        hitArea.width = this.renderer.width - hitArea.x;\n    }\n\n    if ( hitArea.y + hitArea.height > this.renderer.height )\n    {\n        hitArea.height = this.renderer.height - hitArea.y;\n    }\n};\n\n\n/**\n * Adds a DisplayObject to the accessibility manager\n * @private\n */\nAccessibilityManager.prototype.addChild = function(displayObject)\n{\n//\tthis.activate();\n\t\n\tvar div = this.pool.pop();\n\n\tif(!div)\n\t{\n\t\tdiv = document.createElement('button'); \n\n\t    div.style.width = 100 + 'px';\n\t    div.style.height = 100 + 'px';\n\t    div.style.backgroundColor = this.debug ? 'rgba(255,0,0,0.5)' : 'transparent';\n\t    div.style.position = 'absolute';\n\t    div.style.zIndex = 2;\n\t    div.style.borderStyle = 'none';\n\n\t    \n\t    div.addEventListener('click', this._onClick.bind(this));\n\t    div.addEventListener('focus', this._onFocus.bind(this));\n\t    div.addEventListener('focusout', this._onFocusOut.bind(this));\n\t}\n\t   \t\n\n\n\n\tdiv.title = displayObject.accessibleTitle || 'displayObject ' + this.tabIndex;\n\n\t//\n\t\n\tdisplayObject._accessibleActive = true;\n\tdisplayObject._accessibleDiv = div;\n\tdiv.displayObject = displayObject;\n\n\n\tthis.children.push(displayObject);\n\tthis.div.appendChild( displayObject._accessibleDiv );\n\tdisplayObject._accessibleDiv.tabIndex = displayObject.tabIndex;\n};\n\n\n/**\n * Maps the div button press to pixi's InteractionManager (click)\n * @private\n */\nAccessibilityManager.prototype._onClick = function(e)\n{\n\tvar interactionManager = this.renderer.plugins.interaction;\n\tinteractionManager.dispatchEvent(e.target.displayObject, 'click', interactionManager.eventData);\n};\n\n/**\n * Maps the div focus events to pixis InteractionManager (mouseover)\n * @private\n */\nAccessibilityManager.prototype._onFocus = function(e)\n{\n\tvar interactionManager = this.renderer.plugins.interaction;\n\tinteractionManager.dispatchEvent(e.target.displayObject, 'mouseover', interactionManager.eventData);\n};\n\n/**\n * Maps the div focus events to pixis InteractionManager (mouseout)\n * @private\n */\nAccessibilityManager.prototype._onFocusOut = function(e)\n{\n\tvar interactionManager = this.renderer.plugins.interaction;\n\tinteractionManager.dispatchEvent(e.target.displayObject, 'mouseout', interactionManager.eventData);\n};\n\n/**\n * Is called when a key is pressed\n *\n * @private\n */\nAccessibilityManager.prototype._onKeyDown = function(e)\n{\n\tif(e.keyCode !== 9)\n\t{\n\t\treturn;\n\t}\n\n\tthis.activate();\n};\n\n/**\n * Is called when the mouse moves across the renderer element\n *\n * @private\n */\nAccessibilityManager.prototype._onMouseMove = function()\n{\n\tthis.deactivate();\n};\n\n\n/**\n * Destroys the accessibility manager\n *\n */\nAccessibilityManager.prototype.destroy = function () \n{\n\tthis.div = null;\n\n\tfor (var i = 0; i < this.children.length; i++)\n\t{\n\t\tthis.children[i].div = null;\n\t}\n\n\t\n\twindow.document.removeEventListener('mousemove', this._onMouseMove);\n\twindow.removeEventListener('keydown', this._onKeyDown);\n\t\t\n\tthis.pool = null;\n\tthis.children = null;\n\tthis.renderer = null;\n\n};\n\ncore.WebGLRenderer.registerPlugin('accessibility', AccessibilityManager);\ncore.CanvasRenderer.registerPlugin('accessibility', AccessibilityManager);\n\n\n},{\"../core\":29,\"./accessibleTarget\":20}],20:[function(require,module,exports){\n/**\n * Default property values of accessible objects\n * used by {@link PIXI.accessibility.AccessibilityManager}.\n *\n * @mixin\n * @memberof PIXI\n * @example\n *      function MyObject() {}\n *\n *      Object.assign(\n *          MyObject.prototype,\n *          PIXI.accessibility.accessibleTarget\n *      );\n */\nvar accessibleTarget = {\n    \n    /**\n     * @todo Needs docs.\n     */\n    accessible:false,\n\n    /**\n     * @todo Needs docs.\n     */\n    accessibleTitle:null,\n\n    /**\n     * @todo Needs docs.\n     */\n    tabIndex:0,\n\n    /**\n     * @todo Needs docs.\n     */\n    _accessibleActive:false,\n\n    /**\n     * @todo Needs docs.\n     */\n    _accessibleDiv:false\n\n};\n\nmodule.exports = accessibleTarget;\n\n},{}],21:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI accessibility library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI.interaction\n */\nmodule.exports = {\n    accessibleTarget:     require('./accessibleTarget'),\n    AccessibilityManager: require('./AccessibilityManager')\n};\n\n},{\"./AccessibilityManager\":19,\"./accessibleTarget\":20}],22:[function(require,module,exports){\n/**\n * Constant values used in pixi\n *\n * @lends PIXI\n */\nvar CONST = {\n    /**\n     * String of the current PIXI version\n     *\n     * @static\n     * @constant\n     * @property {string} VERSION\n     */\n    VERSION: '3.0.10',\n\n    /**\n     * @property {number} PI_2 - Two Pi\n     * @constant\n     * @static\n     */\n    PI_2: Math.PI * 2,\n\n    /**\n     * @property {number} RAD_TO_DEG - Constant conversion factor for converting radians to degrees\n     * @constant\n     * @static\n     */\n    RAD_TO_DEG: 180 / Math.PI,\n\n    /**\n     * @property {Number} DEG_TO_RAD - Constant conversion factor for converting degrees to radians\n     * @constant\n     * @static\n     */\n    DEG_TO_RAD: Math.PI / 180,\n\n    /**\n     * Target frames per millisecond.\n     *\n     * @static\n     * @constant\n     * @property {number} TARGET_FPMS=0.06\n     */\n    TARGET_FPMS: 0.06,\n\n    /**\n     * Constant to identify the Renderer Type.\n     *\n     * @static\n     * @constant\n     * @property {object} RENDERER_TYPE\n     * @property {number} RENDERER_TYPE.UNKNOWN\n     * @property {number} RENDERER_TYPE.WEBGL\n     * @property {number} RENDERER_TYPE.CANVAS\n     */\n    RENDERER_TYPE: {\n        UNKNOWN:    0,\n        WEBGL:      1,\n        CANVAS:     2\n    },\n\n    /**\n     * Various blend modes supported by PIXI. IMPORTANT - The WebGL renderer only supports\n     * the NORMAL, ADD, MULTIPLY and SCREEN blend modes. Anything else will silently act like\n     * NORMAL.\n     *\n     * @static\n     * @constant\n     * @property {object} BLEND_MODES\n     * @property {number} BLEND_MODES.NORMAL\n     * @property {number} BLEND_MODES.ADD\n     * @property {number} BLEND_MODES.MULTIPLY\n     * @property {number} BLEND_MODES.SCREEN\n     * @property {number} BLEND_MODES.OVERLAY\n     * @property {number} BLEND_MODES.DARKEN\n     * @property {number} BLEND_MODES.LIGHTEN\n     * @property {number} BLEND_MODES.COLOR_DODGE\n     * @property {number} BLEND_MODES.COLOR_BURN\n     * @property {number} BLEND_MODES.HARD_LIGHT\n     * @property {number} BLEND_MODES.SOFT_LIGHT\n     * @property {number} BLEND_MODES.DIFFERENCE\n     * @property {number} BLEND_MODES.EXCLUSION\n     * @property {number} BLEND_MODES.HUE\n     * @property {number} BLEND_MODES.SATURATION\n     * @property {number} BLEND_MODES.COLOR\n     * @property {number} BLEND_MODES.LUMINOSITY\n     */\n    BLEND_MODES: {\n        NORMAL:         0,\n        ADD:            1,\n        MULTIPLY:       2,\n        SCREEN:         3,\n        OVERLAY:        4,\n        DARKEN:         5,\n        LIGHTEN:        6,\n        COLOR_DODGE:    7,\n        COLOR_BURN:     8,\n        HARD_LIGHT:     9,\n        SOFT_LIGHT:     10,\n        DIFFERENCE:     11,\n        EXCLUSION:      12,\n        HUE:            13,\n        SATURATION:     14,\n        COLOR:          15,\n        LUMINOSITY:     16\n    },\n\n    /**\n     * Various webgl draw modes. These can be used to specify which GL drawMode to use\n     * under certain situations and renderers.\n     *\n     * @static\n     * @constant\n     * @property {object} DRAW_MODES\n     * @property {number} DRAW_MODES.POINTS\n     * @property {number} DRAW_MODES.LINES\n     * @property {number} DRAW_MODES.LINE_LOOP\n     * @property {number} DRAW_MODES.LINE_STRIP\n     * @property {number} DRAW_MODES.TRIANGLES\n     * @property {number} DRAW_MODES.TRIANGLE_STRIP\n     * @property {number} DRAW_MODES.TRIANGLE_FAN\n     */\n    DRAW_MODES: {\n        POINTS:         0,\n        LINES:          1,\n        LINE_LOOP:      2,\n        LINE_STRIP:     3,\n        TRIANGLES:      4,\n        TRIANGLE_STRIP: 5,\n        TRIANGLE_FAN:   6\n    },\n\n    /**\n     * The scale modes that are supported by pixi.\n     *\n     * The DEFAULT scale mode affects the default scaling mode of future operations.\n     * It can be re-assigned to either LINEAR or NEAREST, depending upon suitability.\n     *\n     * @static\n     * @constant\n     * @property {object} SCALE_MODES\n     * @property {number} SCALE_MODES.DEFAULT=LINEAR\n     * @property {number} SCALE_MODES.LINEAR Smooth scaling\n     * @property {number} SCALE_MODES.NEAREST Pixelating scaling\n     */\n    SCALE_MODES: {\n        DEFAULT:    0,\n        LINEAR:     0,\n        NEAREST:    1\n    },\n\n    /**\n     * The prefix that denotes a URL is for a retina asset\n     *\n     * @static\n     * @constant\n     * @property {string} RETINA_PREFIX\n     */\n    //example: '@2x',\n    RETINA_PREFIX: /@(.+)x/,\n\n    RESOLUTION:1,\n\n    FILTER_RESOLUTION:1,\n\n    /**\n     * The default render options if none are supplied to {@link PIXI.WebGLRenderer}\n     * or {@link PIXI.CanvasRenderer}.\n     *\n     * @static\n     * @constant\n     * @property {object} DEFAULT_RENDER_OPTIONS\n     * @property {HTMLCanvasElement} DEFAULT_RENDER_OPTIONS.view=null\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.transparent=false\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.antialias=false\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.forceFXAA=false\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.preserveDrawingBuffer=false\n     * @property {number} DEFAULT_RENDER_OPTIONS.resolution=1\n     * @property {number} DEFAULT_RENDER_OPTIONS.backgroundColor=0x000000\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.clearBeforeRender=true\n     * @property {boolean} DEFAULT_RENDER_OPTIONS.autoResize=false\n     */\n    DEFAULT_RENDER_OPTIONS: {\n        view: null,\n        resolution: 1,\n        antialias: false,\n        forceFXAA: false,\n        autoResize: false,\n        transparent: false,\n        backgroundColor: 0x000000,\n        clearBeforeRender: true,\n        preserveDrawingBuffer: false,\n        roundPixels: false\n    },\n\n    /**\n     * Constants that identify shapes, mainly to prevent `instanceof` calls.\n     *\n     * @static\n     * @constant\n     * @property {object} SHAPES\n     * @property {object} SHAPES.POLY=0\n     * @property {object} SHAPES.RECT=1\n     * @property {object} SHAPES.CIRC=2\n     * @property {object} SHAPES.ELIP=3\n     * @property {object} SHAPES.RREC=4\n     */\n    SHAPES: {\n        POLY: 0,\n        RECT: 1,\n        CIRC: 2,\n        ELIP: 3,\n        RREC: 4\n    },\n\n    // TODO: maybe change to SPRITE.BATCH_SIZE: 2000\n    // TODO: maybe add PARTICLE.BATCH_SIZE: 15000\n    SPRITE_BATCH_SIZE: 2000 //nice balance between mobile and desktop machines\n};\n\nmodule.exports = CONST;\n\n},{}],23:[function(require,module,exports){\nvar math = require('../math'),\n    utils = require('../utils'),\n    DisplayObject = require('./DisplayObject'),\n    RenderTexture = require('../textures/RenderTexture'),\n    _tempMatrix = new math.Matrix();\n\n/**\n * A Container represents a collection of display objects.\n * It is the base class of all display objects that act as a container for other objects.\n *\n *```js\n * var container = new PIXI.Container();\n * container.addChild(sprite);\n * ```\n * @class\n * @extends PIXI.DisplayObject\n * @memberof PIXI\n */\nfunction Container()\n{\n    DisplayObject.call(this);\n\n    /**\n     * The array of children of this container.\n     *\n     * @member {PIXI.DisplayObject[]}\n     * @readonly\n     */\n    this.children = [];\n}\n\n// constructor\nContainer.prototype = Object.create(DisplayObject.prototype);\nContainer.prototype.constructor = Container;\nmodule.exports = Container;\n\nObject.defineProperties(Container.prototype, {\n    /**\n     * The width of the Container, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Container#\n     */\n    width: {\n        get: function ()\n        {\n            return this.scale.x * this.getLocalBounds().width;\n        },\n        set: function (value)\n        {\n\n            var width = this.getLocalBounds().width;\n\n            if (width !== 0)\n            {\n                this.scale.x = value / width;\n            }\n            else\n            {\n                this.scale.x = 1;\n            }\n\n\n            this._width = value;\n        }\n    },\n\n    /**\n     * The height of the Container, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Container#\n     */\n    height: {\n        get: function ()\n        {\n            return  this.scale.y * this.getLocalBounds().height;\n        },\n        set: function (value)\n        {\n\n            var height = this.getLocalBounds().height;\n\n            if (height !== 0)\n            {\n                this.scale.y = value / height ;\n            }\n            else\n            {\n                this.scale.y = 1;\n            }\n\n            this._height = value;\n        }\n    }\n});\n\n/**\n * Overridable method that can be used by Container subclasses whenever the children array is modified\n *\n * @private\n */\nContainer.prototype.onChildrenChange = function () {};\n\n/**\n * Adds a child to the container.\n * \n * You can also add multple items like so: myContainer.addChild(thinkOne, thingTwo, thingThree)\n * @param child {PIXI.DisplayObject} The DisplayObject to add to the container\n * @return {PIXI.DisplayObject} The child that was added.\n */\nContainer.prototype.addChild = function (child)\n{ \n    var argumentsLength = arguments.length;\n\n    // if there is only one argument we can bypass looping through the them\n    if(argumentsLength > 1)\n    {\n        // loop through the arguments property and add all children\n        // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes\n        for (var i = 0; i < argumentsLength; i++)\n        {\n            this.addChild( arguments[i] );\n        }\n    }     \n    else\n    {\n        // if the child has a parent then lets remove it as Pixi objects can only exist in one place\n        if (child.parent)\n        {\n            child.parent.removeChild(child);\n        }\n\n        child.parent = this;\n        \n        this.children.push(child);\n\n        // TODO - lets either do all callbacks or all events.. not both!\n        this.onChildrenChange(this.children.length-1);\n        child.emit('added', this);\n    }\n\n    return child;\n};\n\n/**\n * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown\n *\n * @param child {PIXI.DisplayObject} The child to add\n * @param index {number} The index to place the child in\n * @return {PIXI.DisplayObject} The child that was added.\n */\nContainer.prototype.addChildAt = function (child, index)\n{\n    if (index >= 0 && index <= this.children.length)\n    {\n        if (child.parent)\n        {\n            child.parent.removeChild(child);\n        }\n\n        child.parent = this;\n\n        this.children.splice(index, 0, child);\n\n        // TODO - lets either do all callbacks or all events.. not both!\n        this.onChildrenChange(index);\n        child.emit('added', this);\n\n        return child;\n    }\n    else\n    {\n        throw new Error(child + 'addChildAt: The index '+ index +' supplied is out of bounds ' + this.children.length);\n    }\n};\n\n/**\n * Swaps the position of 2 Display Objects within this container.\n *\n * @param child {PIXI.DisplayObject}\n * @param child2 {PIXI.DisplayObject}\n */\nContainer.prototype.swapChildren = function (child, child2)\n{\n    if (child === child2)\n    {\n        return;\n    }\n\n    var index1 = this.getChildIndex(child);\n    var index2 = this.getChildIndex(child2);\n\n    if (index1 < 0 || index2 < 0)\n    {\n        throw new Error('swapChildren: Both the supplied DisplayObjects must be children of the caller.');\n    }\n\n    this.children[index1] = child2;\n    this.children[index2] = child;\n    this.onChildrenChange(index1 < index2 ? index1 : index2);\n};\n\n/**\n * Returns the index position of a child DisplayObject instance\n *\n * @param child {PIXI.DisplayObject} The DisplayObject instance to identify\n * @return {number} The index position of the child display object to identify\n */\nContainer.prototype.getChildIndex = function (child)\n{\n    var index = this.children.indexOf(child);\n\n    if (index === -1)\n    {\n        throw new Error('The supplied DisplayObject must be a child of the caller');\n    }\n\n    return index;\n};\n\n/**\n * Changes the position of an existing child in the display object container\n *\n * @param child {PIXI.DisplayObject} The child DisplayObject instance for which you want to change the index number\n * @param index {number} The resulting index number for the child display object\n */\nContainer.prototype.setChildIndex = function (child, index)\n{\n    if (index < 0 || index >= this.children.length)\n    {\n        throw new Error('The supplied index is out of bounds');\n    }\n\n    var currentIndex = this.getChildIndex(child);\n\n    utils.removeItems(this.children, currentIndex, 1); // remove from old position\n    this.children.splice(index, 0, child); //add at new position\n    this.onChildrenChange(index);\n};\n\n/**\n * Returns the child at the specified index\n *\n * @param index {number} The index to get the child at\n * @return {PIXI.DisplayObject} The child at the given index, if any.\n */\nContainer.prototype.getChildAt = function (index)\n{\n    if (index < 0 || index >= this.children.length)\n    {\n        throw new Error('getChildAt: Supplied index ' + index + ' does not exist in the child list, or the supplied DisplayObject is not a child of the caller');\n    }\n\n    return this.children[index];\n};\n\n/**\n * Removes a child from the container.\n *\n * @param child {PIXI.DisplayObject} The DisplayObject to remove\n * @return {PIXI.DisplayObject} The child that was removed.\n */\nContainer.prototype.removeChild = function (child)\n{\n    var argumentsLength = arguments.length;\n\n    // if there is only one argument we can bypass looping through the them\n    if(argumentsLength > 1)\n    {\n        // loop through the arguments property and add all children\n        // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes\n        for (var i = 0; i < argumentsLength; i++)\n        {\n            this.removeChild( arguments[i] );\n        }\n    }     \n    else\n    {   \n        var index = this.children.indexOf(child);\n\n        if (index === -1)\n        {\n            return;\n        }\n\n        child.parent = null;\n        utils.removeItems(this.children, index, 1);\n\n        // TODO - lets either do all callbacks or all events.. not both!\n        this.onChildrenChange(index);\n        child.emit('removed', this);\n    }\n\n    return child;\n};\n\n/**\n * Removes a child from the specified index position.\n *\n * @param index {number} The index to get the child from\n * @return {PIXI.DisplayObject} The child that was removed.\n */\nContainer.prototype.removeChildAt = function (index)\n{\n    var child = this.getChildAt(index);\n\n    child.parent = null;\n    utils.removeItems(this.children, index, 1);\n\n    // TODO - lets either do all callbacks or all events.. not both!\n    this.onChildrenChange(index);\n    child.emit('removed', this);\n\n    return child;\n};\n\n/**\n * Removes all children from this container that are within the begin and end indexes.\n *\n * @param beginIndex {number} The beginning position. Default value is 0.\n * @param endIndex {number} The ending position. Default value is size of the container.\n */\nContainer.prototype.removeChildren = function (beginIndex, endIndex)\n{\n    var begin = beginIndex || 0;\n    var end = typeof endIndex === 'number' ? endIndex : this.children.length;\n    var range = end - begin;\n    var removed, i;\n\n    if (range > 0 && range <= end)\n    {\n        removed = this.children.splice(begin, range);\n\n        for (i = 0; i < removed.length; ++i)\n        {\n            removed[i].parent = null;\n        }\n\n        this.onChildrenChange(beginIndex);\n\n        for (i = 0; i < removed.length; ++i)\n        {\n            removed[i].emit('removed', this);\n        }\n\n        return removed;\n    }\n    else if (range === 0 && this.children.length === 0)\n    {\n        return [];\n    }\n    else\n    {\n        throw new RangeError('removeChildren: numeric values are outside the acceptable range.');\n    }\n};\n\n/**\n * Useful function that returns a texture of the display object that can then be used to create sprites\n * This can be quite useful if your displayObject is static / complicated and needs to be reused multiple times.\n *\n * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} The renderer used to generate the texture.\n * @param resolution {number} The resolution of the texture being generated\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Texture} a texture of the display object\n */\nContainer.prototype.generateTexture = function (renderer, resolution, scaleMode)\n{\n    var bounds = this.getLocalBounds();\n\n    var renderTexture = new RenderTexture(renderer, bounds.width | 0, bounds.height | 0, scaleMode, resolution);\n\n    _tempMatrix.tx = -bounds.x;\n    _tempMatrix.ty = -bounds.y;\n\n    renderTexture.render(this, _tempMatrix);\n\n    return renderTexture;\n};\n\n/*\n * Updates the transform on all children of this container for rendering\n *\n * @private\n */\nContainer.prototype.updateTransform = function ()\n{\n    if (!this.visible)\n    {\n        return;\n    }\n\n    this.displayObjectUpdateTransform();\n\n    for (var i = 0, j = this.children.length; i < j; ++i)\n    {\n        this.children[i].updateTransform();\n    }\n};\n\n// performance increase to avoid using call.. (10x faster)\nContainer.prototype.containerUpdateTransform = Container.prototype.updateTransform;\n\n/**\n * Retrieves the bounds of the Container as a rectangle. The bounds calculation takes all visible children into consideration.\n *\n * @return {PIXI.Rectangle} The rectangular bounding area\n */\nContainer.prototype.getBounds = function ()\n{\n    if(!this._currentBounds)\n    {\n\n        if (this.children.length === 0)\n        {\n            return math.Rectangle.EMPTY;\n        }\n\n        // TODO the bounds have already been calculated this render session so return what we have\n\n        var minX = Infinity;\n        var minY = Infinity;\n\n        var maxX = -Infinity;\n        var maxY = -Infinity;\n\n        var childBounds;\n        var childMaxX;\n        var childMaxY;\n\n        var childVisible = false;\n\n        for (var i = 0, j = this.children.length; i < j; ++i)\n        {\n            var child = this.children[i];\n\n            if (!child.visible)\n            {\n                continue;\n            }\n\n            childVisible = true;\n\n            childBounds = this.children[i].getBounds();\n\n            minX = minX < childBounds.x ? minX : childBounds.x;\n            minY = minY < childBounds.y ? minY : childBounds.y;\n\n            childMaxX = childBounds.width + childBounds.x;\n            childMaxY = childBounds.height + childBounds.y;\n\n            maxX = maxX > childMaxX ? maxX : childMaxX;\n            maxY = maxY > childMaxY ? maxY : childMaxY;\n        }\n\n        if (!childVisible)\n        {\n            return math.Rectangle.EMPTY;\n        }\n\n        var bounds = this._bounds;\n\n        bounds.x = minX;\n        bounds.y = minY;\n        bounds.width = maxX - minX;\n        bounds.height = maxY - minY;\n\n        this._currentBounds = bounds;\n    }\n\n    return this._currentBounds;\n};\n\nContainer.prototype.containerGetBounds = Container.prototype.getBounds;\n\n/**\n * Retrieves the non-global local bounds of the Container as a rectangle.\n * The calculation takes all visible children into consideration.\n *\n * @return {PIXI.Rectangle} The rectangular bounding area\n */\nContainer.prototype.getLocalBounds = function ()\n{\n    var matrixCache = this.worldTransform;\n\n    this.worldTransform = math.Matrix.IDENTITY;\n\n    for (var i = 0, j = this.children.length; i < j; ++i)\n    {\n        this.children[i].updateTransform();\n    }\n\n    this.worldTransform = matrixCache;\n\n    this._currentBounds = null;\n\n    return this.getBounds( math.Matrix.IDENTITY );\n};\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer\n */\nContainer.prototype.renderWebGL = function (renderer)\n{\n\n    // if the object is not visible or the alpha is 0 then no need to render this element\n    if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n    {\n        return;\n    }\n\n    var i, j;\n\n    // do a quick check to see if this element has a mask or a filter.\n    if (this._mask || this._filters)\n    {\n        renderer.currentRenderer.flush();\n\n        // push filter first as we need to ensure the stencil buffer is correct for any masking\n        if (this._filters && this._filters.length)\n        {\n            renderer.filterManager.pushFilter(this, this._filters);\n        }\n\n        if (this._mask)\n        {\n            renderer.maskManager.pushMask(this, this._mask);\n        }\n\n        renderer.currentRenderer.start();\n\n        // add this object to the batch, only rendered if it has a texture.\n        this._renderWebGL(renderer);\n\n        // now loop through the children and make sure they get rendered\n        for (i = 0, j = this.children.length; i < j; i++)\n        {\n            this.children[i].renderWebGL(renderer);\n        }\n\n        renderer.currentRenderer.flush();\n\n        if (this._mask)\n        {\n            renderer.maskManager.popMask(this, this._mask);\n        }\n\n        if (this._filters)\n        {\n            renderer.filterManager.popFilter();\n\n        }\n        renderer.currentRenderer.start();\n    }\n    else\n    {\n        this._renderWebGL(renderer);\n\n        // simple render children!\n        for (i = 0, j = this.children.length; i < j; ++i)\n        {\n            this.children[i].renderWebGL(renderer);\n        }\n    }\n};\n\n/**\n * To be overridden by the subclass\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer\n * @private\n */\nContainer.prototype._renderWebGL = function (renderer) // jshint unused:false\n{\n    // this is where content itself gets rendered...\n};\n\n/**\n * To be overridden by the subclass\n *\n * @param renderer {PIXI.CanvasRenderer} The renderer\n * @private\n */\nContainer.prototype._renderCanvas = function (renderer) // jshint unused:false\n{\n    // this is where content itself gets rendered...\n};\n\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer} The renderer\n */\nContainer.prototype.renderCanvas = function (renderer)\n{\n    // if not visible or the alpha is 0 then no need to render this\n    if (!this.visible || this.alpha <= 0 || !this.renderable)\n    {\n        return;\n    }\n\n    if (this._mask)\n    {\n        renderer.maskManager.pushMask(this._mask, renderer);\n    }\n\n    this._renderCanvas(renderer);\n    for (var i = 0, j = this.children.length; i < j; ++i)\n    {\n        this.children[i].renderCanvas(renderer);\n    }\n\n    if (this._mask)\n    {\n        renderer.maskManager.popMask(renderer);\n    }\n};\n\n/**\n * Destroys the container\n * @param [destroyChildren=false] {boolean} if set to true, all the children will have their destroy method called as well\n */\nContainer.prototype.destroy = function (destroyChildren)\n{\n    DisplayObject.prototype.destroy.call(this);\n\n    if (destroyChildren)\n    {\n        for (var i = 0, j = this.children.length; i < j; ++i)\n        {\n            this.children[i].destroy(destroyChildren);\n        }\n    }\n\n    this.removeChildren();\n\n    this.children = null;\n};\n\n},{\"../math\":33,\"../textures/RenderTexture\":71,\"../utils\":77,\"./DisplayObject\":24}],24:[function(require,module,exports){\nvar math = require('../math'),\n    RenderTexture = require('../textures/RenderTexture'),\n    EventEmitter = require('eventemitter3'),\n    CONST = require('../const'),\n    _tempMatrix = new math.Matrix(),\n    _tempDisplayObjectParent = {worldTransform:new math.Matrix(), worldAlpha:1, children:[]};\n\n\n/**\n * The base class for all objects that are rendered on the screen.\n * This is an abstract class and should not be used on its own rather it should be extended.\n *\n * @class\n * @extends EventEmitter\n * @memberof PIXI\n */\nfunction DisplayObject()\n{\n    EventEmitter.call(this);\n\n    /**\n     * The coordinate of the object relative to the local coordinates of the parent.\n     *\n     * @member {PIXI.Point}\n     */\n    this.position = new math.Point();\n\n    /**\n     * The scale factor of the object.\n     *\n     * @member {PIXI.Point}\n     */\n    this.scale = new math.Point(1, 1);\n\n    /**\n     * The pivot point of the displayObject that it rotates around\n     *\n     * @member {PIXI.Point}\n     */\n    this.pivot = new math.Point(0, 0);\n\n\n    /**\n     * The skew factor for the object in radians.\n     *\n     * @member {PIXI.Point}\n     */\n    this.skew = new math.Point(0, 0);\n\n    /**\n     * The rotation of the object in radians.\n     *\n     * @member {number}\n     */\n    this.rotation = 0;\n\n    /**\n     * The opacity of the object.\n     *\n     * @member {number}\n     */\n    this.alpha = 1;\n\n    /**\n     * The visibility of the object. If false the object will not be drawn, and\n     * the updateTransform function will not be called.\n     *\n     * @member {boolean}\n     */\n    this.visible = true;\n\n    /**\n     * Can this object be rendered, if false the object will not be drawn but the updateTransform\n     * methods will still be called.\n     *\n     * @member {boolean}\n     */\n    this.renderable = true;\n\n    /**\n     * The display object container that contains this display object.\n     *\n     * @member {PIXI.Container}\n     * @readOnly\n     */\n    this.parent = null;\n\n    /**\n     * The multiplied alpha of the displayObject\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.worldAlpha = 1;\n\n    /**\n     * Current transform of the object based on world (parent) factors\n     *\n     * @member {PIXI.Matrix}\n     * @readOnly\n     */\n    this.worldTransform = new math.Matrix();\n\n    /**\n     * The area the filter is applied to. This is used as more of an optimisation\n     * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.filterArea = null;\n\n    /**\n     * cached sin rotation\n     *\n     * @member {number}\n     * @private\n     */\n    this._sr = 0;\n\n    /**\n     * cached cos rotation\n     *\n     * @member {number}\n     * @private\n     */\n    this._cr = 1;\n\n    /**\n     * The original, cached bounds of the object\n     *\n     * @member {PIXI.Rectangle}\n     * @private\n     */\n    this._bounds = new math.Rectangle(0, 0, 1, 1);\n\n    /**\n     * The most up-to-date bounds of the object\n     *\n     * @member {PIXI.Rectangle}\n     * @private\n     */\n    this._currentBounds = null;\n\n    /**\n     * The original, cached mask of the object\n     *\n     * @member {PIXI.Rectangle}\n     * @private\n     */\n    this._mask = null;\n}\n\n// constructor\nDisplayObject.prototype = Object.create(EventEmitter.prototype);\nDisplayObject.prototype.constructor = DisplayObject;\nmodule.exports = DisplayObject;\n\nObject.defineProperties(DisplayObject.prototype, {\n    /**\n     * The position of the displayObject on the x axis relative to the local coordinates of the parent.\n     *\n     * @member {number}\n     * @memberof PIXI.DisplayObject#\n     */\n    x: {\n        get: function ()\n        {\n            return this.position.x;\n        },\n        set: function (value)\n        {\n            this.position.x = value;\n        }\n    },\n\n    /**\n     * The position of the displayObject on the y axis relative to the local coordinates of the parent.\n     *\n     * @member {number}\n     * @memberof PIXI.DisplayObject#\n     */\n    y: {\n        get: function ()\n        {\n            return this.position.y;\n        },\n        set: function (value)\n        {\n            this.position.y = value;\n        }\n    },\n\n    /**\n     * Indicates if the sprite is globally visible.\n     *\n     * @member {boolean}\n     * @memberof PIXI.DisplayObject#\n     * @readonly\n     */\n    worldVisible: {\n        get: function ()\n        {\n            var item = this;\n\n            do {\n                if (!item.visible)\n                {\n                    return false;\n                }\n\n                item = item.parent;\n            } while (item);\n\n            return true;\n        }\n    },\n\n    /**\n     * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.\n     * In PIXI a regular mask must be a PIXI.Graphics or a PIXI.Sprite object. This allows for much faster masking in canvas as it utilises shape clipping.\n     * To remove a mask, set this property to null.\n     *\n     * @todo For the moment, PIXI.CanvasRenderer doesn't support PIXI.Sprite as mask.\n     *\n     * @member {PIXI.Graphics|PIXI.Sprite}\n     * @memberof PIXI.DisplayObject#\n     */\n    mask: {\n        get: function ()\n        {\n            return this._mask;\n        },\n        set: function (value)\n        {\n            if (this._mask)\n            {\n                this._mask.renderable = true;\n            }\n\n            this._mask = value;\n\n            if (this._mask)\n            {\n                this._mask.renderable = false;\n            }\n        }\n    },\n\n    /**\n     * Sets the filters for the displayObject.\n     * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer.\n     * To remove filters simply set this property to 'null'\n     *\n     * @member {PIXI.AbstractFilter[]}\n     * @memberof PIXI.DisplayObject#\n     */\n    filters: {\n        get: function ()\n        {\n            return this._filters && this._filters.slice();\n        },\n        set: function (value)\n        {\n            this._filters = value && value.slice();\n        }\n    }\n\n});\n\n/*\n * Updates the object transform for rendering\n *\n * TODO - Optimization pass!\n */\nDisplayObject.prototype.updateTransform = function ()\n{\n    // create some matrix refs for easy access\n    var pt = this.parent.worldTransform;\n    var wt = this.worldTransform;\n\n    // temporary matrix variables\n    var a, b, c, d, tx, ty;\n\n    // looks like we are skewing\n    if(this.skew.x || this.skew.y)\n    {\n        // I'm assuming that skewing is not going to be very common\n        // With that in mind, we can do a full setTransform using the temp matrix\n        _tempMatrix.setTransform(\n            this.position.x,\n            this.position.y,\n            this.pivot.x,\n            this.pivot.y,\n            this.scale.x,\n            this.scale.y,\n            this.rotation,\n            this.skew.x,\n            this.skew.y\n        );\n\n        // now concat the matrix (inlined so that we can avoid using copy)\n        wt.a  = _tempMatrix.a  * pt.a + _tempMatrix.b  * pt.c;\n        wt.b  = _tempMatrix.a  * pt.b + _tempMatrix.b  * pt.d;\n        wt.c  = _tempMatrix.c  * pt.a + _tempMatrix.d  * pt.c;\n        wt.d  = _tempMatrix.c  * pt.b + _tempMatrix.d  * pt.d;\n        wt.tx = _tempMatrix.tx * pt.a + _tempMatrix.ty * pt.c + pt.tx;\n        wt.ty = _tempMatrix.tx * pt.b + _tempMatrix.ty * pt.d + pt.ty;\n    }\n    else\n    {\n        // so if rotation is between 0 then we can simplify the multiplication process...\n        if (this.rotation % CONST.PI_2)\n        {\n            // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes\n            if (this.rotation !== this.rotationCache)\n            {\n                this.rotationCache = this.rotation;\n                this._sr = Math.sin(this.rotation);\n                this._cr = Math.cos(this.rotation);\n            }\n\n            // get the matrix values of the displayobject based on its transform properties..\n            a  =  this._cr * this.scale.x;\n            b  =  this._sr * this.scale.x;\n            c  = -this._sr * this.scale.y;\n            d  =  this._cr * this.scale.y;\n            tx =  this.position.x;\n            ty =  this.position.y;\n\n            // check for pivot.. not often used so geared towards that fact!\n            if (this.pivot.x || this.pivot.y)\n            {\n                tx -= this.pivot.x * a + this.pivot.y * c;\n                ty -= this.pivot.x * b + this.pivot.y * d;\n            }\n\n            // concat the parent matrix with the objects transform.\n            wt.a  = a  * pt.a + b  * pt.c;\n            wt.b  = a  * pt.b + b  * pt.d;\n            wt.c  = c  * pt.a + d  * pt.c;\n            wt.d  = c  * pt.b + d  * pt.d;\n            wt.tx = tx * pt.a + ty * pt.c + pt.tx;\n            wt.ty = tx * pt.b + ty * pt.d + pt.ty;\n        }\n        else\n        {\n            // lets do the fast version as we know there is no rotation..\n            a  = this.scale.x;\n            d  = this.scale.y;\n\n            tx = this.position.x - this.pivot.x * a;\n            ty = this.position.y - this.pivot.y * d;\n\n            wt.a  = a  * pt.a;\n            wt.b  = a  * pt.b;\n            wt.c  = d  * pt.c;\n            wt.d  = d  * pt.d;\n            wt.tx = tx * pt.a + ty * pt.c + pt.tx;\n            wt.ty = tx * pt.b + ty * pt.d + pt.ty;\n        }\n    }\n\n    // multiply the alphas..\n    this.worldAlpha = this.alpha * this.parent.worldAlpha;\n\n    // reset the bounds each time this is called!\n    this._currentBounds = null;\n};\n\n// performance increase to avoid using call.. (10x faster)\nDisplayObject.prototype.displayObjectUpdateTransform = DisplayObject.prototype.updateTransform;\n\n/**\n *\n *\n * Retrieves the bounds of the displayObject as a rectangle object\n *\n * @param matrix {PIXI.Matrix}\n * @return {PIXI.Rectangle} the rectangular bounding area\n */\nDisplayObject.prototype.getBounds = function (matrix) // jshint unused:false\n{\n    return math.Rectangle.EMPTY;\n};\n\n/**\n * Retrieves the local bounds of the displayObject as a rectangle object\n *\n * @return {PIXI.Rectangle} the rectangular bounding area\n */\nDisplayObject.prototype.getLocalBounds = function ()\n{\n    return this.getBounds(math.Matrix.IDENTITY);\n};\n\n/**\n * Calculates the global position of the display object\n *\n * @param position {PIXI.Point} The world origin to calculate from\n * @return {PIXI.Point} A point object representing the position of this object\n */\nDisplayObject.prototype.toGlobal = function (position)\n{\n    // this parent check is for just in case the item is a root object.\n    // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly\n    // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)\n    if(!this.parent)\n    {\n        this.parent = _tempDisplayObjectParent;\n        this.displayObjectUpdateTransform();\n        this.parent = null;\n    }\n    else\n    {\n        this.displayObjectUpdateTransform();\n    }\n\n    // don't need to update the lot\n    return this.worldTransform.apply(position);\n};\n\n/**\n * Calculates the local position of the display object relative to another point\n *\n * @param position {PIXI.Point} The world origin to calculate from\n * @param [from] {PIXI.DisplayObject} The DisplayObject to calculate the global position from\n * @param [point] {PIXI.Point} A Point object in which to store the value, optional (otherwise will create a new Point)\n * @return {PIXI.Point} A point object representing the position of this object\n */\nDisplayObject.prototype.toLocal = function (position, from, point)\n{\n    if (from)\n    {\n        position = from.toGlobal(position);\n    }\n\n    // this parent check is for just in case the item is a root object.\n    // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly\n    // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)\n    if(!this.parent)\n    {\n        this.parent = _tempDisplayObjectParent;\n        this.displayObjectUpdateTransform();\n        this.parent = null;\n    }\n    else\n    {\n        this.displayObjectUpdateTransform();\n    }\n\n    // simply apply the matrix..\n    return this.worldTransform.applyInverse(position, point);\n};\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer\n * @private\n */\nDisplayObject.prototype.renderWebGL = function (renderer) // jshint unused:false\n{\n    // OVERWRITE;\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer} The renderer\n * @private\n */\nDisplayObject.prototype.renderCanvas = function (renderer) // jshint unused:false\n{\n    // OVERWRITE;\n};\n/**\n * Useful function that returns a texture of the display object that can then be used to create sprites\n * This can be quite useful if your displayObject is static / complicated and needs to be reused multiple times.\n *\n * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} The renderer used to generate the texture.\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @param resolution {number} The resolution of the texture being generated\n * @return {PIXI.Texture} a texture of the display object\n */\nDisplayObject.prototype.generateTexture = function (renderer, scaleMode, resolution)\n{\n    var bounds = this.getLocalBounds();\n\n    var renderTexture = new RenderTexture(renderer, bounds.width | 0, bounds.height | 0, scaleMode, resolution);\n\n    _tempMatrix.tx = -bounds.x;\n    _tempMatrix.ty = -bounds.y;\n\n    renderTexture.render(this, _tempMatrix);\n\n    return renderTexture;\n};\n\n/**\n * Set the parent Container of this DisplayObject\n *\n * @param container {Container} The Container to add this DisplayObject to\n * @return {Container} The Container that this DisplayObject was added to\n */\nDisplayObject.prototype.setParent = function (container)\n{\n    if (!container || !container.addChild)\n    {\n        throw new Error('setParent: Argument must be a Container');\n    }\n\n    container.addChild(this);\n    return container;\n};\n\n/**\n * Convenience function to set the postion, scale, skew and pivot at once.\n *\n * @param [x=0] {number} The X position\n * @param [y=0] {number} The Y position\n * @param [scaleX=1] {number} The X scale value\n * @param [scaleY=1] {number} The Y scale value\n * @param [rotation=0] {number} The rotation\n * @param [skewX=0] {number} The X skew value\n * @param [skewY=0] {number} The Y skew value\n * @param [pivotX=0] {number} The X pivot value\n * @param [pivotY=0] {number} The Y pivot value\n * @return {PIXI.DisplayObject}\n */\nDisplayObject.prototype.setTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, pivotX, pivotY) //jshint ignore:line\n{\n    this.position.x = x || 0;\n    this.position.y = y || 0;\n    this.scale.x = !scaleX ? 1 : scaleX;\n    this.scale.y = !scaleY ? 1 : scaleY;\n    this.rotation = rotation || 0;\n    this.skew.x = skewX || 0;\n    this.skew.y = skewY || 0;\n    this.pivot.x = pivotX || 0;\n    this.pivot.y = pivotY || 0;\n    return this;\n};\n\n/**\n * Base destroy method for generic display objects\n *\n */\nDisplayObject.prototype.destroy = function ()\n{\n\n    this.position = null;\n    this.scale = null;\n    this.pivot = null;\n    this.skew = null;\n\n    this.parent = null;\n\n    this._bounds = null;\n    this._currentBounds = null;\n    this._mask = null;\n\n    this.worldTransform = null;\n    this.filterArea = null;\n};\n\n},{\"../const\":22,\"../math\":33,\"../textures/RenderTexture\":71,\"eventemitter3\":10}],25:[function(require,module,exports){\nvar Container = require('../display/Container'),\n    Texture = require('../textures/Texture'),\n    CanvasBuffer = require('../renderers/canvas/utils/CanvasBuffer'),\n    CanvasGraphics = require('../renderers/canvas/utils/CanvasGraphics'),\n    GraphicsData = require('./GraphicsData'),\n    math = require('../math'),\n    CONST = require('../const'),\n    tempPoint = new math.Point();\n\n/**\n * The Graphics class contains methods used to draw primitive shapes such as lines, circles and\n * rectangles to the display, and to color and fill them.\n *\n * @class\n * @extends PIXI.Container\n * @memberof PIXI\n */\nfunction Graphics()\n{\n    Container.call(this);\n\n    /**\n     * The alpha value used when filling the Graphics object.\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.fillAlpha = 1;\n\n    /**\n     * The width (thickness) of any lines drawn.\n     *\n     * @member {number}\n     * @default 0\n     */\n    this.lineWidth = 0;\n\n    /**\n     * The color of any lines drawn.\n     *\n     * @member {string}\n     * @default 0\n     */\n    this.lineColor = 0;\n\n    /**\n     * Graphics data\n     *\n     * @member {PIXI.GraphicsData[]}\n     * @private\n     */\n    this.graphicsData = [];\n\n    /**\n     * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint.\n     *\n     * @member {number}\n     * @default 0xFFFFFF\n     */\n    this.tint = 0xFFFFFF;\n\n    /**\n     * The previous tint applied to the graphic shape. Used to compare to the current tint and check if theres change.\n     *\n     * @member {number}\n     * @private\n     * @default 0xFFFFFF\n     */\n    this._prevTint = 0xFFFFFF;\n\n    /**\n     * The blend mode to be applied to the graphic shape. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.\n     *\n     * @member {number}\n     * @default PIXI.BLEND_MODES.NORMAL;\n     * @see PIXI.BLEND_MODES\n     */\n    this.blendMode = CONST.BLEND_MODES.NORMAL;\n\n    /**\n     * Current path\n     *\n     * @member {PIXI.GraphicsData}\n     * @private\n     */\n    this.currentPath = null;\n\n    /**\n     * Array containing some WebGL-related properties used by the WebGL renderer.\n     *\n     * @member {object<number, object>}\n     * @private\n     */\n    // TODO - _webgl should use a prototype object, not a random undocumented object...\n    this._webGL = {};\n\n    /**\n     * Whether this shape is being used as a mask.\n     *\n     * @member {boolean}\n     */\n    this.isMask = false;\n\n    /**\n     * The bounds' padding used for bounds calculation.\n     *\n     * @member {number}\n     */\n    this.boundsPadding = 0;\n\n    /**\n     * A cache of the local bounds to prevent recalculation.\n     *\n     * @member {PIXI.Rectangle}\n     * @private\n     */\n    this._localBounds = new math.Rectangle(0,0,1,1);\n\n    /**\n     * Used to detect if the graphics object has changed. If this is set to true then the graphics\n     * object will be recalculated.\n     *\n     * @member {boolean}\n     * @private\n     */\n    this.dirty = true;\n\n    /**\n     * Used to detect if the WebGL graphics object has changed. If this is set to true then the\n     * graphics object will be recalculated.\n     *\n     * @member {boolean}\n     * @private\n     */\n    this.glDirty = false;\n\n    this.boundsDirty = true;\n\n    /**\n     * Used to detect if the cached sprite object needs to be updated.\n     *\n     * @member {boolean}\n     * @private\n     */\n    this.cachedSpriteDirty = false;\n\n    /**\n     * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.\n     * This is useful if your graphics element does not change often, as it will speed up the rendering\n     * of the object in exchange for taking up texture memory. It is also useful if you need the graphics\n     * object to be anti-aliased, because it will be rendered using canvas. This is not recommended if\n     * you are constantly redrawing the graphics element.\n     *\n     * @name cacheAsBitmap\n     * @member {boolean}\n     * @memberof PIXI.Graphics#\n     * @default false\n     */\n}\n\n// constructor\nGraphics.prototype = Object.create(Container.prototype);\nGraphics.prototype.constructor = Graphics;\nmodule.exports = Graphics;\n\n/**\n * Creates a new Graphics object with the same values as this one.\n * Note that the only the properties of the object are cloned, not its transform (position,scale,etc)\n *\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.clone = function ()\n{\n    var clone = new Graphics();\n\n    clone.renderable    = this.renderable;\n    clone.fillAlpha     = this.fillAlpha;\n    clone.lineWidth     = this.lineWidth;\n    clone.lineColor     = this.lineColor;\n    clone.tint          = this.tint;\n    clone.blendMode     = this.blendMode;\n    clone.isMask        = this.isMask;\n    clone.boundsPadding = this.boundsPadding;\n    clone.dirty         = true;\n    clone.glDirty       = true;\n    clone.cachedSpriteDirty = this.cachedSpriteDirty;\n\n    // copy graphics data\n    for (var i = 0; i < this.graphicsData.length; ++i)\n    {\n        clone.graphicsData.push(this.graphicsData[i].clone());\n    }\n\n    clone.currentPath = clone.graphicsData[clone.graphicsData.length - 1];\n\n    clone.updateLocalBounds();\n\n    return clone;\n};\n\n/**\n * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.\n *\n * @param lineWidth {number} width of the line to draw, will update the objects stored style\n * @param color {number} color of the line to draw, will update the objects stored style\n * @param alpha {number} alpha of the line to draw, will update the objects stored style\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.lineStyle = function (lineWidth, color, alpha)\n{\n    this.lineWidth = lineWidth || 0;\n    this.lineColor = color || 0;\n    this.lineAlpha = (alpha === undefined) ? 1 : alpha;\n\n    if (this.currentPath)\n    {\n        if (this.currentPath.shape.points.length)\n        {\n            // halfway through a line? start a new one!\n            var shape = new math.Polygon(this.currentPath.shape.points.slice(-2));\n            shape.closed = false;\n            this.drawShape(shape);\n        }\n        else\n        {\n            // otherwise its empty so lets just set the line properties\n            this.currentPath.lineWidth = this.lineWidth;\n            this.currentPath.lineColor = this.lineColor;\n            this.currentPath.lineAlpha = this.lineAlpha;\n        }\n    }\n\n    return this;\n};\n\n/**\n * Moves the current drawing position to x, y.\n *\n * @param x {number} the X coordinate to move to\n * @param y {number} the Y coordinate to move to\n * @return {PIXI.Graphics}\n  */\nGraphics.prototype.moveTo = function (x, y)\n{\n    var shape = new math.Polygon([x,y]);\n    shape.closed = false;\n    this.drawShape(shape);\n\n    return this;\n};\n\n/**\n * Draws a line using the current line style from the current drawing position to (x, y);\n * The current drawing position is then set to (x, y).\n *\n * @param x {number} the X coordinate to draw to\n * @param y {number} the Y coordinate to draw to\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.lineTo = function (x, y)\n{\n    this.currentPath.shape.points.push(x, y);\n    this.dirty = true;\n\n    return this;\n};\n\n/**\n * Calculate the points for a quadratic bezier curve and then draws it.\n * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c\n *\n * @param cpX {number} Control point x\n * @param cpY {number} Control point y\n * @param toX {number} Destination point x\n * @param toY {number} Destination point y\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.quadraticCurveTo = function (cpX, cpY, toX, toY)\n{\n    if (this.currentPath)\n    {\n        if (this.currentPath.shape.points.length === 0)\n        {\n            this.currentPath.shape.points = [0, 0];\n        }\n    }\n    else\n    {\n        this.moveTo(0,0);\n    }\n\n    var xa,\n        ya,\n        n = 20,\n        points = this.currentPath.shape.points;\n\n    if (points.length === 0)\n    {\n        this.moveTo(0, 0);\n    }\n\n    var fromX = points[points.length-2];\n    var fromY = points[points.length-1];\n\n    var j = 0;\n    for (var i = 1; i <= n; ++i)\n    {\n        j = i / n;\n\n        xa = fromX + ( (cpX - fromX) * j );\n        ya = fromY + ( (cpY - fromY) * j );\n\n        points.push( xa + ( ((cpX + ( (toX - cpX) * j )) - xa) * j ),\n                     ya + ( ((cpY + ( (toY - cpY) * j )) - ya) * j ) );\n    }\n\n    this.dirty = this.boundsDirty = true;\n\n    return this;\n};\n\n/**\n * Calculate the points for a bezier curve and then draws it.\n *\n * @param cpX {number} Control point x\n * @param cpY {number} Control point y\n * @param cpX2 {number} Second Control point x\n * @param cpY2 {number} Second Control point y\n * @param toX {number} Destination point x\n * @param toY {number} Destination point y\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.bezierCurveTo = function (cpX, cpY, cpX2, cpY2, toX, toY)\n{\n    if (this.currentPath)\n    {\n        if (this.currentPath.shape.points.length === 0)\n        {\n            this.currentPath.shape.points = [0, 0];\n        }\n    }\n    else\n    {\n        this.moveTo(0,0);\n    }\n\n    var n = 20,\n        dt,\n        dt2,\n        dt3,\n        t2,\n        t3,\n        points = this.currentPath.shape.points;\n\n    var fromX = points[points.length-2];\n    var fromY = points[points.length-1];\n\n    var j = 0;\n\n    for (var i = 1; i <= n; ++i)\n    {\n        j = i / n;\n\n        dt = (1 - j);\n        dt2 = dt * dt;\n        dt3 = dt2 * dt;\n\n        t2 = j * j;\n        t3 = t2 * j;\n\n        points.push( dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX,\n                     dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY);\n    }\n\n    this.dirty = this.boundsDirty = true;\n\n    return this;\n};\n\n/**\n * The arcTo() method creates an arc/curve between two tangents on the canvas.\n *\n * \"borrowed\" from https://code.google.com/p/fxcanvas/ - thanks google!\n *\n * @param x1 {number} The x-coordinate of the beginning of the arc\n * @param y1 {number} The y-coordinate of the beginning of the arc\n * @param x2 {number} The x-coordinate of the end of the arc\n * @param y2 {number} The y-coordinate of the end of the arc\n * @param radius {number} The radius of the arc\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.arcTo = function (x1, y1, x2, y2, radius)\n{\n    if (this.currentPath)\n    {\n        if (this.currentPath.shape.points.length === 0)\n        {\n            this.currentPath.shape.points.push(x1, y1);\n        }\n    }\n    else\n    {\n        this.moveTo(x1, y1);\n    }\n\n    var points = this.currentPath.shape.points,\n        fromX = points[points.length-2],\n        fromY = points[points.length-1],\n        a1 = fromY - y1,\n        b1 = fromX - x1,\n        a2 = y2   - y1,\n        b2 = x2   - x1,\n        mm = Math.abs(a1 * b2 - b1 * a2);\n\n    if (mm < 1.0e-8 || radius === 0)\n    {\n        if (points[points.length-2] !== x1 || points[points.length-1] !== y1)\n        {\n            points.push(x1, y1);\n        }\n    }\n    else\n    {\n        var dd = a1 * a1 + b1 * b1,\n            cc = a2 * a2 + b2 * b2,\n            tt = a1 * a2 + b1 * b2,\n            k1 = radius * Math.sqrt(dd) / mm,\n            k2 = radius * Math.sqrt(cc) / mm,\n            j1 = k1 * tt / dd,\n            j2 = k2 * tt / cc,\n            cx = k1 * b2 + k2 * b1,\n            cy = k1 * a2 + k2 * a1,\n            px = b1 * (k2 + j1),\n            py = a1 * (k2 + j1),\n            qx = b2 * (k1 + j2),\n            qy = a2 * (k1 + j2),\n            startAngle = Math.atan2(py - cy, px - cx),\n            endAngle   = Math.atan2(qy - cy, qx - cx);\n\n        this.arc(cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1);\n    }\n\n    this.dirty = this.boundsDirty = true;\n\n    return this;\n};\n\n/**\n * The arc method creates an arc/curve (used to create circles, or parts of circles).\n *\n * @param cx {number} The x-coordinate of the center of the circle\n * @param cy {number} The y-coordinate of the center of the circle\n * @param radius {number} The radius of the circle\n * @param startAngle {number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)\n * @param endAngle {number} The ending angle, in radians\n * @param anticlockwise {boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise)\n{\n    anticlockwise = anticlockwise || false;\n\n    if (startAngle === endAngle)\n    {\n        return this;\n    }\n\n    if( !anticlockwise && endAngle <= startAngle )\n    {\n        endAngle += Math.PI * 2;\n    }\n    else if( anticlockwise && startAngle <= endAngle )\n    {\n        startAngle += Math.PI * 2;\n    }\n\n    var sweep = anticlockwise ? (startAngle - endAngle) * -1 : (endAngle - startAngle);\n    var segs =  Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * 40;\n\n    if(sweep === 0)\n    {\n        return this;\n    }\n\n    var startX = cx + Math.cos(startAngle) * radius;\n    var startY = cy + Math.sin(startAngle) * radius;\n\n    if (this.currentPath)\n    {\n        this.currentPath.shape.points.push(startX, startY);\n    }\n    else\n    {\n        this.moveTo(startX, startY);\n    }\n\n    var points = this.currentPath.shape.points;\n\n    var theta = sweep/(segs*2);\n    var theta2 = theta*2;\n\n    var cTheta = Math.cos(theta);\n    var sTheta = Math.sin(theta);\n\n    var segMinus = segs - 1;\n\n    var remainder = ( segMinus % 1 ) / segMinus;\n\n    for(var i=0; i<=segMinus; i++)\n    {\n        var real =  i + remainder * i;\n\n\n        var angle = ((theta) + startAngle + (theta2 * real));\n\n        var c = Math.cos(angle);\n        var s = -Math.sin(angle);\n\n        points.push(( (cTheta *  c) + (sTheta * s) ) * radius + cx,\n                    ( (cTheta * -s) + (sTheta * c) ) * radius + cy);\n    }\n\n    this.dirty = this.boundsDirty = true;\n\n    return this;\n};\n\n/**\n * Specifies a simple one-color fill that subsequent calls to other Graphics methods\n * (such as lineTo() or drawCircle()) use when drawing.\n *\n * @param color {number} the color of the fill\n * @param alpha {number} the alpha of the fill\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.beginFill = function (color, alpha)\n{\n    this.filling = true;\n    this.fillColor = color || 0;\n    this.fillAlpha = (alpha === undefined) ? 1 : alpha;\n\n    if (this.currentPath)\n    {\n        if (this.currentPath.shape.points.length <= 2)\n        {\n            this.currentPath.fill = this.filling;\n            this.currentPath.fillColor = this.fillColor;\n            this.currentPath.fillAlpha = this.fillAlpha;\n        }\n    }\n    return this;\n};\n\n/**\n * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.\n *\n * @return {Graphics}\n */\nGraphics.prototype.endFill = function ()\n{\n    this.filling = false;\n    this.fillColor = null;\n    this.fillAlpha = 1;\n\n    return this;\n};\n\n/**\n *\n * @param x {number} The X coord of the top-left of the rectangle\n * @param y {number} The Y coord of the top-left of the rectangle\n * @param width {number} The width of the rectangle\n * @param height {number} The height of the rectangle\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.drawRect = function ( x, y, width, height )\n{\n    this.drawShape(new math.Rectangle(x,y, width, height));\n\n    return this;\n};\n\n/**\n *\n * @param x {number} The X coord of the top-left of the rectangle\n * @param y {number} The Y coord of the top-left of the rectangle\n * @param width {number} The width of the rectangle\n * @param height {number} The height of the rectangle\n * @param radius {number} Radius of the rectangle corners\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.drawRoundedRect = function ( x, y, width, height, radius )\n{\n    this.drawShape(new math.RoundedRectangle(x, y, width, height, radius));\n\n    return this;\n};\n\n/**\n * Draws a circle.\n *\n * @param x {number} The X coordinate of the center of the circle\n * @param y {number} The Y coordinate of the center of the circle\n * @param radius {number} The radius of the circle\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.drawCircle = function (x, y, radius)\n{\n    this.drawShape(new math.Circle(x,y, radius));\n\n    return this;\n};\n\n/**\n * Draws an ellipse.\n *\n * @param x {number} The X coordinate of the center of the ellipse\n * @param y {number} The Y coordinate of the center of the ellipse\n * @param width {number} The half width of the ellipse\n * @param height {number} The half height of the ellipse\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.drawEllipse = function (x, y, width, height)\n{\n    this.drawShape(new math.Ellipse(x, y, width, height));\n\n    return this;\n};\n\n/**\n * Draws a polygon using the given path.\n *\n * @param path {number[]|PIXI.Point[]} The path data used to construct the polygon.\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.drawPolygon = function (path)\n{\n    // prevents an argument assignment deopt\n    // see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments\n    var points = path;\n\n    var closed = true;\n\n    if (points instanceof math.Polygon)\n    {\n        closed = points.closed;\n        points = points.points;\n    }\n\n    if (!Array.isArray(points))\n    {\n        // prevents an argument leak deopt\n        // see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments\n        points = new Array(arguments.length);\n\n        for (var i = 0; i < points.length; ++i)\n        {\n            points[i] = arguments[i];\n        }\n    }\n\n    var shape = new math.Polygon(points);\n    shape.closed = closed;\n\n    this.drawShape(shape);\n\n    return this;\n};\n\n/**\n * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.\n *\n * @return {PIXI.Graphics}\n */\nGraphics.prototype.clear = function ()\n{\n    this.lineWidth = 0;\n    this.filling = false;\n\n    this.dirty = true;\n    this.clearDirty = true;\n    this.graphicsData = [];\n\n    return this;\n};\n\n/**\n * Useful function that returns a texture of the graphics object that can then be used to create sprites\n * This can be quite useful if your geometry is complicated and needs to be reused multiple times.\n *\n * @param resolution {number} The resolution of the texture being generated\n * @param scaleMode {number} Should be one of the scaleMode consts\n * @return {PIXI.Texture} a texture of the graphics object\n */\nGraphics.prototype.generateTexture = function (renderer, resolution, scaleMode)\n{\n\n    resolution = resolution || 1;\n\n    var bounds = this.getLocalBounds();\n\n    var canvasBuffer = new CanvasBuffer(bounds.width * resolution, bounds.height * resolution);\n\n    var texture = Texture.fromCanvas(canvasBuffer.canvas, scaleMode);\n    texture.baseTexture.resolution = resolution;\n\n    canvasBuffer.context.scale(resolution, resolution);\n\n    canvasBuffer.context.translate(-bounds.x,-bounds.y);\n\n    CanvasGraphics.renderGraphics(this, canvasBuffer.context);\n\n    return texture;\n};\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer}\n * @private\n */\nGraphics.prototype._renderWebGL = function (renderer)\n{\n    // if the sprite is not visible or the alpha is 0 then no need to render this element\n\n    // this code may still be needed so leaving for now..\n    //\n    /*\n    if (this._cacheAsBitmap)\n    {\n        if (this.dirty || this.cachedSpriteDirty)\n        {\n            this._generateCachedSprite();\n\n            // we will also need to update the texture on the gpu too!\n            this.updateCachedSpriteTexture();\n\n            this.cachedSpriteDirty = false;\n            this.dirty = false;\n        }\n\n        this._cachedSprite.worldAlpha = this.worldAlpha;\n\n        Sprite.prototype.renderWebGL.call(this._cachedSprite, renderer);\n\n        return;\n    }\n\n    */\n\n    if (this.glDirty)\n    {\n        this.dirty = true;\n        this.glDirty = false;\n    }\n\n    renderer.setObjectRenderer(renderer.plugins.graphics);\n    renderer.plugins.graphics.render(this);\n\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer}\n * @private\n */\nGraphics.prototype._renderCanvas = function (renderer)\n{\n    if (this.isMask === true)\n    {\n        return;\n    }\n\n    // if the tint has changed, set the graphics object to dirty.\n    if (this._prevTint !== this.tint) {\n        this.dirty = true;\n    }\n\n    // this code may still be needed so leaving for now..\n    //\n    /*\n    if (this._cacheAsBitmap)\n    {\n        if (this.dirty || this.cachedSpriteDirty)\n        {\n            this._generateCachedSprite();\n\n            // we will also need to update the texture\n            this.updateCachedSpriteTexture();\n\n            this.cachedSpriteDirty = false;\n            this.dirty = false;\n        }\n\n        this._cachedSprite.alpha = this.alpha;\n\n        Sprite.prototype._renderCanvas.call(this._cachedSprite, renderer);\n\n        return;\n    }\n    */\n    var context = renderer.context;\n    var transform = this.worldTransform;\n\n    var compositeOperation = renderer.blendModes[this.blendMode];\n    if (compositeOperation !== context.globalCompositeOperation)\n    {\n        context.globalCompositeOperation = compositeOperation;\n    }\n\n    var resolution = renderer.resolution;\n    context.setTransform(\n        transform.a * resolution,\n        transform.b * resolution,\n        transform.c * resolution,\n        transform.d * resolution,\n        transform.tx * resolution,\n        transform.ty * resolution\n    );\n\n    CanvasGraphics.renderGraphics(this, context);\n};\n\n/**\n * Retrieves the bounds of the graphic shape as a rectangle object\n *\n * @param [matrix] {PIXI.Matrix} The world transform matrix to use, defaults to this\n *  object's worldTransform.\n * @return {PIXI.Rectangle} the rectangular bounding area\n */\nGraphics.prototype.getBounds = function (matrix)\n{\n    if(!this._currentBounds)\n    {\n\n        // return an empty object if the item is a mask!\n        if (!this.renderable)\n        {\n            return math.Rectangle.EMPTY;\n        }\n\n        if (this.boundsDirty)\n        {\n            this.updateLocalBounds();\n\n            this.glDirty = true;\n            this.cachedSpriteDirty = true;\n            this.boundsDirty = false;\n        }\n\n        var bounds = this._localBounds;\n\n        var w0 = bounds.x;\n        var w1 = bounds.width + bounds.x;\n\n        var h0 = bounds.y;\n        var h1 = bounds.height + bounds.y;\n\n        var worldTransform = matrix || this.worldTransform;\n\n        var a = worldTransform.a;\n        var b = worldTransform.b;\n        var c = worldTransform.c;\n        var d = worldTransform.d;\n        var tx = worldTransform.tx;\n        var ty = worldTransform.ty;\n\n        var x1 = a * w1 + c * h1 + tx;\n        var y1 = d * h1 + b * w1 + ty;\n\n        var x2 = a * w0 + c * h1 + tx;\n        var y2 = d * h1 + b * w0 + ty;\n\n        var x3 = a * w0 + c * h0 + tx;\n        var y3 = d * h0 + b * w0 + ty;\n\n        var x4 =  a * w1 + c * h0 + tx;\n        var y4 =  d * h0 + b * w1 + ty;\n\n        var maxX = x1;\n        var maxY = y1;\n\n        var minX = x1;\n        var minY = y1;\n\n        minX = x2 < minX ? x2 : minX;\n        minX = x3 < minX ? x3 : minX;\n        minX = x4 < minX ? x4 : minX;\n\n        minY = y2 < minY ? y2 : minY;\n        minY = y3 < minY ? y3 : minY;\n        minY = y4 < minY ? y4 : minY;\n\n        maxX = x2 > maxX ? x2 : maxX;\n        maxX = x3 > maxX ? x3 : maxX;\n        maxX = x4 > maxX ? x4 : maxX;\n\n        maxY = y2 > maxY ? y2 : maxY;\n        maxY = y3 > maxY ? y3 : maxY;\n        maxY = y4 > maxY ? y4 : maxY;\n\n        this._bounds.x = minX;\n        this._bounds.width = maxX - minX;\n\n        this._bounds.y = minY;\n        this._bounds.height = maxY - minY;\n\n        this._currentBounds = this._bounds;\n    }\n\n    return this._currentBounds;\n};\n\n/**\n* Tests if a point is inside this graphics object\n*\n* @param point {PIXI.Point} the point to test\n* @return {boolean} the result of the test\n*/\nGraphics.prototype.containsPoint = function( point )\n{\n    this.worldTransform.applyInverse(point,  tempPoint);\n\n    var graphicsData = this.graphicsData;\n\n    for (var i = 0; i < graphicsData.length; i++)\n    {\n        var data = graphicsData[i];\n\n        if (!data.fill)\n        {\n            continue;\n        }\n\n        // only deal with fills..\n        if (data.shape)\n        {\n            if ( data.shape.contains( tempPoint.x, tempPoint.y ) )\n            {\n                return true;\n            }\n        }\n    }\n\n    return false;\n};\n\n/**\n * Update the bounds of the object\n *\n */\nGraphics.prototype.updateLocalBounds = function ()\n{\n    var minX = Infinity;\n    var maxX = -Infinity;\n\n    var minY = Infinity;\n    var maxY = -Infinity;\n\n    if (this.graphicsData.length)\n    {\n        var shape, points, x, y, w, h;\n\n        for (var i = 0; i < this.graphicsData.length; i++)\n        {\n            var data = this.graphicsData[i];\n            var type = data.type;\n            var lineWidth = data.lineWidth;\n            shape = data.shape;\n\n            if (type === CONST.SHAPES.RECT || type === CONST.SHAPES.RREC)\n            {\n                x = shape.x - lineWidth/2;\n                y = shape.y - lineWidth/2;\n                w = shape.width + lineWidth;\n                h = shape.height + lineWidth;\n\n                minX = x < minX ? x : minX;\n                maxX = x + w > maxX ? x + w : maxX;\n\n                minY = y < minY ? y : minY;\n                maxY = y + h > maxY ? y + h : maxY;\n            }\n            else if (type === CONST.SHAPES.CIRC)\n            {\n                x = shape.x;\n                y = shape.y;\n                w = shape.radius + lineWidth/2;\n                h = shape.radius + lineWidth/2;\n\n                minX = x - w < minX ? x - w : minX;\n                maxX = x + w > maxX ? x + w : maxX;\n\n                minY = y - h < minY ? y - h : minY;\n                maxY = y + h > maxY ? y + h : maxY;\n            }\n            else if (type === CONST.SHAPES.ELIP)\n            {\n                x = shape.x;\n                y = shape.y;\n                w = shape.width + lineWidth/2;\n                h = shape.height + lineWidth/2;\n\n                minX = x - w < minX ? x - w : minX;\n                maxX = x + w > maxX ? x + w : maxX;\n\n                minY = y - h < minY ? y - h : minY;\n                maxY = y + h > maxY ? y + h : maxY;\n            }\n            else\n            {\n                // POLY\n                points = shape.points;\n\n                for (var j = 0; j < points.length; j += 2)\n                {\n                    x = points[j];\n                    y = points[j+1];\n\n                    minX = x-lineWidth < minX ? x-lineWidth : minX;\n                    maxX = x+lineWidth > maxX ? x+lineWidth : maxX;\n\n                    minY = y-lineWidth < minY ? y-lineWidth : minY;\n                    maxY = y+lineWidth > maxY ? y+lineWidth : maxY;\n                }\n            }\n        }\n    }\n    else\n    {\n        minX = 0;\n        maxX = 0;\n        minY = 0;\n        maxY = 0;\n    }\n\n    var padding = this.boundsPadding;\n\n    this._localBounds.x = minX - padding;\n    this._localBounds.width = (maxX - minX) + padding * 2;\n\n    this._localBounds.y = minY - padding;\n    this._localBounds.height = (maxY - minY) + padding * 2;\n};\n\n/**\n * Generates the cached sprite when the sprite has cacheAsBitmap = true\n *\n * @private\n */\n/*\nGraphics.prototype._generateCachedSprite = function ()\n{\n    var bounds = this.getLocalBounds();\n\n    if (!this._cachedSprite)\n    {\n        var canvasBuffer = new CanvasBuffer(bounds.width, bounds.height);\n        var texture = Texture.fromCanvas(canvasBuffer.canvas);\n\n        this._cachedSprite = new Sprite(texture);\n        this._cachedSprite.buffer = canvasBuffer;\n\n        this._cachedSprite.worldTransform = this.worldTransform;\n    }\n    else\n    {\n        this._cachedSprite.buffer.resize(bounds.width, bounds.height);\n    }\n\n    // leverage the anchor to account for the offset of the element\n    this._cachedSprite.anchor.x = -( bounds.x / bounds.width );\n    this._cachedSprite.anchor.y = -( bounds.y / bounds.height );\n\n    // this._cachedSprite.buffer.context.save();\n    this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y);\n\n    // make sure we set the alpha of the graphics to 1 for the render..\n    this.worldAlpha = 1;\n\n    // now render the graphic..\n    CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context);\n\n    this._cachedSprite.alpha = this.alpha;\n};\n*/\n/**\n * Updates texture size based on canvas size\n *\n * @private\n */\n/*\nGraphics.prototype.updateCachedSpriteTexture = function ()\n{\n    var cachedSprite = this._cachedSprite;\n    var texture = cachedSprite.texture;\n    var canvas = cachedSprite.buffer.canvas;\n\n    texture.baseTexture.width = canvas.width;\n    texture.baseTexture.height = canvas.height;\n    texture.crop.width = texture.frame.width = canvas.width;\n    texture.crop.height = texture.frame.height = canvas.height;\n\n    cachedSprite._width = canvas.width;\n    cachedSprite._height = canvas.height;\n\n    // update the dirty base textures\n    texture.baseTexture.dirty();\n};*/\n\n/**\n * Destroys a previous cached sprite.\n *\n */\n/*\nGraphics.prototype.destroyCachedSprite = function ()\n{\n    this._cachedSprite.texture.destroy(true);\n\n    // let the gc collect the unused sprite\n    // TODO could be object pooled!\n    this._cachedSprite = null;\n};*/\n\n/**\n * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.\n *\n * @param shape {PIXI.Circle|PIXI.Rectangle|PIXI.Ellipse|PIXI.Line|PIXI.Polygon} The shape object to draw.\n * @return {PIXI.GraphicsData} The generated GraphicsData object.\n */\nGraphics.prototype.drawShape = function (shape)\n{\n    if (this.currentPath)\n    {\n        // check current path!\n        if (this.currentPath.shape.points.length <= 2)\n        {\n            this.graphicsData.pop();\n        }\n    }\n\n    this.currentPath = null;\n\n    var data = new GraphicsData(this.lineWidth, this.lineColor, this.lineAlpha, this.fillColor, this.fillAlpha, this.filling, shape);\n\n    this.graphicsData.push(data);\n\n    if (data.type === CONST.SHAPES.POLY)\n    {\n        data.shape.closed = data.shape.closed || this.filling;\n        this.currentPath = data;\n    }\n\n    this.dirty = this.boundsDirty = true;\n\n    return data;\n};\n\n/**\n * Destroys the Graphics object.\n */\nGraphics.prototype.destroy = function () {\n    Container.prototype.destroy.apply(this, arguments);\n\n    // destroy each of the GraphicsData objects\n    for (var i = 0; i < this.graphicsData.length; ++i) {\n        this.graphicsData[i].destroy();\n    }\n\n    // for each webgl data entry, destroy the WebGLGraphicsData\n    for (var id in this._webgl) {\n        for (var j = 0; j < this._webgl[id].data.length; ++j) {\n            this._webgl[id].data[j].destroy();\n        }\n    }\n\n    this.graphicsData = null;\n\n    this.currentPath = null;\n    this._webgl = null;\n    this._localBounds = null;\n};\n\n},{\"../const\":22,\"../display/Container\":23,\"../math\":33,\"../renderers/canvas/utils/CanvasBuffer\":45,\"../renderers/canvas/utils/CanvasGraphics\":46,\"../textures/Texture\":72,\"./GraphicsData\":26}],26:[function(require,module,exports){\n/**\n * A GraphicsData object.\n *\n * @class\n * @memberof PIXI\n * @param lineWidth {number} the width of the line to draw\n * @param lineColor {number} the color of the line to draw\n * @param lineAlpha {number} the alpha of the line to draw\n * @param fillColor {number} the color of the fill\n * @param fillAlpha {number} the alpha of the fill\n * @param fill      {boolean} whether or not the shape is filled with a colour\n * @param shape     {Circle|Rectangle|Ellipse|Line|Polygon} The shape object to draw.\n */\nfunction GraphicsData(lineWidth, lineColor, lineAlpha, fillColor, fillAlpha, fill, shape)\n{\n    /*\n     * @member {number} the width of the line to draw\n     */\n    this.lineWidth = lineWidth;\n\n    /*\n     * @member {number} the color of the line to draw\n     */\n    this.lineColor = lineColor;\n    /*\n     * @member {number} the alpha of the line to draw\n     */\n    this.lineAlpha = lineAlpha;\n    /*\n     * @member {number} cached tint of the line to draw\n     */\n    this._lineTint = lineColor;\n\n    /*\n     * @member {number} the color of the fill\n     */\n    this.fillColor = fillColor;\n\n    /*\n     * @member {number} the alpha of the fill\n     */\n    this.fillAlpha = fillAlpha;\n\n    /*\n     * @member {number} cached tint of the fill\n     */\n    this._fillTint = fillColor;\n\n    /*\n     * @member {boolean} whether or not the shape is filled with a colour\n     */\n    this.fill = fill;\n\n    /*\n     * @member {PIXI.Circle|PIXI.Rectangle|PIXI.Ellipse|PIXI.Line|PIXI.Polygon} The shape object to draw.\n     */\n    this.shape = shape;\n\n    /*\n     * @member {number} The type of the shape, see the Const.Shapes file for all the existing types,\n     */\n    this.type = shape.type;\n}\n\nGraphicsData.prototype.constructor = GraphicsData;\nmodule.exports = GraphicsData;\n\n/**\n * Creates a new GraphicsData object with the same values as this one.\n *\n * @return {PIXI.GraphicsData}\n */\nGraphicsData.prototype.clone = function ()\n{\n    return new GraphicsData(\n        this.lineWidth,\n        this.lineColor,\n        this.lineAlpha,\n        this.fillColor,\n        this.fillAlpha,\n        this.fill,\n        this.shape\n    );\n};\n\n/**\n * Destroys the Graphics data.\n */\nGraphicsData.prototype.destroy = function () {\n    this.shape = null;\n};\n\n},{}],27:[function(require,module,exports){\nvar utils = require('../../utils'),\n    math = require('../../math'),\n    CONST = require('../../const'),\n    ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'),\n    WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'),\n    WebGLGraphicsData = require('./WebGLGraphicsData'),\n    earcut = require('earcut');\n\n/**\n * Renders the graphics object.\n *\n * @class\n * @private\n * @memberof PIXI\n * @extends PIXI.ObjectRenderer\n * @param renderer {PIXI.WebGLRenderer} The renderer this object renderer works for.\n */\nfunction GraphicsRenderer(renderer)\n{\n    ObjectRenderer.call(this, renderer);\n\n    this.graphicsDataPool = [];\n\n    this.primitiveShader = null;\n    this.complexPrimitiveShader = null;\n\n    /**\n     * This is the maximum number of points a poly can contain before it is rendered as a complex polygon (using the stencil buffer)\n     * @type {Number}\n     */\n    this.maximumSimplePolySize = 200;\n}\n\nGraphicsRenderer.prototype = Object.create(ObjectRenderer.prototype);\nGraphicsRenderer.prototype.constructor = GraphicsRenderer;\nmodule.exports = GraphicsRenderer;\n\nWebGLRenderer.registerPlugin('graphics', GraphicsRenderer);\n\n/**\n * Called when there is a WebGL context change\n *\n * @private\n *\n */\nGraphicsRenderer.prototype.onContextChange = function()\n{\n\n};\n\n/**\n * Destroys this renderer.\n *\n */\nGraphicsRenderer.prototype.destroy = function () {\n    ObjectRenderer.prototype.destroy.call(this);\n\n    for (var i = 0; i < this.graphicsDataPool.length; ++i) {\n        this.graphicsDataPool[i].destroy();\n    }\n\n    this.graphicsDataPool = null;\n};\n\n/**\n * Renders a graphics object.\n *\n * @param graphics {PIXI.Graphics} The graphics object to render.\n */\nGraphicsRenderer.prototype.render = function(graphics)\n{\n    var renderer = this.renderer;\n    var gl = renderer.gl;\n\n    var shader = renderer.shaderManager.plugins.primitiveShader,\n        webGLData;\n\n    if (graphics.dirty || !graphics._webGL[gl.id])\n    {\n        this.updateGraphics(graphics);\n    }\n\n    var webGL = graphics._webGL[gl.id];\n\n    // This  could be speeded up for sure!\n\n    renderer.blendModeManager.setBlendMode( graphics.blendMode );\n\n//    var matrix =  graphics.worldTransform.clone();\n//    var matrix =  renderer.currentRenderTarget.projectionMatrix.clone();\n//    matrix.append(graphics.worldTransform);\n\n    for (var i = 0, n = webGL.data.length; i < n; i++)\n    {\n        webGLData = webGL.data[i];\n\n        if (webGL.data[i].mode === 1)\n        {\n\n            renderer.stencilManager.pushStencil(graphics, webGLData);\n\n            gl.uniform1f(renderer.shaderManager.complexPrimitiveShader.uniforms.alpha._location, graphics.worldAlpha * webGLData.alpha);\n\n            // render quad..\n            gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 );\n\n            renderer.stencilManager.popStencil(graphics, webGLData);\n        }\n        else\n        {\n\n            shader = renderer.shaderManager.primitiveShader;\n\n            renderer.shaderManager.setShader( shader );//activatePrimitiveShader();\n\n            gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true));\n\n            gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, renderer.currentRenderTarget.projectionMatrix.toArray(true));\n\n            gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint));\n\n            gl.uniform1f(shader.uniforms.alpha._location, graphics.worldAlpha);\n\n\n            gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer);\n\n            gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);\n            gl.vertexAttribPointer(shader.attributes.aColor, 4, gl.FLOAT, false,4 * 6, 2 * 4);\n\n            // set the index buffer!\n            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer);\n            gl.drawElements(gl.TRIANGLE_STRIP,  webGLData.indices.length, gl.UNSIGNED_SHORT, 0 );\n        }\n\n        renderer.drawCount++;\n    }\n};\n\n/**\n * Updates the graphics object\n *\n * @private\n * @param graphics {PIXI.Graphics} The graphics object to update\n */\nGraphicsRenderer.prototype.updateGraphics = function(graphics)\n{\n    var gl = this.renderer.gl;\n\n     // get the contexts graphics object\n    var webGL = graphics._webGL[gl.id];\n\n    // if the graphics object does not exist in the webGL context time to create it!\n    if (!webGL)\n    {\n        webGL = graphics._webGL[gl.id] = {lastIndex:0, data:[], gl:gl};\n    }\n\n    // flag the graphics as not dirty as we are about to update it...\n    graphics.dirty = false;\n\n    var i;\n\n    // if the user cleared the graphics object we will need to clear every object\n    if (graphics.clearDirty)\n    {\n        graphics.clearDirty = false;\n\n        // loop through and return all the webGLDatas to the object pool so than can be reused later on\n        for (i = 0; i < webGL.data.length; i++)\n        {\n            var graphicsData = webGL.data[i];\n            graphicsData.reset();\n            this.graphicsDataPool.push( graphicsData );\n        }\n\n        // clear the array and reset the index..\n        webGL.data = [];\n        webGL.lastIndex = 0;\n    }\n\n    var webGLData;\n\n    // loop through the graphics datas and construct each one..\n    // if the object is a complex fill then the new stencil buffer technique will be used\n    // other wise graphics objects will be pushed into a batch..\n    for (i = webGL.lastIndex; i < graphics.graphicsData.length; i++)\n    {\n        var data = graphics.graphicsData[i];\n\n        if (data.type === CONST.SHAPES.POLY)\n        {\n            // need to add the points the the graphics object..\n            data.points = data.shape.points.slice();\n            if (data.shape.closed)\n            {\n                // close the poly if the value is true!\n                if (data.points[0] !== data.points[data.points.length-2] || data.points[1] !== data.points[data.points.length-1])\n                {\n                    data.points.push(data.points[0], data.points[1]);\n                }\n            }\n\n            // MAKE SURE WE HAVE THE CORRECT TYPE..\n            if (data.fill)\n            {\n                if (data.points.length >= 6)\n                {\n                    if (data.points.length < this.maximumSimplePolySize * 2)\n                    {\n                        webGLData = this.switchMode(webGL, 0);\n\n                        var canDrawUsingSimple = this.buildPoly(data, webGLData);\n\n                        if (!canDrawUsingSimple)\n                        {\n                            webGLData = this.switchMode(webGL, 1);\n                            this.buildComplexPoly(data, webGLData);\n                        }\n\n                    }\n                    else\n                    {\n                        webGLData = this.switchMode(webGL, 1);\n                        this.buildComplexPoly(data, webGLData);\n                    }\n                }\n            }\n\n            if (data.lineWidth > 0)\n            {\n                webGLData = this.switchMode(webGL, 0);\n                this.buildLine(data, webGLData);\n            }\n        }\n        else\n        {\n            webGLData = this.switchMode(webGL, 0);\n\n            if (data.type === CONST.SHAPES.RECT)\n            {\n                this.buildRectangle(data, webGLData);\n            }\n            else if (data.type === CONST.SHAPES.CIRC || data.type === CONST.SHAPES.ELIP)\n            {\n                this.buildCircle(data, webGLData);\n            }\n            else if (data.type === CONST.SHAPES.RREC)\n            {\n                this.buildRoundedRectangle(data, webGLData);\n            }\n        }\n\n        webGL.lastIndex++;\n    }\n\n    // upload all the dirty data...\n    for (i = 0; i < webGL.data.length; i++)\n    {\n        webGLData = webGL.data[i];\n\n        if (webGLData.dirty)\n        {\n            webGLData.upload();\n        }\n    }\n};\n\n/**\n *\n *\n * @private\n * @param webGL {WebGLRenderingContext} the current WebGL drawing context\n * @param type {number} TODO @Alvin\n */\nGraphicsRenderer.prototype.switchMode = function (webGL, type)\n{\n    var webGLData;\n\n    if (!webGL.data.length)\n    {\n        webGLData = this.graphicsDataPool.pop() || new WebGLGraphicsData(webGL.gl);\n        webGLData.mode = type;\n        webGL.data.push(webGLData);\n    }\n    else\n    {\n        webGLData = webGL.data[webGL.data.length-1];\n\n        if ((webGLData.points.length > 320000) || webGLData.mode !== type || type === 1)\n        {\n            webGLData = this.graphicsDataPool.pop() || new WebGLGraphicsData(webGL.gl);\n            webGLData.mode = type;\n            webGL.data.push(webGLData);\n        }\n    }\n\n    webGLData.dirty = true;\n\n    return webGLData;\n};\n\n/**\n * Builds a rectangle to draw\n *\n * @private\n * @param graphicsData {PIXI.Graphics} The graphics object containing all the necessary properties\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildRectangle = function (graphicsData, webGLData)\n{\n    // --- //\n    // need to convert points to a nice regular data\n    //\n    var rectData = graphicsData.shape;\n    var x = rectData.x;\n    var y = rectData.y;\n    var width = rectData.width;\n    var height = rectData.height;\n\n    if (graphicsData.fill)\n    {\n        var color = utils.hex2rgb(graphicsData.fillColor);\n        var alpha = graphicsData.fillAlpha;\n\n        var r = color[0] * alpha;\n        var g = color[1] * alpha;\n        var b = color[2] * alpha;\n\n        var verts = webGLData.points;\n        var indices = webGLData.indices;\n\n        var vertPos = verts.length/6;\n\n        // start\n        verts.push(x, y);\n        verts.push(r, g, b, alpha);\n\n        verts.push(x + width, y);\n        verts.push(r, g, b, alpha);\n\n        verts.push(x , y + height);\n        verts.push(r, g, b, alpha);\n\n        verts.push(x + width, y + height);\n        verts.push(r, g, b, alpha);\n\n        // insert 2 dead triangles..\n        indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3);\n    }\n\n    if (graphicsData.lineWidth)\n    {\n        var tempPoints = graphicsData.points;\n\n        graphicsData.points = [x, y,\n                  x + width, y,\n                  x + width, y + height,\n                  x, y + height,\n                  x, y];\n\n\n        this.buildLine(graphicsData, webGLData);\n\n        graphicsData.points = tempPoints;\n    }\n};\n\n/**\n * Builds a rounded rectangle to draw\n *\n * @private\n * @param graphicsData {PIXI.Graphics} The graphics object containing all the necessary properties\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildRoundedRectangle = function (graphicsData, webGLData)\n{\n    var rrectData = graphicsData.shape;\n    var x = rrectData.x;\n    var y = rrectData.y;\n    var width = rrectData.width;\n    var height = rrectData.height;\n\n    var radius = rrectData.radius;\n\n    var recPoints = [];\n    recPoints.push(x, y + radius);\n    this.quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height, recPoints);\n    this.quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius, recPoints);\n    this.quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y, recPoints);\n    this.quadraticBezierCurve(x + radius, y, x, y, x, y + radius + 0.0000000001, recPoints);\n\n    // this tiny number deals with the issue that occurs when points overlap and earcut fails to triangulate the item.\n    // TODO - fix this properly, this is not very elegant.. but it works for now.\n\n    if (graphicsData.fill)\n    {\n        var color = utils.hex2rgb(graphicsData.fillColor);\n        var alpha = graphicsData.fillAlpha;\n\n        var r = color[0] * alpha;\n        var g = color[1] * alpha;\n        var b = color[2] * alpha;\n\n        var verts = webGLData.points;\n        var indices = webGLData.indices;\n\n        var vecPos = verts.length/6;\n\n        var triangles = earcut(recPoints, null, 2);\n\n        var i = 0;\n        for (i = 0; i < triangles.length; i+=3)\n        {\n            indices.push(triangles[i] + vecPos);\n            indices.push(triangles[i] + vecPos);\n            indices.push(triangles[i+1] + vecPos);\n            indices.push(triangles[i+2] + vecPos);\n            indices.push(triangles[i+2] + vecPos);\n        }\n\n        for (i = 0; i < recPoints.length; i++)\n        {\n            verts.push(recPoints[i], recPoints[++i], r, g, b, alpha);\n        }\n    }\n\n    if (graphicsData.lineWidth)\n    {\n        var tempPoints = graphicsData.points;\n\n        graphicsData.points = recPoints;\n\n        this.buildLine(graphicsData, webGLData);\n\n        graphicsData.points = tempPoints;\n    }\n};\n\n/**\n * Calculate the points for a quadratic bezier curve. (helper function..)\n * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c\n *\n * @private\n * @param fromX {number} Origin point x\n * @param fromY {number} Origin point x\n * @param cpX {number} Control point x\n * @param cpY {number} Control point y\n * @param toX {number} Destination point x\n * @param toY {number} Destination point y\n * @param [out] {number[]} The output array to add points into. If not passed, a new array is created.\n * @return {number[]} an array of points\n */\nGraphicsRenderer.prototype.quadraticBezierCurve = function (fromX, fromY, cpX, cpY, toX, toY, out)\n{\n    var xa,\n        ya,\n        xb,\n        yb,\n        x,\n        y,\n        n = 20,\n        points = out || [];\n\n    function getPt(n1 , n2, perc) {\n        var diff = n2 - n1;\n\n        return n1 + ( diff * perc );\n    }\n\n    var j = 0;\n    for (var i = 0; i <= n; i++ ) {\n        j = i / n;\n\n        // The Green Line\n        xa = getPt( fromX , cpX , j );\n        ya = getPt( fromY , cpY , j );\n        xb = getPt( cpX , toX , j );\n        yb = getPt( cpY , toY , j );\n\n        // The Black Dot\n        x = getPt( xa , xb , j );\n        y = getPt( ya , yb , j );\n\n        points.push(x, y);\n    }\n\n    return points;\n};\n\n/**\n * Builds a circle to draw\n *\n * @private\n * @param graphicsData {PIXI.Graphics} The graphics object to draw\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildCircle = function (graphicsData, webGLData)\n{\n    // need to convert points to a nice regular data\n    var circleData = graphicsData.shape;\n    var x = circleData.x;\n    var y = circleData.y;\n    var width;\n    var height;\n\n    // TODO - bit hacky??\n    if (graphicsData.type === CONST.SHAPES.CIRC)\n    {\n        width = circleData.radius;\n        height = circleData.radius;\n    }\n    else\n    {\n        width = circleData.width;\n        height = circleData.height;\n    }\n\n    var totalSegs = Math.floor(30 * Math.sqrt(circleData.radius)) || Math.floor(15 * Math.sqrt(circleData.width + circleData.height));\n    var seg = (Math.PI * 2) / totalSegs ;\n\n    var i = 0;\n\n    if (graphicsData.fill)\n    {\n        var color = utils.hex2rgb(graphicsData.fillColor);\n        var alpha = graphicsData.fillAlpha;\n\n        var r = color[0] * alpha;\n        var g = color[1] * alpha;\n        var b = color[2] * alpha;\n\n        var verts = webGLData.points;\n        var indices = webGLData.indices;\n\n        var vecPos = verts.length/6;\n\n        indices.push(vecPos);\n\n        for (i = 0; i < totalSegs + 1 ; i++)\n        {\n            verts.push(x,y, r, g, b, alpha);\n\n            verts.push(x + Math.sin(seg * i) * width,\n                       y + Math.cos(seg * i) * height,\n                       r, g, b, alpha);\n\n            indices.push(vecPos++, vecPos++);\n        }\n\n        indices.push(vecPos-1);\n    }\n\n    if (graphicsData.lineWidth)\n    {\n        var tempPoints = graphicsData.points;\n\n        graphicsData.points = [];\n\n        for (i = 0; i < totalSegs + 1; i++)\n        {\n            graphicsData.points.push(x + Math.sin(seg * i) * width,\n                                     y + Math.cos(seg * i) * height);\n        }\n\n        this.buildLine(graphicsData, webGLData);\n\n        graphicsData.points = tempPoints;\n    }\n};\n\n/**\n * Builds a line to draw\n *\n * @private\n * @param graphicsData {PIXI.Graphics} The graphics object containing all the necessary properties\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildLine = function (graphicsData, webGLData)\n{\n    // TODO OPTIMISE!\n    var i = 0;\n    var points = graphicsData.points;\n\n    if (points.length === 0)\n    {\n        return;\n    }\n    // if the line width is an odd number add 0.5 to align to a whole pixel\n    // commenting this out fixes #711 and #1620\n    // if (graphicsData.lineWidth%2)\n    // {\n    //     for (i = 0; i < points.length; i++)\n    //     {\n    //         points[i] += 0.5;\n    //     }\n    // }\n\n    // get first and last point.. figure out the middle!\n    var firstPoint = new math.Point(points[0], points[1]);\n    var lastPoint = new math.Point(points[points.length - 2], points[points.length - 1]);\n\n    // if the first point is the last point - gonna have issues :)\n    if (firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y)\n    {\n        // need to clone as we are going to slightly modify the shape..\n        points = points.slice();\n\n        points.pop();\n        points.pop();\n\n        lastPoint = new math.Point(points[points.length - 2], points[points.length - 1]);\n\n        var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5;\n        var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5;\n\n        points.unshift(midPointX, midPointY);\n        points.push(midPointX, midPointY);\n    }\n\n    var verts = webGLData.points;\n    var indices = webGLData.indices;\n    var length = points.length / 2;\n    var indexCount = points.length;\n    var indexStart = verts.length/6;\n\n    // DRAW the Line\n    var width = graphicsData.lineWidth / 2;\n\n    // sort color\n    var color = utils.hex2rgb(graphicsData.lineColor);\n    var alpha = graphicsData.lineAlpha;\n    var r = color[0] * alpha;\n    var g = color[1] * alpha;\n    var b = color[2] * alpha;\n\n    var px, py, p1x, p1y, p2x, p2y, p3x, p3y;\n    var perpx, perpy, perp2x, perp2y, perp3x, perp3y;\n    var a1, b1, c1, a2, b2, c2;\n    var denom, pdist, dist;\n\n    p1x = points[0];\n    p1y = points[1];\n\n    p2x = points[2];\n    p2y = points[3];\n\n    perpx = -(p1y - p2y);\n    perpy =  p1x - p2x;\n\n    dist = Math.sqrt(perpx*perpx + perpy*perpy);\n\n    perpx /= dist;\n    perpy /= dist;\n    perpx *= width;\n    perpy *= width;\n\n    // start\n    verts.push(p1x - perpx , p1y - perpy,\n                r, g, b, alpha);\n\n    verts.push(p1x + perpx , p1y + perpy,\n                r, g, b, alpha);\n\n    for (i = 1; i < length-1; i++)\n    {\n        p1x = points[(i-1)*2];\n        p1y = points[(i-1)*2 + 1];\n\n        p2x = points[(i)*2];\n        p2y = points[(i)*2 + 1];\n\n        p3x = points[(i+1)*2];\n        p3y = points[(i+1)*2 + 1];\n\n        perpx = -(p1y - p2y);\n        perpy = p1x - p2x;\n\n        dist = Math.sqrt(perpx*perpx + perpy*perpy);\n        perpx /= dist;\n        perpy /= dist;\n        perpx *= width;\n        perpy *= width;\n\n        perp2x = -(p2y - p3y);\n        perp2y = p2x - p3x;\n\n        dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y);\n        perp2x /= dist;\n        perp2y /= dist;\n        perp2x *= width;\n        perp2y *= width;\n\n        a1 = (-perpy + p1y) - (-perpy + p2y);\n        b1 = (-perpx + p2x) - (-perpx + p1x);\n        c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y);\n        a2 = (-perp2y + p3y) - (-perp2y + p2y);\n        b2 = (-perp2x + p2x) - (-perp2x + p3x);\n        c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);\n\n        denom = a1*b2 - a2*b1;\n\n        if (Math.abs(denom) < 0.1 )\n        {\n\n            denom+=10.1;\n            verts.push(p2x - perpx , p2y - perpy,\n                r, g, b, alpha);\n\n            verts.push(p2x + perpx , p2y + perpy,\n                r, g, b, alpha);\n\n            continue;\n        }\n\n        px = (b1*c2 - b2*c1)/denom;\n        py = (a2*c1 - a1*c2)/denom;\n\n\n        pdist = (px -p2x) * (px -p2x) + (py -p2y) * (py -p2y);\n\n\n        if (pdist > 140 * 140)\n        {\n            perp3x = perpx - perp2x;\n            perp3y = perpy - perp2y;\n\n            dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y);\n            perp3x /= dist;\n            perp3y /= dist;\n            perp3x *= width;\n            perp3y *= width;\n\n            verts.push(p2x - perp3x, p2y -perp3y);\n            verts.push(r, g, b, alpha);\n\n            verts.push(p2x + perp3x, p2y +perp3y);\n            verts.push(r, g, b, alpha);\n\n            verts.push(p2x - perp3x, p2y -perp3y);\n            verts.push(r, g, b, alpha);\n\n            indexCount++;\n        }\n        else\n        {\n\n            verts.push(px , py);\n            verts.push(r, g, b, alpha);\n\n            verts.push(p2x - (px-p2x), p2y - (py - p2y));\n            verts.push(r, g, b, alpha);\n        }\n    }\n\n    p1x = points[(length-2)*2];\n    p1y = points[(length-2)*2 + 1];\n\n    p2x = points[(length-1)*2];\n    p2y = points[(length-1)*2 + 1];\n\n    perpx = -(p1y - p2y);\n    perpy = p1x - p2x;\n\n    dist = Math.sqrt(perpx*perpx + perpy*perpy);\n    perpx /= dist;\n    perpy /= dist;\n    perpx *= width;\n    perpy *= width;\n\n    verts.push(p2x - perpx , p2y - perpy);\n    verts.push(r, g, b, alpha);\n\n    verts.push(p2x + perpx , p2y + perpy);\n    verts.push(r, g, b, alpha);\n\n    indices.push(indexStart);\n\n    for (i = 0; i < indexCount; i++)\n    {\n        indices.push(indexStart++);\n    }\n\n    indices.push(indexStart-1);\n};\n\n/**\n * Builds a complex polygon to draw\n *\n * @private\n * @param graphicsData {PIXI.Graphics} The graphics object containing all the necessary properties\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildComplexPoly = function (graphicsData, webGLData)\n{\n    //TODO - no need to copy this as it gets turned into a FLoat32Array anyways..\n    var points = graphicsData.points.slice();\n\n    if (points.length < 6)\n    {\n        return;\n    }\n\n    // get first and last point.. figure out the middle!\n    var indices = webGLData.indices;\n    webGLData.points = points;\n    webGLData.alpha = graphicsData.fillAlpha;\n    webGLData.color = utils.hex2rgb(graphicsData.fillColor);\n\n    // calclate the bounds..\n    var minX = Infinity;\n    var maxX = -Infinity;\n\n    var minY = Infinity;\n    var maxY = -Infinity;\n\n    var x,y;\n\n    // get size..\n    for (var i = 0; i < points.length; i+=2)\n    {\n        x = points[i];\n        y = points[i+1];\n\n        minX = x < minX ? x : minX;\n        maxX = x > maxX ? x : maxX;\n\n        minY = y < minY ? y : minY;\n        maxY = y > maxY ? y : maxY;\n    }\n\n    // add a quad to the end cos there is no point making another buffer!\n    points.push(minX, minY,\n                maxX, minY,\n                maxX, maxY,\n                minX, maxY);\n\n    // push a quad onto the end..\n\n    //TODO - this aint needed!\n    var length = points.length / 2;\n    for (i = 0; i < length; i++)\n    {\n        indices.push( i );\n    }\n\n};\n\n/**\n * Builds a polygon to draw\n *\n * @private\n * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object containing all the necessary properties\n * @param webGLData {object} an object containing all the webGL-specific information to create this shape\n */\nGraphicsRenderer.prototype.buildPoly = function (graphicsData, webGLData)\n{\n    var points = graphicsData.points;\n\n    if (points.length < 6)\n    {\n        return;\n    }\n\n    // get first and last point.. figure out the middle!\n    var verts = webGLData.points;\n    var indices = webGLData.indices;\n\n    var length = points.length / 2;\n\n    // sort color\n    var color = utils.hex2rgb(graphicsData.fillColor);\n    var alpha = graphicsData.fillAlpha;\n    var r = color[0] * alpha;\n    var g = color[1] * alpha;\n    var b = color[2] * alpha;\n\n    var triangles = earcut(points, null, 2);\n\n    if (!triangles) {\n        return false;\n    }\n\n    var vertPos = verts.length / 6;\n\n    var i = 0;\n\n    for (i = 0; i < triangles.length; i+=3)\n    {\n        indices.push(triangles[i] + vertPos);\n        indices.push(triangles[i] + vertPos);\n        indices.push(triangles[i+1] + vertPos);\n        indices.push(triangles[i+2] +vertPos);\n        indices.push(triangles[i+2] + vertPos);\n    }\n\n    for (i = 0; i < length; i++)\n    {\n        verts.push(points[i * 2], points[i * 2 + 1],\n                   r, g, b, alpha);\n    }\n\n    return true;\n};\n\n},{\"../../const\":22,\"../../math\":33,\"../../renderers/webgl/WebGLRenderer\":49,\"../../renderers/webgl/utils/ObjectRenderer\":63,\"../../utils\":77,\"./WebGLGraphicsData\":28,\"earcut\":9}],28:[function(require,module,exports){\n/**\n * An object containing WebGL specific properties to be used by the WebGL renderer\n *\n * @class\n * @memberof PIXI\n * @param gl {WebGLRenderingContext} the current WebGL drawing context\n * @private\n */\nfunction WebGLGraphicsData(gl) {\n\n    /**\n     * The current WebGL drawing context\n     *\n     * @member {WebGLRenderingContext}\n     */\n    this.gl = gl;\n\n    //TODO does this need to be split before uploding??\n    /**\n     * An array of color components (r,g,b)\n     * @member {number[]}\n     */\n    this.color = [0,0,0]; // color split!\n\n    /**\n     * An array of points to draw\n     * @member {PIXI.Point[]}\n     */\n    this.points = [];\n\n    /**\n     * The indices of the vertices\n     * @member {number[]}\n     */\n    this.indices = [];\n    /**\n     * The main buffer\n     * @member {WebGLBuffer}\n     */\n    this.buffer = gl.createBuffer();\n\n    /**\n     * The index buffer\n     * @member {WebGLBuffer}\n     */\n    this.indexBuffer = gl.createBuffer();\n\n    /**\n     * todo @alvin\n     * @member {number}\n     */\n    this.mode = 1;\n\n    /**\n     * The alpha of the graphics\n     * @member {number}\n     */\n    this.alpha = 1;\n\n    /**\n     * Whether this graphics is dirty or not\n     * @member {boolean}\n     */\n    this.dirty = true;\n\n    this.glPoints = null;\n    this.glIndices = null;\n}\n\nWebGLGraphicsData.prototype.constructor = WebGLGraphicsData;\nmodule.exports = WebGLGraphicsData;\n\n/**\n * Resets the vertices and the indices\n */\nWebGLGraphicsData.prototype.reset = function () {\n    this.points.length = 0;\n    this.indices.length = 0;\n};\n\n/**\n * Binds the buffers and uploads the data\n */\nWebGLGraphicsData.prototype.upload = function () {\n    var gl = this.gl;\n\n//    this.lastIndex = graphics.graphicsData.length;\n    this.glPoints = new Float32Array(this.points);\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n    gl.bufferData(gl.ARRAY_BUFFER, this.glPoints, gl.STATIC_DRAW);\n\n    this.glIndices = new Uint16Array(this.indices);\n\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.glIndices, gl.STATIC_DRAW);\n\n    this.dirty = false;\n};\n\nWebGLGraphicsData.prototype.destroy = function () {\n    this.color = null;\n    this.points = null;\n    this.indices = null;\n\n    this.gl.deleteBuffer(this.buffer);\n    this.gl.deleteBuffer(this.indexBuffer);\n    \n    this.gl = null;\n\n    this.buffer = null;\n    this.indexBuffer = null;\n\n    this.glPoints = null;\n    this.glIndices = null;\n};\n\n},{}],29:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI core library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI\n */\n// export core and const. We assign core to const so that the non-reference types in const remain in-tact\nvar core = module.exports = Object.assign(require('./const'), require('./math'), {\n    // utils\n    utils: require('./utils'),\n    ticker: require('./ticker'),\n\n    // display\n    DisplayObject:          require('./display/DisplayObject'),\n    Container:              require('./display/Container'),\n\n    // sprites\n    Sprite:                 require('./sprites/Sprite'),\n    ParticleContainer:      require('./particles/ParticleContainer'),\n    SpriteRenderer:         require('./sprites/webgl/SpriteRenderer'),\n    ParticleRenderer:       require('./particles/webgl/ParticleRenderer'),\n\n    // text\n    Text:                   require('./text/Text'),\n\n    // primitives\n    Graphics:               require('./graphics/Graphics'),\n    GraphicsData:           require('./graphics/GraphicsData'),\n    GraphicsRenderer:       require('./graphics/webgl/GraphicsRenderer'),\n\n    // textures\n    Texture:                require('./textures/Texture'),\n    BaseTexture:            require('./textures/BaseTexture'),\n    RenderTexture:          require('./textures/RenderTexture'),\n    VideoBaseTexture:       require('./textures/VideoBaseTexture'),\n    TextureUvs:             require('./textures/TextureUvs'),\n\n    // renderers - canvas\n    CanvasRenderer:         require('./renderers/canvas/CanvasRenderer'),\n    CanvasGraphics:         require('./renderers/canvas/utils/CanvasGraphics'),\n    CanvasBuffer:           require('./renderers/canvas/utils/CanvasBuffer'),\n\n    // renderers - webgl\n    WebGLRenderer:          require('./renderers/webgl/WebGLRenderer'),\n    WebGLManager:           require('./renderers/webgl/managers/WebGLManager'),\n    ShaderManager:          require('./renderers/webgl/managers/ShaderManager'),\n    Shader:                 require('./renderers/webgl/shaders/Shader'),\n    TextureShader:          require('./renderers/webgl/shaders/TextureShader'),\n    PrimitiveShader:        require('./renderers/webgl/shaders/PrimitiveShader'),\n    ComplexPrimitiveShader: require('./renderers/webgl/shaders/ComplexPrimitiveShader'),\n    ObjectRenderer:         require('./renderers/webgl/utils/ObjectRenderer'),\n    RenderTarget:           require('./renderers/webgl/utils/RenderTarget'),\n\n    // filters - webgl\n    AbstractFilter:         require('./renderers/webgl/filters/AbstractFilter'),\n    FXAAFilter:             require('./renderers/webgl/filters/FXAAFilter'),\n    SpriteMaskFilter:       require('./renderers/webgl/filters/SpriteMaskFilter'),\n\n    /**\n     * This helper function will automatically detect which renderer you should be using.\n     * WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by\n     * the browser then this function will return a canvas renderer\n     *\n     * @memberof PIXI\n     * @param width=800 {number} the width of the renderers view\n     * @param height=600 {number} the height of the renderers view\n     * @param [options] {object} The optional renderer parameters\n     * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional\n     * @param [options.transparent=false] {boolean} If the render view is transparent, default false\n     * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)\n     * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if you\n     *      need to call toDataUrl on the webgl context\n     * @param [options.resolution=1] {number} the resolution of the renderer, retina would be 2\n     * @param [noWebGL=false] {boolean} prevents selection of WebGL renderer, even if such is present\n     *\n     * @return {WebGLRenderer|CanvasRenderer} Returns WebGL renderer if available, otherwise CanvasRenderer\n     */\n    autoDetectRenderer: function (width, height, options, noWebGL)\n    {\n        width = width || 800;\n        height = height || 600;\n\n        if (!noWebGL && core.utils.isWebGLSupported())\n        {\n            return new core.WebGLRenderer(width, height, options);\n        }\n\n        return new core.CanvasRenderer(width, height, options);\n    }\n});\n\n},{\"./const\":22,\"./display/Container\":23,\"./display/DisplayObject\":24,\"./graphics/Graphics\":25,\"./graphics/GraphicsData\":26,\"./graphics/webgl/GraphicsRenderer\":27,\"./math\":33,\"./particles/ParticleContainer\":39,\"./particles/webgl/ParticleRenderer\":41,\"./renderers/canvas/CanvasRenderer\":44,\"./renderers/canvas/utils/CanvasBuffer\":45,\"./renderers/canvas/utils/CanvasGraphics\":46,\"./renderers/webgl/WebGLRenderer\":49,\"./renderers/webgl/filters/AbstractFilter\":50,\"./renderers/webgl/filters/FXAAFilter\":51,\"./renderers/webgl/filters/SpriteMaskFilter\":52,\"./renderers/webgl/managers/ShaderManager\":56,\"./renderers/webgl/managers/WebGLManager\":58,\"./renderers/webgl/shaders/ComplexPrimitiveShader\":59,\"./renderers/webgl/shaders/PrimitiveShader\":60,\"./renderers/webgl/shaders/Shader\":61,\"./renderers/webgl/shaders/TextureShader\":62,\"./renderers/webgl/utils/ObjectRenderer\":63,\"./renderers/webgl/utils/RenderTarget\":65,\"./sprites/Sprite\":67,\"./sprites/webgl/SpriteRenderer\":68,\"./text/Text\":69,\"./textures/BaseTexture\":70,\"./textures/RenderTexture\":71,\"./textures/Texture\":72,\"./textures/TextureUvs\":73,\"./textures/VideoBaseTexture\":74,\"./ticker\":76,\"./utils\":77}],30:[function(require,module,exports){\n// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16\n\nvar ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];\nvar uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];\nvar vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];\nvar vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];\nvar tempMatrices = [];\nvar Matrix = require('./Matrix');\n\nvar mul = [];\n\nfunction signum(x) {\n    if (x < 0) {\n        return -1;\n    }\n    if (x > 0) {\n        return 1;\n    }\n    return 0;\n}\n\nfunction init() {\n    for (var i = 0; i < 16; i++) {\n        var row = [];\n        mul.push(row);\n        for (var j = 0; j < 16; j++) {\n            var _ux = signum(ux[i] * ux[j] + vx[i] * uy[j]);\n            var _uy = signum(uy[i] * ux[j] + vy[i] * uy[j]);\n            var _vx = signum(ux[i] * vx[j] + vx[i] * vy[j]);\n            var _vy = signum(uy[i] * vx[j] + vy[i] * vy[j]);\n            for (var k = 0; k < 16; k++) {\n                if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) {\n                    row.push(k);\n                    break;\n                }\n            }\n        }\n    }\n\n    for (i=0;i<16;i++) {\n        var mat = new Matrix();\n        mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);\n        tempMatrices.push(mat);\n    }\n}\n\ninit();\n\n/**\n * Implements Dihedral Group D_8, see [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html}, D8 is the same but with diagonals\n * Used for texture rotations\n * Vector xX(i), xY(i) is U-axis of sprite with rotation i\n * Vector yY(i), yY(i) is V-axis of sprite with rotation i\n * Rotations: 0 grad (0), 90 grad (2), 180 grad (4), 270 grad (6)\n * Mirrors: vertical (8), main diagonal (10), horizontal (12), reverse diagonal (14)\n * This is the small part of gameofbombs.com portal system. It works.\n * @author Ivan @ivanpopelyshev\n *\n * @namespace PIXI.GroupD8\n */\nvar GroupD8 = {\n    E: 0,\n    SE: 1,\n    S: 2,\n    SW: 3,\n    W: 4,\n    NW: 5,\n    N: 6,\n    NE: 7,\n    MIRROR_VERTICAL: 8,\n    MIRROR_HORIZONTAL: 12,\n    uX: function (ind) {\n        return ux[ind];\n    },\n    uY: function (ind) {\n        return uy[ind];\n    },\n    vX: function (ind) {\n        return vx[ind];\n    },\n    vY: function (ind) {\n        return vy[ind];\n    },\n    inv: function (rotation) {\n        if (rotation & 8) {\n            return rotation & 15;\n        }\n        return (-rotation) & 7;\n    },\n    add: function (rotationSecond, rotationFirst) {\n        return mul[rotationSecond][rotationFirst];\n    },\n    sub: function (rotationSecond, rotationFirst) {\n        return mul[rotationSecond][GroupD8.inv(rotationFirst)];\n    },\n    /**\n     * Adds 180 degrees to rotation. Commutative operation\n     * @param rotation\n     * @returns {number}\n     */\n    rotate180: function (rotation) {\n        return rotation ^ 4;\n    },\n    /**\n     * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.\n     * @param rotation\n     * @returns {boolean}\n     */\n    isSwapWidthHeight: function(rotation) {\n        return (rotation & 3) === 2;\n    },\n    byDirection: function (dx, dy) {\n        if (Math.abs(dx) * 2 <= Math.abs(dy)) {\n            if (dy >= 0) {\n                return GroupD8.S;\n            }\n            else {\n                return GroupD8.N;\n            }\n        } else if (Math.abs(dy) * 2 <= Math.abs(dx)) {\n            if (dx > 0) {\n                return GroupD8.E;\n            }\n            else {\n                return GroupD8.W;\n            }\n        } else {\n            if (dy > 0) {\n                if (dx > 0) {\n                    return GroupD8.SE;\n                }\n                else {\n                    return GroupD8.SW;\n                }\n            }\n            else if (dx > 0) {\n                return GroupD8.NE;\n            }\n            else {\n                return GroupD8.NW;\n            }\n        }\n    },\n    /**\n     * Helps sprite to compensate texture packer rotation.\n     * @param matrix {PIXI.Matrix} sprite world matrix\n     * @param rotation {number}\n     * @param tx {number|*} sprite anchoring\n     * @param ty {number|*} sprite anchoring\n     */\n    matrixAppendRotationInv: function (matrix, rotation, tx, ty) {\n        //Packer used \"rotation\", we use \"inv(rotation)\"\n        var mat = tempMatrices[GroupD8.inv(rotation)];\n        tx = tx || 0;\n        ty = ty || 0;\n        mat.tx = tx;\n        mat.ty = ty;\n        matrix.append(mat);\n    }\n};\n\nmodule.exports = GroupD8;\n\n},{\"./Matrix\":31}],31:[function(require,module,exports){\n// @todo - ignore the too many parameters warning for now\n// should either fix it or change the jshint config\n// jshint -W072\n\nvar Point = require('./Point');\n\n/**\n * The pixi Matrix class as an object, which makes it a lot faster,\n * here is a representation of it :\n * | a | b | tx|\n * | c | d | ty|\n * | 0 | 0 | 1 |\n *\n * @class\n * @memberof PIXI\n */\nfunction Matrix()\n{\n    /**\n     * @member {number}\n     * @default 1\n     */\n    this.a = 1;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.b = 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.c = 0;\n\n    /**\n     * @member {number}\n     * @default 1\n     */\n    this.d = 1;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.tx = 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.ty = 0;\n}\n\nMatrix.prototype.constructor = Matrix;\nmodule.exports = Matrix;\n\n/**\n * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows:\n *\n * a = array[0]\n * b = array[1]\n * c = array[3]\n * d = array[4]\n * tx = array[2]\n * ty = array[5]\n *\n * @param array {number[]} The array that the matrix will be populated from.\n */\nMatrix.prototype.fromArray = function (array)\n{\n    this.a = array[0];\n    this.b = array[1];\n    this.c = array[3];\n    this.d = array[4];\n    this.tx = array[2];\n    this.ty = array[5];\n};\n\n\n/**\n * sets the matrix properties\n *\n * @param {number} a\n * @param {number} b\n * @param {number} c\n * @param {number} d\n * @param {number} tx\n * @param {number} ty\n *\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.set = function (a, b, c, d, tx, ty)\n{\n    this.a = a;\n    this.b = b;\n    this.c = c;\n    this.d = d;\n    this.tx = tx;\n    this.ty = ty;\n\n    return this;\n};\n\n\n/**\n * Creates an array from the current Matrix object.\n *\n * @param transpose {boolean} Whether we need to transpose the matrix or not\n * @param [out] {Array} If provided the array will be assigned to out\n * @return {number[]} the newly created array which contains the matrix\n */\nMatrix.prototype.toArray = function (transpose, out)\n{\n    if (!this.array)\n    {\n        this.array = new Float32Array(9);\n    }\n\n    var array = out || this.array;\n\n    if (transpose)\n    {\n        array[0] = this.a;\n        array[1] = this.b;\n        array[2] = 0;\n        array[3] = this.c;\n        array[4] = this.d;\n        array[5] = 0;\n        array[6] = this.tx;\n        array[7] = this.ty;\n        array[8] = 1;\n    }\n    else\n    {\n        array[0] = this.a;\n        array[1] = this.c;\n        array[2] = this.tx;\n        array[3] = this.b;\n        array[4] = this.d;\n        array[5] = this.ty;\n        array[6] = 0;\n        array[7] = 0;\n        array[8] = 1;\n    }\n\n    return array;\n};\n\n/**\n * Get a new position with the current transformation applied.\n * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering)\n *\n * @param pos {PIXI.Point} The origin\n * @param [newPos] {PIXI.Point} The point that the new position is assigned to (allowed to be same as input)\n * @return {PIXI.Point} The new point, transformed through this matrix\n */\nMatrix.prototype.apply = function (pos, newPos)\n{\n    newPos = newPos || new Point();\n\n    var x = pos.x;\n    var y = pos.y;\n\n    newPos.x = this.a * x + this.c * y + this.tx;\n    newPos.y = this.b * x + this.d * y + this.ty;\n\n    return newPos;\n};\n\n/**\n * Get a new position with the inverse of the current transformation applied.\n * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input)\n *\n * @param pos {PIXI.Point} The origin\n * @param [newPos] {PIXI.Point} The point that the new position is assigned to (allowed to be same as input)\n * @return {PIXI.Point} The new point, inverse-transformed through this matrix\n */\nMatrix.prototype.applyInverse = function (pos, newPos)\n{\n    newPos = newPos || new Point();\n\n    var id = 1 / (this.a * this.d + this.c * -this.b);\n\n    var x = pos.x;\n    var y = pos.y;\n\n    newPos.x = this.d * id * x + -this.c * id * y + (this.ty * this.c - this.tx * this.d) * id;\n    newPos.y = this.a * id * y + -this.b * id * x + (-this.ty * this.a + this.tx * this.b) * id;\n\n    return newPos;\n};\n\n/**\n * Translates the matrix on the x and y.\n *\n * @param {number} x\n * @param {number} y\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.translate = function (x, y)\n{\n    this.tx += x;\n    this.ty += y;\n\n    return this;\n};\n\n/**\n * Applies a scale transformation to the matrix.\n *\n * @param {number} x The amount to scale horizontally\n * @param {number} y The amount to scale vertically\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.scale = function (x, y)\n{\n    this.a *= x;\n    this.d *= y;\n    this.c *= x;\n    this.b *= y;\n    this.tx *= x;\n    this.ty *= y;\n\n    return this;\n};\n\n\n/**\n * Applies a rotation transformation to the matrix.\n *\n * @param {number} angle - The angle in radians.\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.rotate = function (angle)\n{\n    var cos = Math.cos( angle );\n    var sin = Math.sin( angle );\n\n    var a1 = this.a;\n    var c1 = this.c;\n    var tx1 = this.tx;\n\n    this.a = a1 * cos-this.b * sin;\n    this.b = a1 * sin+this.b * cos;\n    this.c = c1 * cos-this.d * sin;\n    this.d = c1 * sin+this.d * cos;\n    this.tx = tx1 * cos - this.ty * sin;\n    this.ty = tx1 * sin + this.ty * cos;\n\n    return this;\n};\n\n/**\n * Appends the given Matrix to this Matrix.\n *\n * @param {PIXI.Matrix} matrix\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.append = function (matrix)\n{\n    var a1 = this.a;\n    var b1 = this.b;\n    var c1 = this.c;\n    var d1 = this.d;\n\n    this.a  = matrix.a * a1 + matrix.b * c1;\n    this.b  = matrix.a * b1 + matrix.b * d1;\n    this.c  = matrix.c * a1 + matrix.d * c1;\n    this.d  = matrix.c * b1 + matrix.d * d1;\n\n    this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx;\n    this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty;\n\n    return this;\n};\n\n/**\n * Sets the matrix based on all the available properties\n *\n * @param {number} x\n * @param {number} y\n * @param {number} pivotX\n * @param {number} pivotY\n * @param {number} scaleX\n * @param {number} scaleY\n * @param {number} rotation\n * @param {number} skewX\n * @param {number} skewY\n *\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.setTransform = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY)\n{\n    var a, b, c, d, sr, cr, cy, sy, nsx, cx;\n\n    sr  = Math.sin(rotation);\n    cr  = Math.cos(rotation);\n    cy  = Math.cos(skewY);\n    sy  = Math.sin(skewY);\n    nsx = -Math.sin(skewX);\n    cx  =  Math.cos(skewX);\n\n    a  =  cr * scaleX;\n    b  =  sr * scaleX;\n    c  = -sr * scaleY;\n    d  =  cr * scaleY;\n\n    this.a  = cy * a + sy * c;\n    this.b  = cy * b + sy * d;\n    this.c  = nsx * a + cx * c;\n    this.d  = nsx * b + cx * d;\n\n    this.tx = x + ( pivotX * a + pivotY * c );\n    this.ty = y + ( pivotX * b + pivotY * d );\n\n    return this;\n};\n\n/**\n * Prepends the given Matrix to this Matrix.\n *\n * @param {PIXI.Matrix} matrix\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.prepend = function(matrix)\n{\n    var tx1 = this.tx;\n\n    if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1)\n    {\n        var a1 = this.a;\n        var c1 = this.c;\n        this.a  = a1*matrix.a+this.b*matrix.c;\n        this.b  = a1*matrix.b+this.b*matrix.d;\n        this.c  = c1*matrix.a+this.d*matrix.c;\n        this.d  = c1*matrix.b+this.d*matrix.d;\n    }\n\n    this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx;\n    this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty;\n\n    return this;\n};\n\n/**\n * Inverts this matrix\n *\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.invert = function()\n{\n    var a1 = this.a;\n    var b1 = this.b;\n    var c1 = this.c;\n    var d1 = this.d;\n    var tx1 = this.tx;\n    var n = a1*d1-b1*c1;\n\n    this.a = d1/n;\n    this.b = -b1/n;\n    this.c = -c1/n;\n    this.d = a1/n;\n    this.tx = (c1*this.ty-d1*tx1)/n;\n    this.ty = -(a1*this.ty-b1*tx1)/n;\n\n    return this;\n};\n\n\n/**\n * Resets this Matix to an identity (default) matrix.\n *\n * @return {PIXI.Matrix} This matrix. Good for chaining method calls.\n */\nMatrix.prototype.identity = function ()\n{\n    this.a = 1;\n    this.b = 0;\n    this.c = 0;\n    this.d = 1;\n    this.tx = 0;\n    this.ty = 0;\n\n    return this;\n};\n\n/**\n * Creates a new Matrix object with the same values as this one.\n *\n * @return {PIXI.Matrix} A copy of this matrix. Good for chaining method calls.\n */\nMatrix.prototype.clone = function ()\n{\n    var matrix = new Matrix();\n    matrix.a = this.a;\n    matrix.b = this.b;\n    matrix.c = this.c;\n    matrix.d = this.d;\n    matrix.tx = this.tx;\n    matrix.ty = this.ty;\n\n    return matrix;\n};\n\n/**\n * Changes the values of the given matrix to be the same as the ones in this matrix\n *\n * @return {PIXI.Matrix} The matrix given in parameter with its values updated.\n */\nMatrix.prototype.copy = function (matrix)\n{\n    matrix.a = this.a;\n    matrix.b = this.b;\n    matrix.c = this.c;\n    matrix.d = this.d;\n    matrix.tx = this.tx;\n    matrix.ty = this.ty;\n\n    return matrix;\n};\n\n/**\n * A default (identity) matrix\n *\n * @static\n * @const\n */\nMatrix.IDENTITY = new Matrix();\n\n/**\n * A temp matrix\n *\n * @static\n * @const\n */\nMatrix.TEMP_MATRIX = new Matrix();\n\n},{\"./Point\":32}],32:[function(require,module,exports){\n/**\n * The Point object represents a location in a two-dimensional coordinate system, where x represents\n * the horizontal axis and y represents the vertical axis.\n *\n * @class\n * @memberof PIXI\n * @param [x=0] {number} position of the point on the x axis\n * @param [y=0] {number} position of the point on the y axis\n */\nfunction Point(x, y)\n{\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.x = x || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.y = y || 0;\n}\n\nPoint.prototype.constructor = Point;\nmodule.exports = Point;\n\n/**\n * Creates a clone of this point\n *\n * @return {PIXI.Point} a copy of the point\n */\nPoint.prototype.clone = function ()\n{\n    return new Point(this.x, this.y);\n};\n\n/**\n * Copies x and y from the given point\n *\n * @param p {PIXI.Point}\n */\nPoint.prototype.copy = function (p) {\n    this.set(p.x, p.y);\n};\n\n/**\n * Returns true if the given point is equal to this point\n *\n * @param p {PIXI.Point}\n * @returns {boolean}\n */\nPoint.prototype.equals = function (p) {\n    return (p.x === this.x) && (p.y === this.y);\n};\n\n/**\n * Sets the point to a new x and y position.\n * If y is omitted, both x and y will be set to x.\n *\n * @param [x=0] {number} position of the point on the x axis\n * @param [y=0] {number} position of the point on the y axis\n */\nPoint.prototype.set = function (x, y)\n{\n    this.x = x || 0;\n    this.y = y || ( (y !== 0) ? this.x : 0 ) ;\n};\n\n},{}],33:[function(require,module,exports){\n/**\n * Math classes and utilities mixed into PIXI namespace.\n *\n * @lends PIXI\n */\nmodule.exports = {\n    // These will be mixed to be made publicly available,\n    // while this module is used internally in core\n    // to avoid circular dependencies and cut down on\n    // internal module requires.\n\n    Point:      require('./Point'),\n    Matrix:     require('./Matrix'),\n    GroupD8:    require('./GroupD8'),\n\n    Circle:     require('./shapes/Circle'),\n    Ellipse:    require('./shapes/Ellipse'),\n    Polygon:    require('./shapes/Polygon'),\n    Rectangle:  require('./shapes/Rectangle'),\n    RoundedRectangle: require('./shapes/RoundedRectangle')\n};\n\n},{\"./GroupD8\":30,\"./Matrix\":31,\"./Point\":32,\"./shapes/Circle\":34,\"./shapes/Ellipse\":35,\"./shapes/Polygon\":36,\"./shapes/Rectangle\":37,\"./shapes/RoundedRectangle\":38}],34:[function(require,module,exports){\nvar Rectangle = require('./Rectangle'),\n    CONST = require('../../const');\n\n/**\n * The Circle object can be used to specify a hit area for displayObjects\n *\n * @class\n * @memberof PIXI\n * @param x {number} The X coordinate of the center of this circle\n * @param y {number} The Y coordinate of the center of this circle\n * @param radius {number} The radius of the circle\n */\nfunction Circle(x, y, radius)\n{\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.x = x || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.y = y || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.radius = radius || 0;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     *\n     * @member {number}\n     */\n    this.type = CONST.SHAPES.CIRC;\n}\n\nCircle.prototype.constructor = Circle;\nmodule.exports = Circle;\n\n/**\n * Creates a clone of this Circle instance\n *\n * @return {PIXI.Circle} a copy of the Circle\n */\nCircle.prototype.clone = function ()\n{\n    return new Circle(this.x, this.y, this.radius);\n};\n\n/**\n * Checks whether the x and y coordinates given are contained within this circle\n *\n * @param x {number} The X coordinate of the point to test\n * @param y {number} The Y coordinate of the point to test\n * @return {boolean} Whether the x/y coordinates are within this Circle\n */\nCircle.prototype.contains = function (x, y)\n{\n    if (this.radius <= 0)\n    {\n        return false;\n    }\n\n    var dx = (this.x - x),\n        dy = (this.y - y),\n        r2 = this.radius * this.radius;\n\n    dx *= dx;\n    dy *= dy;\n\n    return (dx + dy <= r2);\n};\n\n/**\n* Returns the framing rectangle of the circle as a Rectangle object\n*\n* @return {PIXI.Rectangle} the framing rectangle\n*/\nCircle.prototype.getBounds = function ()\n{\n    return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2);\n};\n\n},{\"../../const\":22,\"./Rectangle\":37}],35:[function(require,module,exports){\nvar Rectangle = require('./Rectangle'),\n    CONST = require('../../const');\n\n/**\n * The Ellipse object can be used to specify a hit area for displayObjects\n *\n * @class\n * @memberof PIXI\n * @param x {number} The X coordinate of the center of the ellipse\n * @param y {number} The Y coordinate of the center of the ellipse\n * @param width {number} The half width of this ellipse\n * @param height {number} The half height of this ellipse\n */\nfunction Ellipse(x, y, width, height)\n{\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.x = x || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.y = y || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.width = width || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.height = height || 0;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     *\n     * @member {number}\n     */\n    this.type = CONST.SHAPES.ELIP;\n}\n\nEllipse.prototype.constructor = Ellipse;\nmodule.exports = Ellipse;\n\n/**\n * Creates a clone of this Ellipse instance\n *\n * @return {PIXI.Ellipse} a copy of the ellipse\n */\nEllipse.prototype.clone = function ()\n{\n    return new Ellipse(this.x, this.y, this.width, this.height);\n};\n\n/**\n * Checks whether the x and y coordinates given are contained within this ellipse\n *\n * @param x {number} The X coordinate of the point to test\n * @param y {number} The Y coordinate of the point to test\n * @return {boolean} Whether the x/y coords are within this ellipse\n */\nEllipse.prototype.contains = function (x, y)\n{\n    if (this.width <= 0 || this.height <= 0)\n    {\n        return false;\n    }\n\n    //normalize the coords to an ellipse with center 0,0\n    var normx = ((x - this.x) / this.width),\n        normy = ((y - this.y) / this.height);\n\n    normx *= normx;\n    normy *= normy;\n\n    return (normx + normy <= 1);\n};\n\n/**\n * Returns the framing rectangle of the ellipse as a Rectangle object\n *\n * @return {PIXI.Rectangle} the framing rectangle\n */\nEllipse.prototype.getBounds = function ()\n{\n    return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height);\n};\n\n},{\"../../const\":22,\"./Rectangle\":37}],36:[function(require,module,exports){\nvar Point = require('../Point'),\n    CONST = require('../../const');\n\n/**\n * @class\n * @memberof PIXI\n * @param points {PIXI.Point[]|number[]|...PIXI.Point|...number} This can be an array of Points that form the polygon,\n *      a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be\n *      all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the\n *      arguments passed can be flat x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are\n *      Numbers.\n */\nfunction Polygon(points_)\n{\n    // prevents an argument assignment deopt\n    // see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments\n    var points = points_;\n\n    //if points isn't an array, use arguments as the array\n    if (!Array.isArray(points))\n    {\n        // prevents an argument leak deopt\n        // see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments\n        points = new Array(arguments.length);\n\n        for (var a = 0; a < points.length; ++a) {\n            points[a] = arguments[a];\n        }\n    }\n\n    // if this is an array of points, convert it to a flat array of numbers\n    if (points[0] instanceof Point)\n    {\n        var p = [];\n        for (var i = 0, il = points.length; i < il; i++)\n        {\n            p.push(points[i].x, points[i].y);\n        }\n\n        points = p;\n    }\n\n    this.closed = true;\n\n    /**\n     * An array of the points of this polygon\n     *\n     * @member {number[]}\n     */\n    this.points = points;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     *\n     * @member {number}\n     */\n    this.type = CONST.SHAPES.POLY;\n}\n\nPolygon.prototype.constructor = Polygon;\nmodule.exports = Polygon;\n\n/**\n * Creates a clone of this polygon\n *\n * @return {PIXI.Polygon} a copy of the polygon\n */\nPolygon.prototype.clone = function ()\n{\n    return new Polygon(this.points.slice());\n};\n\n/**\n * Checks whether the x and y coordinates passed to this function are contained within this polygon\n *\n * @param x {number} The X coordinate of the point to test\n * @param y {number} The Y coordinate of the point to test\n * @return {boolean} Whether the x/y coordinates are within this polygon\n */\nPolygon.prototype.contains = function (x, y)\n{\n    var inside = false;\n\n    // use some raycasting to test hits\n    // https://github.com/substack/point-in-polygon/blob/master/index.js\n    var length = this.points.length / 2;\n\n    for (var i = 0, j = length - 1; i < length; j = i++)\n    {\n        var xi = this.points[i * 2], yi = this.points[i * 2 + 1],\n            xj = this.points[j * 2], yj = this.points[j * 2 + 1],\n            intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);\n\n        if (intersect)\n        {\n            inside = !inside;\n        }\n    }\n\n    return inside;\n};\n\n},{\"../../const\":22,\"../Point\":32}],37:[function(require,module,exports){\nvar CONST = require('../../const');\n\n/**\n * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.\n *\n * @class\n * @memberof PIXI\n * @param x {number} The X coordinate of the upper-left corner of the rectangle\n * @param y {number} The Y coordinate of the upper-left corner of the rectangle\n * @param width {number} The overall width of this rectangle\n * @param height {number} The overall height of this rectangle\n */\nfunction Rectangle(x, y, width, height)\n{\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.x = x || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.y = y || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.width = width || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.height = height || 0;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     *\n     * @member {number}\n     */\n    this.type = CONST.SHAPES.RECT;\n}\n\nRectangle.prototype.constructor = Rectangle;\nmodule.exports = Rectangle;\n\n/**\n * A constant empty rectangle.\n *\n * @static\n * @constant\n */\nRectangle.EMPTY = new Rectangle(0, 0, 0, 0);\n\n\n/**\n * Creates a clone of this Rectangle\n *\n * @return {PIXI.Rectangle} a copy of the rectangle\n */\nRectangle.prototype.clone = function ()\n{\n    return new Rectangle(this.x, this.y, this.width, this.height);\n};\n\n/**\n * Checks whether the x and y coordinates given are contained within this Rectangle\n *\n * @param x {number} The X coordinate of the point to test\n * @param y {number} The Y coordinate of the point to test\n * @return {boolean} Whether the x/y coordinates are within this Rectangle\n */\nRectangle.prototype.contains = function (x, y)\n{\n    if (this.width <= 0 || this.height <= 0)\n    {\n        return false;\n    }\n\n    if (x >= this.x && x < this.x + this.width)\n    {\n        if (y >= this.y && y < this.y + this.height)\n        {\n            return true;\n        }\n    }\n\n    return false;\n};\n\n},{\"../../const\":22}],38:[function(require,module,exports){\nvar CONST = require('../../const');\n\n/**\n * The Rounded Rectangle object is an area that has nice rounded corners, as indicated by its top-left corner point (x, y) and by its width and its height and its radius.\n *\n * @class\n * @memberof PIXI\n * @param x {number} The X coordinate of the upper-left corner of the rounded rectangle\n * @param y {number} The Y coordinate of the upper-left corner of the rounded rectangle\n * @param width {number} The overall width of this rounded rectangle\n * @param height {number} The overall height of this rounded rectangle\n * @param radius {number} Controls the radius of the rounded corners\n */\nfunction RoundedRectangle(x, y, width, height, radius)\n{\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.x = x || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.y = y || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.width = width || 0;\n\n    /**\n     * @member {number}\n     * @default 0\n     */\n    this.height = height || 0;\n\n    /**\n     * @member {number}\n     * @default 20\n     */\n    this.radius = radius || 20;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     *\n     * @member {number}\n     */\n    this.type = CONST.SHAPES.RREC;\n}\n\nRoundedRectangle.prototype.constructor = RoundedRectangle;\nmodule.exports = RoundedRectangle;\n\n/**\n * Creates a clone of this Rounded Rectangle\n *\n * @return {PIXI.RoundedRectangle} a copy of the rounded rectangle\n */\nRoundedRectangle.prototype.clone = function ()\n{\n    return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);\n};\n\n/**\n * Checks whether the x and y coordinates given are contained within this Rounded Rectangle\n *\n * @param x {number} The X coordinate of the point to test\n * @param y {number} The Y coordinate of the point to test\n * @return {boolean} Whether the x/y coordinates are within this Rounded Rectangle\n */\nRoundedRectangle.prototype.contains = function (x, y)\n{\n    if (this.width <= 0 || this.height <= 0)\n    {\n        return false;\n    }\n\n    if (x >= this.x && x <= this.x + this.width)\n    {\n        if (y >= this.y && y <= this.y + this.height)\n        {\n            return true;\n        }\n    }\n\n    return false;\n};\n\n},{\"../../const\":22}],39:[function(require,module,exports){\nvar Container = require('../display/Container'),\n    CONST = require('../const');\n\n/**\n * The ParticleContainer class is a really fast version of the Container built solely for speed,\n * so use when you need a lot of sprites or particles. The tradeoff of the ParticleContainer is that advanced\n * functionality will not work. ParticleContainer implements only the basic object transform (position, scale, rotation).\n * Any other functionality like tinting, masking, etc will not work on sprites in this batch.\n *\n * It's extremely easy to use :\n *\n * ```js\n * var container = new ParticleContainer();\n *\n * for (var i = 0; i < 100; ++i)\n * {\n *     var sprite = new PIXI.Sprite.fromImage(\"myImage.png\");\n *     container.addChild(sprite);\n * }\n * ```\n *\n * And here you have a hundred sprites that will be renderer at the speed of light.\n *\n * @class\n * @extends PIXI.Container\n * @memberof PIXI\n * @param [maxSize=15000] {number} The maximum number of particles that can be renderer by the container.\n * @param [properties] {object} The properties of children that should be uploaded to the gpu and applied.\n * @param [properties.scale=false] {boolean} When true, scale be uploaded and applied.\n * @param [properties.position=true] {boolean} When true, position be uploaded and applied.\n * @param [properties.rotation=false] {boolean} When true, rotation be uploaded and applied.\n * @param [properties.uvs=false] {boolean} When true, uvs be uploaded and applied.\n * @param [properties.alpha=false] {boolean} When true, alpha be uploaded and applied.\n * @param [batchSize=15000] {number} Number of particles per batch.\n */\nfunction ParticleContainer(maxSize, properties, batchSize)\n{\n    Container.call(this);\n\n    batchSize = batchSize || 15000; //CONST.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop\n    maxSize = maxSize || 15000;\n\n    // Making sure the batch size is valid\n    // 65535 is max vertex index in the index buffer (see ParticleRenderer)\n    // so max number of particles is 65536 / 4 = 16384\n    var maxBatchSize = 16384;\n    if (batchSize > maxBatchSize) {\n        batchSize = maxBatchSize;\n    }\n\n    if (batchSize > maxSize) {\n        batchSize = maxSize;\n    }\n\n    /**\n     * Set properties to be dynamic (true) / static (false)\n     *\n     * @member {boolean[]}\n     * @private\n     */\n    this._properties = [false, true, false, false, false];\n\n    /**\n     * @member {number}\n     * @private\n     */\n    this._maxSize = maxSize;\n\n    /**\n     * @member {number}\n     * @private\n     */\n    this._batchSize = batchSize;\n\n    /**\n     * @member {WebGLBuffer}\n     * @private\n     */\n    this._buffers = null;\n\n    /**\n     * @member {number}\n     * @private\n     */\n    this._bufferToUpdate = 0;\n\n    /**\n     * @member {boolean}\n     *\n     */\n    this.interactiveChildren = false;\n\n    /**\n     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.\n     *\n     * @member {number}\n     * @default PIXI.BLEND_MODES.NORMAL\n     * @see PIXI.BLEND_MODES\n     */\n    this.blendMode = CONST.BLEND_MODES.NORMAL;\n\n    /**\n     * Used for canvas renderering. If true then the elements will be positioned at the nearest pixel. This provides a nice speed boost.\n     *\n     * @member {boolean}\n     * @default true;\n     */\n    this.roundPixels = true;\n\n    this.setProperties(properties);\n}\n\nParticleContainer.prototype = Object.create(Container.prototype);\nParticleContainer.prototype.constructor = ParticleContainer;\nmodule.exports = ParticleContainer;\n\n/**\n * Sets the private properties array to dynamic / static based on the passed properties object\n *\n * @param properties {object} The properties to be uploaded\n */\nParticleContainer.prototype.setProperties = function(properties)\n{\n    if ( properties ) {\n        this._properties[0] = 'scale' in properties ? !!properties.scale : this._properties[0];\n        this._properties[1] = 'position' in properties ? !!properties.position : this._properties[1];\n        this._properties[2] = 'rotation' in properties ? !!properties.rotation : this._properties[2];\n        this._properties[3] = 'uvs' in properties ? !!properties.uvs : this._properties[3];\n        this._properties[4] = 'alpha' in properties ? !!properties.alpha : this._properties[4];\n    }\n};\n\n/**\n * Updates the object transform for rendering\n *\n * @private\n */\nParticleContainer.prototype.updateTransform = function ()\n{\n\n    // TODO don't need to!\n    this.displayObjectUpdateTransform();\n    //  PIXI.Container.prototype.updateTransform.call( this );\n};\n\n/**\n * Renders the container using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer} The webgl renderer\n * @private\n */\nParticleContainer.prototype.renderWebGL = function (renderer)\n{\n    if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable)\n    {\n        return;\n    }\n\n    renderer.setObjectRenderer( renderer.plugins.particle );\n    renderer.plugins.particle.render( this );\n};\n\n/**\n * Set the flag that static data should be updated to true\n *\n * @private\n */\nParticleContainer.prototype.onChildrenChange = function (smallestChildIndex)\n{\n    var bufferIndex = Math.floor(smallestChildIndex / this._batchSize);\n    if (bufferIndex < this._bufferToUpdate) {\n        this._bufferToUpdate = bufferIndex;\n    }\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer} The canvas renderer\n * @private\n */\nParticleContainer.prototype.renderCanvas = function (renderer)\n{\n    if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable)\n    {\n        return;\n    }\n\n    var context = renderer.context;\n    var transform = this.worldTransform;\n    var isRotated = true;\n\n    var positionX = 0;\n    var positionY = 0;\n\n    var finalWidth = 0;\n    var finalHeight = 0;\n\n    var compositeOperation = renderer.blendModes[this.blendMode];\n    if (compositeOperation !== context.globalCompositeOperation)\n    {\n        context.globalCompositeOperation = compositeOperation;\n    }\n\n    context.globalAlpha = this.worldAlpha;\n\n    this.displayObjectUpdateTransform();\n\n    for (var i = 0; i < this.children.length; ++i)\n    {\n        var child = this.children[i];\n\n        if (!child.visible)\n        {\n            continue;\n        }\n\n        var frame = child.texture.frame;\n\n        context.globalAlpha = this.worldAlpha * child.alpha;\n\n        if (child.rotation % (Math.PI * 2) === 0)\n        {\n            // this is the fastest  way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call\n            if (isRotated)\n            {\n                context.setTransform(\n                    transform.a,\n                    transform.b,\n                    transform.c,\n                    transform.d,\n                    transform.tx,\n                    transform.ty\n                );\n\n                isRotated = false;\n            }\n\n            positionX = ((child.anchor.x) * (-frame.width * child.scale.x) + child.position.x  + 0.5);\n            positionY = ((child.anchor.y) * (-frame.height * child.scale.y) + child.position.y  + 0.5);\n\n            finalWidth = frame.width * child.scale.x;\n            finalHeight = frame.height * child.scale.y;\n\n        }\n        else\n        {\n            if (!isRotated)\n            {\n                isRotated = true;\n            }\n\n            child.displayObjectUpdateTransform();\n\n            var childTransform = child.worldTransform;\n\n            if (renderer.roundPixels)\n            {\n                context.setTransform(\n                    childTransform.a,\n                    childTransform.b,\n                    childTransform.c,\n                    childTransform.d,\n                    childTransform.tx | 0,\n                    childTransform.ty | 0\n                );\n            }\n            else\n            {\n                context.setTransform(\n                    childTransform.a,\n                    childTransform.b,\n                    childTransform.c,\n                    childTransform.d,\n                    childTransform.tx,\n                    childTransform.ty\n                );\n            }\n\n            positionX = ((child.anchor.x) * (-frame.width) + 0.5);\n            positionY = ((child.anchor.y) * (-frame.height) + 0.5);\n\n            finalWidth = frame.width;\n            finalHeight = frame.height;\n        }\n\n        context.drawImage(\n            child.texture.baseTexture.source,\n            frame.x,\n            frame.y,\n            frame.width,\n            frame.height,\n            positionX,\n            positionY,\n            finalWidth,\n            finalHeight\n        );\n    }\n};\n\n/**\n * Destroys the container\n *\n * @param [destroyChildren=false] {boolean} if set to true, all the children will have their destroy method called as well\n */\nParticleContainer.prototype.destroy = function () {\n    Container.prototype.destroy.apply(this, arguments);\n\n    if (this._buffers) {\n        for (var i = 0; i < this._buffers.length; ++i) {\n            this._buffers[i].destroy();\n        }\n    }\n\n    this._properties = null;\n    this._buffers = null;\n};\n\n},{\"../const\":22,\"../display/Container\":23}],40:[function(require,module,exports){\n\n/**\n * @author Mat Groves\n *\n * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/\n * for creating the original pixi version!\n * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer\n *\n * Heavily inspired by LibGDX's ParticleBuffer:\n * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleBuffer.java\n */\n\n/**\n * The particle buffer manages the static and dynamic buffers for a particle container.\n *\n * @class\n * @private\n * @memberof PIXI\n */\nfunction ParticleBuffer(gl, properties, dynamicPropertyFlags, size)\n{\n    /**\n     * The current WebGL drawing context.\n     *\n     * @member {WebGLRenderingContext}\n     */\n    this.gl = gl;\n\n    /**\n     * Size of a single vertex.\n     *\n     * @member {number}\n     */\n    this.vertSize = 2;\n\n    /**\n     * Size of a single vertex in bytes.\n     *\n     * @member {number}\n     */\n    this.vertByteSize = this.vertSize * 4;\n\n    /**\n     * The number of particles the buffer can hold\n     *\n     * @member {number}\n     */\n    this.size = size;\n\n    /**\n     * A list of the properties that are dynamic.\n     *\n     * @member {object[]}\n     */\n    this.dynamicProperties = [];\n\n    /**\n     * A list of the properties that are static.\n     *\n     * @member {object[]}\n     */\n    this.staticProperties = [];\n\n    for (var i = 0; i < properties.length; i++)\n    {\n        var property = properties[i];\n\n        if(dynamicPropertyFlags[i])\n        {\n            this.dynamicProperties.push(property);\n        }\n        else\n        {\n            this.staticProperties.push(property);\n        }\n    }\n\n    this.staticStride = 0;\n    this.staticBuffer = null;\n    this.staticData = null;\n\n    this.dynamicStride = 0;\n    this.dynamicBuffer = null;\n    this.dynamicData = null;\n\n    this.initBuffers();\n\n}\n\nParticleBuffer.prototype.constructor = ParticleBuffer;\nmodule.exports = ParticleBuffer;\n\n/**\n * Sets up the renderer context and necessary buffers.\n *\n * @private\n */\nParticleBuffer.prototype.initBuffers = function ()\n{\n    var gl = this.gl;\n    var i;\n    var property;\n\n    var dynamicOffset = 0;\n    this.dynamicStride = 0;\n\n    for (i = 0; i < this.dynamicProperties.length; i++)\n    {\n        property = this.dynamicProperties[i];\n\n        property.offset = dynamicOffset;\n        dynamicOffset += property.size;\n        this.dynamicStride += property.size;\n    }\n\n    this.dynamicData = new Float32Array( this.size * this.dynamicStride * 4);\n    this.dynamicBuffer = gl.createBuffer();\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, this.dynamicData, gl.DYNAMIC_DRAW);\n\n\n    // static //\n    var staticOffset = 0;\n    this.staticStride = 0;\n\n    for (i = 0; i < this.staticProperties.length; i++)\n    {\n        property = this.staticProperties[i];\n\n        property.offset = staticOffset;\n        staticOffset += property.size;\n        this.staticStride += property.size;\n    }\n\n    this.staticData = new Float32Array( this.size * this.staticStride * 4);\n    this.staticBuffer = gl.createBuffer();\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, this.staticData, gl.DYNAMIC_DRAW);\n};\n\n/**\n * Uploads the dynamic properties.\n *\n */\nParticleBuffer.prototype.uploadDynamic = function(children, startIndex, amount)\n{\n    var gl = this.gl;\n\n    for (var i = 0; i < this.dynamicProperties.length; i++)\n    {\n        var property = this.dynamicProperties[i];\n        property.uploadFunction(children, startIndex, amount, this.dynamicData, this.dynamicStride, property.offset);\n    }\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer);\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.dynamicData);\n};\n\n/**\n * Uploads the static properties.\n *\n */\nParticleBuffer.prototype.uploadStatic = function(children, startIndex, amount)\n{\n    var gl = this.gl;\n\n    for (var i = 0; i < this.staticProperties.length; i++)\n    {\n        var property = this.staticProperties[i];\n        property.uploadFunction(children, startIndex, amount, this.staticData, this.staticStride, property.offset);\n    }\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer);\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.staticData);\n};\n\n/**\n * Binds the buffers to the GPU\n *\n */\nParticleBuffer.prototype.bind = function ()\n{\n    var gl = this.gl;\n    var i, property;\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer);\n\n    for (i = 0; i < this.dynamicProperties.length; i++)\n    {\n        property = this.dynamicProperties[i];\n        gl.vertexAttribPointer(property.attribute, property.size, gl.FLOAT, false, this.dynamicStride * 4, property.offset * 4);\n    }\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer);\n\n    for (i = 0; i < this.staticProperties.length; i++)\n    {\n        property = this.staticProperties[i];\n        gl.vertexAttribPointer(property.attribute, property.size, gl.FLOAT, false, this.staticStride * 4, property.offset * 4);\n    }\n};\n\n/**\n * Destroys the ParticleBuffer.\n *\n */\nParticleBuffer.prototype.destroy = function ()\n{\n    this.dynamicProperties = null;\n    this.dynamicData = null;\n    this.gl.deleteBuffer(this.dynamicBuffer);\n\n    this.staticProperties = null;\n    this.staticData = null;\n    this.gl.deleteBuffer(this.staticBuffer);\n};\n\n},{}],41:[function(require,module,exports){\nvar ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'),\n    WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'),\n    ParticleShader = require('./ParticleShader'),\n    ParticleBuffer = require('./ParticleBuffer'),\n    math            = require('../../math');\n\n/**\n * @author Mat Groves\n *\n * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/\n * for creating the original pixi version!\n * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer\n *\n * Heavily inspired by LibGDX's ParticleRenderer:\n * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleRenderer.java\n */\n\n/**\n *\n * @class\n * @private\n * @memberof PIXI\n * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for.\n */\nfunction ParticleRenderer(renderer)\n{\n    ObjectRenderer.call(this, renderer);\n\n    // 65535 is max vertex index in the index buffer (see ParticleRenderer)\n    // so max number of particles is 65536 / 4 = 16384\n    // and max number of element in the index buffer is 16384 * 6 = 98304\n    // Creating a full index buffer, overhead is 98304 * 2 = 196Ko\n    var numIndices = 98304;\n\n    /**\n     * Holds the indices\n     *\n     * @member {Uint16Array}\n     */\n    this.indices = new Uint16Array(numIndices);\n\n    for (var i=0, j=0; i < numIndices; i += 6, j += 4)\n    {\n        this.indices[i + 0] = j + 0;\n        this.indices[i + 1] = j + 1;\n        this.indices[i + 2] = j + 2;\n        this.indices[i + 3] = j + 0;\n        this.indices[i + 4] = j + 2;\n        this.indices[i + 5] = j + 3;\n    }\n\n    /**\n     * The default shader that is used if a sprite doesn't have a more specific one.\n     *\n     * @member {PIXI.Shader}\n     */\n    this.shader = null;\n\n    this.indexBuffer = null;\n\n    this.properties = null;\n\n    this.tempMatrix = new math.Matrix();\n}\n\nParticleRenderer.prototype = Object.create(ObjectRenderer.prototype);\nParticleRenderer.prototype.constructor = ParticleRenderer;\nmodule.exports = ParticleRenderer;\n\nWebGLRenderer.registerPlugin('particle', ParticleRenderer);\n\n/**\n * When there is a WebGL context change\n *\n * @private\n */\nParticleRenderer.prototype.onContextChange = function ()\n{\n    var gl = this.renderer.gl;\n\n    // setup default shader\n    this.shader = new ParticleShader(this.renderer.shaderManager);\n\n    this.indexBuffer = gl.createBuffer();\n\n    // 65535 is max index, so 65535 / 6 = 10922.\n\n    //upload the index data\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);\n\n    this.properties = [\n        // verticesData\n        {\n            attribute:this.shader.attributes.aVertexPosition,\n            size:2,\n            uploadFunction:this.uploadVertices,\n            offset:0\n        },\n        // positionData\n        {\n            attribute:this.shader.attributes.aPositionCoord,\n            size:2,\n            uploadFunction:this.uploadPosition,\n            offset:0\n        },\n        // rotationData\n        {\n            attribute:this.shader.attributes.aRotation,\n            size:1,\n            uploadFunction:this.uploadRotation,\n            offset:0\n        },\n        // uvsData\n        {\n            attribute:this.shader.attributes.aTextureCoord,\n            size:2,\n            uploadFunction:this.uploadUvs,\n            offset:0\n        },\n        // alphaData\n        {\n            attribute:this.shader.attributes.aColor,\n            size:1,\n            uploadFunction:this.uploadAlpha,\n            offset:0\n        }\n    ];\n};\n\n/**\n * Starts a new particle batch.\n *\n */\nParticleRenderer.prototype.start = function ()\n{\n    var gl = this.renderer.gl;\n\n    // bind the main texture\n    gl.activeTexture(gl.TEXTURE0);\n\n    // bind the buffers\n\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n\n    var shader = this.shader;\n\n    this.renderer.shaderManager.setShader(shader);\n};\n\n\n/**\n * Renders the particle container object.\n *\n * @param container {PIXI.ParticleContainer} The container to render using this ParticleRenderer\n */\nParticleRenderer.prototype.render = function (container)\n{\n    var children = container.children,\n        totalChildren = children.length,\n        maxSize = container._maxSize,\n        batchSize = container._batchSize;\n\n    if(totalChildren === 0)\n    {\n        return;\n    }\n    else if(totalChildren > maxSize)\n    {\n        totalChildren = maxSize;\n    }\n\n    if(!container._buffers)\n    {\n        container._buffers = this.generateBuffers( container );\n    }\n\n    // if the uvs have not updated then no point rendering just yet!\n    this.renderer.blendModeManager.setBlendMode(container.blendMode);\n\n    var gl = this.renderer.gl;\n\n    var m =  container.worldTransform.copy( this.tempMatrix );\n    m.prepend( this.renderer.currentRenderTarget.projectionMatrix );\n    gl.uniformMatrix3fv(this.shader.uniforms.projectionMatrix._location, false, m.toArray(true));\n    gl.uniform1f(this.shader.uniforms.uAlpha._location, container.worldAlpha);\n\n\n    // make sure the texture is bound..\n    var baseTexture = children[0]._texture.baseTexture;\n\n    if (!baseTexture._glTextures[gl.id])\n    {\n        // if the texture has not updated then lets not upload any static properties\n        if(!this.renderer.updateTexture(baseTexture))\n        {\n            return;\n        }\n\n        if(!container._properties[0] || !container._properties[3])\n        {\n            container._bufferToUpdate = 0;\n        }\n    }\n    else\n    {\n        gl.bindTexture(gl.TEXTURE_2D, baseTexture._glTextures[gl.id]);\n    }\n\n    // now lets upload and render the buffers..\n    for (var i = 0, j = 0; i < totalChildren; i += batchSize, j += 1)\n    {\n        var amount = ( totalChildren - i);\n        if(amount > batchSize)\n        {\n            amount = batchSize;\n        }\n\n        var buffer = container._buffers[j];\n\n        // we always upload the dynamic\n        buffer.uploadDynamic(children, i, amount);\n\n        // we only upload the static content when we have to!\n        if(container._bufferToUpdate === j)\n        {\n            buffer.uploadStatic(children, i, amount);\n            container._bufferToUpdate = j + 1;\n        }\n\n        // bind the buffer\n        buffer.bind( this.shader );\n\n         // now draw those suckas!\n        gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0);\n        this.renderer.drawCount++;\n    }\n};\n\n/**\n * Creates one particle buffer for each child in the container we want to render and updates internal properties\n *\n * @param container {PIXI.ParticleContainer} The container to render using this ParticleRenderer\n */\nParticleRenderer.prototype.generateBuffers = function (container)\n{\n    var gl = this.renderer.gl,\n        buffers = [],\n        size = container._maxSize,\n        batchSize = container._batchSize,\n        dynamicPropertyFlags = container._properties,\n        i;\n\n    for (i = 0; i < size; i += batchSize)\n    {\n        buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize));\n    }\n\n    return buffers;\n};\n\n/**\n * Uploads the verticies.\n *\n * @param children {PIXI.DisplayObject[]} the array of display objects to render\n * @param startIndex {number} the index to start from in the children array\n * @param amount {number} the amount of children that will have their vertices uploaded\n * @param array {number[]}\n * @param stride {number}\n * @param offset {number}\n */\nParticleRenderer.prototype.uploadVertices = function (children, startIndex, amount, array, stride, offset)\n{\n    var sprite,\n        texture,\n        trim,\n        sx,\n        sy,\n        w0, w1, h0, h1;\n\n    for (var i = 0; i < amount; i++) {\n\n        sprite = children[startIndex + i];\n        texture = sprite._texture;\n        sx = sprite.scale.x;\n        sy = sprite.scale.y;\n\n        if (texture.trim)\n        {\n            // if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..\n            trim = texture.trim;\n\n            w1 = trim.x - sprite.anchor.x * trim.width;\n            w0 = w1 + texture.crop.width;\n\n            h1 = trim.y - sprite.anchor.y * trim.height;\n            h0 = h1 + texture.crop.height;\n        }\n        else\n        {\n            w0 = (texture._frame.width ) * (1-sprite.anchor.x);\n            w1 = (texture._frame.width ) * -sprite.anchor.x;\n\n            h0 = texture._frame.height * (1-sprite.anchor.y);\n            h1 = texture._frame.height * -sprite.anchor.y;\n        }\n\n        array[offset] = w1 * sx;\n        array[offset + 1] = h1 * sy;\n\n        array[offset + stride] = w0 * sx;\n        array[offset + stride + 1] = h1 * sy;\n\n        array[offset + stride * 2] = w0 * sx;\n        array[offset + stride * 2 + 1] = h0 * sy;\n\n        array[offset + stride * 3] = w1 * sx;\n        array[offset + stride * 3 + 1] = h0 * sy;\n\n        offset += stride * 4;\n    }\n\n};\n\n/**\n *\n * @param children {PIXI.DisplayObject[]} the array of display objects to render\n * @param startIndex {number} the index to start from in the children array\n * @param amount {number} the amount of children that will have their positions uploaded\n * @param array {number[]}\n * @param stride {number}\n * @param offset {number}\n */\nParticleRenderer.prototype.uploadPosition = function (children,startIndex, amount, array, stride, offset)\n{\n    for (var i = 0; i < amount; i++)\n    {\n        var spritePosition = children[startIndex + i].position;\n\n        array[offset] = spritePosition.x;\n        array[offset + 1] = spritePosition.y;\n\n        array[offset + stride] = spritePosition.x;\n        array[offset + stride + 1] = spritePosition.y;\n\n        array[offset + stride * 2] = spritePosition.x;\n        array[offset + stride * 2 + 1] = spritePosition.y;\n\n        array[offset + stride * 3] = spritePosition.x;\n        array[offset + stride * 3 + 1] = spritePosition.y;\n\n        offset += stride * 4;\n    }\n\n};\n\n/**\n *\n * @param children {PIXI.DisplayObject[]} the array of display objects to render\n * @param startIndex {number} the index to start from in the children array\n * @param amount {number} the amount of children that will have their rotation uploaded\n * @param array {number[]}\n * @param stride {number}\n * @param offset {number}\n */\nParticleRenderer.prototype.uploadRotation = function (children,startIndex, amount, array, stride, offset)\n{\n    for (var i = 0; i < amount; i++)\n    {\n        var spriteRotation = children[startIndex + i].rotation;\n\n\n        array[offset] = spriteRotation;\n        array[offset + stride] = spriteRotation;\n        array[offset + stride * 2] = spriteRotation;\n        array[offset + stride * 3] = spriteRotation;\n\n        offset += stride * 4;\n    }\n};\n\n/**\n *\n * @param children {PIXI.DisplayObject[]} the array of display objects to render\n * @param startIndex {number} the index to start from in the children array\n * @param amount {number} the amount of children that will have their Uvs uploaded\n * @param array {number[]}\n * @param stride {number}\n * @param offset {number}\n */\nParticleRenderer.prototype.uploadUvs = function (children,startIndex, amount, array, stride, offset)\n{\n    for (var i = 0; i < amount; i++)\n    {\n        var textureUvs = children[startIndex + i]._texture._uvs;\n\n        if (textureUvs)\n        {\n            array[offset] = textureUvs.x0;\n            array[offset + 1] = textureUvs.y0;\n\n            array[offset + stride] = textureUvs.x1;\n            array[offset + stride + 1] = textureUvs.y1;\n\n            array[offset + stride * 2] = textureUvs.x2;\n            array[offset + stride * 2 + 1] = textureUvs.y2;\n\n            array[offset + stride * 3] = textureUvs.x3;\n            array[offset + stride * 3 + 1] = textureUvs.y3;\n\n            offset += stride * 4;\n        }\n        else\n        {\n            //TODO you know this can be easier!\n            array[offset] = 0;\n            array[offset + 1] = 0;\n\n            array[offset + stride] = 0;\n            array[offset + stride + 1] = 0;\n\n            array[offset + stride * 2] = 0;\n            array[offset + stride * 2 + 1] = 0;\n\n            array[offset + stride * 3] = 0;\n            array[offset + stride * 3 + 1] = 0;\n\n            offset += stride * 4;\n        }\n    }\n};\n\n/**\n *\n * @param children {PIXI.DisplayObject[]} the array of display objects to render\n * @param startIndex {number} the index to start from in the children array\n * @param amount {number} the amount of children that will have their alpha uploaded\n * @param array {number[]}\n * @param stride {number}\n * @param offset {number}\n */\nParticleRenderer.prototype.uploadAlpha = function (children,startIndex, amount, array, stride, offset)\n{\n     for (var i = 0; i < amount; i++)\n     {\n        var spriteAlpha = children[startIndex + i].alpha;\n\n        array[offset] = spriteAlpha;\n        array[offset + stride] = spriteAlpha;\n        array[offset + stride * 2] = spriteAlpha;\n        array[offset + stride * 3] = spriteAlpha;\n\n        offset += stride * 4;\n    }\n};\n\n\n/**\n * Destroys the ParticleRenderer.\n *\n */\nParticleRenderer.prototype.destroy = function ()\n{\n    if (this.renderer.gl) {\n        this.renderer.gl.deleteBuffer(this.indexBuffer);\n    }\n\n    ObjectRenderer.prototype.destroy.apply(this, arguments);\n\n    this.shader.destroy();\n\n    this.indices = null;\n    this.tempMatrix = null;\n};\n\n},{\"../../math\":33,\"../../renderers/webgl/WebGLRenderer\":49,\"../../renderers/webgl/utils/ObjectRenderer\":63,\"./ParticleBuffer\":40,\"./ParticleShader\":42}],42:[function(require,module,exports){\nvar TextureShader = require('../../renderers/webgl/shaders/TextureShader');\n\n/**\n * @class\n * @extends PIXI.TextureShader\n * @memberof PIXI\n * @param shaderManager {ShaderManager} The webgl shader manager this shader works for.\n */\nfunction ParticleShader(shaderManager)\n{\n    TextureShader.call(this,\n        shaderManager,\n        // vertex shader\n        [\n            'attribute vec2 aVertexPosition;',\n            'attribute vec2 aTextureCoord;',\n            'attribute float aColor;',\n\n            'attribute vec2 aPositionCoord;',\n            'attribute vec2 aScale;',\n            'attribute float aRotation;',\n\n            'uniform mat3 projectionMatrix;',\n\n            'varying vec2 vTextureCoord;',\n            'varying float vColor;',\n\n            'void main(void){',\n            '   vec2 v = aVertexPosition;',\n\n            '   v.x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);',\n            '   v.y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);',\n            '   v = v + aPositionCoord;',\n\n            '   gl_Position = vec4((projectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);',\n\n            '   vTextureCoord = aTextureCoord;',\n            '   vColor = aColor;',\n            '}'\n        ].join('\\n'),\n        // hello\n         [\n            'precision lowp float;',\n\n            'varying vec2 vTextureCoord;',\n            'varying float vColor;',\n\n            'uniform sampler2D uSampler;',\n            'uniform float uAlpha;',\n\n            'void main(void){',\n            '  vec4 color = texture2D(uSampler, vTextureCoord) * vColor * uAlpha;',\n            '  if (color.a == 0.0) discard;',\n            '  gl_FragColor = color;',\n            '}'\n        ].join('\\n'),\n        // custom uniforms\n        {\n            uAlpha:  { type: '1f', value: 1 }\n        },\n        // custom attributes\n        {\n            aPositionCoord: 0,\n           // aScale:         0,\n            aRotation:      0\n        }\n    );\n\n    // TEMP HACK\n\n}\n\nParticleShader.prototype = Object.create(TextureShader.prototype);\nParticleShader.prototype.constructor = ParticleShader;\n\nmodule.exports = ParticleShader;\n\n},{\"../../renderers/webgl/shaders/TextureShader\":62}],43:[function(require,module,exports){\nvar utils = require('../utils'),\n    math = require('../math'),\n    CONST = require('../const'),\n    EventEmitter = require('eventemitter3');\n\n/**\n * The CanvasRenderer draws the scene and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.\n * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)\n *\n * @class\n * @memberof PIXI\n * @param system {string} The name of the system this renderer is for.\n * @param [width=800] {number} the width of the canvas view\n * @param [height=600] {number} the height of the canvas view\n * @param [options] {object} The optional renderer parameters\n * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional\n * @param [options.transparent=false] {boolean} If the render view is transparent, default false\n * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false\n * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)\n * @param [options.resolution=1] {number} the resolution of the renderer retina would be 2\n * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or\n *      not before the new render pass.\n * @param [options.backgroundColor=0x000000] {number} The background color of the rendered area (shown if not transparent).\n * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.\n */\nfunction SystemRenderer(system, width, height, options)\n{\n    EventEmitter.call(this);\n\n    utils.sayHello(system);\n\n    // prepare options\n    if (options)\n    {\n        for (var i in CONST.DEFAULT_RENDER_OPTIONS)\n        {\n            if (typeof options[i] === 'undefined')\n            {\n                options[i] = CONST.DEFAULT_RENDER_OPTIONS[i];\n            }\n        }\n    }\n    else\n    {\n        options = CONST.DEFAULT_RENDER_OPTIONS;\n    }\n\n    /**\n     * The type of the renderer.\n     *\n     * @member {number}\n     * @default PIXI.RENDERER_TYPE.UNKNOWN\n     * @see PIXI.RENDERER_TYPE\n     */\n    this.type = CONST.RENDERER_TYPE.UNKNOWN;\n\n    /**\n     * The width of the canvas view\n     *\n     * @member {number}\n     * @default 800\n     */\n    this.width = width || 800;\n\n    /**\n     * The height of the canvas view\n     *\n     * @member {number}\n     * @default 600\n     */\n    this.height = height || 600;\n\n    /**\n     * The canvas element that everything is drawn to\n     *\n     * @member {HTMLCanvasElement}\n     */\n    this.view = options.view || document.createElement('canvas');\n\n    /**\n     * The resolution of the renderer\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.resolution = options.resolution;\n\n    /**\n     * Whether the render view is transparent\n     *\n     * @member {boolean}\n     */\n    this.transparent = options.transparent;\n\n    /**\n     * Whether the render view should be resized automatically\n     *\n     * @member {boolean}\n     */\n    this.autoResize = options.autoResize || false;\n\n    /**\n     * Tracks the blend modes useful for this renderer.\n     *\n     * @member {object<string, mixed>}\n     */\n    this.blendModes = null;\n\n    /**\n     * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering.\n     *\n     * @member {boolean}\n     */\n    this.preserveDrawingBuffer = options.preserveDrawingBuffer;\n\n    /**\n     * This sets if the CanvasRenderer will clear the canvas or not before the new render pass.\n     * If the scene is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.\n     * If the scene is transparent Pixi will use clearRect to clear the canvas every frame.\n     * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.\n     *\n     * @member {boolean}\n     * @default\n     */\n    this.clearBeforeRender = options.clearBeforeRender;\n\n    /**\n     * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.\n     * Handy for crisp pixel art and speed on legacy devices.\n     *\n     * @member {boolean}\n     */\n    this.roundPixels = options.roundPixels;\n\n    /**\n     * The background color as a number.\n     *\n     * @member {number}\n     * @private\n     */\n    this._backgroundColor = 0x000000;\n\n    /**\n     * The background color as an [R, G, B] array.\n     *\n     * @member {number[]}\n     * @private\n     */\n    this._backgroundColorRgb = [0, 0, 0];\n\n    /**\n     * The background color as a string.\n     *\n     * @member {string}\n     * @private\n     */\n    this._backgroundColorString = '#000000';\n\n    this.backgroundColor = options.backgroundColor || this._backgroundColor; // run bg color setter\n\n    /**\n     * This temporary display object used as the parent of the currently being rendered item\n     *\n     * @member {PIXI.DisplayObject}\n     * @private\n     */\n    this._tempDisplayObjectParent = {worldTransform:new math.Matrix(), worldAlpha:1, children:[]};\n\n    /**\n     * The last root object that the renderer tried to render.\n     *\n     * @member {PIXI.DisplayObject}\n     * @private\n     */\n    this._lastObjectRendered = this._tempDisplayObjectParent;\n}\n\n// constructor\nSystemRenderer.prototype = Object.create(EventEmitter.prototype);\nSystemRenderer.prototype.constructor = SystemRenderer;\nmodule.exports = SystemRenderer;\n\nObject.defineProperties(SystemRenderer.prototype, {\n    /**\n     * The background color to fill if not transparent\n     *\n     * @member {number}\n     * @memberof PIXI.SystemRenderer#\n     */\n    backgroundColor:\n    {\n        get: function ()\n        {\n            return this._backgroundColor;\n        },\n        set: function (val)\n        {\n            this._backgroundColor = val;\n            this._backgroundColorString = utils.hex2string(val);\n            utils.hex2rgb(val, this._backgroundColorRgb);\n        }\n    }\n});\n\n/**\n * Resizes the canvas view to the specified width and height\n *\n * @param width {number} the new width of the canvas view\n * @param height {number} the new height of the canvas view\n */\nSystemRenderer.prototype.resize = function (width, height) {\n    this.width = width * this.resolution;\n    this.height = height * this.resolution;\n\n    this.view.width = this.width;\n    this.view.height = this.height;\n\n    if (this.autoResize)\n    {\n        this.view.style.width = this.width / this.resolution + 'px';\n        this.view.style.height = this.height / this.resolution + 'px';\n    }\n};\n\n/**\n * Removes everything from the renderer and optionally removes the Canvas DOM element.\n *\n * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.\n */\nSystemRenderer.prototype.destroy = function (removeView) {\n    if (removeView && this.view.parentNode)\n    {\n        this.view.parentNode.removeChild(this.view);\n    }\n\n    this.type = CONST.RENDERER_TYPE.UNKNOWN;\n\n    this.width = 0;\n    this.height = 0;\n\n    this.view = null;\n\n    this.resolution = 0;\n\n    this.transparent = false;\n\n    this.autoResize = false;\n\n    this.blendModes = null;\n\n    this.preserveDrawingBuffer = false;\n    this.clearBeforeRender = false;\n\n    this.roundPixels = false;\n\n    this._backgroundColor = 0;\n    this._backgroundColorRgb = null;\n    this._backgroundColorString = null;\n};\n\n},{\"../const\":22,\"../math\":33,\"../utils\":77,\"eventemitter3\":10}],44:[function(require,module,exports){\nvar SystemRenderer = require('../SystemRenderer'),\n    CanvasMaskManager = require('./utils/CanvasMaskManager'),\n    utils = require('../../utils'),\n    math = require('../../math'),\n    CONST = require('../../const');\n\n/**\n * The CanvasRenderer draws the scene and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.\n * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)\n *\n * @class\n * @memberof PIXI\n * @extends PIXI.SystemRenderer\n * @param [width=800] {number} the width of the canvas view\n * @param [height=600] {number} the height of the canvas view\n * @param [options] {object} The optional renderer parameters\n * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional\n * @param [options.transparent=false] {boolean} If the render view is transparent, default false\n * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false\n * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)\n * @param [options.resolution=1] {number} the resolution of the renderer retina would be 2\n * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or\n *      not before the new render pass.\n * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.\n */\nfunction CanvasRenderer(width, height, options)\n{\n    options = options || {};\n\n    SystemRenderer.call(this, 'Canvas', width, height, options);\n\n    this.type = CONST.RENDERER_TYPE.CANVAS;\n\n    /**\n     * The canvas 2d context that everything is drawn with.\n     *\n     * @member {CanvasRenderingContext2D}\n     */\n    this.context = this.view.getContext('2d', { alpha: this.transparent });\n\n    /**\n     * Boolean flag controlling canvas refresh.\n     *\n     * @member {boolean}\n     */\n    this.refresh = true;\n\n    /**\n     * Instance of a CanvasMaskManager, handles masking when using the canvas renderer.\n     *\n     * @member {PIXI.CanvasMaskManager}\n     */\n    this.maskManager = new CanvasMaskManager();\n\n    /**\n     * The canvas property used to set the canvas smoothing property.\n     *\n     * @member {string}\n     */\n    this.smoothProperty = 'imageSmoothingEnabled';\n\n    if (!this.context.imageSmoothingEnabled)\n    {\n        if (this.context.webkitImageSmoothingEnabled)\n        {\n            this.smoothProperty = 'webkitImageSmoothingEnabled';\n        }\n        else if (this.context.mozImageSmoothingEnabled)\n        {\n            this.smoothProperty = 'mozImageSmoothingEnabled';\n        }\n        else if (this.context.oImageSmoothingEnabled)\n        {\n            this.smoothProperty = 'oImageSmoothingEnabled';\n        }\n        else if (this.context.msImageSmoothingEnabled)\n        {\n            this.smoothProperty = 'msImageSmoothingEnabled';\n        }\n    }\n\n    this.initPlugins();\n\n    this._mapBlendModes();\n\n    /**\n     * This temporary display object used as the parent of the currently being rendered item\n     *\n     * @member {PIXI.DisplayObject}\n     * @private\n     */\n    this._tempDisplayObjectParent = {\n        worldTransform: new math.Matrix(),\n        worldAlpha: 1\n    };\n\n\n    this.resize(width, height);\n}\n\n// constructor\nCanvasRenderer.prototype = Object.create(SystemRenderer.prototype);\nCanvasRenderer.prototype.constructor = CanvasRenderer;\nmodule.exports = CanvasRenderer;\nutils.pluginTarget.mixin(CanvasRenderer);\n\n/**\n * Renders the object to this canvas view\n *\n * @param object {PIXI.DisplayObject} the object to be rendered\n */\nCanvasRenderer.prototype.render = function (object)\n{\n    this.emit('prerender');\n\n    var cacheParent = object.parent;\n\n    this._lastObjectRendered = object;\n\n    object.parent = this._tempDisplayObjectParent;\n\n    // update the scene graph\n    object.updateTransform();\n\n    object.parent = cacheParent;\n\n    this.context.setTransform(1, 0, 0, 1, 0, 0);\n\n    this.context.globalAlpha = 1;\n\n    this.context.globalCompositeOperation = this.blendModes[CONST.BLEND_MODES.NORMAL];\n\n    if (navigator.isCocoonJS && this.view.screencanvas)\n    {\n        this.context.fillStyle = 'black';\n        this.context.clear();\n    }\n\n    if (this.clearBeforeRender)\n    {\n        if (this.transparent)\n        {\n            this.context.clearRect(0, 0, this.width, this.height);\n        }\n        else\n        {\n            this.context.fillStyle = this._backgroundColorString;\n            this.context.fillRect(0, 0, this.width , this.height);\n        }\n    }\n\n    this.renderDisplayObject(object, this.context);\n\n    this.emit('postrender');\n};\n\n/**\n * Removes everything from the renderer and optionally removes the Canvas DOM element.\n *\n * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.\n */\nCanvasRenderer.prototype.destroy = function (removeView)\n{\n    this.destroyPlugins();\n\n    // call the base destroy\n    SystemRenderer.prototype.destroy.call(this, removeView);\n\n    this.context = null;\n\n    this.refresh = true;\n\n    this.maskManager.destroy();\n    this.maskManager = null;\n\n    this.smoothProperty = null;\n};\n\n/**\n * Renders a display object\n *\n * @param displayObject {PIXI.DisplayObject} The displayObject to render\n * @private\n */\nCanvasRenderer.prototype.renderDisplayObject = function (displayObject, context)\n{\n    var tempContext = this.context;\n\n    this.context = context;\n    displayObject.renderCanvas(this);\n    this.context = tempContext;\n};\n\n/**\n * @extends PIXI.SystemRenderer#resize\n *\n * @param {number} w\n * @param {number} h\n */\nCanvasRenderer.prototype.resize = function (w, h)\n{\n    SystemRenderer.prototype.resize.call(this, w, h);\n\n    //reset the scale mode.. oddly this seems to be reset when the canvas is resized.\n    //surely a browser bug?? Let pixi fix that for you..\n    if(this.smoothProperty)\n    {\n        this.context[this.smoothProperty] = (CONST.SCALE_MODES.DEFAULT === CONST.SCALE_MODES.LINEAR);\n    }\n\n};\n\n/**\n * Maps Pixi blend modes to canvas blend modes.\n *\n * @private\n */\nCanvasRenderer.prototype._mapBlendModes = function ()\n{\n    if (!this.blendModes)\n    {\n        this.blendModes = {};\n\n        if (utils.canUseNewCanvasBlendModes())\n        {\n            this.blendModes[CONST.BLEND_MODES.NORMAL]        = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.ADD]           = 'lighter'; //IS THIS OK???\n            this.blendModes[CONST.BLEND_MODES.MULTIPLY]      = 'multiply';\n            this.blendModes[CONST.BLEND_MODES.SCREEN]        = 'screen';\n            this.blendModes[CONST.BLEND_MODES.OVERLAY]       = 'overlay';\n            this.blendModes[CONST.BLEND_MODES.DARKEN]        = 'darken';\n            this.blendModes[CONST.BLEND_MODES.LIGHTEN]       = 'lighten';\n            this.blendModes[CONST.BLEND_MODES.COLOR_DODGE]   = 'color-dodge';\n            this.blendModes[CONST.BLEND_MODES.COLOR_BURN]    = 'color-burn';\n            this.blendModes[CONST.BLEND_MODES.HARD_LIGHT]    = 'hard-light';\n            this.blendModes[CONST.BLEND_MODES.SOFT_LIGHT]    = 'soft-light';\n            this.blendModes[CONST.BLEND_MODES.DIFFERENCE]    = 'difference';\n            this.blendModes[CONST.BLEND_MODES.EXCLUSION]     = 'exclusion';\n            this.blendModes[CONST.BLEND_MODES.HUE]           = 'hue';\n            this.blendModes[CONST.BLEND_MODES.SATURATION]    = 'saturate';\n            this.blendModes[CONST.BLEND_MODES.COLOR]         = 'color';\n            this.blendModes[CONST.BLEND_MODES.LUMINOSITY]    = 'luminosity';\n        }\n        else\n        {\n            // this means that the browser does not support the cool new blend modes in canvas 'cough' ie 'cough'\n            this.blendModes[CONST.BLEND_MODES.NORMAL]        = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.ADD]           = 'lighter'; //IS THIS OK???\n            this.blendModes[CONST.BLEND_MODES.MULTIPLY]      = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.SCREEN]        = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.OVERLAY]       = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.DARKEN]        = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.LIGHTEN]       = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.COLOR_DODGE]   = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.COLOR_BURN]    = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.HARD_LIGHT]    = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.SOFT_LIGHT]    = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.DIFFERENCE]    = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.EXCLUSION]     = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.HUE]           = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.SATURATION]    = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.COLOR]         = 'source-over';\n            this.blendModes[CONST.BLEND_MODES.LUMINOSITY]    = 'source-over';\n        }\n    }\n};\n\n},{\"../../const\":22,\"../../math\":33,\"../../utils\":77,\"../SystemRenderer\":43,\"./utils/CanvasMaskManager\":47}],45:[function(require,module,exports){\n/**\n * Creates a Canvas element of the given size.\n *\n * @class\n * @memberof PIXI\n * @param width {number} the width for the newly created canvas\n * @param height {number} the height for the newly created canvas\n */\nfunction CanvasBuffer(width, height)\n{\n    /**\n     * The Canvas object that belongs to this CanvasBuffer.\n     *\n     * @member {HTMLCanvasElement}\n     */\n    this.canvas = document.createElement('canvas');\n\n    /**\n     * A CanvasRenderingContext2D object representing a two-dimensional rendering context.\n     *\n     * @member {CanvasRenderingContext2D}\n     */\n    this.context = this.canvas.getContext('2d');\n\n    this.canvas.width = width;\n    this.canvas.height = height;\n}\n\nCanvasBuffer.prototype.constructor = CanvasBuffer;\nmodule.exports = CanvasBuffer;\n\nObject.defineProperties(CanvasBuffer.prototype, {\n    /**\n     * The width of the canvas buffer in pixels.\n     *\n     * @member {number}\n     * @memberof PIXI.CanvasBuffer#\n     */\n    width: {\n        get: function ()\n        {\n            return this.canvas.width;\n        },\n        set: function (val)\n        {\n            this.canvas.width = val;\n        }\n    },\n    /**\n     * The height of the canvas buffer in pixels.\n     *\n     * @member {number}\n     * @memberof PIXI.CanvasBuffer#\n     */\n    height: {\n        get: function ()\n        {\n            return this.canvas.height;\n        },\n        set: function (val)\n        {\n            this.canvas.height = val;\n        }\n    }\n});\n\n/**\n * Clears the canvas that was created by the CanvasBuffer class.\n *\n * @private\n */\nCanvasBuffer.prototype.clear = function ()\n{\n    this.context.setTransform(1, 0, 0, 1, 0, 0);\n    this.context.clearRect(0,0, this.canvas.width, this.canvas.height);\n};\n\n/**\n * Resizes the canvas to the specified width and height.\n *\n * @param width {number} the new width of the canvas\n * @param height {number} the new height of the canvas\n */\nCanvasBuffer.prototype.resize = function (width, height)\n{\n    this.canvas.width = width;\n    this.canvas.height = height;\n};\n\n/**\n * Destroys this canvas.\n *\n */\nCanvasBuffer.prototype.destroy = function ()\n{\n    this.context = null;\n    this.canvas = null;\n};\n\n},{}],46:[function(require,module,exports){\nvar CONST = require('../../../const');\n\n/**\n * A set of functions used by the canvas renderer to draw the primitive graphics data.\n * @static\n * @class\n * @memberof PIXI\n */\nvar CanvasGraphics = {};\nmodule.exports = CanvasGraphics;\n\n/*\n * Renders a Graphics object to a canvas.\n *\n * @param graphics {PIXI.Graphics} the actual graphics object to render\n * @param context {CanvasRenderingContext2D} the 2d drawing method of the canvas\n */\nCanvasGraphics.renderGraphics = function (graphics, context)\n{\n    var worldAlpha = graphics.worldAlpha;\n\n    if (graphics.dirty)\n    {\n        this.updateGraphicsTint(graphics);\n        graphics.dirty = false;\n    }\n\n    for (var i = 0; i < graphics.graphicsData.length; i++)\n    {\n        var data = graphics.graphicsData[i];\n        var shape = data.shape;\n\n        var fillColor = data._fillTint;\n        var lineColor = data._lineTint;\n\n        context.lineWidth = data.lineWidth;\n\n        if (data.type === CONST.SHAPES.POLY)\n        {\n            context.beginPath();\n\n            var points = shape.points;\n\n            context.moveTo(points[0], points[1]);\n\n            for (var j=1; j < points.length/2; j++)\n            {\n                context.lineTo(points[j * 2], points[j * 2 + 1]);\n            }\n\n            if (shape.closed)\n            {\n                context.lineTo(points[0], points[1]);\n            }\n\n            // if the first and last point are the same close the path - much neater :)\n            if (points[0] === points[points.length-2] && points[1] === points[points.length-1])\n            {\n                context.closePath();\n            }\n\n            if (data.fill)\n            {\n                context.globalAlpha = data.fillAlpha * worldAlpha;\n                context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);\n                context.fill();\n            }\n            if (data.lineWidth)\n            {\n                context.globalAlpha = data.lineAlpha * worldAlpha;\n                context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);\n                context.stroke();\n            }\n        }\n        else if (data.type === CONST.SHAPES.RECT)\n        {\n\n            if (data.fillColor || data.fillColor === 0)\n            {\n                context.globalAlpha = data.fillAlpha * worldAlpha;\n                context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);\n                context.fillRect(shape.x, shape.y, shape.width, shape.height);\n\n            }\n            if (data.lineWidth)\n            {\n                context.globalAlpha = data.lineAlpha * worldAlpha;\n                context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);\n                context.strokeRect(shape.x, shape.y, shape.width, shape.height);\n            }\n        }\n        else if (data.type === CONST.SHAPES.CIRC)\n        {\n            // TODO - need to be Undefined!\n            context.beginPath();\n            context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI);\n            context.closePath();\n\n            if (data.fill)\n            {\n                context.globalAlpha = data.fillAlpha * worldAlpha;\n                context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);\n                context.fill();\n            }\n            if (data.lineWidth)\n            {\n                context.globalAlpha = data.lineAlpha * worldAlpha;\n                context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);\n                context.stroke();\n            }\n        }\n        else if (data.type === CONST.SHAPES.ELIP)\n        {\n            // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas\n\n            var w = shape.width * 2;\n            var h = shape.height * 2;\n\n            var x = shape.x - w/2;\n            var y = shape.y - h/2;\n\n            context.beginPath();\n\n            var kappa = 0.5522848,\n                ox = (w / 2) * kappa, // control point offset horizontal\n                oy = (h / 2) * kappa, // control point offset vertical\n                xe = x + w,           // x-end\n                ye = y + h,           // y-end\n                xm = x + w / 2,       // x-middle\n                ym = y + h / 2;       // y-middle\n\n            context.moveTo(x, ym);\n            context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);\n            context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);\n            context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);\n            context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);\n\n            context.closePath();\n\n            if (data.fill)\n            {\n                context.globalAlpha = data.fillAlpha * worldAlpha;\n                context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);\n                context.fill();\n            }\n            if (data.lineWidth)\n            {\n                context.globalAlpha = data.lineAlpha * worldAlpha;\n                context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);\n                context.stroke();\n            }\n        }\n        else if (data.type === CONST.SHAPES.RREC)\n        {\n            var rx = shape.x;\n            var ry = shape.y;\n            var width = shape.width;\n            var height = shape.height;\n            var radius = shape.radius;\n\n            var maxRadius = Math.min(width, height) / 2 | 0;\n            radius = radius > maxRadius ? maxRadius : radius;\n\n            context.beginPath();\n            context.moveTo(rx, ry + radius);\n            context.lineTo(rx, ry + height - radius);\n            context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);\n            context.lineTo(rx + width - radius, ry + height);\n            context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);\n            context.lineTo(rx + width, ry + radius);\n            context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);\n            context.lineTo(rx + radius, ry);\n            context.quadraticCurveTo(rx, ry, rx, ry + radius);\n            context.closePath();\n\n            if (data.fillColor || data.fillColor === 0)\n            {\n                context.globalAlpha = data.fillAlpha * worldAlpha;\n                context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);\n                context.fill();\n\n            }\n            if (data.lineWidth)\n            {\n                context.globalAlpha = data.lineAlpha * worldAlpha;\n                context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);\n                context.stroke();\n            }\n        }\n    }\n};\n\n/*\n * Renders a graphics mask\n *\n * @private\n * @param graphics {PIXI.Graphics} the graphics which will be used as a mask\n * @param context {CanvasRenderingContext2D} the context 2d method of the canvas\n */\nCanvasGraphics.renderGraphicsMask = function (graphics, context)\n{\n    var len = graphics.graphicsData.length;\n\n    if (len === 0)\n    {\n        return;\n    }\n\n    context.beginPath();\n\n    for (var i = 0; i < len; i++)\n    {\n        var data = graphics.graphicsData[i];\n        var shape = data.shape;\n\n        if (data.type === CONST.SHAPES.POLY)\n        {\n\n            var points = shape.points;\n\n            context.moveTo(points[0], points[1]);\n\n            for (var j=1; j < points.length/2; j++)\n            {\n                context.lineTo(points[j * 2], points[j * 2 + 1]);\n            }\n\n            // if the first and last point are the same close the path - much neater :)\n            if (points[0] === points[points.length-2] && points[1] === points[points.length-1])\n            {\n                context.closePath();\n            }\n\n        }\n        else if (data.type === CONST.SHAPES.RECT)\n        {\n            context.rect(shape.x, shape.y, shape.width, shape.height);\n            context.closePath();\n        }\n        else if (data.type === CONST.SHAPES.CIRC)\n        {\n            // TODO - need to be Undefined!\n            context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI);\n            context.closePath();\n        }\n        else if (data.type === CONST.SHAPES.ELIP)\n        {\n\n            // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas\n\n            var w = shape.width * 2;\n            var h = shape.height * 2;\n\n            var x = shape.x - w/2;\n            var y = shape.y - h/2;\n\n            var kappa = 0.5522848,\n                ox = (w / 2) * kappa, // control point offset horizontal\n                oy = (h / 2) * kappa, // control point offset vertical\n                xe = x + w,           // x-end\n                ye = y + h,           // y-end\n                xm = x + w / 2,       // x-middle\n                ym = y + h / 2;       // y-middle\n\n            context.moveTo(x, ym);\n            context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);\n            context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);\n            context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);\n            context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);\n            context.closePath();\n        }\n        else if (data.type === CONST.SHAPES.RREC)\n        {\n\n            var rx = shape.x;\n            var ry = shape.y;\n            var width = shape.width;\n            var height = shape.height;\n            var radius = shape.radius;\n\n            var maxRadius = Math.min(width, height) / 2 | 0;\n            radius = radius > maxRadius ? maxRadius : radius;\n\n            context.moveTo(rx, ry + radius);\n            context.lineTo(rx, ry + height - radius);\n            context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);\n            context.lineTo(rx + width - radius, ry + height);\n            context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);\n            context.lineTo(rx + width, ry + radius);\n            context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);\n            context.lineTo(rx + radius, ry);\n            context.quadraticCurveTo(rx, ry, rx, ry + radius);\n            context.closePath();\n        }\n    }\n};\n\n/*\n * Updates the tint of a graphics object\n *\n * @private\n * @param graphics {PIXI.Graphics} the graphics that will have its tint updated\n *\n */\nCanvasGraphics.updateGraphicsTint = function (graphics)\n{\n    if (graphics.tint === 0xFFFFFF && graphics._prevTint === graphics.tint)\n    {\n        return;\n    }\n    graphics._prevTint = graphics.tint;\n\n    var tintR = (graphics.tint >> 16 & 0xFF) / 255;\n    var tintG = (graphics.tint >> 8 & 0xFF) / 255;\n    var tintB = (graphics.tint & 0xFF)/ 255;\n\n    for (var i = 0; i < graphics.graphicsData.length; i++)\n    {\n        var data = graphics.graphicsData[i];\n\n        var fillColor = data.fillColor | 0;\n        var lineColor = data.lineColor | 0;\n\n        /*\n        var colorR = (fillColor >> 16 & 0xFF) / 255;\n        var colorG = (fillColor >> 8 & 0xFF) / 255;\n        var colorB = (fillColor & 0xFF) / 255;\n\n        colorR *= tintR;\n        colorG *= tintG;\n        colorB *= tintB;\n\n        fillColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255);\n\n        colorR = (lineColor >> 16 & 0xFF) / 255;\n        colorG = (lineColor >> 8 & 0xFF) / 255;\n        colorB = (lineColor & 0xFF) / 255;\n\n        colorR *= tintR;\n        colorG *= tintG;\n        colorB *= tintB;\n\n        lineColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255);\n        */\n\n        // super inline cos im an optimization NAZI :)\n        data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG*255 << 8) +  (fillColor & 0xFF) / 255 * tintB*255);\n        data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG*255 << 8) +  (lineColor & 0xFF) / 255 * tintB*255);\n\n    }\n};\n\n\n},{\"../../../const\":22}],47:[function(require,module,exports){\nvar CanvasGraphics = require('./CanvasGraphics');\n\n/**\n * A set of functions used to handle masking.\n *\n * @class\n * @memberof PIXI\n */\nfunction CanvasMaskManager()\n{}\n\nCanvasMaskManager.prototype.constructor = CanvasMaskManager;\nmodule.exports = CanvasMaskManager;\n\n/**\n * This method adds it to the current stack of masks.\n *\n * @param maskData {object} the maskData that will be pushed\n * @param renderer {PIXI.WebGLRenderer|PIXI.CanvasRenderer} The renderer context to use.\n */\nCanvasMaskManager.prototype.pushMask = function (maskData, renderer)\n{\n\n    renderer.context.save();\n\n    var cacheAlpha = maskData.alpha;\n    var transform = maskData.worldTransform;\n    var resolution = renderer.resolution;\n\n    renderer.context.setTransform(\n        transform.a * resolution,\n        transform.b * resolution,\n        transform.c * resolution,\n        transform.d * resolution,\n        transform.tx * resolution,\n        transform.ty * resolution\n    );\n\n    //TODO suport sprite alpha masks??\n    //lots of effort required. If demand is great enough..\n    if(!maskData.texture)\n    {\n        CanvasGraphics.renderGraphicsMask(maskData, renderer.context);\n        renderer.context.clip();\n    }\n\n    maskData.worldAlpha = cacheAlpha;\n};\n\n/**\n * Restores the current drawing context to the state it was before the mask was applied.\n *\n * @param renderer {PIXI.WebGLRenderer|PIXI.CanvasRenderer} The renderer context to use.\n */\nCanvasMaskManager.prototype.popMask = function (renderer)\n{\n    renderer.context.restore();\n};\n\nCanvasMaskManager.prototype.destroy = function () {};\n\n},{\"./CanvasGraphics\":46}],48:[function(require,module,exports){\nvar utils = require('../../../utils');\n\n/**\n * Utility methods for Sprite/Texture tinting.\n * @static\n * @class\n * @memberof PIXI\n */\nvar CanvasTinter = {};\nmodule.exports = CanvasTinter;\n\n/**\n * Basically this method just needs a sprite and a color and tints the sprite with the given color.\n *\n * @param sprite {PIXI.Sprite} the sprite to tint\n * @param color {number} the color to use to tint the sprite with\n * @return {HTMLCanvasElement} The tinted canvas\n */\nCanvasTinter.getTintedTexture = function (sprite, color)\n{\n    var texture = sprite.texture;\n\n    color = CanvasTinter.roundColor(color);\n\n    var stringColor = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);\n\n    texture.tintCache = texture.tintCache || {};\n\n    if (texture.tintCache[stringColor])\n    {\n        return texture.tintCache[stringColor];\n    }\n\n     // clone texture..\n    var canvas = CanvasTinter.canvas || document.createElement('canvas');\n\n    //CanvasTinter.tintWithPerPixel(texture, stringColor, canvas);\n    CanvasTinter.tintMethod(texture, color, canvas);\n\n    if (CanvasTinter.convertTintToImage)\n    {\n        // is this better?\n        var tintImage = new Image();\n        tintImage.src = canvas.toDataURL();\n\n        texture.tintCache[stringColor] = tintImage;\n    }\n    else\n    {\n        texture.tintCache[stringColor] = canvas;\n        // if we are not converting the texture to an image then we need to lose the reference to the canvas\n        CanvasTinter.canvas = null;\n    }\n\n    return canvas;\n};\n\n/**\n * Tint a texture using the 'multiply' operation.\n *\n * @param texture {PIXI.Texture} the texture to tint\n * @param color {number} the color to use to tint the sprite with\n * @param canvas {HTMLCanvasElement} the current canvas\n */\nCanvasTinter.tintWithMultiply = function (texture, color, canvas)\n{\n    var context = canvas.getContext( '2d' );\n\n    var resolution = texture.baseTexture.resolution;\n\n    var crop = texture.crop.clone();\n    crop.x *= resolution;\n    crop.y *= resolution;\n    crop.width *= resolution;\n    crop.height *= resolution;\n\n    canvas.width = crop.width;\n    canvas.height = crop.height;\n\n    context.fillStyle = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);\n\n    context.fillRect(0, 0, crop.width, crop.height);\n\n    context.globalCompositeOperation = 'multiply';\n\n    context.drawImage(\n        texture.baseTexture.source,\n        crop.x,\n        crop.y,\n        crop.width,\n        crop.height,\n        0,\n        0,\n        crop.width,\n        crop.height\n    );\n\n    context.globalCompositeOperation = 'destination-atop';\n\n    context.drawImage(\n        texture.baseTexture.source,\n        crop.x,\n        crop.y,\n        crop.width,\n        crop.height,\n        0,\n        0,\n        crop.width,\n        crop.height\n    );\n};\n\n/**\n * Tint a texture using the 'overlay' operation.\n *\n * @param texture {PIXI.Texture} the texture to tint\n * @param color {number} the color to use to tint the sprite with\n * @param canvas {HTMLCanvasElement} the current canvas\n */\nCanvasTinter.tintWithOverlay = function (texture, color, canvas)\n{\n    var context = canvas.getContext( '2d' );\n\n    var resolution = texture.baseTexture.resolution;\n\n    var crop = texture.crop.clone();\n    crop.x *= resolution;\n    crop.y *= resolution;\n    crop.width *= resolution;\n    crop.height *= resolution;\n\n    canvas.width = crop.width;\n    canvas.height = crop.height;\n\n    context.globalCompositeOperation = 'copy';\n    context.fillStyle = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);\n    context.fillRect(0, 0, crop.width, crop.height);\n\n    context.globalCompositeOperation = 'destination-atop';\n    context.drawImage(\n        texture.baseTexture.source,\n        crop.x,\n        crop.y,\n        crop.width,\n        crop.height,\n        0,\n        0,\n        crop.width,\n        crop.height\n    );\n\n    // context.globalCompositeOperation = 'copy';\n};\n\n/**\n * Tint a texture pixel per pixel.\n *\n * @param texture {PIXI.Texture} the texture to tint\n * @param color {number} the color to use to tint the sprite with\n * @param canvas {HTMLCanvasElement} the current canvas\n */\nCanvasTinter.tintWithPerPixel = function (texture, color, canvas)\n{\n    var context = canvas.getContext( '2d' );\n\n    var resolution = texture.baseTexture.resolution;\n\n    var crop = texture.crop.clone();\n    crop.x *= resolution;\n    crop.y *= resolution;\n    crop.width *= resolution;\n    crop.height *= resolution;\n\n    canvas.width = crop.width;\n    canvas.height = crop.height;\n\n    context.globalCompositeOperation = 'copy';\n    context.drawImage(\n        texture.baseTexture.source,\n        crop.x,\n        crop.y,\n        crop.width,\n        crop.height,\n        0,\n        0,\n        crop.width,\n        crop.height\n    );\n\n    var rgbValues = utils.hex2rgb(color);\n    var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2];\n\n    var pixelData = context.getImageData(0, 0, crop.width, crop.height);\n\n    var pixels = pixelData.data;\n\n    for (var i = 0; i < pixels.length; i += 4)\n    {\n        pixels[i+0] *= r;\n        pixels[i+1] *= g;\n        pixels[i+2] *= b;\n    }\n\n    context.putImageData(pixelData, 0, 0);\n};\n\n/**\n * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.\n *\n * @param color {number} the color to round, should be a hex color\n */\nCanvasTinter.roundColor = function (color)\n{\n    var step = CanvasTinter.cacheStepsPerColorChannel;\n\n    var rgbValues = utils.hex2rgb(color);\n\n    rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);\n    rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);\n    rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);\n\n    return utils.rgb2hex(rgbValues);\n};\n\n/**\n * Number of steps which will be used as a cap when rounding colors.\n *\n * @member\n */\nCanvasTinter.cacheStepsPerColorChannel = 8;\n\n/**\n * Tint cache boolean flag.\n *\n * @member\n */\nCanvasTinter.convertTintToImage = false;\n\n/**\n * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.\n *\n * @member\n */\nCanvasTinter.canUseMultiply = utils.canUseNewCanvasBlendModes();\n\n/**\n * The tinting method that will be used.\n *\n */\nCanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply :  CanvasTinter.tintWithPerPixel;\n\n},{\"../../../utils\":77}],49:[function(require,module,exports){\nvar SystemRenderer = require('../SystemRenderer'),\n    ShaderManager = require('./managers/ShaderManager'),\n    MaskManager = require('./managers/MaskManager'),\n    StencilManager = require('./managers/StencilManager'),\n    FilterManager = require('./managers/FilterManager'),\n    BlendModeManager = require('./managers/BlendModeManager'),\n    RenderTarget = require('./utils/RenderTarget'),\n    ObjectRenderer = require('./utils/ObjectRenderer'),\n    FXAAFilter = require('./filters/FXAAFilter'),\n    utils = require('../../utils'),\n    CONST = require('../../const');\n\n/**\n * The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer\n * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.\n * So no need for Sprite Batches or Sprite Clouds.\n * Don't forget to add the view to your DOM or you will not see anything :)\n *\n * @class\n * @memberof PIXI\n * @extends PIXI.SystemRenderer\n * @param [width=0] {number} the width of the canvas view\n * @param [height=0] {number} the height of the canvas view\n * @param [options] {object} The optional renderer parameters\n * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional\n * @param [options.transparent=false] {boolean} If the render view is transparent, default false\n * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false\n * @param [options.antialias=false] {boolean} sets antialias. If not available natively then FXAA antialiasing is used\n * @param [options.forceFXAA=false] {boolean} forces FXAA antialiasing to be used over native. FXAA is faster, but may not always look as great\n * @param [options.resolution=1] {number} the resolution of the renderer retina would be 2\n * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or\n *      not before the new render pass. If you wish to set this to false, you *must* set preserveDrawingBuffer to `true`.\n * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if\n *      you need to call toDataUrl on the webgl context.\n * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.\n */\nfunction WebGLRenderer(width, height, options)\n{\n    options = options || {};\n\n    SystemRenderer.call(this, 'WebGL', width, height, options);\n\n    /**\n     * The type of this renderer as a standardised const\n     *\n     * @member {number}\n     *\n     */\n    this.type = CONST.RENDERER_TYPE.WEBGL;\n\n    this.handleContextLost = this.handleContextLost.bind(this);\n    this.handleContextRestored = this.handleContextRestored.bind(this);\n\n    this.view.addEventListener('webglcontextlost', this.handleContextLost, false);\n    this.view.addEventListener('webglcontextrestored', this.handleContextRestored, false);\n\n    //TODO possibility to force FXAA as it may offer better performance?\n    /**\n     * Does it use FXAA ?\n     *\n     * @member {boolean}\n     * @private\n     */\n    this._useFXAA = !!options.forceFXAA && options.antialias;\n\n    /**\n     * The fxaa filter\n     *\n     * @member {PIXI.FXAAFilter}\n     * @private\n     */\n    this._FXAAFilter = null;\n\n    /**\n     * The options passed in to create a new webgl context.\n     *\n     * @member {object}\n     * @private\n     */\n    this._contextOptions = {\n        alpha: this.transparent,\n        antialias: options.antialias,\n        premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied',\n        stencil: true,\n        preserveDrawingBuffer: options.preserveDrawingBuffer\n    };\n\n    /**\n     * Counter for the number of draws made each frame\n     *\n     * @member {number}\n     */\n    this.drawCount = 0;\n\n    /**\n     * Deals with managing the shader programs and their attribs.\n     *\n     * @member {PIXI.ShaderManager}\n     */\n    this.shaderManager = new ShaderManager(this);\n\n    /**\n     * Manages the masks using the stencil buffer.\n     *\n     * @member {PIXI.MaskManager}\n     */\n    this.maskManager = new MaskManager(this);\n\n    /**\n     * Manages the stencil buffer.\n     *\n     * @member {PIXI.StencilManager}\n     */\n    this.stencilManager = new StencilManager(this);\n\n    /**\n     * Manages the filters.\n     *\n     * @member {PIXI.FilterManager}\n     */\n    this.filterManager = new FilterManager(this);\n\n\n    /**\n     * Manages the blendModes\n     *\n     * @member {PIXI.BlendModeManager}\n     */\n    this.blendModeManager = new BlendModeManager(this);\n\n    /**\n     * Holds the current render target\n     *\n     * @member {PIXI.RenderTarget}\n     */\n    this.currentRenderTarget = null;\n\n    /**\n     * The currently active ObjectRenderer.\n     *\n     * @member {PIXI.ObjectRenderer}\n     */\n    this.currentRenderer = new ObjectRenderer(this);\n\n    this.initPlugins();\n\n    // initialize the context so it is ready for the managers.\n    this._createContext();\n    this._initContext();\n\n    // map some webGL blend modes..\n    this._mapGlModes();\n\n    // track textures in the renderer so we can no longer listen to them on destruction.\n    this._managedTextures = [];\n\n    /**\n     * An array of render targets\n     * @member {PIXI.RenderTarget[]}\n     * @private\n     */\n    this._renderTargetStack = [];\n}\n\n// constructor\nWebGLRenderer.prototype = Object.create(SystemRenderer.prototype);\nWebGLRenderer.prototype.constructor = WebGLRenderer;\nmodule.exports = WebGLRenderer;\nutils.pluginTarget.mixin(WebGLRenderer);\n\nWebGLRenderer.glContextId = 0;\n\n/**\n * Creates the gl context.\n *\n * @private\n */\nWebGLRenderer.prototype._createContext = function () {\n    var gl = this.view.getContext('webgl', this._contextOptions) || this.view.getContext('experimental-webgl', this._contextOptions);\n    this.gl = gl;\n\n    if (!gl)\n    {\n        // fail, not able to get a context\n        throw new Error('This browser does not support webGL. Try using the canvas renderer');\n    }\n\n    this.glContextId = WebGLRenderer.glContextId++;\n    gl.id = this.glContextId;\n    gl.renderer = this;\n};\n\n/**\n * Creates the WebGL context\n *\n * @private\n */\nWebGLRenderer.prototype._initContext = function ()\n{\n    var gl = this.gl;\n\n    // set up the default pixi settings..\n    gl.disable(gl.DEPTH_TEST);\n    gl.disable(gl.CULL_FACE);\n    gl.enable(gl.BLEND);\n\n    this.renderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true);\n\n    this.setRenderTarget(this.renderTarget);\n\n    this.emit('context', gl);\n\n    // setup the width/height properties and gl viewport\n    this.resize(this.width, this.height);\n\n    if(!this._useFXAA)\n    {\n        this._useFXAA = (this._contextOptions.antialias && ! gl.getContextAttributes().antialias);\n    }\n\n\n    if(this._useFXAA)\n    {\n        window.console.warn('FXAA antialiasing being used instead of native antialiasing');\n        this._FXAAFilter = [new FXAAFilter()];\n    }\n};\n\n/**\n * Renders the object to its webGL view\n *\n * @param object {PIXI.DisplayObject} the object to be rendered\n */\nWebGLRenderer.prototype.render = function (object)\n{\n\n    this.emit('prerender');\n\n    // no point rendering if our context has been blown up!\n    if (this.gl.isContextLost())\n    {\n        return;\n    }\n\n    this.drawCount = 0;\n\n    this._lastObjectRendered = object;\n\n    if(this._useFXAA)\n    {\n        this._FXAAFilter[0].uniforms.resolution.value.x = this.width;\n        this._FXAAFilter[0].uniforms.resolution.value.y = this.height;\n        object.filterArea = this.renderTarget.size;\n        object.filters = this._FXAAFilter;\n    }\n\n    var cacheParent = object.parent;\n    object.parent = this._tempDisplayObjectParent;\n\n    // update the scene graph\n    object.updateTransform();\n\n    object.parent = cacheParent;\n\n    var gl = this.gl;\n\n    // make sure we are bound to the main frame buffer\n    this.setRenderTarget(this.renderTarget);\n\n    if (this.clearBeforeRender)\n    {\n        if (this.transparent)\n        {\n            gl.clearColor(0, 0, 0, 0);\n        }\n        else\n        {\n            gl.clearColor(this._backgroundColorRgb[0], this._backgroundColorRgb[1], this._backgroundColorRgb[2], 1);\n        }\n\n        gl.clear(gl.COLOR_BUFFER_BIT);\n    }\n\n    this.renderDisplayObject(object, this.renderTarget);//this.projection);\n\n    this.emit('postrender');\n};\n\n/**\n * Renders a Display Object.\n *\n * @param displayObject {PIXI.DisplayObject} The DisplayObject to render\n * @param renderTarget {PIXI.RenderTarget} The render target to use to render this display object\n *\n */\nWebGLRenderer.prototype.renderDisplayObject = function (displayObject, renderTarget, clear)//projection, buffer)\n{\n    // TODO is this needed...\n    //this.blendModeManager.setBlendMode(CONST.BLEND_MODES.NORMAL);\n    this.setRenderTarget(renderTarget);\n\n    if(clear)\n    {\n        renderTarget.clear();\n    }\n\n    // start the filter manager\n    this.filterManager.setFilterStack( renderTarget.filterStack );\n\n    // render the scene!\n    displayObject.renderWebGL(this);\n\n    // finish the current renderer..\n    this.currentRenderer.flush();\n};\n\n/**\n * Changes the current renderer to the one given in parameter\n *\n * @param objectRenderer {PIXI.ObjectRenderer} The object renderer to use.\n */\nWebGLRenderer.prototype.setObjectRenderer = function (objectRenderer)\n{\n    if (this.currentRenderer === objectRenderer)\n    {\n        return;\n    }\n\n    this.currentRenderer.stop();\n    this.currentRenderer = objectRenderer;\n    this.currentRenderer.start();\n};\n\n/**\n * Changes the current render target to the one given in parameter\n *\n * @param renderTarget {PIXI.RenderTarget} the new render target\n */\nWebGLRenderer.prototype.setRenderTarget = function (renderTarget)\n{\n    if( this.currentRenderTarget === renderTarget)\n    {\n        return;\n    }\n    // TODO - maybe down the line this should be a push pos thing? Leaving for now though.\n    this.currentRenderTarget = renderTarget;\n    this.currentRenderTarget.activate();\n    this.stencilManager.setMaskStack( renderTarget.stencilMaskStack );\n};\n\n\n/**\n * Resizes the webGL view to the specified width and height.\n *\n * @param width {number} the new width of the webGL view\n * @param height {number} the new height of the webGL view\n */\nWebGLRenderer.prototype.resize = function (width, height)\n{\n    SystemRenderer.prototype.resize.call(this, width, height);\n\n    this.filterManager.resize(width, height);\n    this.renderTarget.resize(width, height);\n\n    if(this.currentRenderTarget === this.renderTarget)\n    {\n        this.renderTarget.activate();\n        this.gl.viewport(0, 0, this.width, this.height);\n    }\n};\n\n/**\n * Updates and/or Creates a WebGL texture for the renderer's context.\n *\n * @param texture {PIXI.BaseTexture|PIXI.Texture} the texture to update\n */\nWebGLRenderer.prototype.updateTexture = function (texture)\n{\n    texture = texture.baseTexture || texture;\n\n    if (!texture.hasLoaded)\n    {\n        return;\n    }\n\n    var gl = this.gl;\n\n    if (!texture._glTextures[gl.id])\n    {\n        texture._glTextures[gl.id] = gl.createTexture();\n        texture.on('update', this.updateTexture, this);\n        texture.on('dispose', this.destroyTexture, this);\n        this._managedTextures.push(texture);\n    }\n\n\n    gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);\n\n    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n\n\n    if (texture.mipmap && texture.isPowerOfTwo)\n    {\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);\n        gl.generateMipmap(gl.TEXTURE_2D);\n    }\n    else\n    {\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n    }\n\n    if (!texture.isPowerOfTwo)\n    {\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    }\n    else\n    {\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n    }\n\n    return  texture._glTextures[gl.id];\n};\n\n/**\n * Deletes the texture from WebGL\n *\n * @param texture {PIXI.BaseTexture|PIXI.Texture} the texture to destroy\n */\nWebGLRenderer.prototype.destroyTexture = function (texture, _skipRemove)\n{\n    texture = texture.baseTexture || texture;\n\n    if (!texture.hasLoaded)\n    {\n        return;\n    }\n\n    if (texture._glTextures[this.gl.id])\n    {\n        this.gl.deleteTexture(texture._glTextures[this.gl.id]);\n        delete texture._glTextures[this.gl.id];\n\n        if (!_skipRemove)\n        {\n            var i = this._managedTextures.indexOf(texture);\n            if (i !== -1) {\n                utils.removeItems(this._managedTextures, i, 1);\n            }\n        }\n    }\n};\n\n/**\n * Handles a lost webgl context\n *\n * @private\n */\nWebGLRenderer.prototype.handleContextLost = function (event)\n{\n    event.preventDefault();\n};\n\n/**\n * Handles a restored webgl context\n *\n * @private\n */\nWebGLRenderer.prototype.handleContextRestored = function ()\n{\n    this._initContext();\n\n    // empty all the old gl textures as they are useless now\n    for (var i = 0; i < this._managedTextures.length; ++i)\n    {\n        var texture = this._managedTextures[i];\n        if (texture._glTextures[this.gl.id])\n        {\n            delete texture._glTextures[this.gl.id];\n        }\n    }\n};\n\n/**\n * Removes everything from the renderer (event listeners, spritebatch, etc...)\n *\n * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.\n */\nWebGLRenderer.prototype.destroy = function (removeView)\n{\n    this.destroyPlugins();\n\n    // remove listeners\n    this.view.removeEventListener('webglcontextlost', this.handleContextLost);\n    this.view.removeEventListener('webglcontextrestored', this.handleContextRestored);\n\n    // destroy managed textures\n    for (var i = 0; i < this._managedTextures.length; ++i)\n    {\n        var texture = this._managedTextures[i];\n        this.destroyTexture(texture, true);\n        texture.off('update', this.updateTexture, this);\n        texture.off('dispose', this.destroyTexture, this);\n    }\n\n    // call base destroy\n    SystemRenderer.prototype.destroy.call(this, removeView);\n\n    this.uid = 0;\n\n    // destroy the managers\n    this.shaderManager.destroy();\n    this.maskManager.destroy();\n    this.stencilManager.destroy();\n    this.filterManager.destroy();\n    this.blendModeManager.destroy();\n\n    this.shaderManager = null;\n    this.maskManager = null;\n    this.filterManager = null;\n    this.blendModeManager = null;\n    this.currentRenderer = null;\n\n    this.handleContextLost = null;\n    this.handleContextRestored = null;\n\n    this._contextOptions = null;\n\n    this._managedTextures = null;\n\n    this.drawCount = 0;\n\n    this.gl.useProgram(null);\n\n    this.gl.flush();\n\n    this.gl = null;\n};\n\n/**\n * Maps Pixi blend modes to WebGL blend modes. It works only for pre-multiplied textures.\n *\n * @private\n */\nWebGLRenderer.prototype._mapGlModes = function ()\n{\n    var gl = this.gl;\n\n    if (!this.blendModes)\n    {\n        this.blendModes = {};\n\n        this.blendModes[CONST.BLEND_MODES.NORMAL]        = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.ADD]           = [gl.ONE,       gl.DST_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.MULTIPLY]      = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.SCREEN]        = [gl.ONE,       gl.ONE_MINUS_SRC_COLOR];\n        this.blendModes[CONST.BLEND_MODES.OVERLAY]       = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.DARKEN]        = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.LIGHTEN]       = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.COLOR_DODGE]   = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.COLOR_BURN]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.HARD_LIGHT]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.SOFT_LIGHT]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.DIFFERENCE]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.EXCLUSION]     = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.HUE]           = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.SATURATION]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.COLOR]         = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n        this.blendModes[CONST.BLEND_MODES.LUMINOSITY]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];\n    }\n\n    if (!this.drawModes)\n    {\n        this.drawModes = {};\n\n        this.drawModes[CONST.DRAW_MODES.POINTS]         = gl.POINTS;\n        this.drawModes[CONST.DRAW_MODES.LINES]          = gl.LINES;\n        this.drawModes[CONST.DRAW_MODES.LINE_LOOP]      = gl.LINE_LOOP;\n        this.drawModes[CONST.DRAW_MODES.LINE_STRIP]     = gl.LINE_STRIP;\n        this.drawModes[CONST.DRAW_MODES.TRIANGLES]      = gl.TRIANGLES;\n        this.drawModes[CONST.DRAW_MODES.TRIANGLE_STRIP] = gl.TRIANGLE_STRIP;\n        this.drawModes[CONST.DRAW_MODES.TRIANGLE_FAN]   = gl.TRIANGLE_FAN;\n    }\n};\n\n},{\"../../const\":22,\"../../utils\":77,\"../SystemRenderer\":43,\"./filters/FXAAFilter\":51,\"./managers/BlendModeManager\":53,\"./managers/FilterManager\":54,\"./managers/MaskManager\":55,\"./managers/ShaderManager\":56,\"./managers/StencilManager\":57,\"./utils/ObjectRenderer\":63,\"./utils/RenderTarget\":65}],50:[function(require,module,exports){\nvar DefaultShader = require('../shaders/TextureShader');\n\n/**\n * This is the base class for creating a PIXI filter. Currently only WebGL supports filters.\n * If you want to make a custom filter this should be your base class.\n *\n * @class\n * @memberof PIXI\n * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.\n * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.\n * @param uniforms {object} An object containing the uniforms for this filter.\n */\nfunction AbstractFilter(vertexSrc, fragmentSrc, uniforms)\n{\n\n    /**\n     * An array of shaders\n     * @member {PIXI.Shader[]}\n     * @private\n     */\n    this.shaders = [];\n\n    /**\n     * The extra padding that the filter might need\n     * @member {number}\n     */\n    this.padding = 0;\n\n    /**\n     * The uniforms as an object\n     * @member {object}\n     */\n    this.uniforms = uniforms || {};\n\n\n    /**\n     * The code of the vertex shader\n     * @member {string[]}\n     * @private\n     */\n    this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc;\n\n    /**\n     * The code of the frament shader\n     * @member {string[]}\n     * @private\n     */\n    this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc;\n\n    //TODO a reminder - would be cool to have lower res filters as this would give better performance.\n\n    //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []);\n\n}\n\nAbstractFilter.prototype.constructor = AbstractFilter;\nmodule.exports = AbstractFilter;\n\n/**\n * Grabs a shader from the current renderer\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from\n */\nAbstractFilter.prototype.getShader = function (renderer)\n{\n    var gl = renderer.gl;\n\n    var shader = this.shaders[gl.id];\n\n    if (!shader)\n    {\n        shader = new DefaultShader(renderer.shaderManager,\n            this.vertexSrc,\n            this.fragmentSrc,\n            this.uniforms,\n            this.attributes\n        );\n\n        this.shaders[gl.id] = shader;\n    }\n\n    return shader;\n};\n\n/**\n * Applies the filter\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from\n * @param input {PIXI.RenderTarget}\n * @param output {PIXI.RenderTarget}\n * @param clear {boolean} Whether or not we want to clear the outputTarget\n */\nAbstractFilter.prototype.applyFilter = function (renderer, input, output, clear)\n{\n    var shader = this.getShader(renderer);\n\n    renderer.filterManager.applyFilter(shader, input, output, clear);\n};\n\n/**\n * Syncs a uniform between the class object and the shaders.\n *\n */\nAbstractFilter.prototype.syncUniform = function (uniform)\n{\n    for (var i = 0, j = this.shaders.length; i < j; ++i)\n    {\n        this.shaders[i].syncUniform(uniform);\n    }\n};\n\n},{\"../shaders/TextureShader\":62}],51:[function(require,module,exports){\nvar AbstractFilter = require('./AbstractFilter');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n *\n * Basic FXAA implementation based on the code on geeks3d.com with the\n * modification that the texture2DLod stuff was removed since it's\n * unsupported by WebGL.\n *\n * --\n * From:\n * https://github.com/mitsuhiko/webgl-meincraft\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI\n *\n */\nfunction FXAAFilter()\n{\n    AbstractFilter.call(this,\n        // vertex shader\n        \"\\nprecision mediump float;\\n\\nattribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform mat3 projectionMatrix;\\nuniform vec2 resolution;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nvarying vec2 vResolution;\\n\\n//texcoords computed in vertex step\\n//to avoid dependent texture reads\\nvarying vec2 v_rgbNW;\\nvarying vec2 v_rgbNE;\\nvarying vec2 v_rgbSW;\\nvarying vec2 v_rgbSE;\\nvarying vec2 v_rgbM;\\n\\n\\nvoid texcoords(vec2 fragCoord, vec2 resolution,\\n            out vec2 v_rgbNW, out vec2 v_rgbNE,\\n            out vec2 v_rgbSW, out vec2 v_rgbSE,\\n            out vec2 v_rgbM) {\\n    vec2 inverseVP = 1.0 / resolution.xy;\\n    v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\\n    v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\\n    v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\\n    v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\\n    v_rgbM = vec2(fragCoord * inverseVP);\\n}\\n\\nvoid main(void){\\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\\n   vTextureCoord = aTextureCoord;\\n   vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n   vResolution = resolution;\\n\\n   //compute the texture coords and send them to varyings\\n   texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\\n}\\n\",\n        // fragment shader\n        \"precision lowp float;\\n\\n\\n/**\\nBasic FXAA implementation based on the code on geeks3d.com with the\\nmodification that the texture2DLod stuff was removed since it's\\nunsupported by WebGL.\\n\\n--\\n\\nFrom:\\nhttps://github.com/mitsuhiko/webgl-meincraft\\n\\nCopyright (c) 2011 by Armin Ronacher.\\n\\nSome rights reserved.\\n\\nRedistribution and use in source and binary forms, with or without\\nmodification, are permitted provided that the following conditions are\\nmet:\\n\\n    * Redistributions of source code must retain the above copyright\\n      notice, this list of conditions and the following disclaimer.\\n\\n    * Redistributions in binary form must reproduce the above\\n      copyright notice, this list of conditions and the following\\n      disclaimer in the documentation and/or other materials provided\\n      with the distribution.\\n\\n    * The names of the contributors may not be used to endorse or\\n      promote products derived from this software without specific\\n      prior written permission.\\n\\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\\n\\\"AS IS\\\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\\n*/\\n\\n#ifndef FXAA_REDUCE_MIN\\n    #define FXAA_REDUCE_MIN   (1.0/ 128.0)\\n#endif\\n#ifndef FXAA_REDUCE_MUL\\n    #define FXAA_REDUCE_MUL   (1.0 / 8.0)\\n#endif\\n#ifndef FXAA_SPAN_MAX\\n    #define FXAA_SPAN_MAX     8.0\\n#endif\\n\\n//optimized version for mobile, where dependent\\n//texture reads can be a bottleneck\\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\\n            vec2 v_rgbNW, vec2 v_rgbNE,\\n            vec2 v_rgbSW, vec2 v_rgbSE,\\n            vec2 v_rgbM) {\\n    vec4 color;\\n    mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\\n    vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\\n    vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\\n    vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\\n    vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\\n    vec4 texColor = texture2D(tex, v_rgbM);\\n    vec3 rgbM  = texColor.xyz;\\n    vec3 luma = vec3(0.299, 0.587, 0.114);\\n    float lumaNW = dot(rgbNW, luma);\\n    float lumaNE = dot(rgbNE, luma);\\n    float lumaSW = dot(rgbSW, luma);\\n    float lumaSE = dot(rgbSE, luma);\\n    float lumaM  = dot(rgbM,  luma);\\n    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\\n    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\\n\\n    mediump vec2 dir;\\n    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\\n    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));\\n\\n    float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\\n                          (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\\n\\n    float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\\n    dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\\n              max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\\n              dir * rcpDirMin)) * inverseVP;\\n\\n    vec3 rgbA = 0.5 * (\\n        texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\\n        texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\\n    vec3 rgbB = rgbA * 0.5 + 0.25 * (\\n        texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\\n        texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\\n\\n    float lumaB = dot(rgbB, luma);\\n    if ((lumaB < lumaMin) || (lumaB > lumaMax))\\n        color = vec4(rgbA, texColor.a);\\n    else\\n        color = vec4(rgbB, texColor.a);\\n    return color;\\n}\\n\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\nvarying vec2 vResolution;\\n\\n//texcoords computed in vertex step\\n//to avoid dependent texture reads\\nvarying vec2 v_rgbNW;\\nvarying vec2 v_rgbNE;\\nvarying vec2 v_rgbSW;\\nvarying vec2 v_rgbSE;\\nvarying vec2 v_rgbM;\\n\\nuniform sampler2D uSampler;\\n\\n\\nvoid main(void){\\n\\n    gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\\n\\n}\\n\",\n        // uniforms\n        {\n            resolution: { type: 'v2', value: { x: 1, y: 1 } }\n        }\n    );\n\n}\n\nFXAAFilter.prototype = Object.create(AbstractFilter.prototype);\nFXAAFilter.prototype.constructor = FXAAFilter;\nmodule.exports = FXAAFilter;\n\n/**\n * Applies the filter\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from\n * @param input {PIXI.RenderTarget}\n * @param output {PIXI.RenderTarget}\n */\nFXAAFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var filterManager = renderer.filterManager;\n\n    var shader = this.getShader( renderer );\n     // draw the filter...\n    filterManager.applyFilter(shader, input, output);\n};\n\n},{\"./AbstractFilter\":50}],52:[function(require,module,exports){\nvar AbstractFilter = require('./AbstractFilter'),\n    math =  require('../../../math');\n\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The SpriteMaskFilter class\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI\n * @param sprite {PIXI.Sprite} the target sprite\n */\nfunction SpriteMaskFilter(sprite)\n{\n    var maskMatrix = new math.Matrix();\n\n    AbstractFilter.call(this,\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform mat3 projectionMatrix;\\nuniform mat3 otherMatrix;\\n\\nvarying vec2 vMaskCoord;\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nvoid main(void)\\n{\\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\\n    vTextureCoord = aTextureCoord;\\n    vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0)  ).xy;\\n    vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        \"precision lowp float;\\n\\nvarying vec2 vMaskCoord;\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nuniform sampler2D uSampler;\\nuniform float alpha;\\nuniform sampler2D mask;\\n\\nvoid main(void)\\n{\\n    // check clip! this will stop the mask bleeding out from the edges\\n    vec2 text = abs( vMaskCoord - 0.5 );\\n    text = step(0.5, text);\\n    float clip = 1.0 - max(text.y, text.x);\\n    vec4 original = texture2D(uSampler, vTextureCoord);\\n    vec4 masky = texture2D(mask, vMaskCoord);\\n    original *= (masky.r * masky.a * alpha * clip);\\n    gl_FragColor = original;\\n}\\n\",\n        {\n            mask:           { type: 'sampler2D', value: sprite._texture },\n            alpha:          { type: 'f', value: 1},\n            otherMatrix:    { type: 'mat3', value: maskMatrix.toArray(true) }\n        }\n    );\n\n    this.maskSprite = sprite;\n    this.maskMatrix = maskMatrix;\n}\n\nSpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype);\nSpriteMaskFilter.prototype.constructor = SpriteMaskFilter;\nmodule.exports = SpriteMaskFilter;\n\n/**\n * Applies the filter\n *\n * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from\n * @param input {PIXI.RenderTarget}\n * @param output {PIXI.RenderTarget}\n */\nSpriteMaskFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var filterManager = renderer.filterManager;\n\n    this.uniforms.mask.value = this.maskSprite._texture;\n\n    filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix);\n\n    this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true);\n    this.uniforms.alpha.value = this.maskSprite.worldAlpha;\n\n    var shader = this.getShader(renderer);\n     // draw the filter...\n    filterManager.applyFilter(shader, input, output);\n};\n\n\nObject.defineProperties(SpriteMaskFilter.prototype, {\n    /**\n     * The texture used for the displacement map. Must be power of 2 sized texture.\n     *\n     * @member {PIXI.Texture}\n     * @memberof PIXI.SpriteMaskFilter#\n     */\n    map: {\n        get: function ()\n        {\n            return this.uniforms.mask.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.mask.value = value;\n        }\n    },\n\n    /**\n     * The offset used to move the displacement map.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.SpriteMaskFilter#\n     */\n    offset: {\n        get: function()\n        {\n            return this.uniforms.offset.value;\n        },\n        set: function(value)\n        {\n            this.uniforms.offset.value = value;\n        }\n    }\n});\n\n},{\"../../../math\":33,\"./AbstractFilter\":50}],53:[function(require,module,exports){\nvar WebGLManager = require('./WebGLManager');\n\n/**\n * @class\n * @memberof PIXI\n * @extends PIXI.WebGlManager\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction BlendModeManager(renderer)\n{\n    WebGLManager.call(this, renderer);\n\n    /**\n     * @member {number}\n     */\n    this.currentBlendMode = 99999;\n}\n\nBlendModeManager.prototype = Object.create(WebGLManager.prototype);\nBlendModeManager.prototype.constructor = BlendModeManager;\nmodule.exports = BlendModeManager;\n\n/**\n * Sets-up the given blendMode from WebGL's point of view.\n *\n * @param blendMode {number} the blendMode, should be a Pixi const, such as `PIXI.BLEND_MODES.ADD`. See\n *  {@link PIXI.BLEND_MODES} for possible values.\n */\nBlendModeManager.prototype.setBlendMode = function (blendMode)\n{\n    if (this.currentBlendMode === blendMode)\n    {\n        return false;\n    }\n\n    this.currentBlendMode = blendMode;\n\n    var mode = this.renderer.blendModes[this.currentBlendMode];\n    this.renderer.gl.blendFunc(mode[0], mode[1]);\n\n    return true;\n};\n\n},{\"./WebGLManager\":58}],54:[function(require,module,exports){\nvar WebGLManager = require('./WebGLManager'),\n    RenderTarget = require('../utils/RenderTarget'),\n    CONST = require('../../../const'),\n    Quad = require('../utils/Quad'),\n    math =  require('../../../math');\n\n/**\n * @class\n * @memberof PIXI\n * @extends PIXI.WebGLManager\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction FilterManager(renderer)\n{\n    WebGLManager.call(this, renderer);\n\n    /**\n     * @member {object[]}\n     */\n    this.filterStack = [];\n\n    this.filterStack.push({\n        renderTarget:renderer.currentRenderTarget,\n        filter:[],\n        bounds:null\n    });\n\n    /**\n     * @member {PIXI.RenderTarget[]}\n     */\n    this.texturePool = [];\n\n    /**\n     * The size of the texture\n     *\n     * @member {PIXI.Rectangle}\n     */\n    // listen for context and update necessary buffers\n    //TODO make this dynamic!\n    //TODO test this out by forces power of two?\n    this.textureSize = new math.Rectangle(0, 0, renderer.width, renderer.height);\n\n    /**\n     * The current frame\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.currentFrame = null;\n}\n\nFilterManager.prototype = Object.create(WebGLManager.prototype);\nFilterManager.prototype.constructor = FilterManager;\nmodule.exports = FilterManager;\n\n\n/**\n * Called when there is a WebGL context change.\n *\n */\nFilterManager.prototype.onContextChange = function ()\n{\n    this.texturePool.length = 0;\n\n    var gl = this.renderer.gl;\n    this.quad = new Quad(gl);\n};\n\n/**\n * @param renderer {PIXI.WebGLRenderer}\n * @param buffer {ArrayBuffer}\n */\nFilterManager.prototype.setFilterStack = function ( filterStack )\n{\n    this.filterStack = filterStack;\n};\n\n/**\n * Applies the filter and adds it to the current filter stack.\n *\n * @param target {PIXI.DisplayObject}\n * @param filters {PIXI.AbstractFiler[]} the filters that will be pushed to the current filter stack\n */\nFilterManager.prototype.pushFilter = function (target, filters)\n{\n    // get the bounds of the object..\n    // TODO replace clone with a copy to save object creation\n    var bounds = target.filterArea ? target.filterArea.clone() : target.getBounds();\n\n    //bounds = bounds.clone();\n\n    // round off the rectangle to get a nice smoooooooth filter :)\n    bounds.x = bounds.x | 0;\n    bounds.y = bounds.y | 0;\n    bounds.width = bounds.width | 0;\n    bounds.height = bounds.height | 0;\n\n\n    // padding!\n    var padding = filters[0].padding | 0;\n    bounds.x -= padding;\n    bounds.y -= padding;\n    bounds.width += padding * 2;\n    bounds.height += padding * 2;\n\n\n    if(this.renderer.currentRenderTarget.transform)\n    {\n        //TODO this will break if the renderTexture transform is anything other than a translation.\n        //Will need to take the full matrix transform into acount..\n        var transform = this.renderer.currentRenderTarget.transform;\n\n        bounds.x += transform.tx;\n        bounds.y += transform.ty;\n\n        this.capFilterArea( bounds );\n\n        bounds.x -= transform.tx;\n        bounds.y -= transform.ty;\n    }\n    else\n    {\n         this.capFilterArea( bounds );\n    }\n\n    if(bounds.width > 0 && bounds.height > 0)\n    {\n        this.currentFrame = bounds;\n\n        var texture = this.getRenderTarget();\n\n        this.renderer.setRenderTarget(texture);\n\n        // clear the texture..\n        texture.clear();\n\n        // TODO get rid of object creation!\n        this.filterStack.push({\n            renderTarget: texture,\n            filter: filters\n        });\n\n    }\n    else\n    {\n        // push somthing on to the stack that is empty\n        this.filterStack.push({\n            renderTarget: null,\n            filter: filters\n        });\n    }\n};\n\n\n/**\n * Removes the last filter from the filter stack and returns it.\n *\n */\nFilterManager.prototype.popFilter = function ()\n{\n    var filterData = this.filterStack.pop();\n    var previousFilterData = this.filterStack[this.filterStack.length-1];\n\n    var input = filterData.renderTarget;\n\n    // if the renderTarget is null then we don't apply the filter as its offscreen\n    if(!filterData.renderTarget)\n    {\n        return;\n    }\n\n    var output = previousFilterData.renderTarget;\n\n    // use program\n    var gl = this.renderer.gl;\n\n\n    this.currentFrame = input.frame;\n\n    this.quad.map(this.textureSize, input.frame);\n\n\n    // TODO.. this probably only needs to be done once!\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.quad.vertexBuffer);\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.quad.indexBuffer);\n\n    var filters = filterData.filter;\n\n    // assuming all filters follow the correct format??\n    gl.vertexAttribPointer(this.renderer.shaderManager.defaultShader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0);\n    gl.vertexAttribPointer(this.renderer.shaderManager.defaultShader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 2 * 4 * 4);\n    gl.vertexAttribPointer(this.renderer.shaderManager.defaultShader.attributes.aColor, 4, gl.FLOAT, false, 0, 4 * 4 * 4);\n\n    // restore the normal blendmode!\n    this.renderer.blendModeManager.setBlendMode(CONST.BLEND_MODES.NORMAL);\n\n    if (filters.length === 1)\n    {\n        // TODO (cengler) - There has to be a better way then setting this each time?\n        if (filters[0].uniforms.dimensions)\n        {\n            filters[0].uniforms.dimensions.value[0] = this.renderer.width;\n            filters[0].uniforms.dimensions.value[1] = this.renderer.height;\n            filters[0].uniforms.dimensions.value[2] = this.quad.vertices[0];\n            filters[0].uniforms.dimensions.value[3] = this.quad.vertices[5];\n        }\n\n        filters[0].applyFilter( this.renderer, input, output );\n        this.returnRenderTarget( input );\n\n    }\n    else\n    {\n        var flipTexture = input;\n        var flopTexture = this.getRenderTarget(true);\n\n        for (var i = 0; i < filters.length-1; i++)\n        {\n            var filter = filters[i];\n\n            // TODO (cengler) - There has to be a better way then setting this each time?\n            if (filter.uniforms.dimensions)\n            {\n                filter.uniforms.dimensions.value[0] = this.renderer.width;\n                filter.uniforms.dimensions.value[1] = this.renderer.height;\n                filter.uniforms.dimensions.value[2] = this.quad.vertices[0];\n                filter.uniforms.dimensions.value[3] = this.quad.vertices[5];\n            }\n\n            filter.applyFilter( this.renderer, flipTexture, flopTexture );\n\n            var temp = flipTexture;\n            flipTexture = flopTexture;\n            flopTexture = temp;\n        }\n\n        filters[filters.length-1].applyFilter( this.renderer, flipTexture, output );\n\n        this.returnRenderTarget( flipTexture );\n        this.returnRenderTarget( flopTexture );\n    }\n\n    return filterData.filter;\n};\n\n/**\n * Grabs an render target from the internal pool\n *\n * @param clear {boolean} Whether or not we need to clear the RenderTarget\n * @return {RenderTarget}\n */\nFilterManager.prototype.getRenderTarget = function ( clear )\n{\n    var renderTarget = this.texturePool.pop() || new RenderTarget(this.renderer.gl, this.textureSize.width, this.textureSize.height, CONST.SCALE_MODES.LINEAR, this.renderer.resolution * CONST.FILTER_RESOLUTION);\n    renderTarget.frame = this.currentFrame;\n\n    if (clear)\n    {\n        renderTarget.clear(true);\n    }\n\n    return renderTarget;\n};\n\n/*\n * Returns a RenderTarget to the internal pool\n * @param renderTarget {RenderTarget} The RenderTarget we want to return to the pool\n */\nFilterManager.prototype.returnRenderTarget = function (renderTarget)\n{\n    this.texturePool.push( renderTarget );\n};\n\n/*\n * Applies the filter\n * @param shader {Shader} The shader to upload\n * @param inputTarget {RenderTarget}\n * @param outputTarget {RenderTarget}\n * @param clear {boolean} Whether or not we want to clear the outputTarget\n */\nFilterManager.prototype.applyFilter = function (shader, inputTarget, outputTarget, clear)\n{\n    var gl = this.renderer.gl;\n\n    this.renderer.setRenderTarget(outputTarget);\n\n    if (clear)\n    {\n        outputTarget.clear();\n    }\n\n    // set the shader\n    this.renderer.shaderManager.setShader(shader);\n\n    // TODO (cengler) - Can this be cached and not `toArray`ed each frame?\n    shader.uniforms.projectionMatrix.value = this.renderer.currentRenderTarget.projectionMatrix.toArray(true);\n\n    //TODO can this be optimised?\n    shader.syncUniforms();\n/*\n    gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0);\n    gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 2 * 4 * 4);\n    gl.vertexAttribPointer(shader.attributes.aColor, 4, gl.FLOAT, false, 0, 4 * 4 * 4);\n*/\n\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, inputTarget.texture);\n\n    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n    this.renderer.drawCount++;\n};\n\n/*\n * Calculates the mapped matrix\n * @param filterArea {Rectangle} The filter area\n * @param sprite {Sprite} the target sprite\n * @param outputMatrix {Matrix} @alvin\n */\n// TODO playing around here.. this is temporary - (will end up in the shader)\nFilterManager.prototype.calculateMappedMatrix = function (filterArea, sprite, outputMatrix)\n{\n    var worldTransform = sprite.worldTransform.copy(math.Matrix.TEMP_MATRIX),\n    texture = sprite._texture.baseTexture;\n\n    var mappedMatrix = outputMatrix.identity();\n\n    // scale..\n    var ratio = this.textureSize.height / this.textureSize.width;\n\n    mappedMatrix.translate(filterArea.x / this.textureSize.width, filterArea.y / this.textureSize.height );\n\n    mappedMatrix.scale(1 , ratio);\n\n    var translateScaleX = (this.textureSize.width / texture.width);\n    var translateScaleY = (this.textureSize.height / texture.height);\n\n    worldTransform.tx /= texture.width * translateScaleX;\n    worldTransform.ty /= texture.width * translateScaleX;\n\n    worldTransform.invert();\n\n    mappedMatrix.prepend(worldTransform);\n\n    // apply inverse scale..\n    mappedMatrix.scale(1 , 1/ratio);\n\n    mappedMatrix.scale( translateScaleX , translateScaleY );\n\n    mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y);\n\n    return mappedMatrix;\n\n    // Keeping the orginal as a reminder to me on how this works!\n    //\n    // var m = new math.Matrix();\n\n    // // scale..\n    // var ratio = this.textureSize.height / this.textureSize.width;\n\n    // m.translate(filterArea.x / this.textureSize.width, filterArea.y / this.textureSize.height);\n\n\n    // m.scale(1 , ratio);\n\n\n    // var transform = wt.clone();\n\n    // var translateScaleX = (this.textureSize.width / 620);\n    // var translateScaleY = (this.textureSize.height / 380);\n\n    // transform.tx /= 620 * translateScaleX;\n    // transform.ty /= 620 * translateScaleX;\n\n    // transform.invert();\n\n    // transform.append(m);\n\n    // // apply inverse scale..\n    // transform.scale(1 , 1/ratio);\n\n    // transform.scale( translateScaleX , translateScaleY );\n\n    // return transform;\n};\n\n/*\n * Constrains the filter area to the texture size\n * @param filterArea {Rectangle} The filter area we want to cap\n */\nFilterManager.prototype.capFilterArea = function (filterArea)\n{\n    if (filterArea.x < 0)\n    {\n        filterArea.width += filterArea.x;\n        filterArea.x = 0;\n    }\n\n    if (filterArea.y < 0)\n    {\n        filterArea.height += filterArea.y;\n        filterArea.y = 0;\n    }\n\n    if ( filterArea.x + filterArea.width > this.textureSize.width )\n    {\n        filterArea.width = this.textureSize.width - filterArea.x;\n    }\n\n    if ( filterArea.y + filterArea.height > this.textureSize.height )\n    {\n        filterArea.height = this.textureSize.height - filterArea.y;\n    }\n};\n\n/*\n * Resizes all the render targets in the pool\n * @param width {number} the new width\n * @param height {number} the new height\n */\nFilterManager.prototype.resize = function ( width, height )\n{\n    this.textureSize.width = width;\n    this.textureSize.height = height;\n\n    for (var i = 0; i < this.texturePool.length; i++)\n    {\n        this.texturePool[i].resize( width, height );\n    }\n};\n\n/**\n * Destroys the filter and removes it from the filter stack.\n *\n */\nFilterManager.prototype.destroy = function ()\n{\n    this.quad.destroy();\n    \n    WebGLManager.prototype.destroy.call(this);\n    \n    this.filterStack = null;\n    this.offsetY = 0;\n\n    // destroy textures\n    for (var i = 0; i < this.texturePool.length; i++)\n    {\n        this.texturePool[i].destroy();\n    }\n\n    this.texturePool = null;\n};\n\n},{\"../../../const\":22,\"../../../math\":33,\"../utils/Quad\":64,\"../utils/RenderTarget\":65,\"./WebGLManager\":58}],55:[function(require,module,exports){\nvar WebGLManager = require('./WebGLManager'),\n    AlphaMaskFilter = require('../filters/SpriteMaskFilter');\n\n/**\n * @class\n * @memberof PIXI\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction MaskManager(renderer)\n{\n    WebGLManager.call(this, renderer);\n\n    this.stencilStack = [];\n    this.reverse = true;\n    this.count = 0;\n\n    this.alphaMaskPool = [];\n}\n\nMaskManager.prototype = Object.create(WebGLManager.prototype);\nMaskManager.prototype.constructor = MaskManager;\nmodule.exports = MaskManager;\n\n/**\n * Applies the Mask and adds it to the current filter stack.\n *\n * @param graphics {PIXI.Graphics}\n * @param webGLData {any[]}\n */\nMaskManager.prototype.pushMask = function (target, maskData)\n{\n    if (maskData.texture)\n    {\n        this.pushSpriteMask(target, maskData);\n    }\n    else\n    {\n        this.pushStencilMask(target, maskData);\n    }\n\n};\n\n/**\n * Removes the last mask from the mask stack and doesn't return it.\n *\n * @param target {PIXI.RenderTarget}\n * @param maskData {any[]}\n */\nMaskManager.prototype.popMask = function (target, maskData)\n{\n    if (maskData.texture)\n    {\n        this.popSpriteMask(target, maskData);\n    }\n    else\n    {\n        this.popStencilMask(target, maskData);\n    }\n};\n\n/**\n * Applies the Mask and adds it to the current filter stack.\n *\n * @param target {PIXI.RenderTarget}\n * @param maskData {any[]}\n */\nMaskManager.prototype.pushSpriteMask = function (target, maskData)\n{\n    var alphaMaskFilter = this.alphaMaskPool.pop();\n\n    if (!alphaMaskFilter)\n    {\n        alphaMaskFilter = [new AlphaMaskFilter(maskData)];\n    }\n\n    alphaMaskFilter[0].maskSprite = maskData;\n    this.renderer.filterManager.pushFilter(target, alphaMaskFilter);\n};\n\n/**\n * Removes the last filter from the filter stack and doesn't return it.\n *\n */\nMaskManager.prototype.popSpriteMask = function ()\n{\n    var filters = this.renderer.filterManager.popFilter();\n\n    this.alphaMaskPool.push(filters);\n};\n\n\n/**\n * Applies the Mask and adds it to the current filter stack.\n *\n * @param target {PIXI.RenderTarget}\n * @param maskData {any[]}\n */\nMaskManager.prototype.pushStencilMask = function (target, maskData)\n{\n    this.renderer.stencilManager.pushMask(maskData);\n};\n\n/**\n * Removes the last filter from the filter stack and doesn't return it.\n *\n * @param target {PIXI.RenderTarget}\n * @param maskData {any[]}\n */\nMaskManager.prototype.popStencilMask = function (target, maskData)\n{\n    this.renderer.stencilManager.popMask(maskData);\n};\n\n\n},{\"../filters/SpriteMaskFilter\":52,\"./WebGLManager\":58}],56:[function(require,module,exports){\nvar WebGLManager = require('./WebGLManager'),\n    TextureShader = require('../shaders/TextureShader'),\n    ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'),\n    PrimitiveShader = require('../shaders/PrimitiveShader'),\n    utils = require('../../../utils');\n\n/**\n * @class\n * @memberof PIXI\n * @extends PIXI.WebGLManager\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction ShaderManager(renderer)\n{\n    WebGLManager.call(this, renderer);\n\n    /**\n     * @member {number}\n     */\n    this.maxAttibs = 10;\n\n    /**\n     * @member {any[]}\n     */\n    this.attribState = [];\n\n    /**\n     * @member {any[]}\n     */\n    this.tempAttribState = [];\n\n    for (var i = 0; i < this.maxAttibs; i++)\n    {\n        this.attribState[i] = false;\n    }\n\n    /**\n     * @member {any[]}\n     */\n    this.stack = [];\n\n    /**\n     * @member {number}\n     * @private\n     */\n    this._currentId = -1;\n\n    /**\n     * @member {PIXI.Shader}\n     * @private\n     */\n    this.currentShader = null;\n\n//    this.initPlugins();\n}\n\nShaderManager.prototype = Object.create(WebGLManager.prototype);\nShaderManager.prototype.constructor = ShaderManager;\nutils.pluginTarget.mixin(ShaderManager);\n\nmodule.exports = ShaderManager;\n\n/**\n * Called when there is a WebGL context change.\n *\n */\nShaderManager.prototype.onContextChange = function ()\n{\n    this.initPlugins();\n\n    var gl = this.renderer.gl;\n\n    // get the maximum number of attribute correctly as this tends to vary\n    this.maxAttibs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);\n\n    this.attribState = [];\n\n    for (var i = 0; i < this.maxAttibs; i++)\n    {\n        this.attribState[i] = false;\n    }\n\n    // TODO - Why are these not plugins? We can't decouple primitives unless they are....\n    this.defaultShader = new TextureShader(this);\n    this.primitiveShader = new PrimitiveShader(this);\n    this.complexPrimitiveShader = new ComplexPrimitiveShader(this);\n};\n\n/**\n * Takes the attributes given in parameters and uploads them.\n *\n * @param attribs {any[]} attribs\n */\nShaderManager.prototype.setAttribs = function (attribs)\n{\n    // reset temp state\n    var i;\n\n    for (i = 0; i < this.tempAttribState.length; i++)\n    {\n        this.tempAttribState[i] = false;\n    }\n\n    // set the new attribs\n    for (var a in attribs)\n    {\n        this.tempAttribState[attribs[a]] = true;\n    }\n\n    var gl = this.renderer.gl;\n\n    for (i = 0; i < this.attribState.length; i++)\n    {\n        if (this.attribState[i] !== this.tempAttribState[i])\n        {\n            this.attribState[i] = this.tempAttribState[i];\n\n            if (this.attribState[i])\n            {\n                gl.enableVertexAttribArray(i);\n            }\n            else\n            {\n                gl.disableVertexAttribArray(i);\n            }\n        }\n    }\n};\n\n/**\n * Sets the current shader.\n *\n * @param shader {PIXI.Shader} the shader to upload\n */\nShaderManager.prototype.setShader = function (shader)\n{\n    if (this._currentId === shader.uid)\n    {\n        return false;\n    }\n\n    this._currentId = shader.uid;\n\n    this.currentShader = shader;\n\n    this.renderer.gl.useProgram(shader.program);\n    this.setAttribs(shader.attributes);\n\n    return true;\n};\n\n/**\n * Destroys this object.\n *\n */\nShaderManager.prototype.destroy = function ()\n{\n    this.primitiveShader.destroy();\n    this.complexPrimitiveShader.destroy();\n    WebGLManager.prototype.destroy.call(this);\n\n    this.destroyPlugins();\n\n    this.attribState = null;\n\n    this.tempAttribState = null;\n};\n\n},{\"../../../utils\":77,\"../shaders/ComplexPrimitiveShader\":59,\"../shaders/PrimitiveShader\":60,\"../shaders/TextureShader\":62,\"./WebGLManager\":58}],57:[function(require,module,exports){\nvar WebGLManager = require('./WebGLManager'),\n    utils = require('../../../utils');\n\n/**\n * @class\n * @memberof PIXI\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction WebGLMaskManager(renderer)\n{\n    WebGLManager.call(this, renderer);\n    this.stencilMaskStack = null;\n}\n\nWebGLMaskManager.prototype = Object.create(WebGLManager.prototype);\nWebGLMaskManager.prototype.constructor = WebGLMaskManager;\nmodule.exports = WebGLMaskManager;\n\n/**\n * Changes the mask stack that is used by this manager.\n *\n * @param stencilMaskStack {PIXI.StencilMaskStack} The mask stack\n */\nWebGLMaskManager.prototype.setMaskStack = function ( stencilMaskStack )\n{\n    this.stencilMaskStack = stencilMaskStack;\n\n    var gl = this.renderer.gl;\n\n    if (stencilMaskStack.stencilStack.length === 0)\n    {\n        gl.disable(gl.STENCIL_TEST);\n    }\n    else\n    {\n        gl.enable(gl.STENCIL_TEST);\n    }\n};\n\n/**\n * Applies the Mask and adds it to the current filter stack. @alvin\n *\n * @param graphics {PIXI.Graphics}\n * @param webGLData {any[]}\n */\nWebGLMaskManager.prototype.pushStencil = function (graphics, webGLData)\n{\n    this.renderer.currentRenderTarget.attachStencilBuffer();\n\n    var gl = this.renderer.gl,\n        sms = this.stencilMaskStack;\n\n    this.bindGraphics(graphics, webGLData);\n\n    if (sms.stencilStack.length === 0)\n    {\n        gl.enable(gl.STENCIL_TEST);\n        gl.clear(gl.STENCIL_BUFFER_BIT);\n        sms.reverse = true;\n        sms.count = 0;\n    }\n\n    sms.stencilStack.push(webGLData);\n\n    var level = sms.count;\n\n    gl.colorMask(false, false, false, false);\n\n    gl.stencilFunc(gl.ALWAYS,0,0xFF);\n    gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT);\n\n    // draw the triangle strip!\n\n    if (webGLData.mode === 1)\n    {\n        gl.drawElements(gl.TRIANGLE_FAN,  webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 );\n\n        if (sms.reverse)\n        {\n            gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF);\n            gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);\n        }\n        else\n        {\n            gl.stencilFunc(gl.EQUAL,level, 0xFF);\n            gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);\n        }\n\n        // draw a quad to increment..\n        gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 );\n\n        if (sms.reverse)\n        {\n            gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF);\n        }\n        else\n        {\n            gl.stencilFunc(gl.EQUAL,level+1, 0xFF);\n        }\n\n        sms.reverse = !sms.reverse;\n    }\n    else\n    {\n        if (!sms.reverse)\n        {\n            gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF);\n            gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);\n        }\n        else\n        {\n            gl.stencilFunc(gl.EQUAL,level, 0xFF);\n            gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);\n        }\n\n        gl.drawElements(gl.TRIANGLE_STRIP,  webGLData.indices.length, gl.UNSIGNED_SHORT, 0 );\n\n        if (!sms.reverse)\n        {\n            gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF);\n        }\n        else\n        {\n            gl.stencilFunc(gl.EQUAL,level+1, 0xFF);\n        }\n    }\n\n    gl.colorMask(true, true, true, true);\n    gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);\n\n    sms.count++;\n};\n\n/**\n * TODO this does not belong here!\n *\n * @param graphics {PIXI.Graphics}\n * @param webGLData {any[]}\n */\nWebGLMaskManager.prototype.bindGraphics = function (graphics, webGLData)\n{\n    //if (this._currentGraphics === graphics)return;\n    var gl = this.renderer.gl;\n\n     // bind the graphics object..\n    var shader;// = this.renderer.shaderManager.plugins.primitiveShader;\n\n    if (webGLData.mode === 1)\n    {\n        shader = this.renderer.shaderManager.complexPrimitiveShader;\n\n        this.renderer.shaderManager.setShader(shader);\n\n        gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true));\n\n        gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true));\n\n        gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint));\n\n        gl.uniform3fv(shader.uniforms.color._location, webGLData.color);\n\n        gl.uniform1f(shader.uniforms.alpha._location, graphics.worldAlpha);\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer);\n\n        gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 4 * 2, 0);\n\n\n        // now do the rest..\n        // set the index buffer!\n        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer);\n    }\n    else\n    {\n        //this.renderer.shaderManager.activatePrimitiveShader();\n        shader = this.renderer.shaderManager.primitiveShader;\n\n        this.renderer.shaderManager.setShader(shader);\n\n        gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true));\n\n        gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true));\n\n        gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint));\n\n        gl.uniform1f(shader.uniforms.alpha._location, graphics.worldAlpha);\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer);\n\n        gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);\n        gl.vertexAttribPointer(shader.attributes.aColor, 4, gl.FLOAT, false,4 * 6, 2 * 4);\n\n        // set the index buffer!\n        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer);\n    }\n};\n\n/**\n * TODO @alvin\n * @param graphics {PIXI.Graphics}\n * @param webGLData {any[]}\n */\nWebGLMaskManager.prototype.popStencil = function (graphics, webGLData)\n{\n    var gl = this.renderer.gl,\n        sms = this.stencilMaskStack;\n\n    sms.stencilStack.pop();\n\n    sms.count--;\n\n    if (sms.stencilStack.length === 0)\n    {\n        // the stack is empty!\n        gl.disable(gl.STENCIL_TEST);\n\n    }\n    else\n    {\n\n        var level = sms.count;\n\n        this.bindGraphics(graphics, webGLData);\n\n        gl.colorMask(false, false, false, false);\n\n        if (webGLData.mode === 1)\n        {\n            sms.reverse = !sms.reverse;\n\n            if (sms.reverse)\n            {\n                gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF);\n                gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);\n            }\n            else\n            {\n                gl.stencilFunc(gl.EQUAL,level+1, 0xFF);\n                gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);\n            }\n\n            // draw a quad to increment..\n            gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 );\n\n            gl.stencilFunc(gl.ALWAYS,0,0xFF);\n            gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT);\n\n            // draw the triangle strip!\n            gl.drawElements(gl.TRIANGLE_FAN,  webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 );\n\n            this.renderer.drawCount += 2;\n\n            if (!sms.reverse)\n            {\n                gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF);\n            }\n            else\n            {\n                gl.stencilFunc(gl.EQUAL,level, 0xFF);\n            }\n\n        }\n        else\n        {\n          //  console.log(\"<<>>\")\n            if (!sms.reverse)\n            {\n                gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF);\n                gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);\n            }\n            else\n            {\n                gl.stencilFunc(gl.EQUAL,level+1, 0xFF);\n                gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);\n            }\n\n            gl.drawElements(gl.TRIANGLE_STRIP,  webGLData.indices.length, gl.UNSIGNED_SHORT, 0 );\n\n            this.renderer.drawCount++;\n\n            if (!sms.reverse)\n            {\n                gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF);\n            }\n            else\n            {\n                gl.stencilFunc(gl.EQUAL,level, 0xFF);\n            }\n        }\n\n        gl.colorMask(true, true, true, true);\n        gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);\n\n\n    }\n};\n\n/**\n * Destroys the mask stack.\n *\n */\nWebGLMaskManager.prototype.destroy = function ()\n{\n    WebGLManager.prototype.destroy.call(this);\n\n    this.stencilMaskStack.stencilStack = null;\n};\n\n/**\n * Applies the Mask and adds it to the current filter stack.\n *\n * @param maskData {any[]} The mask data structure to use\n */\nWebGLMaskManager.prototype.pushMask = function (maskData)\n{\n\n\n    this.renderer.setObjectRenderer(this.renderer.plugins.graphics);\n\n    if (maskData.dirty)\n    {\n        this.renderer.plugins.graphics.updateGraphics(maskData, this.renderer.gl);\n    }\n\n    if (!maskData._webGL[this.renderer.gl.id].data.length)\n    {\n        return;\n    }\n\n    this.pushStencil(maskData, maskData._webGL[this.renderer.gl.id].data[0]);\n};\n\n/**\n * Removes the last filter from the filter stack and doesn't return it.\n *\n * @param maskData {any[]}\n */\nWebGLMaskManager.prototype.popMask = function (maskData)\n{\n    this.renderer.setObjectRenderer(this.renderer.plugins.graphics);\n\n    this.popStencil(maskData, maskData._webGL[this.renderer.gl.id].data[0]);\n};\n\n\n},{\"../../../utils\":77,\"./WebGLManager\":58}],58:[function(require,module,exports){\n/**\n * @class\n * @memberof PIXI\n * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.\n */\nfunction WebGLManager(renderer)\n{\n    /**\n     * The renderer this manager works for.\n     *\n     * @member {PIXI.WebGLRenderer}\n     */\n    this.renderer = renderer;\n\n    this.renderer.on('context', this.onContextChange, this);\n}\n\nWebGLManager.prototype.constructor = WebGLManager;\nmodule.exports = WebGLManager;\n\n/**\n * Generic method called when there is a WebGL context change.\n *\n */\nWebGLManager.prototype.onContextChange = function ()\n{\n\t// do some codes init!\n};\n\n/**\n * Generic destroy methods to be overridden by the subclass\n *\n */\nWebGLManager.prototype.destroy = function ()\n{\n    this.renderer.off('context', this.onContextChange, this);\n\n    this.renderer = null;\n};\n\n},{}],59:[function(require,module,exports){\nvar Shader = require('./Shader');\n\n/**\n * This shader is used to draw complex primitive shapes for {@link PIXI.Graphics}.\n *\n * @class\n * @memberof PIXI\n * @extends PIXI.Shader\n * @param shaderManager {PIXI.ShaderManager} The webgl shader manager this shader works for.\n */\nfunction ComplexPrimitiveShader(shaderManager)\n{\n    Shader.call(this,\n        shaderManager,\n        // vertex shader\n        [\n            'attribute vec2 aVertexPosition;',\n\n            'uniform mat3 translationMatrix;',\n            'uniform mat3 projectionMatrix;',\n\n            'uniform vec3 tint;',\n            'uniform float alpha;',\n            'uniform vec3 color;',\n\n            'varying vec4 vColor;',\n\n            'void main(void){',\n            '   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',\n            '   vColor = vec4(color * alpha * tint, alpha);',//\" * vec4(tint * alpha, alpha);',\n            '}'\n        ].join('\\n'),\n        // fragment shader\n        [\n            'precision mediump float;',\n\n            'varying vec4 vColor;',\n\n            'void main(void){',\n            '   gl_FragColor = vColor;',\n            '}'\n        ].join('\\n'),\n        // custom uniforms\n        {\n            tint:   { type: '3f', value: [0, 0, 0] },\n            alpha:  { type: '1f', value: 0 },\n            color:  { type: '3f', value: [0,0,0] },\n            translationMatrix: { type: 'mat3', value: new Float32Array(9) },\n            projectionMatrix: { type: 'mat3', value: new Float32Array(9) }\n        },\n        // attributes\n        {\n            aVertexPosition:0\n        }\n    );\n}\n\nComplexPrimitiveShader.prototype = Object.create(Shader.prototype);\nComplexPrimitiveShader.prototype.constructor = ComplexPrimitiveShader;\nmodule.exports = ComplexPrimitiveShader;\n\n},{\"./Shader\":61}],60:[function(require,module,exports){\nvar Shader = require('./Shader');\n\n/**\n * This shader is used to draw simple primitive shapes for {@link PIXI.Graphics}.\n *\n * @class\n * @memberof PIXI\n * @extends PIXI.Shader\n * @param shaderManager {ShaderManager} The webgl shader manager this shader works for.\n */\nfunction PrimitiveShader(shaderManager)\n{\n    Shader.call(this,\n        shaderManager,\n        // vertex shader\n        [\n            'attribute vec2 aVertexPosition;',\n            'attribute vec4 aColor;',\n\n            'uniform mat3 translationMatrix;',\n            'uniform mat3 projectionMatrix;',\n\n            'uniform float alpha;',\n            'uniform float flipY;',\n            'uniform vec3 tint;',\n\n            'varying vec4 vColor;',\n\n            'void main(void){',\n            '   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',\n            '   vColor = aColor * vec4(tint * alpha, alpha);',\n            '}'\n        ].join('\\n'),\n        // fragment shader\n        [\n            'precision mediump float;',\n\n            'varying vec4 vColor;',\n\n            'void main(void){',\n            '   gl_FragColor = vColor;',\n            '}'\n        ].join('\\n'),\n        // custom uniforms\n        {\n            tint:   { type: '3f', value: [0, 0, 0] },\n            alpha:  { type: '1f', value: 0 },\n            translationMatrix: { type: 'mat3', value: new Float32Array(9) },\n            projectionMatrix: { type: 'mat3', value: new Float32Array(9) }\n        },\n        // custom attributes\n        {\n            aVertexPosition:0,\n            aColor:0\n        }\n    );\n}\n\nPrimitiveShader.prototype = Object.create(Shader.prototype);\nPrimitiveShader.prototype.constructor = PrimitiveShader;\nmodule.exports = PrimitiveShader;\n\n},{\"./Shader\":61}],61:[function(require,module,exports){\n/*global console */\nvar utils = require('../../../utils');\n\n/**\n * Base shader class for PIXI managed shaders.\n *\n * @class\n * @memberof PIXI\n * @param shaderManager {PIXI.ShaderManager} The webgl shader manager this shader works for.\n * @param [vertexSrc] {string} The source of the vertex shader.\n * @param [fragmentSrc] {string} The source of the fragment shader.\n * @param [uniforms] {object} Uniforms for this shader.\n * @param [attributes] {object} Attributes for this shader.\n */\nfunction Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes)\n{\n    if (!vertexSrc || !fragmentSrc)\n    {\n         throw new Error('Pixi.js Error. Shader requires vertexSrc and fragmentSrc');\n    }\n\n    /**\n     * A unique id\n     * @member {number}\n     * @readonly\n     */\n    this.uid = utils.uid();\n\n    /**\n     * The current WebGL drawing context\n     * @member {WebGLRenderingContext}\n     * @readonly\n     */\n    this.gl = shaderManager.renderer.gl;\n\n    //TODO maybe we should pass renderer rather than shader manger?? food for thought..\n    this.shaderManager = shaderManager;\n\n    /**\n     * The WebGL program.\n     *\n     * @member {WebGLProgram}\n     * @readonly\n     */\n    this.program = null;\n\n    /**\n     * The uniforms as an object\n     * @member {object}\n     * @private\n     */\n    this.uniforms = uniforms || {};\n\n    /**\n     * The attributes as an object\n     * @member {object}\n     * @private\n     */\n    this.attributes = attributes || {};\n\n    /**\n     * Internal texture counter\n     * @member {number}\n     * @private\n     */\n    this.textureCount = 1;\n\n    /**\n     * The vertex shader as an array of strings\n     *\n     * @member {string}\n     */\n    this.vertexSrc = vertexSrc;\n\n    /**\n     * The fragment shader as an array of strings\n     *\n     * @member {string}\n     */\n    this.fragmentSrc = fragmentSrc;\n\n    this.init();\n}\n\nShader.prototype.constructor = Shader;\nmodule.exports = Shader;\n\n/**\n * Creates the shader and uses it\n *\n */\nShader.prototype.init = function ()\n{\n    this.compile();\n\n    this.gl.useProgram(this.program);\n\n    this.cacheUniformLocations(Object.keys(this.uniforms));\n    this.cacheAttributeLocations(Object.keys(this.attributes));\n};\n\n/**\n * Caches the locations of the uniform for reuse.\n *\n * @param keys {string} the uniforms to cache\n */\nShader.prototype.cacheUniformLocations = function (keys)\n{\n    for (var i = 0; i < keys.length; ++i)\n    {\n        this.uniforms[keys[i]]._location = this.gl.getUniformLocation(this.program, keys[i]);\n    }\n};\n\n/**\n * Caches the locations of the attribute for reuse.\n *\n * @param keys {string} the attributes to cache\n */\nShader.prototype.cacheAttributeLocations = function (keys)\n{\n    for (var i = 0; i < keys.length; ++i)\n    {\n        this.attributes[keys[i]] = this.gl.getAttribLocation(this.program, keys[i]);\n    }\n\n    // TODO: Check if this is needed anymore...\n\n    // Begin worst hack eva //\n\n    // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?\n    // maybe its something to do with the current state of the gl context.\n    // I'm convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel\n    // If theres any webGL people that know why could happen please help :)\n    // if (this.attributes.aColor === -1){\n    //     this.attributes.aColor = 2;\n    // }\n\n    // End worst hack eva //\n};\n\n/**\n * Attaches the shaders and creates the program.\n *\n * @return {WebGLProgram}\n */\nShader.prototype.compile = function ()\n{\n    var gl = this.gl;\n\n    var glVertShader = this._glCompile(gl.VERTEX_SHADER, this.vertexSrc);\n    var glFragShader = this._glCompile(gl.FRAGMENT_SHADER, this.fragmentSrc);\n\n    var program = gl.createProgram();\n\n    gl.attachShader(program, glVertShader);\n    gl.attachShader(program, glFragShader);\n    gl.linkProgram(program);\n\n    // if linking fails, then log and cleanup\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS))\n    {\n        console.error('Pixi.js Error: Could not initialize shader.');\n        console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));\n        console.error('gl.getError()', gl.getError());\n\n        // if there is a program info log, log it\n        if (gl.getProgramInfoLog(program) !== '')\n        {\n            console.warn('Pixi.js Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));\n        }\n\n        gl.deleteProgram(program);\n        program = null;\n    }\n\n    // clean up some shaders\n    gl.deleteShader(glVertShader);\n    gl.deleteShader(glFragShader);\n\n    return (this.program = program);\n};\n\n/*\nShader.prototype.buildSync = function ()\n{\n   // var str = \"\"\n\n   // str =  \"Shader.prototype.syncUniforms = function()\";\n   // str += \"{\\n\";\n\n    for (var key in this.uniforms)\n    {\n        var uniform = this.uniforms[key];\n\n        Object.defineProperty(this, key, {\n\n            get: function ()\n            {\n                return uniform.value\n            },\n            set: function (value)\n            {\n                this.setUniform(uniform, value);\n            }\n        });\n\n        console.log( makePropSetter( key, \" bloop\", uniform.type )  )\n  //      Object.def\n        //    location = uniform._location,\n          //  value = uniform.value,\n            //i, il;\n\n    //    str += \"gl.uniform1i(this.uniforms.\"+ key +\"._location, this.uniforms.\" + key + \".value );\\n\"\n\n    }\n\n}*/\n\n/**\n* Adds a new uniform\n*\n* @param uniform {object} the new uniform to attach\n*/\nShader.prototype.syncUniform = function (uniform)\n{\n    var location = uniform._location,\n        value = uniform.value,\n        gl = this.gl,\n        i, il;\n\n    switch (uniform.type)\n    {\n        case 'b':\n        case 'bool':\n        case 'boolean':\n            gl.uniform1i(location, value ? 1 : 0);\n            break;\n\n        // single int value\n        case 'i':\n        case '1i':\n            gl.uniform1i(location, value);\n            break;\n\n        // single float value\n        case 'f':\n        case '1f':\n            gl.uniform1f(location, value);\n            break;\n\n        // Float32Array(2) or JS Arrray\n        case '2f':\n            gl.uniform2f(location, value[0], value[1]);\n            break;\n\n        // Float32Array(3) or JS Arrray\n        case '3f':\n            gl.uniform3f(location, value[0], value[1], value[2]);\n            break;\n\n        // Float32Array(4) or JS Arrray\n        case '4f':\n            gl.uniform4f(location, value[0], value[1], value[2], value[3]);\n            break;\n\n        // a 2D Point object\n        case 'v2':\n            gl.uniform2f(location, value.x, value.y);\n            break;\n\n        // a 3D Point object\n        case 'v3':\n            gl.uniform3f(location, value.x, value.y, value.z);\n            break;\n\n        // a 4D Point object\n        case 'v4':\n            gl.uniform4f(location, value.x, value.y, value.z, value.w);\n            break;\n\n        // Int32Array or JS Array\n        case '1iv':\n            gl.uniform1iv(location, value);\n            break;\n\n        // Int32Array or JS Array\n        case '2iv':\n            gl.uniform2iv(location, value);\n            break;\n\n        // Int32Array or JS Array\n        case '3iv':\n            gl.uniform3iv(location, value);\n            break;\n\n        // Int32Array or JS Array\n        case '4iv':\n            gl.uniform4iv(location, value);\n            break;\n\n        // Float32Array or JS Array\n        case '1fv':\n            gl.uniform1fv(location, value);\n            break;\n\n        // Float32Array or JS Array\n        case '2fv':\n            gl.uniform2fv(location, value);\n            break;\n\n        // Float32Array or JS Array\n        case '3fv':\n            gl.uniform3fv(location, value);\n            break;\n\n        // Float32Array or JS Array\n        case '4fv':\n            gl.uniform4fv(location, value);\n            break;\n\n        // Float32Array or JS Array\n        case 'm2':\n        case 'mat2':\n        case 'Matrix2fv':\n            gl.uniformMatrix2fv(location, uniform.transpose, value);\n            break;\n\n        // Float32Array or JS Array\n        case 'm3':\n        case 'mat3':\n        case 'Matrix3fv':\n\n            gl.uniformMatrix3fv(location, uniform.transpose, value);\n            break;\n\n        // Float32Array or JS Array\n        case 'm4':\n        case 'mat4':\n        case 'Matrix4fv':\n            gl.uniformMatrix4fv(location, uniform.transpose, value);\n            break;\n\n        // a Color Value\n        case 'c':\n            if (typeof value === 'number')\n            {\n                value = utils.hex2rgb(value);\n            }\n\n            gl.uniform3f(location, value[0], value[1], value[2]);\n            break;\n\n        // flat array of integers (JS or typed array)\n        case 'iv1':\n            gl.uniform1iv(location, value);\n            break;\n\n        // flat array of integers with 3 x N size (JS or typed array)\n        case 'iv':\n            gl.uniform3iv(location, value);\n            break;\n\n        // flat array of floats (JS or typed array)\n        case 'fv1':\n            gl.uniform1fv(location, value);\n            break;\n\n        // flat array of floats with 3 x N size (JS or typed array)\n        case 'fv':\n            gl.uniform3fv(location, value);\n            break;\n\n        // array of 2D Point objects\n        case 'v2v':\n            if (!uniform._array)\n            {\n                uniform._array = new Float32Array(2 * value.length);\n            }\n\n            for (i = 0, il = value.length; i < il; ++i)\n            {\n                uniform._array[i * 2]       = value[i].x;\n                uniform._array[i * 2 + 1]   = value[i].y;\n            }\n\n            gl.uniform2fv(location, uniform._array);\n            break;\n\n        // array of 3D Point objects\n        case 'v3v':\n            if (!uniform._array)\n            {\n                uniform._array = new Float32Array(3 * value.length);\n            }\n\n            for (i = 0, il = value.length; i < il; ++i)\n            {\n                uniform._array[i * 3]       = value[i].x;\n                uniform._array[i * 3 + 1]   = value[i].y;\n                uniform._array[i * 3 + 2]   = value[i].z;\n\n            }\n\n            gl.uniform3fv(location, uniform._array);\n            break;\n\n        // array of 4D Point objects\n        case 'v4v':\n            if (!uniform._array)\n            {\n                uniform._array = new Float32Array(4 * value.length);\n            }\n\n            for (i = 0, il = value.length; i < il; ++i)\n            {\n                uniform._array[i * 4]       = value[i].x;\n                uniform._array[i * 4 + 1]   = value[i].y;\n                uniform._array[i * 4 + 2]   = value[i].z;\n                uniform._array[i * 4 + 3]   = value[i].w;\n\n            }\n\n            gl.uniform4fv(location, uniform._array);\n            break;\n\n        // PIXI.Texture\n        case 't':\n        case 'sampler2D':\n\n            if (!uniform.value || !uniform.value.baseTexture.hasLoaded)\n            {\n                break;\n            }\n\n            // activate this texture\n            gl.activeTexture(gl['TEXTURE' + this.textureCount]);\n\n            var texture = uniform.value.baseTexture._glTextures[gl.id];\n\n            if (!texture)\n            {\n                this.initSampler2D(uniform);\n\n                // set the textur to the newly created one..\n                texture = uniform.value.baseTexture._glTextures[gl.id];\n            }\n\n            // bind the texture\n            gl.bindTexture(gl.TEXTURE_2D, texture);\n\n            // set uniform to texture index\n            gl.uniform1i(uniform._location, this.textureCount);\n\n            // increment next texture id\n            this.textureCount++;\n\n            break;\n\n        default:\n            console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type);\n    }\n};\n\n/**\n * Updates the shader uniform values.\n *\n */\nShader.prototype.syncUniforms = function ()\n{\n    this.textureCount = 1;\n\n    for (var key in this.uniforms)\n    {\n        this.syncUniform(this.uniforms[key]);\n    }\n};\n\n\n/**\n * Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded)\n *\n */\nShader.prototype.initSampler2D = function (uniform)\n{\n    var gl = this.gl;\n\n    var texture = uniform.value.baseTexture;\n\n    if(!texture.hasLoaded)\n    {\n        return;\n    }\n\n\n\n    if (uniform.textureData)\n    {\n\n        //TODO move this...\n        var data = uniform.textureData;\n\n        texture._glTextures[gl.id] = gl.createTexture();\n\n        gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);\n\n        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);\n        // GLTexture = mag linear, min linear_mipmap_linear, wrap repeat + gl.generateMipmap(gl.TEXTURE_2D);\n        // GLTextureLinear = mag/min linear, wrap clamp\n        // GLTextureNearestRepeat = mag/min NEAREST, wrap repeat\n        // GLTextureNearest = mag/min nearest, wrap clamp\n        // AudioTexture = whatever + luminance + width 512, height 2, border 0\n        // KeyTexture = whatever + luminance + width 256, height 2, border 0\n\n        //  magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST\n        //  wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT\n\n        gl.texImage2D(gl.TEXTURE_2D, 0, data.luminance ? gl.LUMINANCE : gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, data.magFilter ? data.magFilter : gl.LINEAR );\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, data.wrapS ? data.wrapS : gl.CLAMP_TO_EDGE );\n\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, data.wrapS ? data.wrapS : gl.CLAMP_TO_EDGE);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, data.wrapT ? data.wrapT : gl.CLAMP_TO_EDGE);\n    }\n    else\n    {\n        this.shaderManager.renderer.updateTexture(texture);\n    }\n};\n\n/**\n * Destroys the shader.\n *\n */\nShader.prototype.destroy = function ()\n{\n    this.gl.deleteProgram(this.program);\n\n    this.gl = null;\n    this.uniforms = null;\n    this.attributes = null;\n\n    this.vertexSrc = null;\n    this.fragmentSrc = null;\n};\n\nShader.prototype._glCompile = function (type, src)\n{\n    var shader = this.gl.createShader(type);\n\n    this.gl.shaderSource(shader, src);\n    this.gl.compileShader(shader);\n\n    if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS))\n    {\n        console.log(this.gl.getShaderInfoLog(shader));\n        return null;\n    }\n\n    return shader;\n};\n\n},{\"../../../utils\":77}],62:[function(require,module,exports){\nvar Shader = require('./Shader');\n\n/**\n * @class\n * @memberof PIXI\n * @extends PIXI.Shader\n * @param shaderManager {PIXI.ShaderManager} The webgl shader manager this shader works for.\n * @param [vertexSrc] {string} The source of the vertex shader.\n * @param [fragmentSrc] {string} The source of the fragment shader.\n * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones.\n * @param [fragmentSrc] {string} The source of the fragment shader.\n */\nfunction TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes)\n{\n    var uniforms = {\n\n        uSampler:           { type: 'sampler2D', value: 0 },\n        projectionMatrix:   { type: 'mat3', value: new Float32Array([1, 0, 0,\n                                                                     0, 1, 0,\n                                                                     0, 0, 1]) }\n    };\n\n    if (customUniforms)\n    {\n        for (var u in customUniforms)\n        {\n            uniforms[u] = customUniforms[u];\n        }\n    }\n\n\n    var attributes = {\n        aVertexPosition:    0,\n        aTextureCoord:      0,\n        aColor:             0\n    };\n\n    if (customAttributes)\n    {\n        for (var a in customAttributes)\n        {\n            attributes[a] = customAttributes[a];\n        }\n    }\n\n    /**\n     * The vertex shader.\n     *\n     * @member {string}\n     */\n    vertexSrc = vertexSrc || TextureShader.defaultVertexSrc;\n\n    /**\n     * The fragment shader.\n     *\n     * @member {string}\n     */\n    fragmentSrc = fragmentSrc || TextureShader.defaultFragmentSrc;\n\n    Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes);\n}\n\n// constructor\nTextureShader.prototype = Object.create(Shader.prototype);\nTextureShader.prototype.constructor = TextureShader;\nmodule.exports = TextureShader;\n\n/**\n * The default vertex shader source\n *\n * @static\n * @constant\n */\nTextureShader.defaultVertexSrc = [\n    'precision lowp float;',\n    'attribute vec2 aVertexPosition;',\n    'attribute vec2 aTextureCoord;',\n    'attribute vec4 aColor;',\n\n    'uniform mat3 projectionMatrix;',\n\n    'varying vec2 vTextureCoord;',\n    'varying vec4 vColor;',\n\n    'void main(void){',\n    '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',\n    '   vTextureCoord = aTextureCoord;',\n    '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',\n    '}'\n].join('\\n');\n\n/**\n * The default fragment shader source\n *\n * @static\n * @constant\n */\nTextureShader.defaultFragmentSrc = [\n    'precision lowp float;',\n\n    'varying vec2 vTextureCoord;',\n    'varying vec4 vColor;',\n\n    'uniform sampler2D uSampler;',\n\n    'void main(void){',\n    '   gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',\n    '}'\n].join('\\n');\n\n},{\"./Shader\":61}],63:[function(require,module,exports){\nvar WebGLManager = require('../managers/WebGLManager');\n\n/**\n * Base for a common object renderer that can be used as a system renderer plugin.\n *\n * @class\n * @extends PIXI.WebGLManager\n * @memberof PIXI\n * @param renderer {PIXI.WebGLRenderer} The renderer this object renderer works for.\n */\nfunction ObjectRenderer(renderer)\n{\n    WebGLManager.call(this, renderer);\n}\n\n\nObjectRenderer.prototype = Object.create(WebGLManager.prototype);\nObjectRenderer.prototype.constructor = ObjectRenderer;\nmodule.exports = ObjectRenderer;\n\n/**\n * Starts the renderer and sets the shader\n *\n */\nObjectRenderer.prototype.start = function ()\n{\n    // set the shader..\n};\n\n/**\n * Stops the renderer\n *\n */\nObjectRenderer.prototype.stop = function ()\n{\n    this.flush();\n};\n\n/**\n * flushes\n *\n */\nObjectRenderer.prototype.flush = function ()\n{\n    // flush!\n};\n\n/**\n * Renders an object\n *\n * @param object {PIXI.DisplayObject} The object to render.\n */\nObjectRenderer.prototype.render = function (object) // jshint unused:false\n{\n    // render the object\n};\n\n},{\"../managers/WebGLManager\":58}],64:[function(require,module,exports){\n/**\n * Helper class to create a quad\n *\n * @class\n * @memberof PIXI\n * @param gl {WebGLRenderingContext} The gl context for this quad to use.\n */\nfunction Quad(gl)\n{\n    /*\n     * the current WebGL drawing context\n     *\n     * @member {WebGLRenderingContext}\n     */\n    this.gl = gl;\n\n//    this.textures = new TextureUvs();\n\n    /**\n     * An array of vertices\n     *\n     * @member {Float32Array}\n     */\n    this.vertices = new Float32Array([\n        0,0,\n        200,0,\n        200,200,\n        0,200\n    ]);\n\n    /**\n     * The Uvs of the quad\n     *\n     * @member {Float32Array}\n     */\n    this.uvs = new Float32Array([\n        0,0,\n        1,0,\n        1,1,\n        0,1\n    ]);\n\n//    var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24);\n    //TODO convert this to a 32 unsigned int array\n    /**\n     * The color components of the triangles\n     *\n     * @member {Float32Array}\n     */\n    this.colors = new Float32Array([\n        1,1,1,1,\n        1,1,1,1,\n        1,1,1,1,\n        1,1,1,1\n    ]);\n\n    /*\n     * @member {Uint16Array} An array containing the indices of the vertices\n     */\n    this.indices = new Uint16Array([\n        0, 1, 2, 0, 3, 2\n    ]);\n\n    /*\n     * @member {WebGLBuffer} The vertex buffer\n     */\n    this.vertexBuffer = gl.createBuffer();\n\n    /*\n     * @member {WebGLBuffer} The index buffer\n     */\n    this.indexBuffer = gl.createBuffer();\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 16) * 4, gl.DYNAMIC_DRAW);\n\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);\n\n    this.upload();\n}\n\nQuad.prototype.constructor = Quad;\n\n/**\n * Maps two Rectangle to the quad\n * @param rect {PIXI.Rectangle} the first rectangle\n * @param rect2 {PIXI.Rectangle} the second rectangle\n */\nQuad.prototype.map = function(rect, rect2)\n{\n    var x = 0; //rect2.x / rect.width;\n    var y = 0; //rect2.y / rect.height;\n\n    this.uvs[0] = x;\n    this.uvs[1] = y;\n\n    this.uvs[2] = x + rect2.width / rect.width;\n    this.uvs[3] = y;\n\n    this.uvs[4] = x + rect2.width / rect.width;\n    this.uvs[5] = y + rect2.height / rect.height;\n\n    this.uvs[6] = x;\n    this.uvs[7] = y + rect2.height / rect.height;\n\n    /// -----\n    x = rect2.x;\n    y = rect2.y;\n\n    this.vertices[0] = x;\n    this.vertices[1] = y;\n\n    this.vertices[2] = x + rect2.width;\n    this.vertices[3] = y;\n\n    this.vertices[4] = x + rect2.width;\n    this.vertices[5] = y + rect2.height;\n\n    this.vertices[6] = x;\n    this.vertices[7] = y + rect2.height;\n\n    this.upload();\n};\n\n/**\n * Binds the buffer and uploads the data\n */\nQuad.prototype.upload = function()\n{\n    var gl = this.gl;\n\n    // TODO could probably be pushed into one upload!\n    gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer );\n\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);\n\n    gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs);\n\n    gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors);\n};\n\nQuad.prototype.destroy = function()\n{\n    var gl = this.gl;\n    \n     gl.deleteBuffer(this.vertexBuffer);\n     gl.deleteBuffer(this.indexBuffer);\n};\n\nmodule.exports = Quad;\n\n\n\n},{}],65:[function(require,module,exports){\nvar math = require('../../../math'),\n    utils = require('../../../utils'),\n    CONST = require('../../../const'),\n    //StencilManager = require('../managers/StencilManager'),\n    StencilMaskStack = require('./StencilMaskStack');\n\n/**\n * @author Mat Groves http://matgroves.com/ @Doormat23\n */\n\n/**\n * @class\n * @memberof PIXI\n * @param gl {WebGLRenderingContext} the current WebGL drawing context\n * @param width {number} the horizontal range of the filter\n * @param height {number} the vertical range of the filter\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @param resolution {number} the current resolution\n * @param root {boolean} Whether this object is the root element or not\n */\nvar RenderTarget = function(gl, width, height, scaleMode, resolution, root)\n{\n    //TODO Resolution could go here ( eg low res blurs )\n\n    /**\n     * The current WebGL drawing context.\n     *\n     * @member {WebGLRenderingContext}\n     */\n    this.gl = gl;\n\n    // next time to create a frame buffer and texture\n\n    /**\n     * A frame buffer\n     *\n     * @member {WebGLFrameBuffer}\n     */\n    this.frameBuffer = null;\n\n    /**\n     * The texture\n     *\n     * @member {PIXI.Texture}\n     */\n    this.texture = null;\n\n    /**\n     * The size of the object as a rectangle\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.size = new math.Rectangle(0, 0, 1, 1);\n\n    /**\n     * The current resolution\n     *\n     * @member {number}\n     */\n    this.resolution = resolution || CONST.RESOLUTION;\n\n    /**\n     * The projection matrix\n     *\n     * @member {PIXI.Matrix}\n     */\n    this.projectionMatrix = new math.Matrix();\n\n    /**\n     * The object's transform\n     *\n     * @member {PIXI.Matrix}\n     */\n    this.transform = null;\n\n    /**\n     * The frame.\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.frame = null;\n\n    /**\n     * The stencil buffer stores masking data for the render target\n     *\n     * @member {WebGLRenderBuffer}\n     */\n    this.stencilBuffer = null;\n\n    /**\n     * The data structure for the stencil masks\n     *\n     * @member {PIXI.StencilMaskStack}\n     */\n    this.stencilMaskStack = new StencilMaskStack();\n\n    /**\n     * Stores filter data for the render target\n     *\n     * @member {object[]}\n     */\n    this.filterStack = [\n        {\n            renderTarget:this,\n            filter:[],\n            bounds:this.size\n        }\n    ];\n\n\n    /**\n     * The scale mode.\n     *\n     * @member {number}\n     * @default PIXI.SCALE_MODES.DEFAULT\n     * @see PIXI.SCALE_MODES\n     */\n    this.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;\n\n    /**\n     * Whether this object is the root element or not\n     *\n     * @member {boolean}\n     */\n    this.root = root;\n\n    if (!this.root)\n    {\n       // this.flipY = true;\n        this.frameBuffer = gl.createFramebuffer();\n\n        /*\n            A frame buffer needs a target to render to..\n            create a texture and bind it attach it to the framebuffer..\n         */\n\n        this.texture = gl.createTexture();\n\n        gl.bindTexture(gl.TEXTURE_2D,  this.texture);\n\n        // set the scale properties of the texture..\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n\n        // check to see if the texture is a power of two!\n        var isPowerOfTwo = utils.isPowerOfTwo(width, height);\n\n        //TODO for 99% of use cases if a texture is power of two we should tile the texture...\n         if (!isPowerOfTwo)\n        {\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n        }\n        else\n        {\n\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n        }\n\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer );\n        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);\n    }\n\n    this.resize(width, height);\n};\n\nRenderTarget.prototype.constructor = RenderTarget;\nmodule.exports = RenderTarget;\n\n/**\n * Clears the filter texture.\n *\n * @param [bind=false] {boolean} Should we bind our framebuffer before clearing?\n */\nRenderTarget.prototype.clear = function(bind)\n{\n    var gl = this.gl;\n    if(bind)\n    {\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);\n    }\n\n    gl.clearColor(0,0,0,0);\n    gl.clear(gl.COLOR_BUFFER_BIT);\n};\n\n/**\n * Binds the stencil buffer.\n *\n */\nRenderTarget.prototype.attachStencilBuffer = function()\n{\n\n    if (this.stencilBuffer)\n    {\n        return;\n    }\n\n    /**\n     * The stencil buffer is used for masking in pixi\n     * lets create one and then add attach it to the framebuffer..\n     */\n    if (!this.root)\n    {\n        var gl = this.gl;\n\n        this.stencilBuffer = gl.createRenderbuffer();\n        gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencilBuffer);\n        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencilBuffer);\n        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,  this.size.width * this.resolution  , this.size.height * this.resolution );\n    }\n};\n\n/**\n * Binds the buffers and initialises the viewport.\n *\n */\nRenderTarget.prototype.activate = function()\n{\n    //TOOD refactor usage of frame..\n    var gl = this.gl;\n\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);\n\n    var projectionFrame = this.frame || this.size;\n\n    // TODO add a dirty flag to this of a setter for the frame?\n    this.calculateProjection( projectionFrame );\n\n    if(this.transform)\n    {\n        this.projectionMatrix.append(this.transform);\n    }\n\n    gl.viewport(0,0, projectionFrame.width * this.resolution, projectionFrame.height * this.resolution);\n};\n\n/**\n * Updates the projection matrix based on a projection frame (which is a rectangle)\n *\n */\nRenderTarget.prototype.calculateProjection = function (projectionFrame)\n{\n    var pm = this.projectionMatrix;\n\n    pm.identity();\n\n    if (!this.root)\n    {\n        pm.a = 1 / projectionFrame.width*2;\n        pm.d = 1 / projectionFrame.height*2;\n\n        pm.tx = -1 - projectionFrame.x * pm.a;\n        pm.ty = -1 - projectionFrame.y * pm.d;\n    }\n    else\n    {\n        pm.a = 1 / projectionFrame.width*2;\n        pm.d = -1 / projectionFrame.height*2;\n\n        pm.tx = -1 - projectionFrame.x * pm.a;\n        pm.ty = 1 - projectionFrame.y * pm.d;\n    }\n};\n\n\n/**\n * Resizes the texture to the specified width and height\n *\n * @param width {Number} the new width of the texture\n * @param height {Number} the new height of the texture\n */\nRenderTarget.prototype.resize = function (width, height)\n{\n    width = width | 0;\n    height = height | 0;\n\n    if (this.size.width === width && this.size.height === height) {\n        return;\n    }\n\n    this.size.width = width;\n    this.size.height = height;\n\n    if (!this.root)\n    {\n        var gl = this.gl;\n\n        gl.bindTexture(gl.TEXTURE_2D,  this.texture);\n\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  width * this.resolution, height * this.resolution , 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n\n        if (this.stencilBuffer )\n        {\n            // update the stencil buffer width and height\n            gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencilBuffer);\n            gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,  width * this.resolution, height * this.resolution );\n        }\n    }\n\n    var projectionFrame = this.frame || this.size;\n\n    this.calculateProjection( projectionFrame );\n};\n\n/**\n * Destroys the render target.\n *\n */\nRenderTarget.prototype.destroy = function ()\n{\n    var gl = this.gl;\n    gl.deleteRenderbuffer( this.stencilBuffer );\n    gl.deleteFramebuffer( this.frameBuffer );\n    gl.deleteTexture( this.texture );\n\n    this.frameBuffer = null;\n    this.texture = null;\n};\n\n},{\"../../../const\":22,\"../../../math\":33,\"../../../utils\":77,\"./StencilMaskStack\":66}],66:[function(require,module,exports){\n/**\n * Generic Mask Stack data structure\n * @class\n * @memberof PIXI\n */\nfunction StencilMaskStack()\n{\n\t/**\n     * The actual stack\n     *\n     * @member {any[]}\n     */\n    this.stencilStack = [];\n\n    /**\n     * TODO @alvin\n     *\n     * @member {boolean}\n     */\n    this.reverse = true;\n\n    /**\n     * Internal count\n     *\n     * @member {number}\n     */\n    this.count = 0;\n}\n\nStencilMaskStack.prototype.constructor = StencilMaskStack;\nmodule.exports = StencilMaskStack;\n\n},{}],67:[function(require,module,exports){\nvar math = require('../math'),\n    Texture = require('../textures/Texture'),\n    Container = require('../display/Container'),\n    CanvasTinter = require('../renderers/canvas/utils/CanvasTinter'),\n    utils = require('../utils'),\n    CONST = require('../const'),\n    tempPoint = new math.Point(),\n    GroupD8 = math.GroupD8,\n    canvasRenderWorldTransform = new math.Matrix();\n\n/**\n * The Sprite object is the base for all textured objects that are rendered to the screen\n *\n * A sprite can be created directly from an image like this:\n *\n * ```js\n * var sprite = new PIXI.Sprite.fromImage('assets/image.png');\n * ```\n *\n * @class\n * @extends PIXI.Container\n * @memberof PIXI\n * @param texture {PIXI.Texture} The texture for this sprite\n */\nfunction Sprite(texture)\n{\n    Container.call(this);\n\n    /**\n     * The anchor sets the origin point of the texture.\n     * The default is 0,0 this means the texture's origin is the top left\n     * Setting the anchor to 0.5,0.5 means the texture's origin is centered\n     * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner\n     *\n     * @member {PIXI.Point}\n     */\n    this.anchor = new math.Point();\n\n    /**\n     * The texture that the sprite is using\n     *\n     * @member {PIXI.Texture}\n     * @private\n     */\n    this._texture = null;\n\n    /**\n     * The width of the sprite (this is initially set by the texture)\n     *\n     * @member {number}\n     * @private\n     */\n    this._width = 0;\n\n    /**\n     * The height of the sprite (this is initially set by the texture)\n     *\n     * @member {number}\n     * @private\n     */\n    this._height = 0;\n\n    /**\n     * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.\n     *\n     * @member {number}\n     * @default 0xFFFFFF\n     */\n    this.tint = 0xFFFFFF;\n\n    /**\n     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.\n     *\n     * @member {number}\n     * @default PIXI.BLEND_MODES.NORMAL\n     * @see PIXI.BLEND_MODES\n     */\n    this.blendMode = CONST.BLEND_MODES.NORMAL;\n\n    /**\n     * The shader that will be used to render the sprite. Set to null to remove a current shader.\n     *\n     * @member {PIXI.AbstractFilter|PIXI.Shader}\n     */\n    this.shader = null;\n\n    /**\n     * An internal cached value of the tint.\n     *\n     * @member {number}\n     * @default 0xFFFFFF\n     */\n    this.cachedTint = 0xFFFFFF;\n\n    // call texture setter\n    this.texture = texture || Texture.EMPTY;\n}\n\n// constructor\nSprite.prototype = Object.create(Container.prototype);\nSprite.prototype.constructor = Sprite;\nmodule.exports = Sprite;\n\nObject.defineProperties(Sprite.prototype, {\n    /**\n     * The width of the sprite, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Sprite#\n     */\n    width: {\n        get: function ()\n        {\n            return Math.abs(this.scale.x) * this.texture._frame.width;\n        },\n        set: function (value)\n        {\n            var sign = utils.sign(this.scale.x) || 1;\n            this.scale.x = sign * value / this.texture._frame.width;\n            this._width = value;\n        }\n    },\n\n    /**\n     * The height of the sprite, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Sprite#\n     */\n    height: {\n        get: function ()\n        {\n            return  Math.abs(this.scale.y) * this.texture._frame.height;\n        },\n        set: function (value)\n        {\n            var sign = utils.sign(this.scale.y) || 1;\n            this.scale.y = sign * value / this.texture._frame.height;\n            this._height = value;\n        }\n    },\n\n    /**\n     * The texture that the sprite is using\n     *\n     * @member {PIXI.Texture}\n     * @memberof PIXI.Sprite#\n     */\n    texture: {\n        get: function ()\n        {\n            return  this._texture;\n        },\n        set: function (value)\n        {\n            if (this._texture === value)\n            {\n                return;\n            }\n\n            this._texture = value;\n            this.cachedTint = 0xFFFFFF;\n\n            if (value)\n            {\n                // wait for the texture to load\n                if (value.baseTexture.hasLoaded)\n                {\n                    this._onTextureUpdate();\n                }\n                else\n                {\n                    value.once('update', this._onTextureUpdate, this);\n                }\n            }\n        }\n    }\n});\n\n/**\n * When the texture is updated, this event will fire to update the scale and frame\n *\n * @private\n */\nSprite.prototype._onTextureUpdate = function ()\n{\n    // so if _width is 0 then width was not set..\n    if (this._width)\n    {\n        this.scale.x = utils.sign(this.scale.x) * this._width / this.texture.frame.width;\n    }\n\n    if (this._height)\n    {\n        this.scale.y = utils.sign(this.scale.y) * this._height / this.texture.frame.height;\n    }\n};\n\n/**\n*\n* Renders the object using the WebGL renderer\n*\n* @param renderer {PIXI.WebGLRenderer}\n* @private\n*/\nSprite.prototype._renderWebGL = function (renderer)\n{\n    renderer.setObjectRenderer(renderer.plugins.sprite);\n    renderer.plugins.sprite.render(this);\n};\n\n/**\n * Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account.\n *\n * @param matrix {PIXI.Matrix} the transformation matrix of the sprite\n * @return {PIXI.Rectangle} the framing rectangle\n */\nSprite.prototype.getBounds = function (matrix)\n{\n    if(!this._currentBounds)\n    {\n\n        var width = this._texture._frame.width;\n        var height = this._texture._frame.height;\n\n        var w0 = width * (1-this.anchor.x);\n        var w1 = width * -this.anchor.x;\n\n        var h0 = height * (1-this.anchor.y);\n        var h1 = height * -this.anchor.y;\n\n        var worldTransform = matrix || this.worldTransform ;\n\n        var a = worldTransform.a;\n        var b = worldTransform.b;\n        var c = worldTransform.c;\n        var d = worldTransform.d;\n        var tx = worldTransform.tx;\n        var ty = worldTransform.ty;\n\n        var minX,\n            maxX,\n            minY,\n            maxY;\n\n        //TODO - I am SURE this can be optimised, but the below is not accurate enough..\n        /*\n        if (b === 0 && c === 0)\n        {\n            // scale may be negative!\n            if (a < 0)\n            {\n                a *= -1;\n            }\n\n            if (d < 0)\n            {\n                d *= -1;\n            }\n\n            // this means there is no rotation going on right? RIGHT?\n            // if thats the case then we can avoid checking the bound values! yay\n            minX = a * w1 + tx;\n            maxX = a * w0 + tx;\n            minY = d * h1 + ty;\n            maxY = d * h0 + ty;\n        }\n        else\n        {\n        */\n\n        var x1 = a * w1 + c * h1 + tx;\n        var y1 = d * h1 + b * w1 + ty;\n\n        var x2 = a * w0 + c * h1 + tx;\n        var y2 = d * h1 + b * w0 + ty;\n\n        var x3 = a * w0 + c * h0 + tx;\n        var y3 = d * h0 + b * w0 + ty;\n\n        var x4 =  a * w1 + c * h0 + tx;\n        var y4 =  d * h0 + b * w1 + ty;\n\n        minX = x1;\n        minX = x2 < minX ? x2 : minX;\n        minX = x3 < minX ? x3 : minX;\n        minX = x4 < minX ? x4 : minX;\n\n        minY = y1;\n        minY = y2 < minY ? y2 : minY;\n        minY = y3 < minY ? y3 : minY;\n        minY = y4 < minY ? y4 : minY;\n\n        maxX = x1;\n        maxX = x2 > maxX ? x2 : maxX;\n        maxX = x3 > maxX ? x3 : maxX;\n        maxX = x4 > maxX ? x4 : maxX;\n\n        maxY = y1;\n        maxY = y2 > maxY ? y2 : maxY;\n        maxY = y3 > maxY ? y3 : maxY;\n        maxY = y4 > maxY ? y4 : maxY;\n\n        //}\n\n        // check for children\n        if(this.children.length)\n        {\n            var childBounds = this.containerGetBounds();\n\n            w0 = childBounds.x;\n            w1 = childBounds.x + childBounds.width;\n            h0 = childBounds.y;\n            h1 = childBounds.y + childBounds.height;\n\n            minX = (minX < w0) ? minX : w0;\n            minY = (minY < h0) ? minY : h0;\n\n            maxX = (maxX > w1) ? maxX : w1;\n            maxY = (maxY > h1) ? maxY : h1;\n        }\n\n        var bounds = this._bounds;\n\n        bounds.x = minX;\n        bounds.width = maxX - minX;\n\n        bounds.y = minY;\n        bounds.height = maxY - minY;\n\n        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate\n        this._currentBounds = bounds;\n    }\n\n    return this._currentBounds;\n};\n\n/**\n * Gets the local bounds of the sprite object.\n *\n */\nSprite.prototype.getLocalBounds = function ()\n{\n    this._bounds.x = -this._texture._frame.width * this.anchor.x;\n    this._bounds.y = -this._texture._frame.height * this.anchor.y;\n    this._bounds.width = this._texture._frame.width;\n    this._bounds.height = this._texture._frame.height;\n    return this._bounds;\n};\n\n/**\n* Tests if a point is inside this sprite\n*\n* @param point {PIXI.Point} the point to test\n* @return {boolean} the result of the test\n*/\nSprite.prototype.containsPoint = function( point )\n{\n    this.worldTransform.applyInverse(point,  tempPoint);\n\n    var width = this._texture._frame.width;\n    var height = this._texture._frame.height;\n    var x1 = -width * this.anchor.x;\n    var y1;\n\n    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )\n    {\n        y1 = -height * this.anchor.y;\n\n        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )\n        {\n            return true;\n        }\n    }\n\n    return false;\n};\n\n/**\n* Renders the object using the Canvas renderer\n*\n* @param renderer {PIXI.CanvasRenderer} The renderer\n* @private\n*/\nSprite.prototype._renderCanvas = function (renderer)\n{\n    if (this.texture.crop.width <= 0 || this.texture.crop.height <= 0)\n    {\n        return;\n    }\n\n    var compositeOperation = renderer.blendModes[this.blendMode];\n    if (compositeOperation !== renderer.context.globalCompositeOperation)\n    {\n        renderer.context.globalCompositeOperation = compositeOperation;\n    }\n\n    //  Ignore null sources\n    if (this.texture.valid)\n    {\n        var texture = this._texture,\n            wt = this.worldTransform,\n            dx,\n            dy,\n            width = texture.crop.width,\n            height = texture.crop.height;\n\n        renderer.context.globalAlpha = this.worldAlpha;\n\n        // If smoothingEnabled is supported and we need to change the smoothing property for this texture\n        var smoothingEnabled = texture.baseTexture.scaleMode === CONST.SCALE_MODES.LINEAR;\n        if (renderer.smoothProperty && renderer.context[renderer.smoothProperty] !== smoothingEnabled)\n        {\n            renderer.context[renderer.smoothProperty] = smoothingEnabled;\n        }\n\n        //inline GroupD8.isSwapWidthHeight\n        if ((texture.rotate & 3) === 2) {\n            width = texture.crop.height;\n            height = texture.crop.width;\n        }\n        if (texture.trim) {\n            dx = texture.crop.width/2 + texture.trim.x - this.anchor.x * texture.trim.width;\n            dy = texture.crop.height/2 + texture.trim.y - this.anchor.y * texture.trim.height;\n        } else {\n            dx = (0.5 - this.anchor.x) * texture._frame.width;\n            dy = (0.5 - this.anchor.y) * texture._frame.height;\n        }\n        if(texture.rotate) {\n            wt.copy(canvasRenderWorldTransform);\n            wt = canvasRenderWorldTransform;\n            GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);\n            // the anchor has already been applied above, so lets set it to zero\n            dx = 0;\n            dy = 0;\n        }\n        dx -= width/2;\n        dy -= height/2;\n        // Allow for pixel rounding\n        if (renderer.roundPixels)\n        {\n            renderer.context.setTransform(\n                wt.a,\n                wt.b,\n                wt.c,\n                wt.d,\n                (wt.tx * renderer.resolution) | 0,\n                (wt.ty * renderer.resolution) | 0\n            );\n\n            dx = dx | 0;\n            dy = dy | 0;\n        }\n        else\n        {\n\n            renderer.context.setTransform(\n                wt.a,\n                wt.b,\n                wt.c,\n                wt.d,\n                wt.tx * renderer.resolution,\n                wt.ty * renderer.resolution\n            );\n\n\n        }\n\n        var resolution = texture.baseTexture.resolution;\n\n        if (this.tint !== 0xFFFFFF)\n        {\n            if (this.cachedTint !== this.tint)\n            {\n                this.cachedTint = this.tint;\n\n                // TODO clean up caching - how to clean up the caches?\n                this.tintedTexture = CanvasTinter.getTintedTexture(this, this.tint);\n            }\n\n            renderer.context.drawImage(\n                this.tintedTexture,\n                0,\n                0,\n                width * resolution,\n                height * resolution,\n                dx * renderer.resolution,\n                dy * renderer.resolution,\n                width * renderer.resolution,\n                height * renderer.resolution\n            );\n        }\n        else\n        {\n            renderer.context.drawImage(\n                texture.baseTexture.source,\n                texture.crop.x * resolution,\n                texture.crop.y * resolution,\n                width * resolution,\n                height * resolution,\n                dx  * renderer.resolution,\n                dy  * renderer.resolution,\n                width * renderer.resolution,\n                height * renderer.resolution\n            );\n        }\n    }\n};\n\n/**\n * Destroys this sprite and optionally its texture\n *\n * @param [destroyTexture=false] {boolean} Should it destroy the current texture of the sprite as well\n * @param [destroyBaseTexture=false] {boolean} Should it destroy the base texture of the sprite as well\n */\nSprite.prototype.destroy = function (destroyTexture, destroyBaseTexture)\n{\n    Container.prototype.destroy.call(this);\n\n    this.anchor = null;\n\n    if (destroyTexture)\n    {\n        this._texture.destroy(destroyBaseTexture);\n    }\n\n    this._texture = null;\n    this.shader = null;\n};\n\n// some helper functions..\n\n/**\n * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId\n * The frame ids are created when a Texture packer file has been loaded\n *\n * @static\n * @param frameId {string} The frame Id of the texture in the cache\n * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter\n * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId\n */\nSprite.fromFrame = function (frameId)\n{\n    var texture = utils.TextureCache[frameId];\n\n    if (!texture)\n    {\n        throw new Error('The frameId \"' + frameId + '\" does not exist in the texture cache');\n    }\n\n    return new Sprite(texture);\n};\n\n/**\n * Helper function that creates a sprite that will contain a texture based on an image url\n * If the image is not in the texture cache it will be loaded\n *\n * @static\n * @param imageId {string} The image url of the texture\n * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id\n */\nSprite.fromImage = function (imageId, crossorigin, scaleMode)\n{\n    return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));\n};\n\n},{\"../const\":22,\"../display/Container\":23,\"../math\":33,\"../renderers/canvas/utils/CanvasTinter\":48,\"../textures/Texture\":72,\"../utils\":77}],68:[function(require,module,exports){\nvar ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'),\n    WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'),\n    CONST = require('../../const');\n\n/**\n * @author Mat Groves\n *\n * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/\n * for creating the original pixi version!\n * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer\n *\n * Heavily inspired by LibGDX's SpriteRenderer:\n * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/SpriteRenderer.java\n */\n\n/**\n * Renderer dedicated to drawing and batching sprites.\n *\n * @class\n * @private\n * @memberof PIXI\n * @extends PIXI.ObjectRenderer\n * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for.\n */\nfunction SpriteRenderer(renderer)\n{\n    ObjectRenderer.call(this, renderer);\n\n    /**\n     * Number of values sent in the vertex buffer.\n     * positionX, positionY, colorR, colorG, colorB = 5\n     *\n     * @member {number}\n     */\n    this.vertSize = 5;\n\n    /**\n     * The size of the vertex information in bytes.\n     *\n     * @member {number}\n     */\n    this.vertByteSize = this.vertSize * 4;\n\n    /**\n     * The number of images in the SpriteBatch before it flushes.\n     *\n     * @member {number}\n     */\n    this.size = CONST.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop\n\n    // the total number of bytes in our batch\n    var numVerts = (this.size * 4) * this.vertByteSize;\n\n    // the total number of indices in our batch, there are 6 points per quad.\n    var numIndices = this.size * 6;\n\n    /**\n     * Holds the vertex data that will be sent to the vertex shader.\n     *\n     * @member {ArrayBuffer}\n     */\n    this.vertices = new ArrayBuffer(numVerts);\n\n    /**\n     * View on the vertices as a Float32Array for positions\n     *\n     * @member {Float32Array}\n     */\n    this.positions = new Float32Array(this.vertices);\n\n    /**\n     * View on the vertices as a Uint32Array for colors\n     *\n     * @member {Uint32Array}\n     */\n    this.colors = new Uint32Array(this.vertices);\n\n    /**\n     * Holds the indices of the geometry (quads) to draw\n     *\n     * @member {Uint16Array}\n     */\n    this.indices = new Uint16Array(numIndices);\n\n    // fill the indices with the quads to draw\n    for (var i=0, j=0; i < numIndices; i += 6, j += 4)\n    {\n        this.indices[i + 0] = j + 0;\n        this.indices[i + 1] = j + 1;\n        this.indices[i + 2] = j + 2;\n        this.indices[i + 3] = j + 0;\n        this.indices[i + 4] = j + 2;\n        this.indices[i + 5] = j + 3;\n    }\n\n    /**\n     * The current size of the batch, each render() call adds to this number.\n     *\n     * @member {number}\n     */\n    this.currentBatchSize = 0;\n\n    /**\n     * The current sprites in the batch.\n     *\n     * @member {PIXI.Sprite[]}\n     */\n    this.sprites = [];\n\n    /**\n     * The default shader that is used if a sprite doesn't have a more specific one.\n     *\n     * @member {PIXI.Shader}\n     */\n    this.shader = null;\n}\n\nSpriteRenderer.prototype = Object.create(ObjectRenderer.prototype);\nSpriteRenderer.prototype.constructor = SpriteRenderer;\nmodule.exports = SpriteRenderer;\n\nWebGLRenderer.registerPlugin('sprite', SpriteRenderer);\n\n/**\n * Sets up the renderer context and necessary buffers.\n *\n * @private\n * @param gl {WebGLRenderingContext} the current WebGL drawing context\n */\nSpriteRenderer.prototype.onContextChange = function ()\n{\n    var gl = this.renderer.gl;\n\n    // setup default shader\n    this.shader = this.renderer.shaderManager.defaultShader;\n\n    // create a couple of buffers\n    this.vertexBuffer = gl.createBuffer();\n    this.indexBuffer = gl.createBuffer();\n\n    //upload the index data\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);\n\n    this.currentBlendMode = 99999;\n};\n\n/**\n * Renders the sprite object.\n *\n * @param sprite {PIXI.Sprite} the sprite to render when using this spritebatch\n */\nSpriteRenderer.prototype.render = function (sprite)\n{\n    var texture = sprite._texture;\n\n    //TODO set blend modes..\n    // check texture..\n    if (this.currentBatchSize >= this.size)\n    {\n        this.flush();\n    }\n\n    // get the uvs for the texture\n    var uvs = texture._uvs;\n\n    // if the uvs have not updated then no point rendering just yet!\n    if (!uvs)\n    {\n        return;\n    }\n\n    // TODO trim??\n    var aX = sprite.anchor.x;\n    var aY = sprite.anchor.y;\n\n    var w0, w1, h0, h1;\n\n    if (texture.trim && sprite.tileScale === undefined)\n    {\n        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..\n        var trim = texture.trim;\n\n        w1 = trim.x - aX * trim.width;\n        w0 = w1 + texture.crop.width;\n\n        h1 = trim.y - aY * trim.height;\n        h0 = h1 + texture.crop.height;\n\n    }\n    else\n    {\n        w0 = (texture._frame.width ) * (1-aX);\n        w1 = (texture._frame.width ) * -aX;\n\n        h0 = texture._frame.height * (1-aY);\n        h1 = texture._frame.height * -aY;\n    }\n\n    var index = this.currentBatchSize * this.vertByteSize;\n\n    var worldTransform = sprite.worldTransform;\n\n    var a = worldTransform.a;\n    var b = worldTransform.b;\n    var c = worldTransform.c;\n    var d = worldTransform.d;\n    var tx = worldTransform.tx;\n    var ty = worldTransform.ty;\n\n    var colors = this.colors;\n    var positions = this.positions;\n\n    if (this.renderer.roundPixels)\n    {\n        var resolution = this.renderer.resolution;\n\n        // xy\n        positions[index] = (((a * w1 + c * h1 + tx) * resolution) | 0) / resolution;\n        positions[index+1] = (((d * h1 + b * w1 + ty) * resolution) | 0) / resolution;\n\n        // xy\n        positions[index+5] = (((a * w0 + c * h1 + tx) * resolution) | 0) / resolution;\n        positions[index+6] = (((d * h1 + b * w0 + ty) * resolution) | 0) / resolution;\n\n         // xy\n        positions[index+10] = (((a * w0 + c * h0 + tx) * resolution) | 0) / resolution;\n        positions[index+11] = (((d * h0 + b * w0 + ty) * resolution) | 0) / resolution;\n\n        // xy\n        positions[index+15] = (((a * w1 + c * h0 + tx) * resolution) | 0) / resolution;\n        positions[index+16] = (((d * h0 + b * w1 + ty) * resolution) | 0) / resolution;\n    }\n    else\n    {\n\n        // xy\n        positions[index] = a * w1 + c * h1 + tx;\n        positions[index+1] = d * h1 + b * w1 + ty;\n\n        // xy\n        positions[index+5] = a * w0 + c * h1 + tx;\n        positions[index+6] = d * h1 + b * w0 + ty;\n\n         // xy\n        positions[index+10] = a * w0 + c * h0 + tx;\n        positions[index+11] = d * h0 + b * w0 + ty;\n\n        // xy\n        positions[index+15] = a * w1 + c * h0 + tx;\n        positions[index+16] = d * h0 + b * w1 + ty;\n    }\n\n    // uv\n    positions[index+2] = uvs.x0;\n    positions[index+3] = uvs.y0;\n\n    // uv\n    positions[index+7] = uvs.x1;\n    positions[index+8] = uvs.y1;\n\n     // uv\n    positions[index+12] = uvs.x2;\n    positions[index+13] = uvs.y2;\n\n    // uv\n    positions[index+17] = uvs.x3;\n    positions[index+18] = uvs.y3;\n\n    // color and alpha\n    var tint = sprite.tint;\n    colors[index+4] = colors[index+9] = colors[index+14] = colors[index+19] = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (sprite.worldAlpha * 255 << 24);\n\n    // increment the batchsize\n    this.sprites[this.currentBatchSize++] = sprite;\n};\n\n/**\n * Renders the content and empties the current batch.\n *\n */\nSpriteRenderer.prototype.flush = function ()\n{\n    // If the batch is length 0 then return as there is nothing to draw\n    if (this.currentBatchSize === 0)\n    {\n        return;\n    }\n\n    var gl = this.renderer.gl;\n    var shader;\n\n    // upload the verts to the buffer\n    if (this.currentBatchSize > ( this.size * 0.5 ) )\n    {\n        gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);\n    }\n    else\n    {\n        var view = this.positions.subarray(0, this.currentBatchSize * this.vertByteSize);\n        gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);\n    }\n\n    var nextTexture, nextBlendMode, nextShader;\n    var batchSize = 0;\n    var start = 0;\n\n    var currentBaseTexture = null;\n    var currentBlendMode = this.renderer.blendModeManager.currentBlendMode;\n    var currentShader = null;\n\n    var blendSwap = false;\n    var shaderSwap = false;\n    var sprite;\n\n    for (var i = 0, j = this.currentBatchSize; i < j; i++)\n    {\n\n        sprite = this.sprites[i];\n\n        nextTexture = sprite._texture.baseTexture;\n        nextBlendMode = sprite.blendMode;\n        nextShader = sprite.shader || this.shader;\n\n        blendSwap = currentBlendMode !== nextBlendMode;\n        shaderSwap = currentShader !== nextShader; // should I use uidS???\n\n        if (currentBaseTexture !== nextTexture || blendSwap || shaderSwap)\n        {\n            this.renderBatch(currentBaseTexture, batchSize, start);\n\n            start = i;\n            batchSize = 0;\n            currentBaseTexture = nextTexture;\n\n            if (blendSwap)\n            {\n                currentBlendMode = nextBlendMode;\n                this.renderer.blendModeManager.setBlendMode( currentBlendMode );\n            }\n\n            if (shaderSwap)\n            {\n                currentShader = nextShader;\n\n\n\n                shader = currentShader.shaders ? currentShader.shaders[gl.id] : currentShader;\n\n                if (!shader)\n                {\n                    shader = currentShader.getShader(this.renderer);\n\n                }\n\n                // set shader function???\n                this.renderer.shaderManager.setShader(shader);\n\n                //TODO - i KNOW this can be optimised! Once v3 is stable il look at this next...\n                shader.uniforms.projectionMatrix.value = this.renderer.currentRenderTarget.projectionMatrix.toArray(true);\n                //Make this a little more dynamic / intelligent!\n                shader.syncUniforms();\n\n                //TODO investigate some kind of texture state managment??\n                // need to make sure this texture is the active one for all the batch swaps..\n                gl.activeTexture(gl.TEXTURE0);\n\n                // both thease only need to be set if they are changing..\n                // set the projection\n                //gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true));\n\n\n            }\n        }\n\n        batchSize++;\n    }\n\n    this.renderBatch(currentBaseTexture, batchSize, start);\n\n    // then reset the batch!\n    this.currentBatchSize = 0;\n};\n\n/**\n * Draws the currently batches sprites.\n *\n * @private\n * @param texture {PIXI.Texture}\n * @param size {number}\n * @param startIndex {number}\n */\nSpriteRenderer.prototype.renderBatch = function (texture, size, startIndex)\n{\n    if (size === 0)\n    {\n        return;\n    }\n\n    var gl = this.renderer.gl;\n\n    if (!texture._glTextures[gl.id])\n    {\n        this.renderer.updateTexture(texture);\n    }\n    else\n    {\n        // bind the current texture\n        gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);\n    }\n\n    // now draw those suckas!\n    gl.drawElements(gl.TRIANGLES, size * 6, gl.UNSIGNED_SHORT, startIndex * 6 * 2);\n\n    // increment the draw count\n    this.renderer.drawCount++;\n};\n\n/**\n * Starts a new sprite batch.\n *\n */\nSpriteRenderer.prototype.start = function ()\n{\n    var gl = this.renderer.gl;\n\n    // bind the main texture\n\n\n    // bind the buffers\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n\n    // this is the same for each shader?\n    var stride =  this.vertByteSize;\n    gl.vertexAttribPointer(this.shader.attributes.aVertexPosition, 2, gl.FLOAT, false, stride, 0);\n    gl.vertexAttribPointer(this.shader.attributes.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4);\n\n    // color attributes will be interpreted as unsigned bytes and normalized\n    gl.vertexAttribPointer(this.shader.attributes.aColor, 4, gl.UNSIGNED_BYTE, true, stride, 4 * 4);\n};\n\n/**\n * Destroys the SpriteBatch.\n *\n */\nSpriteRenderer.prototype.destroy = function ()\n{\n    this.renderer.gl.deleteBuffer(this.vertexBuffer);\n    this.renderer.gl.deleteBuffer(this.indexBuffer);\n\n    ObjectRenderer.prototype.destroy.call(this);\n\n    this.shader.destroy();\n\n    this.renderer = null;\n\n    this.vertices = null;\n    this.positions = null;\n    this.colors = null;\n    this.indices = null;\n\n    this.vertexBuffer = null;\n    this.indexBuffer = null;\n\n    this.sprites = null;\n    this.shader = null;\n};\n\n},{\"../../const\":22,\"../../renderers/webgl/WebGLRenderer\":49,\"../../renderers/webgl/utils/ObjectRenderer\":63}],69:[function(require,module,exports){\nvar Sprite = require('../sprites/Sprite'),\n    Texture = require('../textures/Texture'),\n    math = require('../math'),\n    utils = require('../utils'),\n    CONST = require('../const');\n\n/**\n * A Text Object will create a line or multiple lines of text. To split a line you can use '\\n' in your text string,\n * or add a wordWrap property set to true and and wordWrapWidth property with a value in the style object.\n *\n * A Text can be created directly from a string and a style object\n *\n * ```js\n * var text = new PIXI.Text('This is a pixi text',{font : '24px Arial', fill : 0xff1010, align : 'center'});\n * ```\n *\n * @class\n * @extends PIXI.Sprite\n * @memberof PIXI\n * @param text {string} The copy that you would like the text to display\n * @param [style] {object} The style parameters\n * @param [style.font] {string} default 'bold 20px Arial' The style and size of the font\n * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00'\n * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text\n * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00'\n * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)\n * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used\n * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true\n * @param [style.letterSpacing=0] {number} The amount of spacing between letters, default is 0\n * @param [style.breakWords=false] {boolean} Indicates if lines can be wrapped within words, it needs wordWrap to be set to true\n * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses\n * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text\n * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00'\n * @param [style.dropShadowAngle=Math.PI/4] {number} Set a angle of the drop shadow\n * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow\n * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius\n * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will\n *      prevent this from happening by adding padding to the top and bottom of text height.\n * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered.\n * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve\n *      spiked text issues. Default is 'miter' (creates a sharp corner).\n * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce\n *      or increase the spikiness of rendered text.\n */\nfunction Text(text, style, resolution)\n{\n    /**\n     * The canvas element that everything is drawn to\n     *\n     * @member {HTMLCanvasElement}\n     */\n    this.canvas = document.createElement('canvas');\n\n    /**\n     * The canvas 2d context that everything is drawn with\n     * @member {HTMLCanvasElement}\n     */\n    this.context = this.canvas.getContext('2d');\n\n    /**\n     * The resolution of the canvas.\n     * @member {number}\n     */\n    this.resolution = resolution || CONST.RESOLUTION;\n\n    /**\n     * Private tracker for the current text.\n     *\n     * @member {string}\n     * @private\n     */\n    this._text = null;\n\n    /**\n     * Private tracker for the current style.\n     *\n     * @member {object}\n     * @private\n     */\n    this._style = null;\n\n    var texture = Texture.fromCanvas(this.canvas);\n    texture.trim = new math.Rectangle();\n    Sprite.call(this, texture);\n\n    this.text = text;\n    this.style = style;\n}\n\n// constructor\nText.prototype = Object.create(Sprite.prototype);\nText.prototype.constructor = Text;\nmodule.exports = Text;\n\nText.fontPropertiesCache = {};\nText.fontPropertiesCanvas = document.createElement('canvas');\nText.fontPropertiesContext = Text.fontPropertiesCanvas.getContext('2d');\n\nObject.defineProperties(Text.prototype, {\n    /**\n     * The width of the Text, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Text#\n     */\n    width: {\n        get: function ()\n        {\n            if (this.dirty)\n            {\n                this.updateText();\n            }\n\n            return this.scale.x * this._texture._frame.width;\n        },\n        set: function (value)\n        {\n            this.scale.x = value / this._texture._frame.width;\n            this._width = value;\n        }\n    },\n\n    /**\n     * The height of the Text, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.Text#\n     */\n    height: {\n        get: function ()\n        {\n            if (this.dirty)\n            {\n                this.updateText();\n            }\n\n            return  this.scale.y * this._texture._frame.height;\n        },\n        set: function (value)\n        {\n            this.scale.y = value / this._texture._frame.height;\n            this._height = value;\n        }\n    },\n\n    /**\n     * Set the style of the text\n     *\n     * @param [style] {object} The style parameters\n     * @param [style.font='bold 20pt Arial'] {string} The style and size of the font\n     * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text eg 'red', '#00FF00'\n     * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text\n     * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00'\n     * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)\n     * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used\n     * @param [style.wordWrapWidth=100] {number} The width at which text will wrap\n     * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses\n     * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text\n     * @param [style.dropShadowColor='#000000'] {string|number} A fill style to be used on the dropshadow e.g 'red', '#00FF00'\n     * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow\n     * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow\n     * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius\n     * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will\n     *      prevent this from happening by adding padding to the top and bottom of text height.\n     * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered.\n     * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve\n     *      spiked text issues. Default is 'miter' (creates a sharp corner).\n     * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce\n     *      or increase the spikiness of rendered text.\n     * @memberof PIXI.Text#\n     */\n    style: {\n        get: function ()\n        {\n            return this._style;\n        },\n        set: function (style)\n        {\n            style = style || {};\n\n            if (typeof style.fill === 'number') {\n                style.fill = utils.hex2string(style.fill);\n            }\n\n            if (typeof style.stroke === 'number') {\n                style.stroke = utils.hex2string(style.stroke);\n            }\n\n            if (typeof style.dropShadowColor === 'number') {\n                style.dropShadowColor = utils.hex2string(style.dropShadowColor);\n            }\n\n            style.font = style.font || 'bold 20pt Arial';\n            style.fill = style.fill || 'black';\n            style.align = style.align || 'left';\n            style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/pixijs/pixi.js/issues/136\n            style.strokeThickness = style.strokeThickness || 0;\n            style.wordWrap = style.wordWrap || false;\n            style.wordWrapWidth = style.wordWrapWidth || 100;\n            style.breakWords = style.breakWords || false;\n            style.letterSpacing = style.letterSpacing || 0;\n\n            style.dropShadow = style.dropShadow || false;\n            style.dropShadowColor = style.dropShadowColor || '#000000';\n            style.dropShadowAngle = style.dropShadowAngle !== undefined ? style.dropShadowAngle : Math.PI / 6;\n            style.dropShadowDistance = style.dropShadowDistance !== undefined ? style.dropShadowDistance : 5;\n            style.dropShadowBlur = style.dropShadowBlur !== undefined ? style.dropShadowBlur : 0; //shadowBlur is '0' by default according to HTML\n\n            style.padding = style.padding || 0;\n\n            style.textBaseline = style.textBaseline || 'alphabetic';\n\n            style.lineJoin = style.lineJoin || 'miter';\n            style.miterLimit = style.miterLimit || 10;\n\n            this._style = style;\n            this.dirty = true;\n        }\n    },\n\n    /**\n     * Set the copy for the text object. To split a line you can use '\\n'.\n     *\n     * @param text {string} The copy that you would like the text to display\n     * @memberof PIXI.Text#\n     */\n    text: {\n        get: function()\n        {\n            return this._text;\n        },\n        set: function (text){\n            text = text.toString() || ' ';\n            if (this._text === text)\n            {\n                return;\n            }\n            this._text = text;\n            this.dirty = true;\n        }\n    }\n});\n\n/**\n * Renders text and updates it when needed\n *\n * @private\n */\nText.prototype.updateText = function ()\n{\n    var style = this._style;\n    this.context.font = style.font;\n\n    // word wrap\n    // preserve original text\n    var outputText = style.wordWrap ? this.wordWrap(this._text) : this._text;\n\n    // split text into lines\n    var lines = outputText.split(/(?:\\r\\n|\\r|\\n)/);\n\n    // calculate text width\n    var lineWidths = new Array(lines.length);\n    var maxLineWidth = 0;\n    var fontProperties = this.determineFontProperties(style.font);\n    for (var i = 0; i < lines.length; i++)\n    {\n        var lineWidth = this.context.measureText(lines[i]).width + ((lines[i].length - 1) * style.letterSpacing);\n        lineWidths[i] = lineWidth;\n        maxLineWidth = Math.max(maxLineWidth, lineWidth);\n    }\n\n    var width = maxLineWidth + style.strokeThickness;\n    if (style.dropShadow)\n    {\n        width += style.dropShadowDistance;\n    }\n\n    this.canvas.width = Math.ceil( ( width + this.context.lineWidth ) * this.resolution );\n\n    // calculate text height\n    var lineHeight = this.style.lineHeight || fontProperties.fontSize + style.strokeThickness;\n\n    var height = lineHeight * lines.length;\n    if (style.dropShadow)\n    {\n        height += style.dropShadowDistance;\n    }\n\n    this.canvas.height = Math.ceil( ( height + this._style.padding * 2 ) * this.resolution );\n\n    this.context.scale( this.resolution, this.resolution);\n\n    if (navigator.isCocoonJS)\n    {\n        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n    }\n\n    //this.context.fillStyle=\"#FF0000\";\n    //this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n    this.context.font = style.font;\n    this.context.strokeStyle = style.stroke;\n    this.context.lineWidth = style.strokeThickness;\n    this.context.textBaseline = style.textBaseline;\n    this.context.lineJoin = style.lineJoin;\n    this.context.miterLimit = style.miterLimit;\n\n    var linePositionX;\n    var linePositionY;\n\n    if (style.dropShadow)\n    {\n        if (style.dropShadowBlur > 0) {\n            this.context.shadowColor = style.dropShadowColor;\n            this.context.shadowBlur = style.dropShadowBlur;\n        } else {\n            this.context.fillStyle = style.dropShadowColor;\n        }\n\n        var xShadowOffset = Math.cos(style.dropShadowAngle) * style.dropShadowDistance;\n        var yShadowOffset = Math.sin(style.dropShadowAngle) * style.dropShadowDistance;\n\n        for (i = 0; i < lines.length; i++)\n        {\n            linePositionX = style.strokeThickness / 2;\n            linePositionY = (style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent;\n\n            if (style.align === 'right')\n            {\n                linePositionX += maxLineWidth - lineWidths[i];\n            }\n            else if (style.align === 'center')\n            {\n                linePositionX += (maxLineWidth - lineWidths[i]) / 2;\n            }\n\n            if (style.fill)\n            {\n                this.drawLetterSpacing(lines[i], linePositionX + xShadowOffset, linePositionY + yShadowOffset + style.padding);\n            }\n        }\n    }\n\n    //set canvas text styles\n    this.context.fillStyle = style.fill;\n\n    //draw lines line by line\n    for (i = 0; i < lines.length; i++)\n    {\n        linePositionX = style.strokeThickness / 2;\n        linePositionY = (style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent;\n\n        if (style.align === 'right')\n        {\n            linePositionX += maxLineWidth - lineWidths[i];\n        }\n        else if (style.align === 'center')\n        {\n            linePositionX += (maxLineWidth - lineWidths[i]) / 2;\n        }\n\n        if (style.stroke && style.strokeThickness)\n        {\n            this.drawLetterSpacing(lines[i], linePositionX, linePositionY + style.padding, true);\n        }\n\n        if (style.fill)\n        {\n            this.drawLetterSpacing(lines[i], linePositionX, linePositionY + style.padding);\n        }\n    }\n\n    this.updateTexture();\n};\n\n/**\n * Render the text with letter-spacing.\n *\n * @private\n */\nText.prototype.drawLetterSpacing = function(text, x, y, isStroke)\n{\n    var style = this._style;\n\n    // letterSpacing of 0 means normal\n    var letterSpacing = style.letterSpacing;\n\n    if (letterSpacing === 0)\n    {\n        if (isStroke)\n        {\n            this.context.strokeText(text, x, y);\n        }\n        else\n        {\n            this.context.fillText(text, x, y);\n        }\n        return;\n    }\n\n    var characters = String.prototype.split.call(text, ''),\n        index = 0,\n        current,\n        currentPosition = x;\n\n    while (index < text.length)\n    {\n        current = characters[index++];\n        if (isStroke) \n        {\n            this.context.strokeText(current, currentPosition, y);\n        }\n        else\n        {\n            this.context.fillText(current, currentPosition, y);\n        }\n        currentPosition += this.context.measureText(current).width + letterSpacing;\n    }\n};\n\n/**\n * Updates texture size based on canvas size\n *\n * @private\n */\nText.prototype.updateTexture = function ()\n{\n    var texture = this._texture;\n    var style = this._style;\n\n    texture.baseTexture.hasLoaded = true;\n    texture.baseTexture.resolution = this.resolution;\n\n    texture.baseTexture.width = this.canvas.width / this.resolution;\n    texture.baseTexture.height = this.canvas.height / this.resolution;\n    texture.crop.width = texture._frame.width = this.canvas.width / this.resolution;\n    texture.crop.height = texture._frame.height = this.canvas.height / this.resolution;\n\n    texture.trim.x = 0;\n    texture.trim.y = -style.padding;\n\n    texture.trim.width = texture._frame.width;\n    texture.trim.height = texture._frame.height - style.padding*2;\n\n    this._width = this.canvas.width / this.resolution;\n    this._height = this.canvas.height / this.resolution;\n\n    texture.baseTexture.emit('update',  texture.baseTexture);\n\n    this.dirty = false;\n};\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer}\n */\nText.prototype.renderWebGL = function (renderer)\n{\n    if (this.dirty)\n    {\n        //this.resolution = 1//renderer.resolution;\n\n        this.updateText();\n    }\n\n    Sprite.prototype.renderWebGL.call(this, renderer);\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer}\n * @private\n */\nText.prototype._renderCanvas = function (renderer)\n{\n    if (this.dirty)\n    {\n     //   this.resolution = 1//renderer.resolution;\n\n        this.updateText();\n    }\n\n    Sprite.prototype._renderCanvas.call(this, renderer);\n};\n\n/**\n * Calculates the ascent, descent and fontSize of a given fontStyle\n *\n * @param fontStyle {object}\n * @private\n */\nText.prototype.determineFontProperties = function (fontStyle)\n{\n    var properties = Text.fontPropertiesCache[fontStyle];\n\n    if (!properties)\n    {\n        properties = {};\n\n        var canvas = Text.fontPropertiesCanvas;\n        var context = Text.fontPropertiesContext;\n\n        context.font = fontStyle;\n\n        var width = Math.ceil(context.measureText('|MÉq').width);\n        var baseline = Math.ceil(context.measureText('M').width);\n        var height = 2 * baseline;\n\n        baseline = baseline * 1.4 | 0;\n\n        canvas.width = width;\n        canvas.height = height;\n\n        context.fillStyle = '#f00';\n        context.fillRect(0, 0, width, height);\n\n        context.font = fontStyle;\n\n        context.textBaseline = 'alphabetic';\n        context.fillStyle = '#000';\n        context.fillText('|MÉq', 0, baseline);\n\n        var imagedata = context.getImageData(0, 0, width, height).data;\n        var pixels = imagedata.length;\n        var line = width * 4;\n\n        var i, j;\n\n        var idx = 0;\n        var stop = false;\n\n        // ascent. scan from top to bottom until we find a non red pixel\n        for (i = 0; i < baseline; i++)\n        {\n            for (j = 0; j < line; j += 4)\n            {\n                if (imagedata[idx + j] !== 255)\n                {\n                    stop = true;\n                    break;\n                }\n            }\n            if (!stop)\n            {\n                idx += line;\n            }\n            else\n            {\n                break;\n            }\n        }\n\n        properties.ascent = baseline - i;\n\n        idx = pixels - line;\n        stop = false;\n\n        // descent. scan from bottom to top until we find a non red pixel\n        for (i = height; i > baseline; i--)\n        {\n            for (j = 0; j < line; j += 4)\n            {\n                if (imagedata[idx + j] !== 255)\n                {\n                    stop = true;\n                    break;\n                }\n            }\n            if (!stop)\n            {\n                idx -= line;\n            }\n            else\n            {\n                break;\n            }\n        }\n\n        properties.descent = i - baseline;\n        properties.fontSize = properties.ascent + properties.descent;\n\n        Text.fontPropertiesCache[fontStyle] = properties;\n    }\n\n    return properties;\n};\n\n/**\n * Applies newlines to a string to have it optimally fit into the horizontal\n * bounds set by the Text object's wordWrapWidth property.\n *\n * @param text {string}\n * @private\n */\nText.prototype.wordWrap = function (text)\n{\n    // Greedy wrapping algorithm that will wrap words as the line grows longer\n    // than its horizontal bounds.\n    var result = '';\n    var lines = text.split('\\n');\n    var wordWrapWidth = this._style.wordWrapWidth;\n    for (var i = 0; i < lines.length; i++)\n    {\n        var spaceLeft = wordWrapWidth;\n        var words = lines[i].split(' ');\n        for (var j = 0; j < words.length; j++)\n        {\n            var wordWidth = this.context.measureText(words[j]).width;\n            if (this._style.breakWords && wordWidth > wordWrapWidth) \n            {\n                // Word should be split in the middle\n                var characters = words[j].split('');\n                for (var c = 0; c < characters.length; c++) \n                {\n                  var characterWidth = this.context.measureText(characters[c]).width;\n                  if (characterWidth > spaceLeft) \n                  {\n                    result += '\\n' + characters[c];\n                    spaceLeft = wordWrapWidth - characterWidth;\n                  } \n                  else \n                  {\n                    if (c === 0) \n                    {\n                      result += ' ';\n                    }\n                    result += characters[c];\n                    spaceLeft -= characterWidth;\n                  }\n                }\n            }\n            else \n            {\n                var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width;\n                if (j === 0 || wordWidthWithSpace > spaceLeft)\n                {\n                    // Skip printing the newline if it's the first word of the line that is\n                    // greater than the word wrap width.\n                    if (j > 0)\n                    {\n                        result += '\\n';\n                    }\n                    result += words[j];\n                    spaceLeft = wordWrapWidth - wordWidth;\n                }\n                else\n                {\n                    spaceLeft -= wordWidthWithSpace;\n                    result += ' ' + words[j];\n                }\n            }\n        }\n\n        if (i < lines.length-1)\n        {\n            result += '\\n';\n        }\n    }\n    return result;\n};\n\n/**\n * Returns the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account.\n *\n * @param matrix {PIXI.Matrix} the transformation matrix of the Text\n * @return {PIXI.Rectangle} the framing rectangle\n */\nText.prototype.getBounds = function (matrix)\n{\n    if (this.dirty)\n    {\n        this.updateText();\n    }\n\n    return Sprite.prototype.getBounds.call(this, matrix);\n};\n\n/**\n * Destroys this text object.\n *\n * @param [destroyBaseTexture=true] {boolean} whether to destroy the base texture as well\n */\nText.prototype.destroy = function (destroyBaseTexture)\n{\n    // make sure to reset the the context and canvas.. dont want this hanging around in memory!\n    this.context = null;\n    this.canvas = null;\n\n    this._style = null;\n\n    this._texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture);\n};\n\n},{\"../const\":22,\"../math\":33,\"../sprites/Sprite\":67,\"../textures/Texture\":72,\"../utils\":77}],70:[function(require,module,exports){\nvar utils = require('../utils'),\n    CONST = require('../const'),\n    EventEmitter = require('eventemitter3');\n\n/**\n * A texture stores the information that represents an image. All textures have a base texture.\n *\n * @class\n * @memberof PIXI\n * @param source {Image|Canvas} the source object of the texture.\n * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values\n * @param resolution {number} the resolution of the texture for devices with different pixel ratios\n */\nfunction BaseTexture(source, scaleMode, resolution)\n{\n    EventEmitter.call(this);\n\n    this.uid = utils.uid();\n\n    /**\n     * The Resolution of the texture.\n     *\n     * @member {number}\n     */\n    this.resolution = resolution || 1;\n\n    /**\n     * The width of the base texture set when the image has loaded\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.width = 100;\n\n    /**\n     * The height of the base texture set when the image has loaded\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.height = 100;\n\n    // TODO docs\n    // used to store the actual dimensions of the source\n    /**\n     * Used to store the actual width of the source of this texture\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.realWidth = 100;\n    /**\n     * Used to store the actual height of the source of this texture\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.realHeight = 100;\n\n    /**\n     * The scale mode to apply when scaling this texture\n     *\n     * @member {number}\n     * @default PIXI.SCALE_MODES.LINEAR\n     * @see PIXI.SCALE_MODES\n     */\n    this.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;\n\n    /**\n     * Set to true once the base texture has successfully loaded.\n     *\n     * This is never true if the underlying source fails to load or has no texture data.\n     *\n     * @member {boolean}\n     * @readOnly\n     */\n    this.hasLoaded = false;\n\n    /**\n     * Set to true if the source is currently loading.\n     *\n     * If an Image source is loading the 'loaded' or 'error' event will be\n     * dispatched when the operation ends. An underyling source that is\n     * immediately-available bypasses loading entirely.\n     *\n     * @member {boolean}\n     * @readonly\n     */\n    this.isLoading = false;\n\n    /**\n     * The image source that is used to create the texture.\n     *\n     * TODO: Make this a setter that calls loadSource();\n     *\n     * @member {Image|Canvas}\n     * @readonly\n     */\n    this.source = null; // set in loadSource, if at all\n\n    /**\n     * Controls if RGB channels should be pre-multiplied by Alpha  (WebGL only)\n     * All blend modes, and shaders written for default value. Change it on your own risk.\n     *\n     * @member {boolean}\n     * @default true\n     */\n    this.premultipliedAlpha = true;\n\n    /**\n     * @member {string}\n     */\n    this.imageUrl = null;\n\n    /**\n     * Wether or not the texture is a power of two, try to use power of two textures as much as you can\n     * @member {boolean}\n     * @private\n     */\n    this.isPowerOfTwo = false;\n\n    // used for webGL\n\n    /**\n     *\n     * Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used\n     * Also the texture must be a power of two size to work\n     *\n     * @member {boolean}\n     */\n    this.mipmap = false;\n\n    /**\n     * A map of renderer IDs to webgl textures\n     *\n     * @member {object<number, WebGLTexture>}\n     * @private\n     */\n    this._glTextures = {};\n\n    // if no source passed don't try to load\n    if (source)\n    {\n        this.loadSource(source);\n    }\n\n    /**\n     * Fired when a not-immediately-available source finishes loading.\n     *\n     * @event loaded\n     * @memberof PIXI.BaseTexture#\n     * @protected\n     */\n\n    /**\n     * Fired when a not-immediately-available source fails to load.\n     *\n     * @event error\n     * @memberof PIXI.BaseTexture#\n     * @protected\n     */\n}\n\nBaseTexture.prototype = Object.create(EventEmitter.prototype);\nBaseTexture.prototype.constructor = BaseTexture;\nmodule.exports = BaseTexture;\n\n/**\n * Updates the texture on all the webgl renderers, this also assumes the src has changed.\n *\n * @fires update\n */\nBaseTexture.prototype.update = function ()\n{\n    this.realWidth = this.source.naturalWidth || this.source.width;\n    this.realHeight = this.source.naturalHeight || this.source.height;\n\n    this.width = this.realWidth / this.resolution;\n    this.height = this.realHeight / this.resolution;\n\n    this.isPowerOfTwo = utils.isPowerOfTwo(this.realWidth, this.realHeight);\n\n    this.emit('update', this);\n};\n\n/**\n * Load a source.\n *\n * If the source is not-immediately-available, such as an image that needs to be\n * downloaded, then the 'loaded' or 'error' event will be dispatched in the future\n * and `hasLoaded` will remain false after this call.\n *\n * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is:\n *\n *     if (texture.hasLoaded)\n {\n *        // texture ready for use\n *     } else if (texture.isLoading)\n {\n *        // listen to 'loaded' and/or 'error' events on texture\n *     } else {\n *        // not loading, not going to load UNLESS the source is reloaded\n *        // (it may still make sense to listen to the events)\n *     }\n *\n * @protected\n * @param source {Image|Canvas} the source object of the texture.\n */\nBaseTexture.prototype.loadSource = function (source)\n{\n    var wasLoading = this.isLoading;\n    this.hasLoaded = false;\n    this.isLoading = false;\n\n    if (wasLoading && this.source)\n    {\n        this.source.onload = null;\n        this.source.onerror = null;\n    }\n\n    this.source = source;\n\n    // Apply source if loaded. Otherwise setup appropriate loading monitors.\n    if ((this.source.complete || this.source.getContext) && this.source.width && this.source.height)\n    {\n        this._sourceLoaded();\n    }\n    else if (!source.getContext)\n    {\n\n        // Image fail / not ready\n        this.isLoading = true;\n\n        var scope = this;\n\n        source.onload = function ()\n        {\n            source.onload = null;\n            source.onerror = null;\n\n            if (!scope.isLoading)\n            {\n                return;\n            }\n\n            scope.isLoading = false;\n            scope._sourceLoaded();\n\n            scope.emit('loaded', scope);\n        };\n\n        source.onerror = function ()\n        {\n            source.onload = null;\n            source.onerror = null;\n\n            if (!scope.isLoading)\n            {\n                return;\n            }\n\n            scope.isLoading = false;\n            scope.emit('error', scope);\n        };\n\n        // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element\n        //   \"The value of `complete` can thus change while a script is executing.\"\n        // So complete needs to be re-checked after the callbacks have been added..\n        // NOTE: complete will be true if the image has no src so best to check if the src is set.\n        if (source.complete && source.src)\n        {\n            this.isLoading = false;\n\n            // ..and if we're complete now, no need for callbacks\n            source.onload = null;\n            source.onerror = null;\n\n            if (source.width && source.height)\n            {\n                this._sourceLoaded();\n\n                // If any previous subscribers possible\n                if (wasLoading)\n                {\n                    this.emit('loaded', this);\n                }\n            }\n            else\n            {\n                // If any previous subscribers possible\n                if (wasLoading)\n                {\n                    this.emit('error', this);\n                }\n            }\n        }\n    }\n};\n\n/**\n * Used internally to update the width, height, and some other tracking vars once\n * a source has successfully loaded.\n *\n * @private\n */\nBaseTexture.prototype._sourceLoaded = function ()\n{\n    this.hasLoaded = true;\n    this.update();\n};\n\n/**\n * Destroys this base texture\n *\n */\nBaseTexture.prototype.destroy = function ()\n{\n    if (this.imageUrl)\n    {\n        delete utils.BaseTextureCache[this.imageUrl];\n        delete utils.TextureCache[this.imageUrl];\n\n        this.imageUrl = null;\n\n        if (!navigator.isCocoonJS)\n        {\n            this.source.src = '';\n        }\n    }\n    else if (this.source && this.source._pixiId)\n    {\n        delete utils.BaseTextureCache[this.source._pixiId];\n    }\n\n    this.source = null;\n\n    this.dispose();\n};\n\n/**\n * Frees the texture from WebGL memory without destroying this texture object.\n * This means you can still use the texture later which will upload it to GPU\n * memory again.\n *\n */\nBaseTexture.prototype.dispose = function ()\n{\n    this.emit('dispose', this);\n\n    // this should no longer be needed, the renderers should cleanup all the gl textures.\n    // this._glTextures = {};\n};\n\n/**\n * Changes the source image of the texture.\n * The original source must be an Image element.\n *\n * @param newSrc {string} the path of the image\n */\nBaseTexture.prototype.updateSourceImage = function (newSrc)\n{\n    this.source.src = newSrc;\n\n    this.loadSource(this.source);\n};\n\n/**\n * Helper function that creates a base texture from the given image url.\n * If the image is not in the base texture cache it will be created and loaded.\n *\n * @static\n * @param imageUrl {string} The image url of the texture\n * @param [crossorigin=(auto)] {boolean} Should use anonymous CORS? Defaults to true if the URL is not a data-URI.\n * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return PIXI.BaseTexture\n */\nBaseTexture.fromImage = function (imageUrl, crossorigin, scaleMode)\n{\n    var baseTexture = utils.BaseTextureCache[imageUrl];\n\n    if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0)\n    {\n        crossorigin = true;\n    }\n\n    if (!baseTexture)\n    {\n        // new Image() breaks tex loading in some versions of Chrome.\n        // See https://code.google.com/p/chromium/issues/detail?id=238071\n        var image = new Image();//document.createElement('img');\n        if (crossorigin)\n        {\n            image.crossOrigin = '';\n        }\n\n        baseTexture = new BaseTexture(image, scaleMode);\n        baseTexture.imageUrl = imageUrl;\n\n        image.src = imageUrl;\n\n        utils.BaseTextureCache[imageUrl] = baseTexture;\n\n        // if there is an @2x at the end of the url we are going to assume its a highres image\n        baseTexture.resolution = utils.getResolutionOfUrl(imageUrl);\n    }\n\n    return baseTexture;\n};\n\n/**\n * Helper function that creates a base texture from the given canvas element.\n *\n * @static\n * @param canvas {Canvas} The canvas element source of the texture\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return PIXI.BaseTexture\n */\nBaseTexture.fromCanvas = function (canvas, scaleMode)\n{\n    if (!canvas._pixiId)\n    {\n        canvas._pixiId = 'canvas_' + utils.uid();\n    }\n\n    var baseTexture = utils.BaseTextureCache[canvas._pixiId];\n\n    if (!baseTexture)\n    {\n        baseTexture = new BaseTexture(canvas, scaleMode);\n        utils.BaseTextureCache[canvas._pixiId] = baseTexture;\n    }\n\n    return baseTexture;\n};\n\n},{\"../const\":22,\"../utils\":77,\"eventemitter3\":10}],71:[function(require,module,exports){\nvar BaseTexture = require('./BaseTexture'),\n    Texture = require('./Texture'),\n    RenderTarget = require('../renderers/webgl/utils/RenderTarget'),\n    FilterManager = require('../renderers/webgl/managers/FilterManager'),\n    CanvasBuffer = require('../renderers/canvas/utils/CanvasBuffer'),\n    math = require('../math'),\n    CONST = require('../const'),\n    tempMatrix = new math.Matrix();\n\n/**\n * A RenderTexture is a special texture that allows any Pixi display object to be rendered to it.\n *\n * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded\n * otherwise black rectangles will be drawn instead.\n *\n * A RenderTexture takes a snapshot of any Display Object given to its render method. The position\n * and rotation of the given Display Objects is ignored. For example:\n *\n * ```js\n * var renderer = PIXI.autoDetectRenderer(1024, 1024, { view: canvas, ratio: 1 });\n * var renderTexture = new PIXI.RenderTexture(renderer, 800, 600);\n * var sprite = PIXI.Sprite.fromImage(\"spinObj_01.png\");\n *\n * sprite.position.x = 800/2;\n * sprite.position.y = 600/2;\n * sprite.anchor.x = 0.5;\n * sprite.anchor.y = 0.5;\n *\n * renderTexture.render(sprite);\n * ```\n *\n * The Sprite in this case will be rendered to a position of 0,0. To render this sprite at its actual\n * position a Container should be used:\n *\n * ```js\n * var doc = new PIXI.Container();\n *\n * doc.addChild(sprite);\n *\n * renderTexture.render(doc);  // Renders to center of renderTexture\n * ```\n *\n * @class\n * @extends PIXI.Texture\n * @memberof PIXI\n * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} The renderer used for this RenderTexture\n * @param [width=100] {number} The width of the render texture\n * @param [height=100] {number} The height of the render texture\n * @param [scaleMode] {number} See {@link PIXI.SCALE_MODES} for possible values\n * @param [resolution=1] {number} The resolution of the texture being generated\n */\nfunction RenderTexture(renderer, width, height, scaleMode, resolution)\n{\n    if (!renderer)\n    {\n        throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.');\n    }\n\n    width = width || 100;\n    height = height || 100;\n    resolution = resolution || CONST.RESOLUTION;\n\n    /**\n     * The base texture object that this texture uses\n     *\n     * @member {BaseTexture}\n     */\n    var baseTexture = new BaseTexture();\n    baseTexture.width = width;\n    baseTexture.height = height;\n    baseTexture.resolution = resolution;\n    baseTexture.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;\n    baseTexture.hasLoaded = true;\n\n\n    Texture.call(this,\n        baseTexture,\n        new math.Rectangle(0, 0, width, height)\n    );\n\n\n    /**\n     * The with of the render texture\n     *\n     * @member {number}\n     */\n    this.width = width;\n\n    /**\n     * The height of the render texture\n     *\n     * @member {number}\n     */\n    this.height = height;\n\n    /**\n     * The Resolution of the texture.\n     *\n     * @member {number}\n     */\n    this.resolution = resolution;\n\n    /**\n     * Draw/render the given DisplayObject onto the texture.\n     *\n     * The displayObject and descendents are transformed during this operation.\n     * If `updateTransform` is true then the transformations will be restored before the\n     * method returns. Otherwise it is up to the calling code to correctly use or reset\n     * the transformed display objects.\n     *\n     * The display object is always rendered with a worldAlpha value of 1.\n     *\n     * @method\n     * @param displayObject {PIXI.DisplayObject} The display object to render this texture on\n     * @param [matrix] {PIXI.Matrix} Optional matrix to apply to the display object before rendering.\n     * @param [clear=false] {boolean} If true the texture will be cleared before the displayObject is drawn\n     * @param [updateTransform=true] {boolean} If true the displayObject's worldTransform/worldAlpha and all children\n     *  transformations will be restored. Not restoring this information will be a little faster.\n     */\n    this.render = null;\n\n    /**\n     * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL.\n     *\n     * @member {PIXI.CanvasRenderer|PIXI.WebGLRenderer}\n     */\n    this.renderer = renderer;\n\n    if (this.renderer.type === CONST.RENDERER_TYPE.WEBGL)\n    {\n        var gl = this.renderer.gl;\n\n        this.textureBuffer = new RenderTarget(gl, this.width, this.height, baseTexture.scaleMode, this.resolution);//, this.baseTexture.scaleMode);\n        this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture;\n\n        //TODO refactor filter manager.. as really its no longer a manager if we use it here..\n        this.filterManager = new FilterManager(this.renderer);\n        this.filterManager.onContextChange();\n        this.filterManager.resize(width, height);\n        this.render = this.renderWebGL;\n\n        // the creation of a filter manager unbinds the buffers..\n        this.renderer.currentRenderer.start();\n        this.renderer.currentRenderTarget.activate();\n    }\n    else\n    {\n\n        this.render = this.renderCanvas;\n        this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution);\n        this.baseTexture.source = this.textureBuffer.canvas;\n    }\n\n    /**\n     * @member {boolean}\n     */\n    this.valid = true;\n\n    this._updateUvs();\n}\n\nRenderTexture.prototype = Object.create(Texture.prototype);\nRenderTexture.prototype.constructor = RenderTexture;\nmodule.exports = RenderTexture;\n\n/**\n * Resizes the RenderTexture.\n *\n * @param width {number} The width to resize to.\n * @param height {number} The height to resize to.\n * @param updateBase {boolean} Should the baseTexture.width and height values be resized as well?\n */\nRenderTexture.prototype.resize = function (width, height, updateBase)\n{\n    if (width === this.width && height === this.height)\n    {\n        return;\n    }\n\n    this.valid = (width > 0 && height > 0);\n\n    this.width = this._frame.width = this.crop.width = width;\n    this.height =  this._frame.height = this.crop.height = height;\n\n    if (updateBase)\n    {\n        this.baseTexture.width = this.width;\n        this.baseTexture.height = this.height;\n    }\n\n    if (!this.valid)\n    {\n        return;\n    }\n\n    this.textureBuffer.resize(this.width, this.height);\n\n    if(this.filterManager)\n    {\n        this.filterManager.resize(this.width, this.height);\n    }\n};\n\n/**\n * Clears the RenderTexture.\n *\n */\nRenderTexture.prototype.clear = function ()\n{\n    if (!this.valid)\n    {\n        return;\n    }\n\n    if (this.renderer.type === CONST.RENDERER_TYPE.WEBGL)\n    {\n        this.renderer.gl.bindFramebuffer(this.renderer.gl.FRAMEBUFFER, this.textureBuffer.frameBuffer);\n    }\n\n    this.textureBuffer.clear();\n};\n\n/**\n * Internal method assigned to the `render` property if using a CanvasRenderer.\n *\n * @private\n * @param displayObject {PIXI.DisplayObject} The display object to render this texture on\n * @param [matrix] {PIXI.Matrix} Optional matrix to apply to the display object before rendering.\n * @param [clear=false] {boolean} If true the texture will be cleared before the displayObject is drawn\n * @param [updateTransform=true] {boolean} If true the displayObject's worldTransform/worldAlpha and all children\n *  transformations will be restored. Not restoring this information will be a little faster.\n */\nRenderTexture.prototype.renderWebGL = function (displayObject, matrix, clear, updateTransform)\n{\n    if (!this.valid)\n    {\n        return;\n    }\n\n\n    updateTransform = (updateTransform !== undefined) ? updateTransform : true;//!updateTransform;\n\n    this.textureBuffer.transform = matrix;\n\n    //TODO not a fan that this is here... it will move!\n    this.textureBuffer.activate();\n\n    // setWorld Alpha to ensure that the object is renderer at full opacity\n    displayObject.worldAlpha = 1;\n\n    if (updateTransform)\n    {\n\n        // reset the matrix of the displatyObject..\n        displayObject.worldTransform.identity();\n\n        displayObject.currentBounds = null;\n\n        // Time to update all the children of the displayObject with the new matrix..\n        var children = displayObject.children;\n        var i, j;\n\n        for (i = 0, j = children.length; i < j; ++i)\n        {\n            children[i].updateTransform();\n        }\n    }\n\n    //TODO rename textureBuffer to renderTarget..\n    var temp =  this.renderer.filterManager;\n\n    this.renderer.filterManager = this.filterManager;\n    this.renderer.renderDisplayObject(displayObject, this.textureBuffer, clear);\n\n    this.renderer.filterManager = temp;\n};\n\n\n/**\n * Internal method assigned to the `render` property if using a CanvasRenderer.\n *\n * @private\n * @param displayObject {PIXI.DisplayObject} The display object to render this texture on\n * @param [matrix] {PIXI.Matrix} Optional matrix to apply to the display object before rendering.\n * @param [clear] {boolean} If true the texture will be cleared before the displayObject is drawn\n */\nRenderTexture.prototype.renderCanvas = function (displayObject, matrix, clear, updateTransform)\n{\n    if (!this.valid)\n    {\n        return;\n    }\n\n    updateTransform = !!updateTransform;\n\n    var wt = tempMatrix;\n\n    wt.identity();\n\n    if (matrix)\n    {\n        wt.append(matrix);\n    }\n\n    var cachedWt = displayObject.worldTransform;\n    displayObject.worldTransform = wt;\n\n    // setWorld Alpha to ensure that the object is renderer at full opacity\n    displayObject.worldAlpha = 1;\n\n    // Time to update all the children of the displayObject with the new matrix..\n    var children = displayObject.children;\n    var i, j;\n\n    for (i = 0, j = children.length; i < j; ++i)\n    {\n        children[i].updateTransform();\n    }\n\n    if (clear)\n    {\n        this.textureBuffer.clear();\n    }\n\n\n//    this.textureBuffer.\n    var context = this.textureBuffer.context;\n\n    var realResolution = this.renderer.resolution;\n\n    this.renderer.resolution = this.resolution;\n\n    this.renderer.renderDisplayObject(displayObject, context);\n\n    this.renderer.resolution = realResolution;\n\n    if(displayObject.worldTransform === wt)\n    {\n        // fixes cacheAsBitmap Happening during the above..\n        displayObject.worldTransform = cachedWt;\n    }\n\n};\n\n/**\n * Destroys this texture\n *\n * @param destroyBase {boolean} Whether to destroy the base texture as well\n */\nRenderTexture.prototype.destroy = function ()\n{\n    Texture.prototype.destroy.call(this, true);\n\n    this.textureBuffer.destroy();\n\n    // destroy the filtermanager..\n    if(this.filterManager)\n    {\n        this.filterManager.destroy();\n    }\n\n    this.renderer = null;\n};\n\n/**\n * Will return a HTML Image of the texture\n *\n * @return {Image}\n */\nRenderTexture.prototype.getImage = function ()\n{\n    var image = new Image();\n    image.src = this.getBase64();\n    return image;\n};\n\n/**\n * Will return a a base64 encoded string of this texture. It works by calling RenderTexture.getCanvas and then running toDataURL on that.\n *\n * @return {string} A base64 encoded string of the texture.\n */\nRenderTexture.prototype.getBase64 = function ()\n{\n    return this.getCanvas().toDataURL();\n};\n\n/**\n * Creates a Canvas element, renders this RenderTexture to it and then returns it.\n *\n * @return {HTMLCanvasElement} A Canvas element with the texture rendered on.\n */\nRenderTexture.prototype.getCanvas = function ()\n{\n    if (this.renderer.type === CONST.RENDERER_TYPE.WEBGL)\n    {\n        var gl = this.renderer.gl;\n        var width = this.textureBuffer.size.width;\n        var height = this.textureBuffer.size.height;\n\n        var webGLPixels = new Uint8Array(4 * width * height);\n\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer);\n        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, webGLPixels);\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n        var tempCanvas = new CanvasBuffer(width, height);\n        var canvasData = tempCanvas.context.getImageData(0, 0, width, height);\n        canvasData.data.set(webGLPixels);\n\n        tempCanvas.context.putImageData(canvasData, 0, 0);\n\n        return tempCanvas.canvas;\n    }\n    else\n    {\n        return this.textureBuffer.canvas;\n    }\n};\n\n/**\n * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA order, with integer values between 0 and 255 (included).\n *\n * @return {Uint8ClampedArray}\n */\nRenderTexture.prototype.getPixels = function ()\n{\n    var width, height;\n\n    if (this.renderer.type === CONST.RENDERER_TYPE.WEBGL)\n    {\n        var gl = this.renderer.gl;\n        width = this.textureBuffer.size.width;\n        height = this.textureBuffer.size.height;\n\n        var webGLPixels = new Uint8Array(4 * width * height);\n\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer);\n        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, webGLPixels);\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n        return webGLPixels;\n    }\n    else\n    {\n        width = this.textureBuffer.canvas.width;\n        height = this.textureBuffer.canvas.height;\n\n        return this.textureBuffer.canvas.getContext('2d').getImageData(0, 0, width, height).data;\n    }\n};\n\n/**\n * Will return a one-dimensional array containing the pixel data of a pixel within the texture in RGBA order, with integer values between 0 and 255 (included).\n *\n * @param x {number} The x coordinate of the pixel to retrieve.\n * @param y {number} The y coordinate of the pixel to retrieve.\n * @return {Uint8ClampedArray}\n */\nRenderTexture.prototype.getPixel = function (x, y)\n{\n    if (this.renderer.type === CONST.RENDERER_TYPE.WEBGL)\n    {\n        var gl = this.renderer.gl;\n\n        var webGLPixels = new Uint8Array(4);\n\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer);\n        gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, webGLPixels);\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n        return webGLPixels;\n    }\n    else\n    {\n        return this.textureBuffer.canvas.getContext('2d').getImageData(x, y, 1, 1).data;\n    }\n};\n\n},{\"../const\":22,\"../math\":33,\"../renderers/canvas/utils/CanvasBuffer\":45,\"../renderers/webgl/managers/FilterManager\":54,\"../renderers/webgl/utils/RenderTarget\":65,\"./BaseTexture\":70,\"./Texture\":72}],72:[function(require,module,exports){\nvar BaseTexture = require('./BaseTexture'),\n    VideoBaseTexture = require('./VideoBaseTexture'),\n    TextureUvs = require('./TextureUvs'),\n    EventEmitter = require('eventemitter3'),\n    math = require('../math'),\n    utils = require('../utils');\n\n/**\n * A texture stores the information that represents an image or part of an image. It cannot be added\n * to the display list directly. Instead use it as the texture for a Sprite. If no frame is provided then the whole image is used.\n *\n * You can directly create a texture from an image and then reuse it multiple times like this :\n *\n * ```js\n * var texture = PIXI.Texture.fromImage('assets/image.png');\n * var sprite1 = new PIXI.Sprite(texture);\n * var sprite2 = new PIXI.Sprite(texture);\n * ```\n *\n * @class\n * @memberof PIXI\n * @param baseTexture {PIXI.BaseTexture} The base texture source to create the texture from\n * @param [frame] {PIXI.Rectangle} The rectangle frame of the texture to show\n * @param [crop] {PIXI.Rectangle} The area of original texture\n * @param [trim] {PIXI.Rectangle} Trimmed texture rectangle\n * @param [rotate] {number} indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}\n */\nfunction Texture(baseTexture, frame, crop, trim, rotate)\n{\n    EventEmitter.call(this);\n\n    /**\n     * Does this Texture have any frame data assigned to it?\n     *\n     * @member {boolean}\n     */\n    this.noFrame = false;\n\n    if (!frame)\n    {\n        this.noFrame = true;\n        frame = new math.Rectangle(0, 0, 1, 1);\n    }\n\n    if (baseTexture instanceof Texture)\n    {\n        baseTexture = baseTexture.baseTexture;\n    }\n\n    /**\n     * The base texture that this texture uses.\n     *\n     * @member {PIXI.BaseTexture}\n     */\n    this.baseTexture = baseTexture;\n\n    /**\n     * The frame specifies the region of the base texture that this texture uses\n     *\n     * @member {PIXI.Rectangle}\n     * @private\n     */\n    this._frame = frame;\n\n    /**\n     * The texture trim data.\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.trim = trim;\n\n    /**\n     * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.\n     *\n     * @member {boolean}\n     */\n    this.valid = false;\n\n    /**\n     * This will let a renderer know that a texture has been updated (used mainly for webGL uv updates)\n     *\n     * @member {boolean}\n     */\n    this.requiresUpdate = false;\n\n    /**\n     * The WebGL UV data cache.\n     *\n     * @member {PIXI.TextureUvs}\n     * @private\n     */\n    this._uvs = null;\n\n    /**\n     * The width of the Texture in pixels.\n     *\n     * @member {number}\n     */\n    this.width = 0;\n\n    /**\n     * The height of the Texture in pixels.\n     *\n     * @member {number}\n     */\n    this.height = 0;\n\n    /**\n     * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering,\n     * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases)\n     *\n     * @member {PIXI.Rectangle}\n     */\n    this.crop = crop || frame;//new math.Rectangle(0, 0, 1, 1);\n\n    this._rotate = +(rotate || 0);\n\n    if (rotate === true) {\n        // this is old texturepacker legacy, some games/libraries are passing \"true\" for rotated textures\n        this._rotate = 2;\n    } else {\n        if (this._rotate % 2 !== 0) {\n            throw 'attempt to use diamond-shaped UVs. If you are sure, set rotation manually';\n        }\n    }\n\n    if (baseTexture.hasLoaded)\n    {\n        if (this.noFrame)\n        {\n            frame = new math.Rectangle(0, 0, baseTexture.width, baseTexture.height);\n\n            // if there is no frame we should monitor for any base texture changes..\n            baseTexture.on('update', this.onBaseTextureUpdated, this);\n        }\n        this.frame = frame;\n    }\n    else\n    {\n        baseTexture.once('loaded', this.onBaseTextureLoaded, this);\n    }\n\n    /**\n     * Fired when the texture is updated. This happens if the frame or the baseTexture is updated.\n     *\n     * @event update\n     * @memberof PIXI.Texture#\n     * @protected\n     */\n}\n\nTexture.prototype = Object.create(EventEmitter.prototype);\nTexture.prototype.constructor = Texture;\nmodule.exports = Texture;\n\nObject.defineProperties(Texture.prototype, {\n    /**\n     * The frame specifies the region of the base texture that this texture uses.\n     *\n     * @member {PIXI.Rectangle}\n     * @memberof PIXI.Texture#\n     */\n    frame: {\n        get: function ()\n        {\n            return this._frame;\n        },\n        set: function (frame)\n        {\n            this._frame = frame;\n\n            this.noFrame = false;\n\n            this.width = frame.width;\n            this.height = frame.height;\n\n            if (!this.trim && !this.rotate && (frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height))\n            {\n                throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this);\n            }\n\n            //this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded;\n            this.valid = frame && frame.width && frame.height && this.baseTexture.hasLoaded;\n\n            if (this.trim)\n            {\n                this.width = this.trim.width;\n                this.height = this.trim.height;\n                this._frame.width = this.trim.width;\n                this._frame.height = this.trim.height;\n            }\n            else\n            {\n                this.crop = frame;\n            }\n\n            if (this.valid)\n            {\n                this._updateUvs();\n            }\n        }\n    },\n    /**\n     * Indicates whether the texture is rotated inside the atlas\n     * set to 2 to compensate for texture packer rotation\n     * set to 6 to compensate for spine packer rotation\n     * can be used to rotate or mirror sprites\n     * See {@link PIXI.GroupD8} for explanation\n     *\n     * @member {number}\n     */\n    rotate: {\n        get: function ()\n        {\n            return this._rotate;\n        },\n        set: function (rotate)\n        {\n            this._rotate = rotate;\n            if (this.valid)\n            {\n                this._updateUvs();\n            }\n        }\n    }\n});\n\n/**\n * Updates this texture on the gpu.\n *\n */\nTexture.prototype.update = function ()\n{\n    this.baseTexture.update();\n};\n\n/**\n * Called when the base texture is loaded\n *\n * @private\n */\nTexture.prototype.onBaseTextureLoaded = function (baseTexture)\n{\n    // TODO this code looks confusing.. boo to abusing getters and setterss!\n    if (this.noFrame)\n    {\n        this.frame = new math.Rectangle(0, 0, baseTexture.width, baseTexture.height);\n    }\n    else\n    {\n        this.frame = this._frame;\n    }\n\n    this.emit('update', this);\n};\n\n/**\n * Called when the base texture is updated\n *\n * @private\n */\nTexture.prototype.onBaseTextureUpdated = function (baseTexture)\n{\n    this._frame.width = baseTexture.width;\n    this._frame.height = baseTexture.height;\n\n    this.emit('update', this);\n};\n\n/**\n * Destroys this texture\n *\n * @param [destroyBase=false] {boolean} Whether to destroy the base texture as well\n */\nTexture.prototype.destroy = function (destroyBase)\n{\n    if (this.baseTexture)\n    {\n        if (destroyBase)\n        {\n            this.baseTexture.destroy();\n        }\n\n        this.baseTexture.off('update', this.onBaseTextureUpdated, this);\n        this.baseTexture.off('loaded', this.onBaseTextureLoaded, this);\n\n        this.baseTexture = null;\n    }\n\n    this._frame = null;\n    this._uvs = null;\n    this.trim = null;\n    this.crop = null;\n\n    this.valid = false;\n\n    this.off('dispose', this.dispose, this);\n    this.off('update', this.update, this);\n};\n\n/**\n * Creates a new texture object that acts the same as this one.\n *\n * @return {PIXI.Texture}\n */\nTexture.prototype.clone = function ()\n{\n    return new Texture(this.baseTexture, this.frame, this.crop, this.trim, this.rotate);\n};\n\n/**\n * Updates the internal WebGL UV cache.\n *\n * @private\n */\nTexture.prototype._updateUvs = function ()\n{\n    if (!this._uvs)\n    {\n        this._uvs = new TextureUvs();\n    }\n\n    this._uvs.set(this.crop, this.baseTexture, this.rotate);\n};\n\n/**\n * Helper function that creates a Texture object from the given image url.\n * If the image is not in the texture cache it will be  created and loaded.\n *\n * @static\n * @param imageUrl {string} The image url of the texture\n * @param crossorigin {boolean} Whether requests should be treated as crossorigin\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Texture} The newly created texture\n */\nTexture.fromImage = function (imageUrl, crossorigin, scaleMode)\n{\n    var texture = utils.TextureCache[imageUrl];\n\n    if (!texture)\n    {\n        texture = new Texture(BaseTexture.fromImage(imageUrl, crossorigin, scaleMode));\n        utils.TextureCache[imageUrl] = texture;\n    }\n\n    return texture;\n};\n\n/**\n * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId\n * The frame ids are created when a Texture packer file has been loaded\n *\n * @static\n * @param frameId {string} The frame Id of the texture in the cache\n * @return {PIXI.Texture} The newly created texture\n */\nTexture.fromFrame = function (frameId)\n{\n    var texture = utils.TextureCache[frameId];\n\n    if (!texture)\n    {\n        throw new Error('The frameId \"' + frameId + '\" does not exist in the texture cache');\n    }\n\n    return texture;\n};\n\n/**\n * Helper function that creates a new Texture based on the given canvas element.\n *\n * @static\n * @param canvas {Canvas} The canvas element source of the texture\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Texture}\n */\nTexture.fromCanvas = function (canvas, scaleMode)\n{\n    return new Texture(BaseTexture.fromCanvas(canvas, scaleMode));\n};\n\n/**\n * Helper function that creates a new Texture based on the given video element.\n *\n * @static\n * @param video {HTMLVideoElement}\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Texture} A Texture\n */\nTexture.fromVideo = function (video, scaleMode)\n{\n    if (typeof video === 'string')\n    {\n        return Texture.fromVideoUrl(video, scaleMode);\n    }\n    else\n    {\n        return new Texture(VideoBaseTexture.fromVideo(video, scaleMode));\n    }\n};\n\n/**\n * Helper function that creates a new Texture based on the video url.\n *\n * @static\n * @param videoUrl {string}\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.Texture} A Texture\n */\nTexture.fromVideoUrl = function (videoUrl, scaleMode)\n{\n    return new Texture(VideoBaseTexture.fromUrl(videoUrl, scaleMode));\n};\n\n/**\n * Adds a texture to the global utils.TextureCache. This cache is shared across the whole PIXI object.\n *\n * @static\n * @param texture {PIXI.Texture} The Texture to add to the cache.\n * @param id {string} The id that the texture will be stored against.\n */\nTexture.addTextureToCache = function (texture, id)\n{\n    utils.TextureCache[id] = texture;\n};\n\n/**\n * Remove a texture from the global utils.TextureCache.\n *\n * @static\n * @param id {string} The id of the texture to be removed\n * @return {PIXI.Texture} The texture that was removed\n */\nTexture.removeTextureFromCache = function (id)\n{\n    var texture = utils.TextureCache[id];\n\n    delete utils.TextureCache[id];\n    delete utils.BaseTextureCache[id];\n\n    return texture;\n};\n\n/**\n * An empty texture, used often to not have to create multiple empty textures.\n *\n * @static\n * @constant\n */\nTexture.EMPTY = new Texture(new BaseTexture());\n\n},{\"../math\":33,\"../utils\":77,\"./BaseTexture\":70,\"./TextureUvs\":73,\"./VideoBaseTexture\":74,\"eventemitter3\":10}],73:[function(require,module,exports){\n\n/**\n * A standard object to store the Uvs of a texture\n *\n * @class\n * @private\n * @memberof PIXI\n */\nfunction TextureUvs()\n{\n    this.x0 = 0;\n    this.y0 = 0;\n\n    this.x1 = 1;\n    this.y1 = 0;\n\n    this.x2 = 1;\n    this.y2 = 1;\n\n    this.x3 = 0;\n    this.y3 = 1;\n}\n\nmodule.exports = TextureUvs;\n\nvar GroupD8 = require('../math/GroupD8');\n\n/**\n * Sets the texture Uvs based on the given frame information\n * @param frame {PIXI.Rectangle}\n * @param baseFrame {PIXI.Rectangle}\n * @param rotate {number} Rotation of frame, see {@link PIXI.GroupD8}\n * @private\n */\nTextureUvs.prototype.set = function (frame, baseFrame, rotate)\n{\n    var tw = baseFrame.width;\n    var th = baseFrame.height;\n\n    if(rotate)\n    {\n        //width and height div 2 div baseFrame size\n        var swapWidthHeight = GroupD8.isSwapWidthHeight(rotate);\n        var w2 = (swapWidthHeight ? frame.height : frame.width) / 2 / tw;\n        var h2 = (swapWidthHeight ? frame.width : frame.height) / 2 / th;\n        //coordinates of center\n        var cX = frame.x / tw + w2;\n        var cY = frame.y / th + h2;\n        rotate = GroupD8.add(rotate, GroupD8.NW); //NW is top-left corner\n        this.x0 = cX + w2 * GroupD8.uX(rotate);\n        this.y0 = cY + h2 * GroupD8.uY(rotate);\n        rotate = GroupD8.add(rotate, 2); //rotate 90 degrees clockwise\n        this.x1 = cX + w2 * GroupD8.uX(rotate);\n        this.y1 = cY + h2 * GroupD8.uY(rotate);\n        rotate = GroupD8.add(rotate, 2);\n        this.x2 = cX + w2 * GroupD8.uX(rotate);\n        this.y2 = cY + h2 * GroupD8.uY(rotate);\n        rotate = GroupD8.add(rotate, 2);\n        this.x3 = cX + w2 * GroupD8.uX(rotate);\n        this.y3 = cY + h2 * GroupD8.uY(rotate);\n    }\n    else\n    {\n\n        this.x0 = frame.x / tw;\n        this.y0 = frame.y / th;\n\n        this.x1 = (frame.x + frame.width) / tw;\n        this.y1 = frame.y / th;\n\n        this.x2 = (frame.x + frame.width) / tw;\n        this.y2 = (frame.y + frame.height) / th;\n\n        this.x3 = frame.x / tw;\n        this.y3 = (frame.y + frame.height) / th;\n    }\n};\n\n},{\"../math/GroupD8\":30}],74:[function(require,module,exports){\nvar BaseTexture = require('./BaseTexture'),\n    utils = require('../utils');\n\n/**\n * A texture of a [playing] Video.\n *\n * Video base textures mimic Pixi BaseTexture.from.... method in their creation process.\n *\n * This can be used in several ways, such as:\n *\n * ```js\n * var texture = PIXI.VideoBaseTexture.fromUrl('http://mydomain.com/video.mp4');\n *\n * var texture = PIXI.VideoBaseTexture.fromUrl({ src: 'http://mydomain.com/video.mp4', mime: 'video/mp4' });\n *\n * var texture = PIXI.VideoBaseTexture.fromUrls(['/video.webm', '/video.mp4']);\n *\n * var texture = PIXI.VideoBaseTexture.fromUrls([\n *     { src: '/video.webm', mime: 'video/webm' },\n *     { src: '/video.mp4', mime: 'video/mp4' }\n * ]);\n * ```\n *\n * See the [\"deus\" demo](http://www.goodboydigital.com/pixijs/examples/deus/).\n *\n * @class\n * @extends PIXI.BaseTexture\n * @memberof PIXI\n * @param source {HTMLVideoElement}\n * @param [scaleMode] {number} See {@link PIXI.SCALE_MODES} for possible values\n */\nfunction VideoBaseTexture(source, scaleMode)\n{\n    if (!source)\n    {\n        throw new Error('No video source element specified.');\n    }\n\n    // hook in here to check if video is already available.\n    // BaseTexture looks for a source.complete boolean, plus width & height.\n\n    if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height)\n    {\n        source.complete = true;\n    }\n\n    BaseTexture.call(this, source, scaleMode);\n\n    /**\n     * Should the base texture automatically update itself, set to true by default\n     *\n     * @member {boolean}\n     * @default true\n     */\n    this.autoUpdate = false;\n\n    this._onUpdate = this._onUpdate.bind(this);\n    this._onCanPlay = this._onCanPlay.bind(this);\n\n    if (!source.complete)\n    {\n        source.addEventListener('canplay', this._onCanPlay);\n        source.addEventListener('canplaythrough', this._onCanPlay);\n\n        // started playing..\n        source.addEventListener('play', this._onPlayStart.bind(this));\n        source.addEventListener('pause', this._onPlayStop.bind(this));\n    }\n\n    this.__loaded = false;\n}\n\nVideoBaseTexture.prototype = Object.create(BaseTexture.prototype);\nVideoBaseTexture.prototype.constructor = VideoBaseTexture;\nmodule.exports = VideoBaseTexture;\n\n/**\n * The internal update loop of the video base texture, only runs when autoUpdate is set to true\n *\n * @private\n */\nVideoBaseTexture.prototype._onUpdate = function ()\n{\n    if (this.autoUpdate)\n    {\n        window.requestAnimationFrame(this._onUpdate);\n        this.update();\n    }\n};\n\n/**\n * Runs the update loop when the video is ready to play\n *\n * @private\n */\nVideoBaseTexture.prototype._onPlayStart = function ()\n{\n    if (!this.autoUpdate)\n    {\n        window.requestAnimationFrame(this._onUpdate);\n        this.autoUpdate = true;\n    }\n};\n\n/**\n * Fired when a pause event is triggered, stops the update loop\n *\n * @private\n */\nVideoBaseTexture.prototype._onPlayStop = function ()\n{\n    this.autoUpdate = false;\n};\n\n/**\n * Fired when the video is loaded and ready to play\n *\n * @private\n */\nVideoBaseTexture.prototype._onCanPlay = function ()\n{\n    this.hasLoaded = true;\n\n    if (this.source)\n    {\n        this.source.removeEventListener('canplay', this._onCanPlay);\n        this.source.removeEventListener('canplaythrough', this._onCanPlay);\n\n        this.width = this.source.videoWidth;\n        this.height = this.source.videoHeight;\n\n        this.source.play();\n\n        // prevent multiple loaded dispatches..\n        if (!this.__loaded)\n        {\n            this.__loaded = true;\n            this.emit('loaded', this);\n        }\n    }\n};\n\n/**\n * Destroys this texture\n *\n */\nVideoBaseTexture.prototype.destroy = function ()\n{\n    if (this.source && this.source._pixiId)\n    {\n        delete utils.BaseTextureCache[ this.source._pixiId ];\n        delete this.source._pixiId;\n    }\n\n    BaseTexture.prototype.destroy.call(this);\n};\n\n/**\n * Mimic Pixi BaseTexture.from.... method.\n *\n * @static\n * @param video {HTMLVideoElement}\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.VideoBaseTexture}\n */\nVideoBaseTexture.fromVideo = function (video, scaleMode)\n{\n    if (!video._pixiId)\n    {\n        video._pixiId = 'video_' + utils.uid();\n    }\n\n    var baseTexture = utils.BaseTextureCache[video._pixiId];\n\n    if (!baseTexture)\n    {\n        baseTexture = new VideoBaseTexture(video, scaleMode);\n        utils.BaseTextureCache[ video._pixiId ] = baseTexture;\n    }\n\n    return baseTexture;\n};\n\n/**\n * Helper function that creates a new BaseTexture based on the given video element.\n * This BaseTexture can then be used to create a texture\n *\n * @static\n * @param videoSrc {string|object|string[]|object[]} The URL(s) for the video.\n * @param [videoSrc.src] {string} One of the source urls for the video\n * @param [videoSrc.mime] {string} The mimetype of the video (e.g. 'video/mp4'). If not specified\n *  the url's extension will be used as the second part of the mime type.\n * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.VideoBaseTexture}\n */\nVideoBaseTexture.fromUrl = function (videoSrc, scaleMode)\n{\n    var video = document.createElement('video');\n\n    // array of objects or strings\n    if (Array.isArray(videoSrc))\n    {\n        for (var i = 0; i < videoSrc.length; ++i)\n        {\n            video.appendChild(createSource(videoSrc[i].src || videoSrc[i], videoSrc[i].mime));\n        }\n    }\n    // single object or string\n    else\n    {\n        video.appendChild(createSource(videoSrc.src || videoSrc, videoSrc.mime));\n    }\n\n    video.load();\n    video.play();\n\n    return VideoBaseTexture.fromVideo(video, scaleMode);\n};\n\nVideoBaseTexture.fromUrls = VideoBaseTexture.fromUrl;\n\nfunction createSource(path, type)\n{\n    if (!type)\n    {\n        type = 'video/' + path.substr(path.lastIndexOf('.') + 1);\n    }\n\n    var source = document.createElement('source');\n\n    source.src = path;\n    source.type = type;\n\n    return source;\n}\n\n},{\"../utils\":77,\"./BaseTexture\":70}],75:[function(require,module,exports){\nvar CONST = require('../const'),\n    EventEmitter = require('eventemitter3'),\n    // Internal event used by composed emitter\n    TICK = 'tick';\n\n/**\n * A Ticker class that runs an update loop that other objects listen to.\n * This class is composed around an EventEmitter object to add listeners\n * meant for execution on the next requested animation frame.\n * Animation frames are requested only when necessary,\n * e.g. When the ticker is started and the emitter has listeners.\n *\n * @class\n * @memberof PIXI.ticker\n */\nfunction Ticker()\n{\n    var _this = this;\n\n    /**\n     * Internal tick method bound to ticker instance.\n     * This is because in early 2015, Function.bind\n     * is still 60% slower in high performance scenarios.\n     * Also separating frame requests from update method\n     * so listeners may be called at any time and with\n     * any animation API, just invoke ticker.update(time).\n     *\n     * @private\n     */\n    this._tick = function _tick(time) {\n\n        _this._requestId = null;\n\n        if (_this.started)\n        {\n            // Invoke listeners now\n            _this.update(time);\n            // Listener side effects may have modified ticker state.\n            if (_this.started && _this._requestId === null && _this._emitter.listeners(TICK, true))\n            {\n                _this._requestId = requestAnimationFrame(_this._tick);\n            }\n        }\n    };\n\n    /**\n     * Internal emitter used to fire 'tick' event\n     * @private\n     */\n    this._emitter = new EventEmitter();\n\n    /**\n     * Internal current frame request ID\n     * @private\n     */\n    this._requestId = null;\n\n    /**\n     * Internal value managed by minFPS property setter and getter.\n     * This is the maximum allowed milliseconds between updates.\n     * @private\n     */\n    this._maxElapsedMS = 100;\n\n    /**\n     * Whether or not this ticker should invoke the method\n     * {@link PIXI.ticker.Ticker#start} automatically\n     * when a listener is added.\n     *\n     * @member {boolean}\n     * @default false\n     */\n    this.autoStart = false;\n\n    /**\n     * Scalar time value from last frame to this frame.\n     * This value is capped by setting {@link PIXI.ticker.Ticker#minFPS}\n     * and is scaled with {@link PIXI.ticker.Ticker#speed}.\n     * **Note:** The cap may be exceeded by scaling.\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.deltaTime = 1;\n\n    /**\n     * Time elapsed in milliseconds from last frame to this frame.\n     * Opposed to what the scalar {@link PIXI.ticker.Ticker#deltaTime}\n     * is based, this value is neither capped nor scaled.\n     * If the platform supports DOMHighResTimeStamp,\n     * this value will have a precision of 1 µs.\n     *\n     * @member {DOMHighResTimeStamp|number}\n     * @default 1 / TARGET_FPMS\n     */\n    this.elapsedMS = 1 / CONST.TARGET_FPMS; // default to target frame time\n\n    /**\n     * The last time {@link PIXI.ticker.Ticker#update} was invoked.\n     * This value is also reset internally outside of invoking\n     * update, but only when a new animation frame is requested.\n     * If the platform supports DOMHighResTimeStamp,\n     * this value will have a precision of 1 µs.\n     *\n     * @member {DOMHighResTimeStamp|number}\n     * @default 0\n     */\n    this.lastTime = 0;\n\n    /**\n     * Factor of current {@link PIXI.ticker.Ticker#deltaTime}.\n     * @example\n     * // Scales ticker.deltaTime to what would be\n     * // the equivalent of approximately 120 FPS\n     * ticker.speed = 2;\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.speed = 1;\n\n    /**\n     * Whether or not this ticker has been started.\n     * `true` if {@link PIXI.ticker.Ticker#start} has been called.\n     * `false` if {@link PIXI.ticker.Ticker#stop} has been called.\n     * While `false`, this value may change to `true` in the\n     * event of {@link PIXI.ticker.Ticker#autoStart} being `true`\n     * and a listener is added.\n     *\n     * @member {boolean}\n     * @default false\n     */\n    this.started = false;\n}\n\nObject.defineProperties(Ticker.prototype, {\n    /**\n     * The frames per second at which this ticker is running.\n     * The default is approximately 60 in most modern browsers.\n     * **Note:** This does not factor in the value of\n     * {@link PIXI.ticker.Ticker#speed}, which is specific\n     * to scaling {@link PIXI.ticker.Ticker#deltaTime}.\n     *\n     * @member\n     * @memberof PIXI.ticker.Ticker#\n     * @readonly\n     */\n    FPS: {\n        get: function()\n        {\n            return 1000 / this.elapsedMS;\n        }\n    },\n\n    /**\n     * Manages the maximum amount of milliseconds allowed to\n     * elapse between invoking {@link PIXI.ticker.Ticker#update}.\n     * This value is used to cap {@link PIXI.ticker.Ticker#deltaTime},\n     * but does not effect the measured value of {@link PIXI.ticker.Ticker#FPS}.\n     * When setting this property it is clamped to a value between\n     * `0` and `PIXI.TARGET_FPMS * 1000`.\n     *\n     * @member\n     * @memberof PIXI.ticker.Ticker#\n     * @default 10\n     */\n    minFPS: {\n        get: function()\n        {\n            return 1000 / this._maxElapsedMS;\n        },\n        set: function(fps)\n        {\n            // Clamp: 0 to TARGET_FPMS\n            var minFPMS = Math.min(Math.max(0, fps) / 1000, CONST.TARGET_FPMS);\n            this._maxElapsedMS = 1 / minFPMS;\n        }\n    }\n});\n\n/**\n * Conditionally requests a new animation frame.\n * If a frame has not already been requested, and if the internal\n * emitter has listeners, a new frame is requested.\n *\n * @private\n */\nTicker.prototype._requestIfNeeded = function _requestIfNeeded()\n{\n    if (this._requestId === null && this._emitter.listeners(TICK, true))\n    {\n        // ensure callbacks get correct delta\n        this.lastTime = performance.now();\n        this._requestId = requestAnimationFrame(this._tick);\n    }\n};\n\n/**\n * Conditionally cancels a pending animation frame.\n *\n * @private\n */\nTicker.prototype._cancelIfNeeded = function _cancelIfNeeded()\n{\n    if (this._requestId !== null)\n    {\n        cancelAnimationFrame(this._requestId);\n        this._requestId = null;\n    }\n};\n\n/**\n * Conditionally requests a new animation frame.\n * If the ticker has been started it checks if a frame has not already\n * been requested, and if the internal emitter has listeners. If these\n * conditions are met, a new frame is requested. If the ticker has not\n * been started, but autoStart is `true`, then the ticker starts now,\n * and continues with the previous conditions to request a new frame.\n *\n * @private\n */\nTicker.prototype._startIfPossible = function _startIfPossible()\n{\n    if (this.started)\n    {\n        this._requestIfNeeded();\n    }\n    else if (this.autoStart)\n    {\n        this.start();\n    }\n};\n\n/**\n * Calls {@link module:eventemitter3.EventEmitter#on} internally for the\n * internal 'tick' event. It checks if the emitter has listeners,\n * and if so it requests a new animation frame at this point.\n *\n * @param fn {Function} The listener function to be added for updates\n * @param [context] {Function} The listener context\n * @returns {PIXI.ticker.Ticker} this\n */\nTicker.prototype.add = function add(fn, context)\n{\n    this._emitter.on(TICK, fn, context);\n\n    this._startIfPossible();\n\n    return this;\n};\n\n/**\n * Calls {@link module:eventemitter3.EventEmitter#once} internally for the\n * internal 'tick' event. It checks if the emitter has listeners,\n * and if so it requests a new animation frame at this point.\n *\n * @param fn {Function} The listener function to be added for one update\n * @param [context] {Function} The listener context\n * @returns {PIXI.ticker.Ticker} this\n */\nTicker.prototype.addOnce = function addOnce(fn, context)\n{\n    this._emitter.once(TICK, fn, context);\n\n    this._startIfPossible();\n\n    return this;\n};\n\n/**\n * Calls {@link module:eventemitter3.EventEmitter#off} internally for 'tick' event.\n * It checks if the emitter has listeners for 'tick' event.\n * If it does, then it cancels the animation frame.\n *\n * @param [fn] {Function} The listener function to be removed\n * @param [context] {Function} The listener context to be removed\n * @returns {PIXI.ticker.Ticker} this\n */\nTicker.prototype.remove = function remove(fn, context)\n{\n    this._emitter.off(TICK, fn, context);\n\n    if (!this._emitter.listeners(TICK, true))\n    {\n        this._cancelIfNeeded();\n    }\n\n    return this;\n};\n\n/**\n * Starts the ticker. If the ticker has listeners\n * a new animation frame is requested at this point.\n */\nTicker.prototype.start = function start()\n{\n    if (!this.started)\n    {\n        this.started = true;\n        this._requestIfNeeded();\n    }\n};\n\n/**\n * Stops the ticker. If the ticker has requested\n * an animation frame it is canceled at this point.\n */\nTicker.prototype.stop = function stop()\n{\n    if (this.started)\n    {\n        this.started = false;\n        this._cancelIfNeeded();\n    }\n};\n\n/**\n * Triggers an update. An update entails setting the\n * current {@link PIXI.ticker.Ticker#elapsedMS},\n * the current {@link PIXI.ticker.Ticker#deltaTime},\n * invoking all listeners with current deltaTime,\n * and then finally setting {@link PIXI.ticker.Ticker#lastTime}\n * with the value of currentTime that was provided.\n * This method will be called automatically by animation\n * frame callbacks if the ticker instance has been started\n * and listeners are added.\n *\n * @param [currentTime=performance.now()] {DOMHighResTimeStamp|number} the current time of execution\n */\nTicker.prototype.update = function update(currentTime)\n{\n    var elapsedMS;\n\n    // Allow calling update directly with default currentTime.\n    currentTime = currentTime || performance.now();\n    // Save uncapped elapsedMS for measurement\n    elapsedMS = this.elapsedMS = currentTime - this.lastTime;\n\n    // cap the milliseconds elapsed used for deltaTime\n    if (elapsedMS > this._maxElapsedMS)\n    {\n        elapsedMS = this._maxElapsedMS;\n    }\n\n    this.deltaTime = elapsedMS * CONST.TARGET_FPMS * this.speed;\n\n    // Invoke listeners added to internal emitter\n    this._emitter.emit(TICK, this.deltaTime);\n\n    this.lastTime = currentTime;\n};\n\nmodule.exports = Ticker;\n\n},{\"../const\":22,\"eventemitter3\":10}],76:[function(require,module,exports){\nvar Ticker = require('./Ticker');\n\n/**\n * The shared ticker instance used by {@link PIXI.extras.MovieClip}.\n * and by {@link PIXI.interaction.InteractionManager}.\n * The property {@link PIXI.ticker.Ticker#autoStart} is set to `true`\n * for this instance. Please follow the examples for usage, including\n * how to opt-out of auto-starting the shared ticker.\n *\n * @example\n * var ticker = PIXI.ticker.shared;\n * // Set this to prevent starting this ticker when listeners are added.\n * // By default this is true only for the PIXI.ticker.shared instance.\n * ticker.autoStart = false;\n * // FYI, call this to ensure the ticker is stopped. It should be stopped\n * // if you have not attempted to render anything yet.\n * ticker.stop();\n * // Call this when you are ready for a running shared ticker.\n * ticker.start();\n *\n * @example\n * // You may use the shared ticker to render...\n * var renderer = PIXI.autoDetectRenderer(800, 600);\n * var stage = new PIXI.Container();\n * var interactionManager = PIXI.interaction.InteractionManager(renderer);\n * document.body.appendChild(renderer.view);\n * ticker.add(function (time) {\n *     renderer.render(stage);\n * });\n *\n * @example\n * // Or you can just update it manually.\n * ticker.autoStart = false;\n * ticker.stop();\n * function animate(time) {\n *     ticker.update(time);\n *     renderer.render(stage);\n *     requestAnimationFrame(animate);\n * }\n * animate(performance.now());\n *\n * @type {PIXI.ticker.Ticker}\n * @memberof PIXI.ticker\n */\nvar shared = new Ticker();\nshared.autoStart = true;\n\n/**\n * @namespace PIXI.ticker\n */\nmodule.exports = {\n    shared: shared,\n    Ticker: Ticker\n};\n\n},{\"./Ticker\":75}],77:[function(require,module,exports){\nvar CONST = require('../const');\n\n/**\n * @namespace PIXI.utils\n */\nvar utils = module.exports = {\n    _uid: 0,\n    _saidHello: false,\n\n    EventEmitter:   require('eventemitter3'),\n    pluginTarget:   require('./pluginTarget'),\n    async:          require('async'),\n\n    /**\n     * Gets the next unique identifier\n     *\n     * @return {number} The next unique identifier to use.\n     */\n    uid: function ()\n    {\n        return ++utils._uid;\n    },\n\n    /**\n     * Converts a hex color number to an [R, G, B] array\n     *\n     * @param hex {number}\n     * @param  {number[]} [out=[]]\n     * @return {number[]} An array representing the [R, G, B] of the color.\n     */\n    hex2rgb: function (hex, out)\n    {\n        out = out || [];\n\n        out[0] = (hex >> 16 & 0xFF) / 255;\n        out[1] = (hex >> 8 & 0xFF) / 255;\n        out[2] = (hex & 0xFF) / 255;\n\n        return out;\n    },\n\n    /**\n     * Converts a hex color number to a string.\n     *\n     * @param hex {number}\n     * @return {string} The string color.\n     */\n    hex2string: function (hex)\n    {\n        hex = hex.toString(16);\n        hex = '000000'.substr(0, 6 - hex.length) + hex;\n\n        return '#' + hex;\n    },\n\n    /**\n     * Converts a color as an [R, G, B] array to a hex number\n     *\n     * @param rgb {number[]}\n     * @return {number} The color number\n     */\n    rgb2hex: function (rgb)\n    {\n        return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);\n    },\n\n    /**\n     * Checks whether the Canvas BlendModes are supported by the current browser\n     *\n     * @return {boolean} whether they are supported\n     */\n    canUseNewCanvasBlendModes: function ()\n    {\n        if (typeof document === 'undefined')\n        {\n            return false;\n        }\n\n        var pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/';\n        var pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';\n\n        var magenta = new Image();\n        magenta.src = pngHead + 'AP804Oa6' + pngEnd;\n\n        var yellow = new Image();\n        yellow.src = pngHead + '/wCKxvRF' + pngEnd;\n\n        var canvas = document.createElement('canvas');\n        canvas.width = 6;\n        canvas.height = 1;\n\n        var context = canvas.getContext('2d');\n        context.globalCompositeOperation = 'multiply';\n        context.drawImage(magenta, 0, 0);\n        context.drawImage(yellow, 2, 0);\n\n        var data = context.getImageData(2,0,1,1).data;\n\n        return (data[0] === 255 && data[1] === 0 && data[2] === 0);\n    },\n\n    /**\n     * Given a number, this function returns the closest number that is a power of two\n     * this function is taken from Starling Framework as its pretty neat ;)\n     *\n     * @param number {number}\n     * @return {number} the closest number that is a power of two\n     */\n    getNextPowerOfTwo: function (number)\n    {\n        // see: http://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_positive_number_is_a_power_of_two\n        if (number > 0 && (number & (number - 1)) === 0)\n        {\n            return number;\n        }\n        else\n        {\n            var result = 1;\n\n            while (result < number)\n            {\n                result <<= 1;\n            }\n\n            return result;\n        }\n    },\n\n    /**\n     * checks if the given width and height make a power of two rectangle\n     *\n     * @param width {number}\n     * @param height {number}\n     * @return {boolean}\n     */\n    isPowerOfTwo: function (width, height)\n    {\n        return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0);\n    },\n\n    /**\n     * get the resolution of an asset by looking for the prefix\n     * used by spritesheets and image urls\n     *\n     * @param url {string} the image path\n     * @return {number}\n     */\n    getResolutionOfUrl: function (url)\n    {\n        var resolution = CONST.RETINA_PREFIX.exec(url);\n\n        if (resolution)\n        {\n           return parseFloat(resolution[1]);\n        }\n\n        return 1;\n    },\n\n    /**\n     * Logs out the version and renderer information for this running instance of PIXI.\n     * If you don't want to see this message you can set `PIXI.utils._saidHello = true;`\n     * so the library thinks it already said it. Keep in mind that doing that will forever\n     * makes you a jerk face.\n     *\n     * @param {string} type - The string renderer type to log.\n     * @constant\n     * @static\n     */\n    sayHello: function (type)\n    {\n        if (utils._saidHello)\n        {\n            return;\n        }\n\n        if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)\n        {\n            var args = [\n                '\\n %c %c %c Pixi.js ' + CONST.VERSION + ' - ✰ ' + type + ' ✰  %c ' + ' %c ' + ' http://www.pixijs.com/  %c %c ♥%c♥%c♥ \\n\\n',\n                'background: #ff66a5; padding:5px 0;',\n                'background: #ff66a5; padding:5px 0;',\n                'color: #ff66a5; background: #030307; padding:5px 0;',\n                'background: #ff66a5; padding:5px 0;',\n                'background: #ffc3dc; padding:5px 0;',\n                'background: #ff66a5; padding:5px 0;',\n                'color: #ff2424; background: #fff; padding:5px 0;',\n                'color: #ff2424; background: #fff; padding:5px 0;',\n                'color: #ff2424; background: #fff; padding:5px 0;'\n            ];\n\n            window.console.log.apply(console, args); //jshint ignore:line\n        }\n        else if (window.console)\n        {\n            window.console.log('Pixi.js ' + CONST.VERSION + ' - ' + type + ' - http://www.pixijs.com/'); //jshint ignore:line\n        }\n\n        utils._saidHello = true;\n    },\n\n    /**\n     * Helper for checking for webgl support\n     *\n     * @return {boolean}\n     */\n    isWebGLSupported: function ()\n    {\n        var contextOptions = { stencil: true };\n        try\n        {\n            if (!window.WebGLRenderingContext)\n            {\n                return false;\n            }\n\n            var canvas = document.createElement('canvas'),\n                gl = canvas.getContext('webgl', contextOptions) || canvas.getContext('experimental-webgl', contextOptions);\n\n            return !!(gl && gl.getContextAttributes().stencil);\n        }\n        catch (e)\n        {\n            return false;\n        }\n    },\n\n    /**\n     * Returns sign of number\n     *\n     * @param n {number}\n     * @returns {number} 0 if n is 0, -1 if n is negative, 1 if n i positive\n     */\n    sign: function (n)\n    {\n        return n ? (n < 0 ? -1 : 1) : 0;\n    },\n\n    /**\n     * removeItems\n     *\n     * @param {array} arr The target array\n     * @param {number} startIdx The index to begin removing from (inclusive)\n     * @param {number} removeCount How many items to remove\n     */\n    removeItems: function (arr, startIdx, removeCount)\n    {\n        var length = arr.length;\n\n        if (startIdx >= length || removeCount === 0)\n        {\n            return;\n        }\n\n        removeCount = (startIdx+removeCount > length ? length-startIdx : removeCount);\n        for (var i = startIdx, len = length-removeCount; i < len; ++i)\n        {\n            arr[i] = arr[i + removeCount];\n        }\n\n        arr.length = len;\n    },\n\n    /**\n     * @todo Describe property usage\n     * @private\n     */\n    TextureCache: {},\n\n    /**\n     * @todo Describe property usage\n     * @private\n     */\n    BaseTextureCache: {}\n};\n\n},{\"../const\":22,\"./pluginTarget\":78,\"async\":1,\"eventemitter3\":10}],78:[function(require,module,exports){\n/**\n * Mixins functionality to make an object have \"plugins\".\n *\n * @mixin\n * @memberof PIXI.utils\n * @param obj {object} The object to mix into.\n * @example\n *      function MyObject() {}\n *\n *      pluginTarget.mixin(MyObject);\n */\nfunction pluginTarget(obj)\n{\n    obj.__plugins = {};\n\n    /**\n     * Adds a plugin to an object\n     *\n     * @param pluginName {string} The events that should be listed.\n     * @param ctor {Function} The constructor function for the plugin.\n     */\n    obj.registerPlugin = function (pluginName, ctor)\n    {\n        obj.__plugins[pluginName] = ctor;\n    };\n\n    /**\n     * Instantiates all the plugins of this object\n     *\n     */\n    obj.prototype.initPlugins = function ()\n    {\n        this.plugins = this.plugins || {};\n\n        for (var o in obj.__plugins)\n        {\n            this.plugins[o] = new (obj.__plugins[o])(this);\n        }\n    };\n\n    /**\n     * Removes all the plugins of this object\n     *\n     */\n    obj.prototype.destroyPlugins = function ()\n    {\n        for (var o in this.plugins)\n        {\n            this.plugins[o].destroy();\n            this.plugins[o] = null;\n        }\n\n        this.plugins = null;\n    };\n}\n\n\nmodule.exports = {\n    /**\n     * Mixes in the properties of the pluginTarget into another object\n     *\n     * @param object {object} The obj to mix into\n     */\n    mixin: function mixin(obj)\n    {\n        pluginTarget(obj);\n    }\n};\n\n},{}],79:[function(require,module,exports){\n/*global console */\nvar core = require('./core'),\n    mesh = require('./mesh'),\n    extras = require('./extras'),\n    filters = require('./filters');\n\n/**\n * @class\n * @private\n * @name SpriteBatch\n * @memberof PIXI\n * @see PIXI.ParticleContainer\n * @throws {ReferenceError} SpriteBatch does not exist any more, please use the new ParticleContainer instead.\n * @deprecated since version 3.0.0\n */\ncore.SpriteBatch = function()\n{\n    throw new ReferenceError('SpriteBatch does not exist any more, please use the new ParticleContainer instead.');\n};\n\n/**\n * @class\n * @private\n * @name AssetLoader\n * @memberof PIXI\n * @see PIXI.loaders.Loader\n * @throws {ReferenceError} The loader system was overhauled in pixi v3, please see the new PIXI.loaders.Loader class.\n * @deprecated since version 3.0.0\n */\ncore.AssetLoader = function()\n{\n    throw new ReferenceError('The loader system was overhauled in pixi v3, please see the new PIXI.loaders.Loader class.');\n};\n\nObject.defineProperties(core, {\n\n    /**\n     * @class\n     * @private\n     * @name Stage\n     * @memberof PIXI\n     * @see PIXI.Container\n     * @deprecated since version 3.0.0\n     */\n    Stage: {\n        get: function()\n        {\n            console.warn('You do not need to use a PIXI Stage any more, you can simply render any container.');\n            return core.Container;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name DisplayObjectContainer\n     * @memberof PIXI\n     * @see PIXI.Container\n     * @deprecated since version 3.0.0\n     */\n    DisplayObjectContainer: {\n        get: function()\n        {\n            console.warn('DisplayObjectContainer has been shortened to Container, please use Container from now on.');\n            return core.Container;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name Strip\n     * @memberof PIXI\n     * @see PIXI.mesh.Mesh\n     * @deprecated since version 3.0.0\n     */\n    Strip: {\n        get: function()\n        {\n            console.warn('The Strip class has been renamed to Mesh and moved to mesh.Mesh, please use mesh.Mesh from now on.');\n            return mesh.Mesh;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name Rope\n     * @memberof PIXI\n     * @see PIXI.mesh.Rope\n     * @deprecated since version 3.0.0\n     */\n    Rope: {\n        get: function()\n        {\n            console.warn('The Rope class has been moved to mesh.Rope, please use mesh.Rope from now on.');\n            return mesh.Rope;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name MovieClip\n     * @memberof PIXI\n     * @see PIXI.extras.MovieClip\n     * @deprecated since version 3.0.0\n     */\n    MovieClip: {\n        get: function()\n        {\n            console.warn('The MovieClip class has been moved to extras.MovieClip, please use extras.MovieClip from now on.');\n            return extras.MovieClip;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name TilingSprite\n     * @memberof PIXI\n     * @see PIXI.extras.TilingSprite\n     * @deprecated since version 3.0.0\n     */\n    TilingSprite: {\n        get: function()\n        {\n            console.warn('The TilingSprite class has been moved to extras.TilingSprite, please use extras.TilingSprite from now on.');\n            return extras.TilingSprite;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name BitmapText\n     * @memberof PIXI\n     * @see PIXI.extras.BitmapText\n     * @deprecated since version 3.0.0\n     */\n    BitmapText: {\n        get: function()\n        {\n            console.warn('The BitmapText class has been moved to extras.BitmapText, please use extras.BitmapText from now on.');\n            return extras.BitmapText;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name blendModes\n     * @memberof PIXI\n     * @see PIXI.BLEND_MODES\n     * @deprecated since version 3.0.0\n     */\n    blendModes: {\n        get: function()\n        {\n            console.warn('The blendModes has been moved to BLEND_MODES, please use BLEND_MODES from now on.');\n            return core.BLEND_MODES;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name scaleModes\n     * @memberof PIXI\n     * @see PIXI.SCALE_MODES\n     * @deprecated since version 3.0.0\n     */\n    scaleModes: {\n        get: function()\n        {\n            console.warn('The scaleModes has been moved to SCALE_MODES, please use SCALE_MODES from now on.');\n            return core.SCALE_MODES;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name BaseTextureCache\n     * @memberof PIXI\n     * @see PIXI.utils.BaseTextureCache\n     * @deprecated since version 3.0.0\n     */\n    BaseTextureCache: {\n        get: function ()\n        {\n            console.warn('The BaseTextureCache class has been moved to utils.BaseTextureCache, please use utils.BaseTextureCache from now on.');\n            return core.utils.BaseTextureCache;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name TextureCache\n     * @memberof PIXI\n     * @see PIXI.utils.TextureCache\n     * @deprecated since version 3.0.0\n     */\n    TextureCache: {\n        get: function ()\n        {\n            console.warn('The TextureCache class has been moved to utils.TextureCache, please use utils.TextureCache from now on.');\n            return core.utils.TextureCache;\n        }\n    },\n\n    /**\n     * @namespace\n     * @private\n     * @name math\n     * @memberof PIXI\n     * @see PIXI\n     * @deprecated since version 3.0.6\n     */\n    math: {\n        get: function ()\n        {\n            console.warn('The math namespace is deprecated, please access members already accessible on PIXI.');\n            return core;\n        }\n    }\n});\n\n/**\n * @method\n * @private\n * @name PIXI.Sprite#setTexture\n * @see PIXI.Sprite#texture\n * @deprecated since version 3.0.0\n */\ncore.Sprite.prototype.setTexture = function(texture)\n{\n    this.texture = texture;\n    console.warn('setTexture is now deprecated, please use the texture property, e.g : sprite.texture = texture;');\n};\n\n/**\n * @method\n * @name PIXI.extras.BitmapText#setText\n * @see PIXI.extras.BitmapText#text\n * @deprecated since version 3.0.0\n */\nextras.BitmapText.prototype.setText = function(text)\n{\n    this.text = text;\n    console.warn('setText is now deprecated, please use the text property, e.g : myBitmapText.text = \\'my text\\';');\n};\n\n/**\n * @method\n * @name PIXI.Text#setText\n * @see PIXI.Text#text\n * @deprecated since version 3.0.0\n */\ncore.Text.prototype.setText = function(text)\n{\n    this.text = text;\n    console.warn('setText is now deprecated, please use the text property, e.g : myText.text = \\'my text\\';');\n};\n\n/**\n * @method\n * @name PIXI.Text#setStyle\n * @see PIXI.Text#style\n * @deprecated since version 3.0.0\n */\ncore.Text.prototype.setStyle = function(style)\n{\n    this.style = style;\n    console.warn('setStyle is now deprecated, please use the style property, e.g : myText.style = style;');\n};\n\n/**\n * @method\n * @name PIXI.Texture#setFrame\n * @see PIXI.Texture#setFrame\n * @deprecated since version 3.0.0\n */\ncore.Texture.prototype.setFrame = function(frame)\n{\n    this.frame = frame;\n    console.warn('setFrame is now deprecated, please use the frame property, e.g : myTexture.frame = frame;');\n};\n\nObject.defineProperties(filters, {\n\n    /**\n     * @class\n     * @private\n     * @name PIXI.filters.AbstractFilter\n     * @see PIXI.AbstractFilter\n     * @deprecated since version 3.0.6\n     */\n    AbstractFilter: {\n        get: function()\n        {\n            console.warn('filters.AbstractFilter is an undocumented alias, please use AbstractFilter from now on.');\n            return core.AbstractFilter;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name PIXI.filters.FXAAFilter\n     * @see PIXI.FXAAFilter\n     * @deprecated since version 3.0.6\n     */\n    FXAAFilter: {\n        get: function()\n        {\n            console.warn('filters.FXAAFilter is an undocumented alias, please use FXAAFilter from now on.');\n            return core.FXAAFilter;\n        }\n    },\n\n    /**\n     * @class\n     * @private\n     * @name PIXI.filters.SpriteMaskFilter\n     * @see PIXI.SpriteMaskFilter\n     * @deprecated since version 3.0.6\n     */\n    SpriteMaskFilter: {\n        get: function()\n        {\n            console.warn('filters.SpriteMaskFilter is an undocumented alias, please use SpriteMaskFilter from now on.');\n            return core.SpriteMaskFilter;\n        }\n    }\n});\n\n/**\n * @method\n * @name PIXI.utils.uuid\n * @see PIXI.utils.uid\n * @deprecated since version 3.0.6\n */\ncore.utils.uuid = function ()\n{\n    console.warn('utils.uuid() is deprecated, please use utils.uid() from now on.');\n    return core.utils.uid();\n};\n\n},{\"./core\":29,\"./extras\":86,\"./filters\":103,\"./mesh\":128}],80:[function(require,module,exports){\nvar core = require('../core');\n\n/**\n * A BitmapText object will create a line or multiple lines of text using bitmap font. To\n * split a line you can use '\\n', '\\r' or '\\r\\n' in your string. You can generate the fnt files using:\n *\n * A BitmapText can only be created when the font is loaded\n *\n * ```js\n * // in this case the font is in a file called 'desyrel.fnt'\n * var bitmapText = new PIXI.extras.BitmapText(\"text using a fancy font!\", {font: \"35px Desyrel\", align: \"right\"});\n * ```\n *\n *\n * http://www.angelcode.com/products/bmfont/ for windows or\n * http://www.bmglyph.com/ for mac.\n *\n * @class\n * @extends PIXI.Container\n * @memberof PIXI.extras\n * @param text {string} The copy that you would like the text to display\n * @param style {object} The style parameters\n * @param style.font {string|object} The font descriptor for the object, can be passed as a string of form\n *      \"24px FontName\" or \"FontName\" or as an object with explicit name/size properties.\n * @param [style.font.name] {string} The bitmap font id\n * @param [style.font.size] {number} The size of the font in pixels, e.g. 24\n * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect\n *      single line text\n * @param [style.tint=0xFFFFFF] {number} The tint color\n */\nfunction BitmapText(text, style)\n{\n    core.Container.call(this);\n\n    style = style || {};\n\n    /**\n     * The width of the overall text, different from fontSize,\n     * which is defined in the style object\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.textWidth = 0;\n\n    /**\n     * The height of the overall text, different from fontSize,\n     * which is defined in the style object\n     *\n     * @member {number}\n     * @readOnly\n     */\n    this.textHeight = 0;\n\n    /**\n     * Private tracker for the letter sprite pool.\n     *\n     * @member {PIXI.Sprite[]}\n     * @private\n     */\n    this._glyphs = [];\n\n    /**\n     * Private tracker for the current style.\n     *\n     * @member {object}\n     * @private\n     */\n    this._font = {\n        tint: style.tint !== undefined ? style.tint : 0xFFFFFF,\n        align: style.align || 'left',\n        name: null,\n        size: 0\n    };\n\n    /**\n     * Private tracker for the current font.\n     *\n     * @member {object}\n     * @private\n     */\n    this.font = style.font; // run font setter\n\n    /**\n     * Private tracker for the current text.\n     *\n     * @member {string}\n     * @private\n     */\n    this._text = text;\n\n    /**\n     * The max width of this bitmap text in pixels. If the text provided is longer than the value provided, line breaks will be automatically inserted in the last whitespace.\n     * Disable by setting value to 0\n     *\n     * @member {number}\n     */\n    this.maxWidth = 0;\n\n    /**\n     * The max line height. This is useful when trying to use the total height of the Text, ie: when trying to vertically align.\n     *\n     * @member {number}\n     */\n    this.maxLineHeight = 0;\n\n    /**\n     * The dirty state of this object.\n     *\n     * @member {boolean}\n     */\n    this.dirty = false;\n\n    this.updateText();\n}\n\n// constructor\nBitmapText.prototype = Object.create(core.Container.prototype);\nBitmapText.prototype.constructor = BitmapText;\nmodule.exports = BitmapText;\n\nObject.defineProperties(BitmapText.prototype, {\n    /**\n     * The tint of the BitmapText object\n     *\n     * @member {number}\n     * @memberof PIXI.extras.BitmapText#\n     */\n    tint: {\n        get: function ()\n        {\n            return this._font.tint;\n        },\n        set: function (value)\n        {\n            this._font.tint = (typeof value === 'number' && value >= 0) ? value : 0xFFFFFF;\n\n            this.dirty = true;\n        }\n    },\n\n    /**\n     * The alignment of the BitmapText object\n     *\n     * @member {string}\n     * @default 'left'\n     * @memberof PIXI.extras.BitmapText#\n     */\n    align: {\n        get: function ()\n        {\n            return this._font.align;\n        },\n        set: function (value)\n        {\n            this._font.align = value || 'left';\n\n            this.dirty = true;\n        }\n    },\n\n    /**\n     * The font descriptor of the BitmapText object\n     *\n     * @member {Font}\n     * @memberof PIXI.extras.BitmapText#\n     */\n    font: {\n        get: function ()\n        {\n            return this._font;\n        },\n        set: function (value)\n        {\n            if (!value) {\n                return;\n            }\n\n            if (typeof value === 'string') {\n                value = value.split(' ');\n\n                this._font.name = value.length === 1 ? value[0] : value.slice(1).join(' ');\n                this._font.size = value.length >= 2 ? parseInt(value[0], 10) : BitmapText.fonts[this._font.name].size;\n            }\n            else {\n                this._font.name = value.name;\n                this._font.size = typeof value.size === 'number' ? value.size : parseInt(value.size, 10);\n            }\n\n            this.dirty = true;\n        }\n    },\n\n    /**\n     * The text of the BitmapText object\n     *\n     * @member {string}\n     * @memberof PIXI.extras.BitmapText#\n     */\n    text: {\n        get: function ()\n        {\n            return this._text;\n        },\n        set: function (value)\n        {\n            value = value.toString() || ' ';\n            if (this._text === value)\n            {\n                return;\n            }\n            this._text = value;\n            this.dirty = true;\n        }\n    }\n});\n\n/**\n * Renders text and updates it when needed\n *\n * @private\n */\nBitmapText.prototype.updateText = function ()\n{\n    var data = BitmapText.fonts[this._font.name];\n    var pos = new core.Point();\n    var prevCharCode = null;\n    var chars = [];\n    var lastLineWidth = 0;\n    var maxLineWidth = 0;\n    var lineWidths = [];\n    var line = 0;\n    var scale = this._font.size / data.size;\n    var lastSpace = -1;\n    var maxLineHeight = 0;\n\n    for (var i = 0; i < this.text.length; i++)\n    {\n        var charCode = this.text.charCodeAt(i);\n        lastSpace = /(\\s)/.test(this.text.charAt(i)) ? i : lastSpace;\n\n        if (/(?:\\r\\n|\\r|\\n)/.test(this.text.charAt(i)))\n        {\n            lineWidths.push(lastLineWidth);\n            maxLineWidth = Math.max(maxLineWidth, lastLineWidth);\n            line++;\n\n            pos.x = 0;\n            pos.y += data.lineHeight;\n            prevCharCode = null;\n            continue;\n        }\n\n        if (lastSpace !== -1 && this.maxWidth > 0 && pos.x * scale > this.maxWidth)\n        {\n            core.utils.removeItems(chars, lastSpace, i - lastSpace);\n            i = lastSpace;\n            lastSpace = -1;\n\n            lineWidths.push(lastLineWidth);\n            maxLineWidth = Math.max(maxLineWidth, lastLineWidth);\n            line++;\n\n            pos.x = 0;\n            pos.y += data.lineHeight;\n            prevCharCode = null;\n            continue;\n        }\n\n        var charData = data.chars[charCode];\n\n        if (!charData)\n        {\n            continue;\n        }\n\n        if (prevCharCode && charData.kerning[prevCharCode])\n        {\n            pos.x += charData.kerning[prevCharCode];\n        }\n\n        chars.push({texture:charData.texture, line: line, charCode: charCode, position: new core.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)});\n        lastLineWidth = pos.x + (charData.texture.width + charData.xOffset);\n        pos.x += charData.xAdvance;\n        maxLineHeight = Math.max(maxLineHeight, (charData.yOffset + charData.texture.height));\n        prevCharCode = charCode;\n    }\n\n    lineWidths.push(lastLineWidth);\n    maxLineWidth = Math.max(maxLineWidth, lastLineWidth);\n\n    var lineAlignOffsets = [];\n\n    for (i = 0; i <= line; i++)\n    {\n        var alignOffset = 0;\n\n        if (this._font.align === 'right')\n        {\n            alignOffset = maxLineWidth - lineWidths[i];\n        }\n        else if (this._font.align === 'center')\n        {\n            alignOffset = (maxLineWidth - lineWidths[i]) / 2;\n        }\n\n        lineAlignOffsets.push(alignOffset);\n    }\n\n    var lenChars = chars.length;\n    var tint = this.tint;\n\n    for (i = 0; i < lenChars; i++)\n    {\n        var c = this._glyphs[i]; // get the next glyph sprite\n\n        if (c)\n        {\n            c.texture = chars[i].texture;\n        }\n        else\n        {\n            c = new core.Sprite(chars[i].texture);\n            this._glyphs.push(c);\n        }\n\n        c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale;\n        c.position.y = chars[i].position.y * scale;\n        c.scale.x = c.scale.y = scale;\n        c.tint = tint;\n\n        if (!c.parent)\n        {\n            this.addChild(c);\n        }\n    }\n\n    // remove unnecessary children.\n    for (i = lenChars; i < this._glyphs.length; ++i)\n    {\n        this.removeChild(this._glyphs[i]);\n    }\n\n    this.textWidth = maxLineWidth * scale;\n    this.textHeight = (pos.y + data.lineHeight) * scale;\n    this.maxLineHeight = maxLineHeight * scale;\n};\n\n/**\n * Updates the transform of this object\n *\n * @private\n */\nBitmapText.prototype.updateTransform = function ()\n{\n    this.validate();\n    this.containerUpdateTransform();\n};\n\n/**\n * Validates text before calling parent's getLocalBounds\n *\n * @return {PIXI.Rectangle} The rectangular bounding area\n */\n\nBitmapText.prototype.getLocalBounds = function()\n{\n    this.validate();\n    return core.Container.prototype.getLocalBounds.call(this);\n};\n\n/**\n * Updates text when needed\n *\n * @private\n */\nBitmapText.prototype.validate = function()\n{\n    if (this.dirty)\n    {\n        this.updateText();\n        this.dirty = false;\n    }\n};\n\nBitmapText.fonts = {};\n\n},{\"../core\":29}],81:[function(require,module,exports){\nvar core = require('../core');\n\n/**\n * A MovieClip is a simple way to display an animation depicted by a list of textures.\n *\n * ```js\n * var alienImages = [\"image_sequence_01.png\",\"image_sequence_02.png\",\"image_sequence_03.png\",\"image_sequence_04.png\"];\n * var textureArray = [];\n *\n * for (var i=0; i < 4; i++)\n * {\n *      var texture = PIXI.Texture.fromImage(alienImages[i]);\n *      textureArray.push(texture);\n * };\n *\n * var mc = new PIXI.MovieClip(textureArray);\n * ```\n *\n * @class\n * @extends PIXI.Sprite\n * @memberof PIXI.extras\n * @param textures {PIXI.Texture[]|Object[]} an array of {@link PIXI.Texture} or frame objects that make up the animation\n * @param textures[].texture {PIXI.Texture} the {@link PIXI.Texture} of the frame\n * @param textures[].time {number} the duration of the frame in ms\n */\nfunction MovieClip(textures)\n{\n    core.Sprite.call(this, textures[0] instanceof core.Texture ? textures[0] : textures[0].texture);\n\n    /**\n     * @private\n     */\n    this._textures = null;\n\n    /**\n     * @private\n     */\n    this._durations = null;\n\n    this.textures = textures;\n\n    /**\n     * The speed that the MovieClip will play at. Higher is faster, lower is slower\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.animationSpeed = 1;\n\n    /**\n     * Whether or not the movie clip repeats after playing.\n     *\n     * @member {boolean}\n     * @default true\n     */\n    this.loop = true;\n\n    /**\n     * Function to call when a MovieClip finishes playing\n     *\n     * @method\n     * @memberof PIXI.extras.MovieClip#\n     */\n    this.onComplete = null;\n\n    /**\n     * Elapsed time since animation has been started, used internally to display current texture\n     *\n     * @member {number}\n     * @private\n     */\n    this._currentTime = 0;\n\n    /**\n     * Indicates if the MovieClip is currently playing\n     *\n     * @member {boolean}\n     * @readonly\n     */\n    this.playing = false;\n}\n\n// constructor\nMovieClip.prototype = Object.create(core.Sprite.prototype);\nMovieClip.prototype.constructor = MovieClip;\nmodule.exports = MovieClip;\n\nObject.defineProperties(MovieClip.prototype, {\n    /**\n     * totalFrames is the total number of frames in the MovieClip. This is the same as number of textures\n     * assigned to the MovieClip.\n     *\n     * @member {number}\n     * @memberof PIXI.extras.MovieClip#\n     * @default 0\n     * @readonly\n     */\n    totalFrames: {\n        get: function()\n        {\n            return this._textures.length;\n        }\n    },\n\n    /**\n     * The array of textures used for this MovieClip\n     *\n     * @member {PIXI.Texture[]}\n     * @memberof PIXI.extras.MovieClip#\n     *\n     */\n    textures: {\n        get: function ()\n        {\n            return this._textures;\n        },\n        set: function (value)\n        {\n            if(value[0] instanceof core.Texture)\n            {\n                this._textures = value;\n                this._durations = null;\n            }\n            else\n            {\n                this._textures = [];\n                this._durations = [];\n                for(var i = 0; i < value.length; i++)\n                {\n                    this._textures.push(value[i].texture);\n                    this._durations.push(value[i].time);\n                }\n            }\n        }\n    },\n\n    /**\n    * The MovieClips current frame index\n    *\n    * @member {number}\n    * @memberof PIXI.extras.MovieClip#\n    * @readonly\n    */\n    currentFrame: {\n        get: function ()\n        {\n            var currentFrame = Math.floor(this._currentTime) % this._textures.length;\n            if (currentFrame < 0)\n            {\n                currentFrame += this._textures.length;\n            }\n            return currentFrame;\n        }\n    }\n\n});\n\n/**\n * Stops the MovieClip\n *\n */\nMovieClip.prototype.stop = function ()\n{\n    if(!this.playing)\n    {\n        return;\n    }\n\n    this.playing = false;\n    core.ticker.shared.remove(this.update, this);\n};\n\n/**\n * Plays the MovieClip\n *\n */\nMovieClip.prototype.play = function ()\n{\n    if(this.playing)\n    {\n        return;\n    }\n\n    this.playing = true;\n    core.ticker.shared.add(this.update, this);\n};\n\n/**\n * Stops the MovieClip and goes to a specific frame\n *\n * @param frameNumber {number} frame index to stop at\n */\nMovieClip.prototype.gotoAndStop = function (frameNumber)\n{\n    this.stop();\n\n    this._currentTime = frameNumber;\n\n    this._texture = this._textures[this.currentFrame];\n};\n\n/**\n * Goes to a specific frame and begins playing the MovieClip\n *\n * @param frameNumber {number} frame index to start at\n */\nMovieClip.prototype.gotoAndPlay = function (frameNumber)\n{\n    this._currentTime = frameNumber;\n\n    this.play();\n};\n\n/*\n * Updates the object transform for rendering\n * @private\n */\nMovieClip.prototype.update = function (deltaTime)\n{\n    var elapsed = this.animationSpeed * deltaTime;\n\n    if (this._durations !== null)\n    {\n        var lag = this._currentTime % 1 * this._durations[this.currentFrame];\n\n        lag += elapsed / 60 * 1000;\n\n        while (lag < 0)\n        {\n            this._currentTime--;\n            lag += this._durations[this.currentFrame];\n        }\n\n        var sign = Math.sign(this.animationSpeed * deltaTime);\n        this._currentTime = Math.floor(this._currentTime);\n\n        while (lag >= this._durations[this.currentFrame])\n        {\n            lag -= this._durations[this.currentFrame] * sign;\n            this._currentTime += sign;\n        }\n\n        this._currentTime += lag / this._durations[this.currentFrame];\n    }\n    else\n    {\n        this._currentTime += elapsed;\n    }\n\n    if (this._currentTime < 0 && !this.loop)\n    {\n        this.gotoAndStop(0);\n\n        if (this.onComplete)\n        {\n            this.onComplete();\n        }\n    }\n    else if (this._currentTime >= this._textures.length && !this.loop)\n    {\n        this.gotoAndStop(this._textures.length - 1);\n\n        if (this.onComplete)\n        {\n            this.onComplete();\n        }\n    }\n    else\n    {\n        this._texture = this._textures[this.currentFrame];\n    }\n\n};\n\n/*\n * Stops the MovieClip and destroys it\n *\n */\nMovieClip.prototype.destroy = function ( )\n{\n    this.stop();\n    core.Sprite.prototype.destroy.call(this);\n};\n\n/**\n * A short hand way of creating a movieclip from an array of frame ids\n *\n * @static\n * @param frames {string[]} the array of frames ids the movieclip will use as its texture frames\n */\nMovieClip.fromFrames = function (frames)\n{\n    var textures = [];\n\n    for (var i = 0; i < frames.length; ++i)\n    {\n        textures.push(new core.Texture.fromFrame(frames[i]));\n    }\n\n    return new MovieClip(textures);\n};\n\n/**\n * A short hand way of creating a movieclip from an array of image ids\n *\n * @static\n * @param images {string[]} the array of image urls the movieclip will use as its texture frames\n */\nMovieClip.fromImages = function (images)\n{\n    var textures = [];\n\n    for (var i = 0; i < images.length; ++i)\n    {\n        textures.push(new core.Texture.fromImage(images[i]));\n    }\n\n    return new MovieClip(textures);\n};\n},{\"../core\":29}],82:[function(require,module,exports){\nvar core = require('../core'),\n    // a sprite use dfor rendering textures..\n    tempPoint = new core.Point(),\n    CanvasTinter = require('../core/renderers/canvas/utils/CanvasTinter');\n\n/**\n * A tiling sprite is a fast way of rendering a tiling image\n *\n * @class\n * @extends PIXI.Sprite\n * @memberof PIXI.extras\n * @param texture {Texture} the texture of the tiling sprite\n * @param width {number}  the width of the tiling sprite\n * @param height {number} the height of the tiling sprite\n */\nfunction TilingSprite(texture, width, height)\n{\n    core.Sprite.call(this, texture);\n\n    /**\n     * The scaling of the image that is being tiled\n     *\n     * @member {PIXI.Point}\n     */\n    this.tileScale = new core.Point(1,1);\n\n\n    /**\n     * The offset position of the image that is being tiled\n     *\n     * @member {PIXI.Point}\n     */\n    this.tilePosition = new core.Point(0,0);\n\n    ///// private\n\n    /**\n     * The with of the tiling sprite\n     *\n     * @member {number}\n     * @private\n     */\n    this._width = width || 100;\n\n    /**\n     * The height of the tiling sprite\n     *\n     * @member {number}\n     * @private\n     */\n    this._height = height || 100;\n\n    /**\n     * An internal WebGL UV cache.\n     *\n     * @member {PIXI.TextureUvs}\n     * @private\n     */\n    this._uvs = new core.TextureUvs();\n\n    this._canvasPattern = null;\n\n    //TODO move..\n    this.shader = new core.AbstractFilter(\n\n      [\n        'precision lowp float;',\n        'attribute vec2 aVertexPosition;',\n        'attribute vec2 aTextureCoord;',\n        'attribute vec4 aColor;',\n\n        'uniform mat3 projectionMatrix;',\n\n        'uniform vec4 uFrame;',\n        'uniform vec4 uTransform;',\n\n        'varying vec2 vTextureCoord;',\n        'varying vec4 vColor;',\n\n        'void main(void){',\n        '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',\n\n        '   vec2 coord = aTextureCoord;',\n        '   coord -= uTransform.xy;',\n        '   coord /= uTransform.zw;',\n        '   vTextureCoord = coord;',\n\n        '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',\n        '}'\n      ].join('\\n'),\n      [\n        'precision lowp float;',\n\n        'varying vec2 vTextureCoord;',\n        'varying vec4 vColor;',\n\n        'uniform sampler2D uSampler;',\n        'uniform vec4 uFrame;',\n        'uniform vec2 uPixelSize;',\n\n        'void main(void){',\n\n        '   vec2 coord = mod(vTextureCoord, uFrame.zw);',\n        '   coord = clamp(coord, uPixelSize, uFrame.zw - uPixelSize);',\n        '   coord += uFrame.xy;',\n\n        '   gl_FragColor =  texture2D(uSampler, coord) * vColor ;',\n        '}'\n      ].join('\\n'),\n\n            // set the uniforms\n            {\n                uFrame: { type: '4fv', value: [0,0,1,1] },\n                uTransform: { type: '4fv', value: [0,0,1,1] },\n                uPixelSize : { type : '2fv', value: [1, 1]}\n            }\n      );\n}\n\nTilingSprite.prototype = Object.create(core.Sprite.prototype);\nTilingSprite.prototype.constructor = TilingSprite;\nmodule.exports = TilingSprite;\n\n\nObject.defineProperties(TilingSprite.prototype, {\n    /**\n     * The width of the sprite, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.extras.TilingSprite#\n     */\n    width: {\n        get: function ()\n        {\n            return this._width;\n        },\n        set: function (value)\n        {\n            this._width = value;\n        }\n    },\n\n    /**\n     * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set\n     *\n     * @member {number}\n     * @memberof PIXI.extras.TilingSprite#\n     */\n    height: {\n        get: function ()\n        {\n            return this._height;\n        },\n        set: function (value)\n        {\n            this._height = value;\n        }\n    }\n});\n\nTilingSprite.prototype._onTextureUpdate = function ()\n{\n    return;\n};\n\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer}\n * @private\n */\nTilingSprite.prototype._renderWebGL = function (renderer)\n{\n    // tweak our texture temporarily..\n    var texture = this._texture;\n\n    if(!texture || !texture._uvs)\n    {\n        return;\n    }\n\n    var tempUvs = texture._uvs,\n        tempWidth = texture._frame.width,\n        tempHeight = texture._frame.height,\n        tw = texture.baseTexture.width,\n        th = texture.baseTexture.height;\n\n    texture._uvs = this._uvs;\n    texture._frame.width = this.width;\n    texture._frame.height = this.height;\n\n    this.shader.uniforms.uPixelSize.value[0] = 1.0/tw;\n    this.shader.uniforms.uPixelSize.value[1] = 1.0/th;\n\n    this.shader.uniforms.uFrame.value[0] = tempUvs.x0;\n    this.shader.uniforms.uFrame.value[1] = tempUvs.y0;\n    this.shader.uniforms.uFrame.value[2] = tempUvs.x1 - tempUvs.x0;\n    this.shader.uniforms.uFrame.value[3] = tempUvs.y2 - tempUvs.y0;\n\n    this.shader.uniforms.uTransform.value[0] = (this.tilePosition.x % (tempWidth * this.tileScale.x)) / this._width;\n    this.shader.uniforms.uTransform.value[1] = (this.tilePosition.y % (tempHeight * this.tileScale.y)) / this._height;\n    this.shader.uniforms.uTransform.value[2] = ( tw / this._width ) * this.tileScale.x;\n    this.shader.uniforms.uTransform.value[3] = ( th / this._height ) * this.tileScale.y;\n\n    renderer.setObjectRenderer(renderer.plugins.sprite);\n    renderer.plugins.sprite.render(this);\n\n    texture._uvs = tempUvs;\n    texture._frame.width = tempWidth;\n    texture._frame.height = tempHeight;\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer} a reference to the canvas renderer\n * @private\n */\nTilingSprite.prototype._renderCanvas = function (renderer)\n{\n    var texture = this._texture;\n\n    if (!texture.baseTexture.hasLoaded)\n    {\n      return;\n    }\n\n    var context = renderer.context,\n        transform = this.worldTransform,\n        resolution = renderer.resolution,\n        baseTexture = texture.baseTexture,\n        modX = (this.tilePosition.x / this.tileScale.x) % texture._frame.width,\n        modY = (this.tilePosition.y / this.tileScale.y) % texture._frame.height;\n\n    // create a nice shiny pattern!\n    // TODO this needs to be refreshed if texture changes..\n    if(!this._canvasPattern)\n    {\n        // cut an object from a spritesheet..\n        var tempCanvas = new core.CanvasBuffer(texture._frame.width * resolution, texture._frame.height * resolution);\n\n        // Tint the tiling sprite\n        if (this.tint !== 0xFFFFFF)\n        {\n            if (this.cachedTint !== this.tint)\n            {\n                this.cachedTint = this.tint;\n\n                this.tintedTexture = CanvasTinter.getTintedTexture(this, this.tint);\n            }\n            tempCanvas.context.drawImage(this.tintedTexture, 0, 0);\n        }\n        else\n        {\n            tempCanvas.context.drawImage(baseTexture.source, -texture._frame.x * resolution, -texture._frame.y * resolution);\n        }\n        this._canvasPattern = tempCanvas.context.createPattern( tempCanvas.canvas, 'repeat' );\n    }\n\n    // set context state..\n    context.globalAlpha = this.worldAlpha;\n    context.setTransform(transform.a * resolution,\n                       transform.b * resolution,\n                       transform.c * resolution,\n                       transform.d * resolution,\n                       transform.tx * resolution,\n                       transform.ty * resolution);\n\n    // TODO - this should be rolled into the setTransform above..\n    context.scale(this.tileScale.x / resolution, this.tileScale.y / resolution);\n\n    context.translate(modX + (this.anchor.x * -this._width ),\n                      modY + (this.anchor.y * -this._height));\n\n    // check blend mode\n    var compositeOperation = renderer.blendModes[this.blendMode];\n    if (compositeOperation !== renderer.context.globalCompositeOperation)\n    {\n        context.globalCompositeOperation = compositeOperation;\n    }\n\n    // fill the pattern!\n    context.fillStyle = this._canvasPattern;\n    context.fillRect(-modX,\n                     -modY,\n                     this._width * resolution / this.tileScale.x,\n                     this._height * resolution / this.tileScale.y);\n\n\n    //TODO - pretty sure this can be deleted...\n    //context.translate(-this.tilePosition.x + (this.anchor.x * this._width), -this.tilePosition.y + (this.anchor.y * this._height));\n    //context.scale(1 / this.tileScale.x, 1 / this.tileScale.y);\n};\n\n\n/**\n * Returns the framing rectangle of the sprite as a Rectangle object\n*\n * @return {PIXI.Rectangle} the framing rectangle\n */\nTilingSprite.prototype.getBounds = function ()\n{\n    var width = this._width;\n    var height = this._height;\n\n    var w0 = width * (1-this.anchor.x);\n    var w1 = width * -this.anchor.x;\n\n    var h0 = height * (1-this.anchor.y);\n    var h1 = height * -this.anchor.y;\n\n    var worldTransform = this.worldTransform;\n\n    var a = worldTransform.a;\n    var b = worldTransform.b;\n    var c = worldTransform.c;\n    var d = worldTransform.d;\n    var tx = worldTransform.tx;\n    var ty = worldTransform.ty;\n\n    var x1 = a * w1 + c * h1 + tx;\n    var y1 = d * h1 + b * w1 + ty;\n\n    var x2 = a * w0 + c * h1 + tx;\n    var y2 = d * h1 + b * w0 + ty;\n\n    var x3 = a * w0 + c * h0 + tx;\n    var y3 = d * h0 + b * w0 + ty;\n\n    var x4 =  a * w1 + c * h0 + tx;\n    var y4 =  d * h0 + b * w1 + ty;\n\n    var minX,\n        maxX,\n        minY,\n        maxY;\n\n    minX = x1;\n    minX = x2 < minX ? x2 : minX;\n    minX = x3 < minX ? x3 : minX;\n    minX = x4 < minX ? x4 : minX;\n\n    minY = y1;\n    minY = y2 < minY ? y2 : minY;\n    minY = y3 < minY ? y3 : minY;\n    minY = y4 < minY ? y4 : minY;\n\n    maxX = x1;\n    maxX = x2 > maxX ? x2 : maxX;\n    maxX = x3 > maxX ? x3 : maxX;\n    maxX = x4 > maxX ? x4 : maxX;\n\n    maxY = y1;\n    maxY = y2 > maxY ? y2 : maxY;\n    maxY = y3 > maxY ? y3 : maxY;\n    maxY = y4 > maxY ? y4 : maxY;\n\n    var bounds = this._bounds;\n\n    bounds.x = minX;\n    bounds.width = maxX - minX;\n\n    bounds.y = minY;\n    bounds.height = maxY - minY;\n\n    // store a reference so that if this function gets called again in the render cycle we do not have to recalculate\n    this._currentBounds = bounds;\n\n    return bounds;\n};\n\n/**\n * Checks if a point is inside this tiling sprite\n * @param point {PIXI.Point} the point to check\n */\nTilingSprite.prototype.containsPoint = function( point )\n{\n    this.worldTransform.applyInverse(point,  tempPoint);\n\n    var width = this._width;\n    var height = this._height;\n    var x1 = -width * this.anchor.x;\n    var y1;\n\n    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )\n    {\n        y1 = -height * this.anchor.y;\n\n        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )\n        {\n            return true;\n        }\n    }\n\n    return false;\n};\n\n/**\n * Destroys this tiling sprite\n *\n */\nTilingSprite.prototype.destroy = function () {\n    core.Sprite.prototype.destroy.call(this);\n\n    this.tileScale = null;\n    this._tileScaleOffset = null;\n    this.tilePosition = null;\n\n    this._uvs = null;\n};\n\n/**\n * Helper function that creates a tiling sprite that will use a texture from the TextureCache based on the frameId\n * The frame ids are created when a Texture packer file has been loaded\n *\n * @static\n * @param frameId {string} The frame Id of the texture in the cache\n * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the frameId\n * @param width {number}  the width of the tiling sprite\n * @param height {number} the height of the tiling sprite\n */\nTilingSprite.fromFrame = function (frameId,width,height)\n{\n    var texture = core.utils.TextureCache[frameId];\n\n    if (!texture)\n    {\n        throw new Error('The frameId \"' + frameId + '\" does not exist in the texture cache ' + this);\n    }\n\n    return new TilingSprite(texture,width,height);\n};\n\n/**\n * Helper function that creates a sprite that will contain a texture based on an image url\n * If the image is not in the texture cache it will be loaded\n *\n * @static\n * @param imageId {string} The image url of the texture\n * @param width {number}  the width of the tiling sprite\n * @param height {number} the height of the tiling sprite\n * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter\n * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values\n * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the image id\n */\nTilingSprite.fromImage = function (imageId, width, height, crossorigin, scaleMode)\n{\n    return new TilingSprite(core.Texture.fromImage(imageId, crossorigin, scaleMode),width,height);\n};\n\n},{\"../core\":29,\"../core/renderers/canvas/utils/CanvasTinter\":48}],83:[function(require,module,exports){\nvar core = require('../core'),\n    DisplayObject = core.DisplayObject,\n    _tempMatrix = new core.Matrix();\n\nDisplayObject.prototype._cacheAsBitmap = false;\nDisplayObject.prototype._originalRenderWebGL = null;\nDisplayObject.prototype._originalRenderCanvas = null;\n\nDisplayObject.prototype._originalUpdateTransform = null;\nDisplayObject.prototype._originalHitTest = null;\nDisplayObject.prototype._originalDestroy = null;\nDisplayObject.prototype._cachedSprite = null;\n\nObject.defineProperties(DisplayObject.prototype, {\n\n    /**\n     * Set this to true if you want this display object to be cached as a bitmap.\n     * This basically takes a snap shot of the display object as it is at that moment. It can provide a performance benefit for complex static displayObjects.\n     * To remove simply set this property to 'false'\n     *\n     * @member {boolean}\n     * @memberof PIXI.DisplayObject#\n     */\n    cacheAsBitmap: {\n        get: function ()\n        {\n            return this._cacheAsBitmap;\n        },\n        set: function (value)\n        {\n            if (this._cacheAsBitmap === value)\n            {\n                return;\n            }\n\n            this._cacheAsBitmap = value;\n\n            if (value)\n            {\n                this._originalRenderWebGL = this.renderWebGL;\n                this._originalRenderCanvas = this.renderCanvas;\n\n                this._originalUpdateTransform = this.updateTransform;\n                this._originalGetBounds = this.getBounds;\n\n                this._originalDestroy = this.destroy;\n\n                this._originalContainsPoint = this.containsPoint;\n\n                this.renderWebGL = this._renderCachedWebGL;\n                this.renderCanvas = this._renderCachedCanvas;\n\n                this.destroy = this._cacheAsBitmapDestroy;\n\n            }\n            else\n            {\n                if (this._cachedSprite)\n                {\n                    this._destroyCachedDisplayObject();\n                }\n\n                this.renderWebGL = this._originalRenderWebGL;\n                this.renderCanvas = this._originalRenderCanvas;\n                this.getBounds = this._originalGetBounds;\n\n                this.destroy = this._originalDestroy;\n\n                this.updateTransform = this._originalUpdateTransform;\n                this.containsPoint = this._originalContainsPoint;\n            }\n        }\n    }\n});\n/**\n* Renders a cached version of the sprite with WebGL\n*\n* @param renderer {PIXI.WebGLRenderer} the WebGL renderer\n* @private\n*/\nDisplayObject.prototype._renderCachedWebGL = function (renderer)\n{\n    if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n    {\n        return;\n    }\n\n    this._initCachedDisplayObject( renderer );\n\n    this._cachedSprite.worldAlpha = this.worldAlpha;\n\n    renderer.setObjectRenderer(renderer.plugins.sprite);\n    renderer.plugins.sprite.render( this._cachedSprite );\n};\n\n/**\n* Prepares the WebGL renderer to cache the sprite\n*\n* @param renderer {PIXI.WebGLRenderer} the WebGL renderer\n* @private\n*/\nDisplayObject.prototype._initCachedDisplayObject = function (renderer)\n{\n    if(this._cachedSprite)\n    {\n        return;\n    }\n\n    // first we flush anything left in the renderer (otherwise it would get rendered to the cached texture)\n    renderer.currentRenderer.flush();\n    //this.filters= [];\n    // next we find the dimensions of the untransformed object\n    // this function also calls updatetransform on all its children as part of the measuring. This means we don't need to update the transform again in this function\n    // TODO pass an object to clone too? saves having to create a new one each time!\n    var bounds = this.getLocalBounds().clone();\n\n    // add some padding!\n    if(this._filters)\n    {\n        var padding = this._filters[0].padding;\n        bounds.x -= padding;\n        bounds.y -= padding;\n\n        bounds.width += padding * 2;\n        bounds.height += padding * 2;\n    }\n\n    // for now we cache the current renderTarget that the webGL renderer is currently using.\n    // this could be more elegent..\n    var cachedRenderTarget = renderer.currentRenderTarget;\n    // We also store the filter stack - I will definitely look to change how this works a little later down the line.\n    var stack = renderer.filterManager.filterStack;\n\n    // this renderTexture will be used to store the cached DisplayObject\n    var renderTexture = new core.RenderTexture(renderer, bounds.width | 0, bounds.height | 0);\n\n    // need to set //\n    var m = _tempMatrix;\n\n    m.tx = -bounds.x;\n    m.ty = -bounds.y;\n\n\n\n    // set all properties to there original so we can render to a texture\n    this.renderWebGL = this._originalRenderWebGL;\n\n    renderTexture.render(this, m, true, true);\n\n    // now restore the state be setting the new properties\n    renderer.setRenderTarget(cachedRenderTarget);\n    renderer.filterManager.filterStack = stack;\n\n    this.renderWebGL     = this._renderCachedWebGL;\n    this.updateTransform = this.displayObjectUpdateTransform;\n    this.getBounds       = this._getCachedBounds;\n\n\n    // create our cached sprite\n    this._cachedSprite = new core.Sprite(renderTexture);\n    this._cachedSprite.worldTransform = this.worldTransform;\n    this._cachedSprite.anchor.x = -( bounds.x / bounds.width );\n    this._cachedSprite.anchor.y = -( bounds.y / bounds.height );\n\n    // restore the transform of the cached sprite to avoid the nasty flicker..\n    this.updateTransform();\n\n    // map the hit test..\n    this.containsPoint = this._cachedSprite.containsPoint.bind(this._cachedSprite);\n};\n\n/**\n* Renders a cached version of the sprite with canvas\n*\n* @param renderer {PIXI.CanvasRenderer} the Canvas renderer\n* @private\n*/\nDisplayObject.prototype._renderCachedCanvas = function (renderer)\n{\n    if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n    {\n        return;\n    }\n\n    this._initCachedDisplayObjectCanvas( renderer );\n\n    this._cachedSprite.worldAlpha = this.worldAlpha;\n\n    this._cachedSprite.renderCanvas(renderer);\n};\n\n//TODO this can be the same as the webGL verison.. will need to do a little tweaking first though..\n/**\n* Prepares the Canvas renderer to cache the sprite\n*\n* @param renderer {PIXI.CanvasRenderer} the Canvas renderer\n* @private\n*/\nDisplayObject.prototype._initCachedDisplayObjectCanvas = function (renderer)\n{\n    if(this._cachedSprite)\n    {\n        return;\n    }\n\n    //get bounds actually transforms the object for us already!\n    var bounds = this.getLocalBounds();\n\n    var cachedRenderTarget = renderer.context;\n\n    var renderTexture = new core.RenderTexture(renderer, bounds.width | 0, bounds.height | 0);\n\n    // need to set //\n    var m = _tempMatrix;\n\n    m.tx = -bounds.x;\n    m.ty = -bounds.y;\n\n    // set all properties to there original so we can render to a texture\n    this.renderCanvas = this._originalRenderCanvas;\n\n    renderTexture.render(this, m, true);\n\n    // now restore the state be setting the new properties\n    renderer.context = cachedRenderTarget;\n\n    this.renderCanvas = this._renderCachedCanvas;\n    this.updateTransform = this.displayObjectUpdateTransform;\n    this.getBounds  = this._getCachedBounds;\n\n\n    // create our cached sprite\n    this._cachedSprite = new core.Sprite(renderTexture);\n    this._cachedSprite.worldTransform = this.worldTransform;\n    this._cachedSprite.anchor.x = -( bounds.x / bounds.width );\n    this._cachedSprite.anchor.y = -( bounds.y / bounds.height );\n\n    this.updateTransform();\n\n    this.containsPoint = this._cachedSprite.containsPoint.bind(this._cachedSprite);\n};\n\n/**\n* Calculates the bounds of the cached sprite\n*\n* @private\n*/\nDisplayObject.prototype._getCachedBounds = function ()\n{\n    this._cachedSprite._currentBounds = null;\n\n    return this._cachedSprite.getBounds();\n};\n\n/**\n* Destroys the cached sprite.\n*\n* @private\n*/\nDisplayObject.prototype._destroyCachedDisplayObject = function ()\n{\n    this._cachedSprite._texture.destroy();\n    this._cachedSprite = null;\n};\n\nDisplayObject.prototype._cacheAsBitmapDestroy = function ()\n{\n    this.cacheAsBitmap = false;\n    this._originalDestroy();\n};\n\n},{\"../core\":29}],84:[function(require,module,exports){\nvar core = require('../core');\n\n/**\n * The instance name of the object.\n *\n * @memberof PIXI.DisplayObject#\n * @member {string}\n */\ncore.DisplayObject.prototype.name = null;\n\n/**\n* Returns the display object in the container\n*\n* @memberof PIXI.Container#\n* @param name {string} instance name\n* @return {PIXI.DisplayObject}\n*/\ncore.Container.prototype.getChildByName = function (name)\n{\n    for (var i = 0; i < this.children.length; i++)\n    {\n        if (this.children[i].name === name)\n        {\n            return this.children[i];\n        }\n    }\n    return null;\n};\n\n},{\"../core\":29}],85:[function(require,module,exports){\nvar core = require('../core');\n\n/**\n* Returns the global position of the displayObject\n*\n* @memberof PIXI.DisplayObject#\n* @param point {Point} the point to write the global value to. If null a new point will be returned\n* @return {Point}\n*/\ncore.DisplayObject.prototype.getGlobalPosition = function (point)\n{\n    point = point || new core.Point();\n\n    if(this.parent)\n    {\n        this.displayObjectUpdateTransform();\n\n        point.x = this.worldTransform.tx;\n        point.y = this.worldTransform.ty;\n    }\n    else\n    {\n        point.x = this.position.x;\n        point.y = this.position.y;\n    }\n\n    return point;\n};\n\n},{\"../core\":29}],86:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI extras library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\nrequire('./cacheAsBitmap');\nrequire('./getChildByName');\nrequire('./getGlobalPosition');\n\n/**\n * @namespace PIXI.extras\n */\nmodule.exports = {\n    MovieClip:      require('./MovieClip'),\n    TilingSprite:   require('./TilingSprite'),\n    BitmapText:     require('./BitmapText')\n};\n\n},{\"./BitmapText\":80,\"./MovieClip\":81,\"./TilingSprite\":82,\"./cacheAsBitmap\":83,\"./getChildByName\":84,\"./getGlobalPosition\":85}],87:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n// TODO (cengler) - The Y is flipped in this shader for some reason.\n\n/**\n * @author Vico @vicocotea\n * original shader : https://www.shadertoy.com/view/lssGDj by @movAX13h\n */\n\n/**\n * An ASCII filter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction AsciiFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nuniform vec4 dimensions;\\nuniform float pixelSize;\\nuniform sampler2D uSampler;\\n\\nfloat character(float n, vec2 p)\\n{\\n    p = floor(p*vec2(4.0, -4.0) + 2.5);\\n    if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)\\n    {\\n        if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0;\\n    }\\n    return 0.0;\\n}\\n\\nvoid main()\\n{\\n    vec2 uv = gl_FragCoord.xy;\\n\\n    vec3 col = texture2D(uSampler, floor( uv / pixelSize ) * pixelSize / dimensions.xy).rgb;\\n\\n    float gray = (col.r + col.g + col.b) / 3.0;\\n\\n    float n =  65536.0;             // .\\n    if (gray > 0.2) n = 65600.0;    // :\\n    if (gray > 0.3) n = 332772.0;   // *\\n    if (gray > 0.4) n = 15255086.0; // o\\n    if (gray > 0.5) n = 23385164.0; // &\\n    if (gray > 0.6) n = 15252014.0; // 8\\n    if (gray > 0.7) n = 13199452.0; // @\\n    if (gray > 0.8) n = 11512810.0; // #\\n\\n    vec2 p = mod( uv / ( pixelSize * 0.5 ), 2.0) - vec2(1.0);\\n    col = col * character(n, p);\\n\\n    gl_FragColor = vec4(col, 1.0);\\n}\\n\",\n        // custom uniforms\n        {\n            dimensions: { type: '4fv', value: new Float32Array([0, 0, 0, 0]) },\n            pixelSize:  { type: '1f', value: 8 }\n        }\n    );\n}\n\nAsciiFilter.prototype = Object.create(core.AbstractFilter.prototype);\nAsciiFilter.prototype.constructor = AsciiFilter;\nmodule.exports = AsciiFilter;\n\nObject.defineProperties(AsciiFilter.prototype, {\n    /**\n     * The pixel size used by the filter.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.AsciiFilter#\n     */\n    size: {\n        get: function ()\n        {\n            return this.uniforms.pixelSize.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.pixelSize.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],88:[function(require,module,exports){\nvar core = require('../../core'),\n    BlurXFilter = require('../blur/BlurXFilter'),\n    BlurYFilter = require('../blur/BlurYFilter');\n\n/**\n * The BloomFilter applies a Gaussian blur to an object.\n * The strength of the blur can be set for x- and y-axis separately.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BloomFilter()\n{\n    core.AbstractFilter.call(this);\n\n    this.blurXFilter = new BlurXFilter();\n    this.blurYFilter = new BlurYFilter();\n\n    this.defaultFilter = new core.AbstractFilter();\n}\n\nBloomFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBloomFilter.prototype.constructor = BloomFilter;\nmodule.exports = BloomFilter;\n\nBloomFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var renderTarget = renderer.filterManager.getRenderTarget(true);\n\n    //TODO - copyTexSubImage2D could be used here?\n    this.defaultFilter.applyFilter(renderer, input, output);\n\n    this.blurXFilter.applyFilter(renderer, input, renderTarget);\n\n    renderer.blendModeManager.setBlendMode(core.BLEND_MODES.SCREEN);\n\n    this.blurYFilter.applyFilter(renderer, renderTarget, output);\n\n    renderer.blendModeManager.setBlendMode(core.BLEND_MODES.NORMAL);\n\n    renderer.filterManager.returnRenderTarget(renderTarget);\n};\n\nObject.defineProperties(BloomFilter.prototype, {\n    /**\n     * Sets the strength of both the blurX and blurY properties simultaneously\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BloomFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.blur = this.blurYFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurX property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BloomFilter#\n     * @default 2\n     */\n    blurX: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurY property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BloomFilter#\n     * @default 2\n     */\n    blurY: {\n        get: function ()\n        {\n            return this.blurYFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurYFilter.blur = value;\n        }\n    }\n});\n\n},{\"../../core\":29,\"../blur/BlurXFilter\":91,\"../blur/BlurYFilter\":92}],89:[function(require,module,exports){\nvar core = require('../../core');\n\n\n/**\n * The BlurDirFilter applies a Gaussian blur toward a direction to an object.\n *\n * @class\n * @param {number} dirX\n * @param {number} dirY\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BlurDirFilter(dirX, dirY)\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform float strength;\\nuniform float dirX;\\nuniform float dirY;\\nuniform mat3 projectionMatrix;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\nvarying vec2 vBlurTexCoords[3];\\n\\nvoid main(void)\\n{\\n    gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);\\n    vTextureCoord = aTextureCoord;\\n\\n    vBlurTexCoords[0] = aTextureCoord + vec2( (0.004 * strength) * dirX, (0.004 * strength) * dirY );\\n    vBlurTexCoords[1] = aTextureCoord + vec2( (0.008 * strength) * dirX, (0.008 * strength) * dirY );\\n    vBlurTexCoords[2] = aTextureCoord + vec2( (0.012 * strength) * dirX, (0.012 * strength) * dirY );\\n\\n    vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        // fragment shader\n        \"precision lowp float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec2 vBlurTexCoords[3];\\nvarying vec4 vColor;\\n\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    gl_FragColor = vec4(0.0);\\n\\n    gl_FragColor += texture2D(uSampler, vTextureCoord     ) * 0.3989422804014327;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 0]) * 0.2419707245191454;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 1]) * 0.05399096651318985;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 2]) * 0.004431848411938341;\\n}\\n\",\n        // set the uniforms\n        {\n            strength: { type: '1f', value: 1 },\n            dirX: { type: '1f', value: dirX || 0 },\n            dirY: { type: '1f', value: dirY || 0 }\n        }\n    );\n\n    this.defaultFilter = new core.AbstractFilter();\n\n    /**\n     * Sets the number of passes for blur. More passes means higher quaility bluring.\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.passes = 1;\n\n    /**\n     * Sets the X direction of the blur\n     *\n     * @member {number}\n     * @default 0\n     */\n    this.dirX = dirX || 0;\n\n    /**\n     * Sets the Y direction of the blur\n     *\n     * @member {number}\n     * @default 0\n     */\n    this.dirY = dirY || 0;\n\n    this.strength = 4;\n}\n\nBlurDirFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBlurDirFilter.prototype.constructor = BlurDirFilter;\nmodule.exports = BlurDirFilter;\n\nBlurDirFilter.prototype.applyFilter = function (renderer, input, output, clear) {\n\n    var shader = this.getShader(renderer);\n\n    this.uniforms.strength.value = this.strength / 4 / this.passes * (input.frame.width / input.size.width);\n\n    if (this.passes === 1) {\n        renderer.filterManager.applyFilter(shader, input, output, clear);\n    } else {\n        var renderTarget = renderer.filterManager.getRenderTarget(true);\n\n        renderer.filterManager.applyFilter(shader, input, renderTarget, clear);\n\n        for(var i = 0; i < this.passes-2; i++)\n        {\n            //this.uniforms.strength.value = this.strength / 4 / (this.passes+(i*2)) * (input.frame.width / input.size.width);\n            renderer.filterManager.applyFilter(shader, renderTarget, renderTarget, clear);\n        }\n\n        renderer.filterManager.applyFilter(shader, renderTarget, output, clear);\n\n        renderer.filterManager.returnRenderTarget(renderTarget);\n    }\n};\n\n\nObject.defineProperties(BlurDirFilter.prototype, {\n    /**\n     * Sets the strength of both the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurDirFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return this.strength;\n        },\n        set: function (value)\n        {\n            this.padding = value * 0.5;\n            this.strength = value;\n        }\n    },\n    /**\n     * Sets the X direction of the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurYFilter#\n     * @default 0\n     */\n    dirX: {\n        get: function ()\n        {\n            return this.dirX;\n        },\n        set: function (value)\n        {\n            this.uniforms.dirX.value = value;\n        }\n    },\n    /**\n     * Sets the Y direction of the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurDirFilter#\n     * @default 0\n     */\n    dirY: {\n        get: function ()\n        {\n            return this.dirY;\n        },\n        set: function (value)\n        {\n            this.uniforms.dirY.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],90:[function(require,module,exports){\nvar core = require('../../core'),\n    BlurXFilter = require('./BlurXFilter'),\n    BlurYFilter = require('./BlurYFilter');\n\n/**\n * The BlurFilter applies a Gaussian blur to an object.\n * The strength of the blur can be set for x- and y-axis separately.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BlurFilter()\n{\n    core.AbstractFilter.call(this);\n\n    this.blurXFilter = new BlurXFilter();\n    this.blurYFilter = new BlurYFilter();\n}\n\nBlurFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBlurFilter.prototype.constructor = BlurFilter;\nmodule.exports = BlurFilter;\n\nBlurFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var renderTarget = renderer.filterManager.getRenderTarget(true);\n\n    this.blurXFilter.applyFilter(renderer, input, renderTarget);\n    this.blurYFilter.applyFilter(renderer, renderTarget, output);\n\n    renderer.filterManager.returnRenderTarget(renderTarget);\n};\n\nObject.defineProperties(BlurFilter.prototype, {\n    /**\n     * Sets the strength of both the blurX and blurY properties simultaneously\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BlurFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.padding = Math.abs(value) * 0.5;\n            this.blurXFilter.blur = this.blurYFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the number of passes for blur. More passes means higher quaility bluring.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurYFilter#\n     * @default 1\n     */\n    passes: {\n        get: function ()\n        {\n            return  this.blurXFilter.passes;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.passes = this.blurYFilter.passes = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurX property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BlurFilter#\n     * @default 2\n     */\n    blurX: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurY property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.BlurFilter#\n     * @default 2\n     */\n    blurY: {\n        get: function ()\n        {\n            return this.blurYFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurYFilter.blur = value;\n        }\n    }\n});\n\n},{\"../../core\":29,\"./BlurXFilter\":91,\"./BlurYFilter\":92}],91:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The BlurXFilter applies a horizontal Gaussian blur to an object.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BlurXFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform float strength;\\nuniform mat3 projectionMatrix;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\nvarying vec2 vBlurTexCoords[6];\\n\\nvoid main(void)\\n{\\n    gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);\\n    vTextureCoord = aTextureCoord;\\n\\n    vBlurTexCoords[ 0] = aTextureCoord + vec2(-0.012 * strength, 0.0);\\n    vBlurTexCoords[ 1] = aTextureCoord + vec2(-0.008 * strength, 0.0);\\n    vBlurTexCoords[ 2] = aTextureCoord + vec2(-0.004 * strength, 0.0);\\n    vBlurTexCoords[ 3] = aTextureCoord + vec2( 0.004 * strength, 0.0);\\n    vBlurTexCoords[ 4] = aTextureCoord + vec2( 0.008 * strength, 0.0);\\n    vBlurTexCoords[ 5] = aTextureCoord + vec2( 0.012 * strength, 0.0);\\n\\n    vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        // fragment shader\n        \"precision lowp float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec2 vBlurTexCoords[6];\\nvarying vec4 vColor;\\n\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    gl_FragColor = vec4(0.0);\\n\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 0])*0.004431848411938341;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 1])*0.05399096651318985;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 2])*0.2419707245191454;\\n    gl_FragColor += texture2D(uSampler, vTextureCoord     )*0.3989422804014327;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 3])*0.2419707245191454;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 4])*0.05399096651318985;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 5])*0.004431848411938341;\\n}\\n\",\n        // set the uniforms\n        {\n            strength: { type: '1f', value: 1 }\n        }\n    );\n\n    /**\n     * Sets the number of passes for blur. More passes means higher quaility bluring.\n     *\n     * @member {number}\n     * @default 1\n     */\n    this.passes = 1;\n\n    this.strength = 4;\n}\n\nBlurXFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBlurXFilter.prototype.constructor = BlurXFilter;\nmodule.exports = BlurXFilter;\n\nBlurXFilter.prototype.applyFilter = function (renderer, input, output, clear)\n{\n    var shader = this.getShader(renderer);\n\n    this.uniforms.strength.value = this.strength / 4 / this.passes * (input.frame.width / input.size.width);\n\n    if(this.passes === 1)\n    {\n        renderer.filterManager.applyFilter(shader, input, output, clear);\n    }\n    else\n    {\n        var renderTarget = renderer.filterManager.getRenderTarget(true);\n        var flip = input;\n        var flop = renderTarget;\n\n        for(var i = 0; i < this.passes-1; i++)\n        {\n            renderer.filterManager.applyFilter(shader, flip, flop, true);\n\n           var temp = flop;\n           flop = flip;\n           flip = temp;\n        }\n\n        renderer.filterManager.applyFilter(shader, flip, output, clear);\n\n        renderer.filterManager.returnRenderTarget(renderTarget);\n    }\n};\n\n\nObject.defineProperties(BlurXFilter.prototype, {\n    /**\n     * Sets the strength of both the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurXFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return  this.strength;\n        },\n        set: function (value)\n        {\n            this.padding =  Math.abs(value) * 0.5;\n            this.strength = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],92:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The BlurYFilter applies a horizontal Gaussian blur to an object.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BlurYFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform float strength;\\nuniform mat3 projectionMatrix;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\nvarying vec2 vBlurTexCoords[6];\\n\\nvoid main(void)\\n{\\n    gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);\\n    vTextureCoord = aTextureCoord;\\n\\n    vBlurTexCoords[ 0] = aTextureCoord + vec2(0.0, -0.012 * strength);\\n    vBlurTexCoords[ 1] = aTextureCoord + vec2(0.0, -0.008 * strength);\\n    vBlurTexCoords[ 2] = aTextureCoord + vec2(0.0, -0.004 * strength);\\n    vBlurTexCoords[ 3] = aTextureCoord + vec2(0.0,  0.004 * strength);\\n    vBlurTexCoords[ 4] = aTextureCoord + vec2(0.0,  0.008 * strength);\\n    vBlurTexCoords[ 5] = aTextureCoord + vec2(0.0,  0.012 * strength);\\n\\n   vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        // fragment shader\n        \"precision lowp float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec2 vBlurTexCoords[6];\\nvarying vec4 vColor;\\n\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    gl_FragColor = vec4(0.0);\\n\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 0])*0.004431848411938341;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 1])*0.05399096651318985;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 2])*0.2419707245191454;\\n    gl_FragColor += texture2D(uSampler, vTextureCoord     )*0.3989422804014327;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 3])*0.2419707245191454;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 4])*0.05399096651318985;\\n    gl_FragColor += texture2D(uSampler, vBlurTexCoords[ 5])*0.004431848411938341;\\n}\\n\",\n        // set the uniforms\n        {\n            strength: { type: '1f', value: 1 }\n        }\n    );\n\n    this.passes = 1;\n    this.strength = 4;\n}\n\nBlurYFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBlurYFilter.prototype.constructor = BlurYFilter;\nmodule.exports = BlurYFilter;\n\nBlurYFilter.prototype.applyFilter = function (renderer, input, output, clear)\n{\n    var shader = this.getShader(renderer);\n\n    this.uniforms.strength.value = Math.abs(this.strength) / 4 / this.passes * (input.frame.height / input.size.height);\n\n    if(this.passes === 1)\n    {\n        renderer.filterManager.applyFilter(shader, input, output, clear);\n    }\n    else\n    {\n        var renderTarget = renderer.filterManager.getRenderTarget(true);\n        var flip = input;\n        var flop = renderTarget;\n\n        for(var i = 0; i < this.passes-1; i++)\n        {\n            renderer.filterManager.applyFilter(shader, flip, flop, true);\n\n           var temp = flop;\n           flop = flip;\n           flip = temp;\n        }\n\n        renderer.filterManager.applyFilter(shader, flip, output, clear);\n\n        renderer.filterManager.returnRenderTarget(renderTarget);\n    }\n};\n\n\nObject.defineProperties(BlurYFilter.prototype, {\n    /**\n     * Sets the strength of both the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurYFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return  this.strength;\n        },\n        set: function (value)\n        {\n            this.padding = Math.abs(value) * 0.5;\n            this.strength = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],93:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * A Smart Blur Filter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction SmartBlurFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform vec2 delta;\\n\\nfloat random(vec3 scale, float seed)\\n{\\n    return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\\n}\\n\\nvoid main(void)\\n{\\n    vec4 color = vec4(0.0);\\n    float total = 0.0;\\n\\n    float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\\n\\n    for (float t = -30.0; t <= 30.0; t++)\\n    {\\n        float percent = (t + offset - 0.5) / 30.0;\\n        float weight = 1.0 - abs(percent);\\n        vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);\\n        sample.rgb *= sample.a;\\n        color += sample * weight;\\n        total += weight;\\n    }\\n\\n    gl_FragColor = color / total;\\n    gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\\n}\\n\",\n        // uniforms\n        {\n          delta: { type: 'v2', value: { x: 0.1, y: 0.0 } }\n        }\n    );\n}\n\nSmartBlurFilter.prototype = Object.create(core.AbstractFilter.prototype);\nSmartBlurFilter.prototype.constructor = SmartBlurFilter;\nmodule.exports = SmartBlurFilter;\n\n},{\"../../core\":29}],94:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The ColorMatrixFilter class lets you apply a 5x4 matrix transformation on the RGBA\n * color and alpha values of every pixel on your displayObject to produce a result\n * with a new set of RGBA color and alpha values. It's pretty powerful!\n *\n * ```js\n *  var colorMatrix = new PIXI.ColorMatrixFilter();\n *  container.filters = [colorMatrix];\n *  colorMatrix.contrast(2);\n * ```\n * @author Clément Chenebault <clement@goodboydigital.com>\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction ColorMatrixFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\nuniform sampler2D uSampler;\\nuniform float m[25];\\n\\nvoid main(void)\\n{\\n\\n    vec4 c = texture2D(uSampler, vTextureCoord);\\n\\n    gl_FragColor.r = (m[0] * c.r);\\n        gl_FragColor.r += (m[1] * c.g);\\n        gl_FragColor.r += (m[2] * c.b);\\n        gl_FragColor.r += (m[3] * c.a);\\n        gl_FragColor.r += m[4] * c.a;\\n\\n    gl_FragColor.g = (m[5] * c.r);\\n        gl_FragColor.g += (m[6] * c.g);\\n        gl_FragColor.g += (m[7] * c.b);\\n        gl_FragColor.g += (m[8] * c.a);\\n        gl_FragColor.g += m[9] * c.a;\\n\\n     gl_FragColor.b = (m[10] * c.r);\\n        gl_FragColor.b += (m[11] * c.g);\\n        gl_FragColor.b += (m[12] * c.b);\\n        gl_FragColor.b += (m[13] * c.a);\\n        gl_FragColor.b += m[14] * c.a;\\n\\n     gl_FragColor.a = (m[15] * c.r);\\n        gl_FragColor.a += (m[16] * c.g);\\n        gl_FragColor.a += (m[17] * c.b);\\n        gl_FragColor.a += (m[18] * c.a);\\n        gl_FragColor.a += m[19] * c.a;\\n\\n}\\n\",\n        // custom uniforms\n        {\n            m: {\n                type: '1fv', value: [\n                    1, 0, 0, 0, 0,\n                    0, 1, 0, 0, 0,\n                    0, 0, 1, 0, 0,\n                    0, 0, 0, 1, 0\n                ]\n            }\n        }\n    );\n}\n\nColorMatrixFilter.prototype = Object.create(core.AbstractFilter.prototype);\nColorMatrixFilter.prototype.constructor = ColorMatrixFilter;\nmodule.exports = ColorMatrixFilter;\n\n\n/**\n * Transforms current matrix and set the new one\n *\n * @param matrix {number[]} (mat 5x4)\n * @param multiply {boolean} if true, current matrix and matrix are multiplied. If false, just set the current matrix with @param matrix\n */\nColorMatrixFilter.prototype._loadMatrix = function (matrix, multiply)\n{\n    multiply = !!multiply;\n\n    var newMatrix = matrix;\n\n    if (multiply) {\n        this._multiply(newMatrix, this.uniforms.m.value, matrix);\n        newMatrix = this._colorMatrix(newMatrix);\n    }\n\n    // set the new matrix\n    this.uniforms.m.value = newMatrix;\n};\n\n/**\n * Multiplies two mat5's\n *\n * @param out {number[]} (mat 5x4) the receiving matrix\n * @param a {number[]} (mat 5x4) the first operand\n * @param b {number[]} (mat 5x4) the second operand\n * @returns out {number[]} (mat 5x4)\n */\nColorMatrixFilter.prototype._multiply = function (out, a, b)\n{\n\n    // Red Channel\n    out[0] = (a[0] * b[0]) + (a[1] * b[5]) + (a[2] * b[10]) + (a[3] * b[15]);\n    out[1] = (a[0] * b[1]) + (a[1] * b[6]) + (a[2] * b[11]) + (a[3] * b[16]);\n    out[2] = (a[0] * b[2]) + (a[1] * b[7]) + (a[2] * b[12]) + (a[3] * b[17]);\n    out[3] = (a[0] * b[3]) + (a[1] * b[8]) + (a[2] * b[13]) + (a[3] * b[18]);\n    out[4] = (a[0] * b[4]) + (a[1] * b[9]) + (a[2] * b[14]) + (a[3] * b[19]);\n\n    // Green Channel\n    out[5] = (a[5] * b[0]) + (a[6] * b[5]) + (a[7] * b[10]) + (a[8] * b[15]);\n    out[6] = (a[5] * b[1]) + (a[6] * b[6]) + (a[7] * b[11]) + (a[8] * b[16]);\n    out[7] = (a[5] * b[2]) + (a[6] * b[7]) + (a[7] * b[12]) + (a[8] * b[17]);\n    out[8] = (a[5] * b[3]) + (a[6] * b[8]) + (a[7] * b[13]) + (a[8] * b[18]);\n    out[9] = (a[5] * b[4]) + (a[6] * b[9]) + (a[7] * b[14]) + (a[8] * b[19]);\n\n    // Blue Channel\n    out[10] = (a[10] * b[0]) + (a[11] * b[5]) + (a[12] * b[10]) + (a[13] * b[15]);\n    out[11] = (a[10] * b[1]) + (a[11] * b[6]) + (a[12] * b[11]) + (a[13] * b[16]);\n    out[12] = (a[10] * b[2]) + (a[11] * b[7]) + (a[12] * b[12]) + (a[13] * b[17]);\n    out[13] = (a[10] * b[3]) + (a[11] * b[8]) + (a[12] * b[13]) + (a[13] * b[18]);\n    out[14] = (a[10] * b[4]) + (a[11] * b[9]) + (a[12] * b[14]) + (a[13] * b[19]);\n\n    // Alpha Channel\n    out[15] = (a[15] * b[0]) + (a[16] * b[5]) + (a[17] * b[10]) + (a[18] * b[15]);\n    out[16] = (a[15] * b[1]) + (a[16] * b[6]) + (a[17] * b[11]) + (a[18] * b[16]);\n    out[17] = (a[15] * b[2]) + (a[16] * b[7]) + (a[17] * b[12]) + (a[18] * b[17]);\n    out[18] = (a[15] * b[3]) + (a[16] * b[8]) + (a[17] * b[13]) + (a[18] * b[18]);\n    out[19] = (a[15] * b[4]) + (a[16] * b[9]) + (a[17] * b[14]) + (a[18] * b[19]);\n\n    return out;\n};\n\n/**\n * Create a Float32 Array and normalize the offset component to 0-1\n *\n * @param matrix {number[]} (mat 5x4)\n * @return m {number[]} (mat 5x4) with all values between 0-1\n */\nColorMatrixFilter.prototype._colorMatrix = function (matrix)\n{\n    // Create a Float32 Array and normalize the offset component to 0-1\n    var m = new Float32Array(matrix);\n    m[4] /= 255;\n    m[9] /= 255;\n    m[14] /= 255;\n    m[19] /= 255;\n\n    return m;\n};\n\n/**\n * Adjusts brightness\n *\n * @param b {number} value of the brigthness (0 is black)\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.brightness = function (b, multiply)\n{\n    var matrix = [\n        b, 0, 0, 0, 0,\n        0, b, 0, 0, 0,\n        0, 0, b, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Set the matrices in grey scales\n *\n * @param scale {number} value of the grey (0 is black)\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.greyscale = function (scale, multiply)\n{\n    var matrix = [\n        scale, scale, scale, 0, 0,\n        scale, scale, scale, 0, 0,\n        scale, scale, scale, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n//Americanized alias\nColorMatrixFilter.prototype.grayscale = ColorMatrixFilter.prototype.greyscale;\n\n/**\n * Set the black and white matrice\n * Multiply the current matrix\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.blackAndWhite = function (multiply)\n{\n    var matrix = [\n        0.3, 0.6, 0.1, 0, 0,\n        0.3, 0.6, 0.1, 0, 0,\n        0.3, 0.6, 0.1, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Set the hue property of the color\n *\n * @param rotation {number} in degrees\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.hue = function (rotation, multiply)\n{\n    rotation = (rotation || 0) / 180 * Math.PI;\n    var cos = Math.cos(rotation),\n        sin = Math.sin(rotation);\n\n    // luminanceRed, luminanceGreen, luminanceBlue\n    var lumR = 0.213, // or 0.3086\n        lumG = 0.715, // or 0.6094\n        lumB = 0.072; // or 0.0820\n\n    var matrix = [\n        lumR + cos * (1 - lumR) + sin * (-lumR), lumG + cos * (-lumG) + sin * (-lumG), lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0,\n        lumR + cos * (-lumR) + sin * (0.143), lumG + cos * (1 - lumG) + sin * (0.140), lumB + cos * (-lumB) + sin * (-0.283), 0, 0,\n        lumR + cos * (-lumR) + sin * (-(1 - lumR)), lumG + cos * (-lumG) + sin * (lumG), lumB + cos * (1 - lumB) + sin * (lumB), 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n\n/**\n * Set the contrast matrix, increase the separation between dark and bright\n * Increase contrast : shadows darker and highlights brighter\n * Decrease contrast : bring the shadows up and the highlights down\n *\n * @param amount {number} value of the contrast\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.contrast = function (amount, multiply)\n{\n    var v = (amount || 0) + 1;\n    var o = -128 * (v - 1);\n\n    var matrix = [\n        v, 0, 0, 0, o,\n        0, v, 0, 0, o,\n        0, 0, v, 0, o,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Set the saturation matrix, increase the separation between colors\n * Increase saturation : increase contrast, brightness, and sharpness\n *\n * @param amount {number}\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.saturate = function (amount, multiply)\n{\n    var x = (amount || 0) * 2 / 3 + 1;\n    var y = ((x - 1) * -0.5);\n\n    var matrix = [\n        x, y, y, 0, 0,\n        y, x, y, 0, 0,\n        y, y, x, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Desaturate image (remove color)\n *\n * Call the saturate function\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.desaturate = function (multiply) // jshint unused:false\n{\n    this.saturate(-1);\n};\n\n/**\n * Negative image (inverse of classic rgb matrix)\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.negative = function (multiply)\n{\n    var matrix = [\n        0, 1, 1, 0, 0,\n        1, 0, 1, 0, 0,\n        1, 1, 0, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Sepia image\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.sepia = function (multiply)\n{\n    var matrix = [\n        0.393, 0.7689999, 0.18899999, 0, 0,\n        0.349, 0.6859999, 0.16799999, 0, 0,\n        0.272, 0.5339999, 0.13099999, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Color motion picture process invented in 1916 (thanks Dominic Szablewski)\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.technicolor = function (multiply)\n{\n    var matrix = [\n        1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337,\n        -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398,\n        -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Polaroid filter\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.polaroid = function (multiply)\n{\n    var matrix = [\n        1.438, -0.062, -0.062, 0, 0,\n        -0.122, 1.378, -0.122, 0, 0,\n        -0.016, -0.016, 1.483, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Filter who transforms : Red -> Blue and Blue -> Red\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.toBGR = function (multiply)\n{\n    var matrix = [\n        0, 0, 1, 0, 0,\n        0, 1, 0, 0, 0,\n        1, 0, 0, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Color reversal film introduced by Eastman Kodak in 1935. (thanks Dominic Szablewski)\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.kodachrome = function (multiply)\n{\n    var matrix = [\n        1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n        -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n        -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/**\n * Brown delicious browni filter (thanks Dominic Szablewski)\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.browni = function (multiply)\n{\n    var matrix = [\n        0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873,\n        -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127,\n        0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/*\n * Vintage filter (thanks Dominic Szablewski)\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.vintage = function (multiply)\n{\n    var matrix = [\n        0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123,\n        0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591,\n        0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/*\n * We don't know exactly what it does, kind of gradient map, but funny to play with!\n *\n * @param desaturation {number}\n * @param toned {number}\n * @param lightColor {string} (example : \"0xFFE580\")\n * @param darkColor {string}  (example : \"0xFFE580\")\n *\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.colorTone = function (desaturation, toned, lightColor, darkColor, multiply)\n{\n    desaturation = desaturation || 0.2;\n    toned = toned || 0.15;\n    lightColor = lightColor || 0xFFE580;\n    darkColor = darkColor || 0x338000;\n\n    var lR = ((lightColor >> 16) & 0xFF) / 255;\n    var lG = ((lightColor >> 8) & 0xFF) / 255;\n    var lB = (lightColor & 0xFF) / 255;\n\n    var dR = ((darkColor >> 16) & 0xFF) / 255;\n    var dG = ((darkColor >> 8) & 0xFF) / 255;\n    var dB = (darkColor & 0xFF) / 255;\n\n    var matrix = [\n        0.3, 0.59, 0.11, 0, 0,\n        lR, lG, lB, desaturation, 0,\n        dR, dG, dB, toned, 0,\n        lR - dR, lG - dG, lB - dB, 0, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/*\n * Night effect\n *\n * @param intensity {number}\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.night = function (intensity, multiply)\n{\n    intensity = intensity || 0.1;\n    var matrix = [\n        intensity * ( -2.0), -intensity, 0, 0, 0,\n        -intensity, 0, intensity, 0, 0,\n        0, intensity, intensity * 2.0, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n\n/*\n * Predator effect\n *\n * Erase the current matrix by setting a new indepent one\n *\n * @param amount {number} how much the predator feels his future victim\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.predator = function (amount, multiply)\n{\n    var matrix = [\n        11.224130630493164 * amount, -4.794486999511719 * amount, -2.8746118545532227 * amount, 0 * amount, 0.40342438220977783 * amount,\n        -3.6330697536468506 * amount, 9.193157196044922 * amount, -2.951810836791992 * amount, 0 * amount, -1.316135048866272 * amount,\n        -3.2184197902679443 * amount, -4.2375030517578125 * amount, 7.476448059082031 * amount, 0 * amount, 0.8044459223747253 * amount,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/*\n * LSD effect\n *\n * Multiply the current matrix\n *\n * @param amount {number} How crazy is your effect\n * @param multiply {boolean} refer to ._loadMatrix() method\n */\nColorMatrixFilter.prototype.lsd = function (multiply)\n{\n    var matrix = [\n        2, -0.4, 0.5, 0, 0,\n        -0.5, 2, -0.4, 0, 0,\n        -0.4, -0.5, 3, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, multiply);\n};\n\n/*\n * Erase the current matrix by setting the default one\n *\n */\nColorMatrixFilter.prototype.reset = function ()\n{\n    var matrix = [\n        1, 0, 0, 0, 0,\n        0, 1, 0, 0, 0,\n        0, 0, 1, 0, 0,\n        0, 0, 0, 1, 0\n    ];\n\n    this._loadMatrix(matrix, false);\n};\n\n\nObject.defineProperties(ColorMatrixFilter.prototype, {\n    /**\n     * Sets the matrix of the color matrix filter\n     *\n     * @member {number[]}\n     * @memberof PIXI.filters.ColorMatrixFilter#\n     * @default [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]\n     */\n    matrix: {\n        get: function ()\n        {\n            return this.uniforms.m.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.m.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],95:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This lowers the color depth of your image by the given amount, producing an image with a smaller palette.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction ColorStepFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform float step;\\n\\nvoid main(void)\\n{\\n    vec4 color = texture2D(uSampler, vTextureCoord);\\n\\n    color = floor(color * step) / step;\\n\\n    gl_FragColor = color;\\n}\\n\",\n        // custom uniforms\n        {\n            step: { type: '1f', value: 5 }\n        }\n    );\n}\n\nColorStepFilter.prototype = Object.create(core.AbstractFilter.prototype);\nColorStepFilter.prototype.constructor = ColorStepFilter;\nmodule.exports = ColorStepFilter;\n\nObject.defineProperties(ColorStepFilter.prototype, {\n    /**\n     * The number of steps to reduce the palette by.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.ColorStepFilter#\n     */\n    step: {\n        get: function ()\n        {\n            return this.uniforms.step.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.step.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],96:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The ConvolutionFilter class applies a matrix convolution filter effect.\n * A convolution combines pixels in the input image with neighboring pixels to produce a new image.\n * A wide variety of image effects can be achieved through convolutions, including blurring, edge\n * detection, sharpening, embossing, and beveling. The matrix should be specified as a 9 point Array.\n * See http://docs.gimp.org/en/plug-in-convmatrix.html for more info.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n * @param matrix {number[]} An array of values used for matrix transformation. Specified as a 9 point Array.\n * @param width {number} Width of the object you are transforming\n * @param height {number} Height of the object you are transforming\n */\nfunction ConvolutionFilter(matrix, width, height)\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying mediump vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform vec2 texelSize;\\nuniform float matrix[9];\\n\\nvoid main(void)\\n{\\n   vec4 c11 = texture2D(uSampler, vTextureCoord - texelSize); // top left\\n   vec4 c12 = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - texelSize.y)); // top center\\n   vec4 c13 = texture2D(uSampler, vec2(vTextureCoord.x + texelSize.x, vTextureCoord.y - texelSize.y)); // top right\\n\\n   vec4 c21 = texture2D(uSampler, vec2(vTextureCoord.x - texelSize.x, vTextureCoord.y)); // mid left\\n   vec4 c22 = texture2D(uSampler, vTextureCoord); // mid center\\n   vec4 c23 = texture2D(uSampler, vec2(vTextureCoord.x + texelSize.x, vTextureCoord.y)); // mid right\\n\\n   vec4 c31 = texture2D(uSampler, vec2(vTextureCoord.x - texelSize.x, vTextureCoord.y + texelSize.y)); // bottom left\\n   vec4 c32 = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + texelSize.y)); // bottom center\\n   vec4 c33 = texture2D(uSampler, vTextureCoord + texelSize); // bottom right\\n\\n   gl_FragColor =\\n       c11 * matrix[0] + c12 * matrix[1] + c13 * matrix[2] +\\n       c21 * matrix[3] + c22 * matrix[4] + c23 * matrix[5] +\\n       c31 * matrix[6] + c32 * matrix[7] + c33 * matrix[8];\\n\\n   gl_FragColor.a = c22.a;\\n}\\n\",\n        // custom uniforms\n        {\n            matrix:     { type: '1fv', value: new Float32Array(matrix) },\n            texelSize:  { type: 'v2', value: { x: 1 / width, y: 1 / height } }\n        }\n    );\n}\n\nConvolutionFilter.prototype = Object.create(core.AbstractFilter.prototype);\nConvolutionFilter.prototype.constructor = ConvolutionFilter;\nmodule.exports = ConvolutionFilter;\n\nObject.defineProperties(ConvolutionFilter.prototype, {\n    /**\n     * An array of values used for matrix transformation. Specified as a 9 point Array.\n     *\n     * @member {number[]}\n     * @memberof PIXI.filters.ConvolutionFilter#\n     */\n    matrix: {\n        get: function ()\n        {\n            return this.uniforms.matrix.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.matrix.value = new Float32Array(value);\n        }\n    },\n\n    /**\n     * Width of the object you are transforming\n     *\n     * @member {number}\n     * @memberof PIXI.filters.ConvolutionFilter#\n     */\n    width: {\n        get: function ()\n        {\n            return 1/this.uniforms.texelSize.value.x;\n        },\n        set: function (value)\n        {\n            this.uniforms.texelSize.value.x = 1/value;\n        }\n    },\n\n    /**\n     * Height of the object you are transforming\n     *\n     * @member {number}\n     * @memberof PIXI.filters.ConvolutionFilter#\n     */\n    height: {\n        get: function ()\n        {\n            return 1/this.uniforms.texelSize.value.y;\n        },\n        set: function (value)\n        {\n            this.uniforms.texelSize.value.y = 1/value;\n        }\n    }\n});\n\n},{\"../../core\":29}],97:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * A Cross Hatch effect filter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction CrossHatchFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);\\n\\n    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\\n\\n    if (lum < 1.00)\\n    {\\n        if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0)\\n        {\\n            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\\n        }\\n    }\\n\\n    if (lum < 0.75)\\n    {\\n        if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0)\\n        {\\n            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\\n        }\\n    }\\n\\n    if (lum < 0.50)\\n    {\\n        if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0)\\n        {\\n            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\\n        }\\n    }\\n\\n    if (lum < 0.3)\\n    {\\n        if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0)\\n        {\\n            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\\n        }\\n    }\\n}\\n\"\n    );\n}\n\nCrossHatchFilter.prototype = Object.create(core.AbstractFilter.prototype);\nCrossHatchFilter.prototype.constructor = CrossHatchFilter;\nmodule.exports = CrossHatchFilter;\n\n},{\"../../core\":29}],98:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.\n * You can use this filter to apply all manor of crazy warping effects\n * Currently the r property of the texture is used to offset the x and the g property of the texture is used to offset the y.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n * @param sprite {PIXI.Sprite} the sprite used for the displacement map. (make sure its added to the scene!)\n */\nfunction DisplacementFilter(sprite, scale)\n{\n    var maskMatrix = new core.Matrix();\n    sprite.renderable = false;\n\n    core.AbstractFilter.call(this,\n        // vertex shader\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform mat3 projectionMatrix;\\nuniform mat3 otherMatrix;\\n\\nvarying vec2 vMapCoord;\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nvoid main(void)\\n{\\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\\n   vTextureCoord = aTextureCoord;\\n   vMapCoord = ( otherMatrix * vec3( aTextureCoord, 1.0)  ).xy;\\n   vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vMapCoord;\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nuniform vec2 scale;\\n\\nuniform sampler2D uSampler;\\nuniform sampler2D mapSampler;\\n\\nvoid main(void)\\n{\\n   vec4 map =  texture2D(mapSampler, vMapCoord);\\n\\n   map -= 0.5;\\n   map.xy *= scale;\\n\\n   gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y));\\n}\\n\",\n        // uniforms\n        {\n            mapSampler:     { type: 'sampler2D', value: sprite.texture },\n            otherMatrix:    { type: 'mat3', value: maskMatrix.toArray(true) },\n            scale:          { type: 'v2', value: { x: 1, y: 1 } }\n        }\n    );\n\n    this.maskSprite = sprite;\n    this.maskMatrix = maskMatrix;\n\n    if (scale === null || scale === undefined)\n    {\n        scale = 20;\n    }\n\n    this.scale = new core.Point(scale, scale);\n}\n\nDisplacementFilter.prototype = Object.create(core.AbstractFilter.prototype);\nDisplacementFilter.prototype.constructor = DisplacementFilter;\nmodule.exports = DisplacementFilter;\n\nDisplacementFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var filterManager = renderer.filterManager;\n\n    filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix);\n\n    this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true);\n    this.uniforms.scale.value.x = this.scale.x * (1/input.frame.width);\n    this.uniforms.scale.value.y = this.scale.y * (1/input.frame.height);\n\n    var shader = this.getShader(renderer);\n     // draw the filter...\n    filterManager.applyFilter(shader, input, output);\n};\n\n\nObject.defineProperties(DisplacementFilter.prototype, {\n    /**\n     * The texture used for the displacement map. Must be power of 2 sized texture.\n     *\n     * @member {PIXI.Texture}\n     * @memberof PIXI.filters.DisplacementFilter#\n     */\n    map: {\n        get: function ()\n        {\n            return this.uniforms.mapSampler.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.mapSampler.value = value;\n\n        }\n    }\n});\n\n},{\"../../core\":29}],99:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * @author Mat Groves http://matgroves.com/ @Doormat23\n * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js\n */\n\n/**\n * This filter applies a dotscreen effect making display objects appear to be made out of\n * black and white halftone dots like an old printer.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction DotScreenFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nuniform vec4 dimensions;\\nuniform sampler2D uSampler;\\n\\nuniform float angle;\\nuniform float scale;\\n\\nfloat pattern()\\n{\\n   float s = sin(angle), c = cos(angle);\\n   vec2 tex = vTextureCoord * dimensions.xy;\\n   vec2 point = vec2(\\n       c * tex.x - s * tex.y,\\n       s * tex.x + c * tex.y\\n   ) * scale;\\n   return (sin(point.x) * sin(point.y)) * 4.0;\\n}\\n\\nvoid main()\\n{\\n   vec4 color = texture2D(uSampler, vTextureCoord);\\n   float average = (color.r + color.g + color.b) / 3.0;\\n   gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);\\n}\\n\",\n        // custom uniforms\n        {\n            scale:      { type: '1f', value: 1 },\n            angle:      { type: '1f', value: 5 },\n            dimensions: { type: '4fv', value: [0, 0, 0, 0] }\n        }\n    );\n}\n\nDotScreenFilter.prototype = Object.create(core.AbstractFilter.prototype);\nDotScreenFilter.prototype.constructor = DotScreenFilter;\nmodule.exports = DotScreenFilter;\n\nObject.defineProperties(DotScreenFilter.prototype, {\n    /**\n     * The scale of the effect.\n     * @member {number}\n     * @memberof PIXI.filters.DotScreenFilter#\n     */\n    scale: {\n        get: function ()\n        {\n            return this.uniforms.scale.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.scale.value = value;\n        }\n    },\n\n    /**\n     * The radius of the effect.\n     * @member {number}\n     * @memberof PIXI.filters.DotScreenFilter#\n     */\n    angle: {\n        get: function ()\n        {\n            return this.uniforms.angle.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.angle.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],100:[function(require,module,exports){\nvar core = require('../../core');\n\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The BlurYTintFilter applies a vertical Gaussian blur to an object.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction BlurYTintFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        \"attribute vec2 aVertexPosition;\\nattribute vec2 aTextureCoord;\\nattribute vec4 aColor;\\n\\nuniform float strength;\\nuniform vec2 offset;\\n\\nuniform mat3 projectionMatrix;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\nvarying vec2 vBlurTexCoords[6];\\n\\nvoid main(void)\\n{\\n    gl_Position = vec4((projectionMatrix * vec3((aVertexPosition+offset), 1.0)).xy, 0.0, 1.0);\\n    vTextureCoord = aTextureCoord;\\n\\n    vBlurTexCoords[ 0] = aTextureCoord + vec2(0.0, -0.012 * strength);\\n    vBlurTexCoords[ 1] = aTextureCoord + vec2(0.0, -0.008 * strength);\\n    vBlurTexCoords[ 2] = aTextureCoord + vec2(0.0, -0.004 * strength);\\n    vBlurTexCoords[ 3] = aTextureCoord + vec2(0.0,  0.004 * strength);\\n    vBlurTexCoords[ 4] = aTextureCoord + vec2(0.0,  0.008 * strength);\\n    vBlurTexCoords[ 5] = aTextureCoord + vec2(0.0,  0.012 * strength);\\n\\n   vColor = vec4(aColor.rgb * aColor.a, aColor.a);\\n}\\n\",\n        // fragment shader\n        \"precision lowp float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec2 vBlurTexCoords[6];\\nvarying vec4 vColor;\\n\\nuniform vec3 color;\\nuniform float alpha;\\n\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    vec4 sum = vec4(0.0);\\n\\n    sum += texture2D(uSampler, vBlurTexCoords[ 0])*0.004431848411938341;\\n    sum += texture2D(uSampler, vBlurTexCoords[ 1])*0.05399096651318985;\\n    sum += texture2D(uSampler, vBlurTexCoords[ 2])*0.2419707245191454;\\n    sum += texture2D(uSampler, vTextureCoord     )*0.3989422804014327;\\n    sum += texture2D(uSampler, vBlurTexCoords[ 3])*0.2419707245191454;\\n    sum += texture2D(uSampler, vBlurTexCoords[ 4])*0.05399096651318985;\\n    sum += texture2D(uSampler, vBlurTexCoords[ 5])*0.004431848411938341;\\n\\n    gl_FragColor = vec4( color.rgb * sum.a * alpha, sum.a * alpha );\\n}\\n\",\n        // set the uniforms\n        {\n            blur: { type: '1f', value: 1 / 512 },\n            color: { type: 'c', value: [0,0,0]},\n            alpha: { type: '1f', value: 0.7 },\n            offset: { type: '2f', value:[5, 5]},\n            strength: { type: '1f', value:1}\n        }\n    );\n\n    this.passes = 1;\n    this.strength = 4;\n}\n\nBlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype);\nBlurYTintFilter.prototype.constructor = BlurYTintFilter;\nmodule.exports = BlurYTintFilter;\n\nBlurYTintFilter.prototype.applyFilter = function (renderer, input, output, clear)\n{\n    var shader = this.getShader(renderer);\n\n    this.uniforms.strength.value = this.strength / 4 / this.passes * (input.frame.height / input.size.height);\n\n    if(this.passes === 1)\n    {\n        renderer.filterManager.applyFilter(shader, input, output, clear);\n    }\n    else\n    {\n        var renderTarget = renderer.filterManager.getRenderTarget(true);\n        var flip = input;\n        var flop = renderTarget;\n\n        for(var i = 0; i < this.passes-1; i++)\n        {\n            renderer.filterManager.applyFilter(shader, flip, flop, clear);\n\n           var temp = flop;\n           flop = flip;\n           flip = temp;\n        }\n\n        renderer.filterManager.applyFilter(shader, flip, output, clear);\n\n        renderer.filterManager.returnRenderTarget(renderTarget);\n    }\n};\n\n\nObject.defineProperties(BlurYTintFilter.prototype, {\n    /**\n     * Sets the strength of both the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.BlurYTintFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return  this.strength;\n        },\n        set: function (value)\n        {\n            this.padding = value * 0.5;\n            this.strength = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],101:[function(require,module,exports){\nvar core = require('../../core'),\n    BlurXFilter = require('../blur/BlurXFilter'),\n    BlurYTintFilter = require('./BlurYTintFilter');\n\n/**\n * The DropShadowFilter applies a Gaussian blur to an object.\n * The strength of the blur can be set for x- and y-axis separately.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction DropShadowFilter()\n{\n    core.AbstractFilter.call(this);\n\n    this.blurXFilter = new BlurXFilter();\n    this.blurYTintFilter = new BlurYTintFilter();\n\n    this.defaultFilter = new core.AbstractFilter();\n\n    this.padding = 30;\n\n    this._dirtyPosition = true;\n    this._angle = 45 * Math.PI / 180;\n    this._distance = 10;\n    this.alpha = 0.75;\n    this.hideObject = false;\n    this.blendMode = core.BLEND_MODES.MULTIPLY;\n}\n\nDropShadowFilter.prototype = Object.create(core.AbstractFilter.prototype);\nDropShadowFilter.prototype.constructor = DropShadowFilter;\nmodule.exports = DropShadowFilter;\n\nDropShadowFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var renderTarget = renderer.filterManager.getRenderTarget(true);\n\n    //TODO - copyTexSubImage2D could be used here?\n    if(this._dirtyPosition)\n    {\n        this._dirtyPosition = false;\n\n        this.blurYTintFilter.uniforms.offset.value[0] = Math.sin(this._angle) * this._distance;\n        this.blurYTintFilter.uniforms.offset.value[1] = Math.cos(this._angle) * this._distance;\n    }\n\n    this.blurXFilter.applyFilter(renderer, input, renderTarget);\n\n    renderer.blendModeManager.setBlendMode(this.blendMode);\n\n    this.blurYTintFilter.applyFilter(renderer, renderTarget, output);\n\n    renderer.blendModeManager.setBlendMode(core.BLEND_MODES.NORMAL);\n\n    if(!this.hideObject)\n    {\n\n        this.defaultFilter.applyFilter(renderer, input, output);\n    }\n\n\n    renderer.filterManager.returnRenderTarget(renderTarget);\n};\n\nObject.defineProperties(DropShadowFilter.prototype, {\n    /**\n     * Sets the strength of both the blurX and blurY properties simultaneously\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     * @default 2\n     */\n    blur: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.blur = this.blurYTintFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurX property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     * @default 2\n     */\n    blurX: {\n        get: function ()\n        {\n            return this.blurXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurXFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the strength of the blurY property\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     * @default 2\n     */\n    blurY: {\n        get: function ()\n        {\n            return this.blurYTintFilter.blur;\n        },\n        set: function (value)\n        {\n            this.blurYTintFilter.blur = value;\n        }\n    },\n\n    /**\n     * Sets the color of the shadow\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     */\n    color: {\n        get: function ()\n        {\n            return  core.utils.rgb2hex( this.blurYTintFilter.uniforms.color.value );\n        },\n        set: function (value)\n        {\n            this.blurYTintFilter.uniforms.color.value = core.utils.hex2rgb(value);\n        }\n    },\n\n    /**\n     * Sets the alpha of the shadow\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     */\n    alpha: {\n        get: function ()\n        {\n            return  this.blurYTintFilter.uniforms.alpha.value;\n        },\n        set: function (value)\n        {\n            this.blurYTintFilter.uniforms.alpha.value = value;\n        }\n    },\n\n    /**\n     * Sets the distance of the shadow\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     */\n    distance: {\n        get: function ()\n        {\n            return  this._distance;\n        },\n        set: function (value)\n        {\n            this._dirtyPosition = true;\n            this._distance = value;\n        }\n    },\n\n    /**\n     * Sets the angle of the shadow\n     *\n     * @member {number}\n     * @memberOf PIXI.filters.DropShadowFilter#\n     */\n    angle: {\n        get: function ()\n        {\n            return  this._angle;\n        },\n        set: function (value)\n        {\n            this._dirtyPosition = true;\n            this._angle = value;\n        }\n    }\n});\n\n},{\"../../core\":29,\"../blur/BlurXFilter\":91,\"./BlurYTintFilter\":100}],102:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This greyscales the palette of your Display Objects.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction GrayFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nuniform sampler2D uSampler;\\nuniform float gray;\\n\\nvoid main(void)\\n{\\n   gl_FragColor = texture2D(uSampler, vTextureCoord);\\n   gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);\\n}\\n\",\n        // set the uniforms\n        {\n            gray: { type: '1f', value: 1 }\n        }\n    );\n}\n\nGrayFilter.prototype = Object.create(core.AbstractFilter.prototype);\nGrayFilter.prototype.constructor = GrayFilter;\nmodule.exports = GrayFilter;\n\nObject.defineProperties(GrayFilter.prototype, {\n    /**\n     * The strength of the gray. 1 will make the object black and white, 0 will make the object its normal color.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.GrayFilter#\n     */\n    gray: {\n        get: function ()\n        {\n            return this.uniforms.gray.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.gray.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],103:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI filters library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI.filters\n */\nmodule.exports = {\n    AsciiFilter:        require('./ascii/AsciiFilter'),\n    BloomFilter:        require('./bloom/BloomFilter'),\n    BlurFilter:         require('./blur/BlurFilter'),\n    BlurXFilter:        require('./blur/BlurXFilter'),\n    BlurYFilter:        require('./blur/BlurYFilter'),\n    BlurDirFilter:      require('./blur/BlurDirFilter'),\n    ColorMatrixFilter:  require('./color/ColorMatrixFilter'),\n    ColorStepFilter:    require('./color/ColorStepFilter'),\n    ConvolutionFilter:  require('./convolution/ConvolutionFilter'),\n    CrossHatchFilter:   require('./crosshatch/CrossHatchFilter'),\n    DisplacementFilter: require('./displacement/DisplacementFilter'),\n    DotScreenFilter:    require('./dot/DotScreenFilter'),\n    GrayFilter:         require('./gray/GrayFilter'),\n    DropShadowFilter:   require('./dropshadow/DropShadowFilter'),\n    InvertFilter:       require('./invert/InvertFilter'),\n    NoiseFilter:        require('./noise/NoiseFilter'),\n    PixelateFilter:     require('./pixelate/PixelateFilter'),\n    RGBSplitFilter:     require('./rgb/RGBSplitFilter'),\n    ShockwaveFilter:    require('./shockwave/ShockwaveFilter'),\n    SepiaFilter:        require('./sepia/SepiaFilter'),\n    SmartBlurFilter:    require('./blur/SmartBlurFilter'),\n    TiltShiftFilter:    require('./tiltshift/TiltShiftFilter'),\n    TiltShiftXFilter:   require('./tiltshift/TiltShiftXFilter'),\n    TiltShiftYFilter:   require('./tiltshift/TiltShiftYFilter'),\n    TwistFilter:        require('./twist/TwistFilter')\n};\n\n},{\"./ascii/AsciiFilter\":87,\"./bloom/BloomFilter\":88,\"./blur/BlurDirFilter\":89,\"./blur/BlurFilter\":90,\"./blur/BlurXFilter\":91,\"./blur/BlurYFilter\":92,\"./blur/SmartBlurFilter\":93,\"./color/ColorMatrixFilter\":94,\"./color/ColorStepFilter\":95,\"./convolution/ConvolutionFilter\":96,\"./crosshatch/CrossHatchFilter\":97,\"./displacement/DisplacementFilter\":98,\"./dot/DotScreenFilter\":99,\"./dropshadow/DropShadowFilter\":101,\"./gray/GrayFilter\":102,\"./invert/InvertFilter\":104,\"./noise/NoiseFilter\":105,\"./pixelate/PixelateFilter\":106,\"./rgb/RGBSplitFilter\":107,\"./sepia/SepiaFilter\":108,\"./shockwave/ShockwaveFilter\":109,\"./tiltshift/TiltShiftFilter\":111,\"./tiltshift/TiltShiftXFilter\":112,\"./tiltshift/TiltShiftYFilter\":113,\"./twist/TwistFilter\":114}],104:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This inverts your Display Objects colors.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction InvertFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform float invert;\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    gl_FragColor = texture2D(uSampler, vTextureCoord);\\n\\n    gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);\\n}\\n\",\n        // custom uniforms\n        {\n            invert: { type: '1f', value: 1 }\n        }\n    );\n}\n\nInvertFilter.prototype = Object.create(core.AbstractFilter.prototype);\nInvertFilter.prototype.constructor = InvertFilter;\nmodule.exports = InvertFilter;\n\nObject.defineProperties(InvertFilter.prototype, {\n    /**\n     * The strength of the invert. `1` will fully invert the colors, and\n     * `0` will make the object its normal color.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.InvertFilter#\n     */\n    invert: {\n        get: function ()\n        {\n            return this.uniforms.invert.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.invert.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],105:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * @author Vico @vicocotea\n * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/noise.js\n */\n\n/**\n * A Noise effect filter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction NoiseFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision highp float;\\n\\nvarying vec2 vTextureCoord;\\nvarying vec4 vColor;\\n\\nuniform float noise;\\nuniform sampler2D uSampler;\\n\\nfloat rand(vec2 co)\\n{\\n    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\\n}\\n\\nvoid main()\\n{\\n    vec4 color = texture2D(uSampler, vTextureCoord);\\n\\n    float diff = (rand(vTextureCoord) - 0.5) * noise;\\n\\n    color.r += diff;\\n    color.g += diff;\\n    color.b += diff;\\n\\n    gl_FragColor = color;\\n}\\n\",\n        // custom uniforms\n        {\n            noise: { type: '1f', value: 0.5 }\n        }\n    );\n}\n\nNoiseFilter.prototype = Object.create(core.AbstractFilter.prototype);\nNoiseFilter.prototype.constructor = NoiseFilter;\nmodule.exports = NoiseFilter;\n\nObject.defineProperties(NoiseFilter.prototype, {\n    /**\n     * The amount of noise to apply.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.NoiseFilter#\n     * @default 0.5\n     */\n    noise: {\n        get: function ()\n        {\n            return this.uniforms.noise.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.noise.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],106:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This filter applies a pixelate effect making display objects appear 'blocky'.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction PixelateFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform vec4 dimensions;\\nuniform vec2 pixelSize;\\nuniform sampler2D uSampler;\\n\\nvoid main(void)\\n{\\n    vec2 coord = vTextureCoord;\\n\\n    vec2 size = dimensions.xy / pixelSize;\\n\\n    vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;\\n\\n    gl_FragColor = texture2D(uSampler, color);\\n}\\n\",\n        // custom uniforms\n        {\n            dimensions: { type: '4fv',  value: new Float32Array([0, 0, 0, 0]) },\n            pixelSize:  { type: 'v2',   value: { x: 10, y: 10 } }\n        }\n    );\n}\n\nPixelateFilter.prototype = Object.create(core.AbstractFilter.prototype);\nPixelateFilter.prototype.constructor = PixelateFilter;\nmodule.exports = PixelateFilter;\n\nObject.defineProperties(PixelateFilter.prototype, {\n    /**\n     * This a point that describes the size of the blocks.\n     * x is the width of the block and y is the height.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.PixelateFilter#\n     */\n    size: {\n        get: function ()\n        {\n            return this.uniforms.pixelSize.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.pixelSize.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],107:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * An RGB Split Filter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction RGBSplitFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform vec4 dimensions;\\nuniform vec2 red;\\nuniform vec2 green;\\nuniform vec2 blue;\\n\\nvoid main(void)\\n{\\n   gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;\\n   gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;\\n   gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;\\n   gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;\\n}\\n\",\n        // custom uniforms\n        {\n            red:        { type: 'v2', value: { x: 20, y: 20 } },\n            green:      { type: 'v2', value: { x: -20, y: 20 } },\n            blue:       { type: 'v2', value: { x: 20, y: -20 } },\n            dimensions: { type: '4fv', value: [0, 0, 0, 0] }\n        }\n    );\n}\n\nRGBSplitFilter.prototype = Object.create(core.AbstractFilter.prototype);\nRGBSplitFilter.prototype.constructor = RGBSplitFilter;\nmodule.exports = RGBSplitFilter;\n\nObject.defineProperties(RGBSplitFilter.prototype, {\n    /**\n     * Red channel offset.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.RGBSplitFilter#\n     */\n    red: {\n        get: function ()\n        {\n            return this.uniforms.red.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.red.value = value;\n        }\n    },\n\n    /**\n     * Green channel offset.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.RGBSplitFilter#\n     */\n    green: {\n        get: function ()\n        {\n            return this.uniforms.green.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.green.value = value;\n        }\n    },\n\n    /**\n     * Blue offset.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.RGBSplitFilter#\n     */\n    blue: {\n        get: function ()\n        {\n            return this.uniforms.blue.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.blue.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],108:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This applies a sepia effect to your Display Objects.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction SepiaFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform float sepia;\\n\\nconst mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);\\n\\nvoid main(void)\\n{\\n   gl_FragColor = texture2D(uSampler, vTextureCoord);\\n   gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);\\n}\\n\",\n        // custom uniforms\n        {\n            sepia: { type: '1f', value: 1 }\n        }\n    );\n}\n\nSepiaFilter.prototype = Object.create(core.AbstractFilter.prototype);\nSepiaFilter.prototype.constructor = SepiaFilter;\nmodule.exports = SepiaFilter;\n\nObject.defineProperties(SepiaFilter.prototype, {\n    /**\n     * The strength of the sepia. `1` will apply the full sepia effect, and\n     * `0` will make the object its normal color.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.SepiaFilter#\n     */\n    sepia: {\n        get: function ()\n        {\n            return this.uniforms.sepia.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.sepia.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],109:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA\n * color and alpha values of every pixel on your displayObject to produce a result\n * with a new set of RGBA color and alpha values. It's pretty powerful!\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction ShockwaveFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision lowp float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\n\\nuniform vec2 center;\\nuniform vec3 params; // 10.0, 0.8, 0.1\\nuniform float time;\\n\\nvoid main()\\n{\\n    vec2 uv = vTextureCoord;\\n    vec2 texCoord = uv;\\n\\n    float dist = distance(uv, center);\\n\\n    if ( (dist <= (time + params.z)) && (dist >= (time - params.z)) )\\n    {\\n        float diff = (dist - time);\\n        float powDiff = 1.0 - pow(abs(diff*params.x), params.y);\\n\\n        float diffTime = diff  * powDiff;\\n        vec2 diffUV = normalize(uv - center);\\n        texCoord = uv + (diffUV * diffTime);\\n    }\\n\\n    gl_FragColor = texture2D(uSampler, texCoord);\\n}\\n\",\n        // custom uniforms\n        {\n            center: { type: 'v2', value: { x: 0.5, y: 0.5 } },\n            params: { type: 'v3', value: { x: 10, y: 0.8, z: 0.1 } },\n            time: { type: '1f', value: 0 }\n        }\n    );\n}\n\nShockwaveFilter.prototype = Object.create(core.AbstractFilter.prototype);\nShockwaveFilter.prototype.constructor = ShockwaveFilter;\nmodule.exports = ShockwaveFilter;\n\nObject.defineProperties(ShockwaveFilter.prototype, {\n    /**\n     * Sets the center of the shockwave in normalized screen coords. That is\n     * (0,0) is the top-left and (1,1) is the bottom right.\n     *\n     * @member {object<string, number>}\n     * @memberof PIXI.filters.ShockwaveFilter#\n     */\n    center: {\n        get: function ()\n        {\n            return this.uniforms.center.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.center.value = value;\n        }\n    },\n    /**\n     * Sets the params of the shockwave. These modify the look and behavior of\n     * the shockwave as it ripples out.\n     *\n     * @member {object<string, number>}\n     * @memberof PIXI.filters.ShockwaveFilter#\n     */\n    params: {\n        get: function ()\n        {\n            return this.uniforms.params.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.params.value = value;\n        }\n    },\n    /**\n     * Sets the elapsed time of the shockwave. This controls the speed at which\n     * the shockwave ripples out.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.ShockwaveFilter#\n     */\n    time: {\n        get: function ()\n        {\n            return this.uniforms.time.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.time.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],110:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * @author Vico @vicocotea\n * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/\n */\n\n/**\n * A TiltShiftAxisFilter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction TiltShiftAxisFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform float blur;\\nuniform float gradientBlur;\\nuniform vec2 start;\\nuniform vec2 end;\\nuniform vec2 delta;\\nuniform vec2 texSize;\\n\\nfloat random(vec3 scale, float seed)\\n{\\n    return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\\n}\\n\\nvoid main(void)\\n{\\n    vec4 color = vec4(0.0);\\n    float total = 0.0;\\n\\n    float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\\n    vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));\\n    float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * texSize - start, normal)) / gradientBlur) * blur;\\n\\n    for (float t = -30.0; t <= 30.0; t++)\\n    {\\n        float percent = (t + offset - 0.5) / 30.0;\\n        float weight = 1.0 - abs(percent);\\n        vec4 sample = texture2D(uSampler, vTextureCoord + delta / texSize * percent * radius);\\n        sample.rgb *= sample.a;\\n        color += sample * weight;\\n        total += weight;\\n    }\\n\\n    gl_FragColor = color / total;\\n    gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\\n}\\n\",\n        // custom uniforms\n        {\n            blur:           { type: '1f', value: 100 },\n            gradientBlur:   { type: '1f', value: 600 },\n            start:          { type: 'v2', value: { x: 0,    y: window.innerHeight / 2 } },\n            end:            { type: 'v2', value: { x: 600,  y: window.innerHeight / 2 } },\n            delta:          { type: 'v2', value: { x: 30,   y: 30 } },\n            texSize:        { type: 'v2', value: { x: window.innerWidth, y: window.innerHeight } }\n        }\n    );\n\n    this.updateDelta();\n}\n\nTiltShiftAxisFilter.prototype = Object.create(core.AbstractFilter.prototype);\nTiltShiftAxisFilter.prototype.constructor = TiltShiftAxisFilter;\nmodule.exports = TiltShiftAxisFilter;\n\n/**\n * Updates the filter delta values.\n * This is overridden in the X and Y filters, does nothing for this class.\n *\n */\nTiltShiftAxisFilter.prototype.updateDelta = function ()\n{\n    this.uniforms.delta.value.x = 0;\n    this.uniforms.delta.value.y = 0;\n};\n\nObject.defineProperties(TiltShiftAxisFilter.prototype, {\n    /**\n     * The strength of the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftAxisFilter#\n     */\n    blur: {\n        get: function ()\n        {\n            return this.uniforms.blur.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.blur.value = value;\n        }\n    },\n\n    /**\n     * The strength of the gradient blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftAxisFilter#\n     */\n    gradientBlur: {\n        get: function ()\n        {\n            return this.uniforms.gradientBlur.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.gradientBlur.value = value;\n        }\n    },\n\n    /**\n     * The X value to start the effect at.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.TiltShiftAxisFilter#\n     */\n    start: {\n        get: function ()\n        {\n            return this.uniforms.start.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.start.value = value;\n            this.updateDelta();\n        }\n    },\n\n    /**\n     * The X value to end the effect at.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.TiltShiftAxisFilter#\n     */\n    end: {\n        get: function ()\n        {\n            return this.uniforms.end.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.end.value = value;\n            this.updateDelta();\n        }\n    }\n});\n\n},{\"../../core\":29}],111:[function(require,module,exports){\nvar core = require('../../core'),\n    TiltShiftXFilter = require('./TiltShiftXFilter'),\n    TiltShiftYFilter = require('./TiltShiftYFilter');\n\n/**\n * @author Vico @vicocotea\n * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/\n */\n\n/**\n * A TiltShift Filter. Manages the pass of both a TiltShiftXFilter and TiltShiftYFilter.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction TiltShiftFilter()\n{\n    core.AbstractFilter.call(this);\n\n    this.tiltShiftXFilter = new TiltShiftXFilter();\n    this.tiltShiftYFilter = new TiltShiftYFilter();\n}\n\nTiltShiftFilter.prototype = Object.create(core.AbstractFilter.prototype);\nTiltShiftFilter.prototype.constructor = TiltShiftFilter;\nmodule.exports = TiltShiftFilter;\n\nTiltShiftFilter.prototype.applyFilter = function (renderer, input, output)\n{\n    var renderTarget = renderer.filterManager.getRenderTarget(true);\n\n    this.tiltShiftXFilter.applyFilter(renderer, input, renderTarget);\n\n    this.tiltShiftYFilter.applyFilter(renderer, renderTarget, output);\n\n    renderer.filterManager.returnRenderTarget(renderTarget);\n};\n\nObject.defineProperties(TiltShiftFilter.prototype, {\n    /**\n     * The strength of the blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftFilter#\n     */\n    blur: {\n        get: function ()\n        {\n            return this.tiltShiftXFilter.blur;\n        },\n        set: function (value)\n        {\n            this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value;\n        }\n    },\n\n    /**\n     * The strength of the gradient blur.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftFilter#\n     */\n    gradientBlur: {\n        get: function ()\n        {\n            return this.tiltShiftXFilter.gradientBlur;\n        },\n        set: function (value)\n        {\n            this.tiltShiftXFilter.gradientBlur = this.tiltShiftYFilter.gradientBlur = value;\n        }\n    },\n\n    /**\n     * The Y value to start the effect at.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftFilter#\n     */\n    start: {\n        get: function ()\n        {\n            return this.tiltShiftXFilter.start;\n        },\n        set: function (value)\n        {\n            this.tiltShiftXFilter.start = this.tiltShiftYFilter.start = value;\n        }\n    },\n\n    /**\n     * The Y value to end the effect at.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TiltShiftFilter#\n     */\n    end: {\n        get: function ()\n        {\n            return this.tiltShiftXFilter.end;\n        },\n        set: function (value)\n        {\n            this.tiltShiftXFilter.end = this.tiltShiftYFilter.end = value;\n        }\n    }\n});\n\n},{\"../../core\":29,\"./TiltShiftXFilter\":112,\"./TiltShiftYFilter\":113}],112:[function(require,module,exports){\nvar TiltShiftAxisFilter = require('./TiltShiftAxisFilter');\n\n/**\n * @author Vico @vicocotea\n * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/\n */\n\n/**\n * A TiltShiftXFilter.\n *\n * @class\n * @extends PIXI.TiltShiftAxisFilter\n * @memberof PIXI.filters\n */\nfunction TiltShiftXFilter()\n{\n    TiltShiftAxisFilter.call(this);\n}\n\nTiltShiftXFilter.prototype = Object.create(TiltShiftAxisFilter.prototype);\nTiltShiftXFilter.prototype.constructor = TiltShiftXFilter;\nmodule.exports = TiltShiftXFilter;\n\n/**\n * Updates the filter delta values.\n *\n */\nTiltShiftXFilter.prototype.updateDelta = function ()\n{\n    var dx = this.uniforms.end.value.x - this.uniforms.start.value.x;\n    var dy = this.uniforms.end.value.y - this.uniforms.start.value.y;\n    var d = Math.sqrt(dx * dx + dy * dy);\n\n    this.uniforms.delta.value.x = dx / d;\n    this.uniforms.delta.value.y = dy / d;\n};\n\n},{\"./TiltShiftAxisFilter\":110}],113:[function(require,module,exports){\nvar TiltShiftAxisFilter = require('./TiltShiftAxisFilter');\n\n/**\n * @author Vico @vicocotea\n * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/\n */\n\n/**\n * A TiltShiftYFilter.\n *\n * @class\n * @extends PIXI.TiltShiftAxisFilter\n * @memberof PIXI.filters\n */\nfunction TiltShiftYFilter()\n{\n    TiltShiftAxisFilter.call(this);\n}\n\nTiltShiftYFilter.prototype = Object.create(TiltShiftAxisFilter.prototype);\nTiltShiftYFilter.prototype.constructor = TiltShiftYFilter;\nmodule.exports = TiltShiftYFilter;\n\n/**\n * Updates the filter delta values.\n *\n */\nTiltShiftYFilter.prototype.updateDelta = function ()\n{\n    var dx = this.uniforms.end.value.x - this.uniforms.start.value.x;\n    var dy = this.uniforms.end.value.y - this.uniforms.start.value.y;\n    var d = Math.sqrt(dx * dx + dy * dy);\n\n    this.uniforms.delta.value.x = -dy / d;\n    this.uniforms.delta.value.y = dx / d;\n};\n\n},{\"./TiltShiftAxisFilter\":110}],114:[function(require,module,exports){\nvar core = require('../../core');\n// @see https://github.com/substack/brfs/issues/25\n\n\n/**\n * This filter applies a twist effect making display objects appear twisted in the given direction.\n *\n * @class\n * @extends PIXI.AbstractFilter\n * @memberof PIXI.filters\n */\nfunction TwistFilter()\n{\n    core.AbstractFilter.call(this,\n        // vertex shader\n        null,\n        // fragment shader\n        \"precision mediump float;\\n\\nvarying vec2 vTextureCoord;\\n\\nuniform sampler2D uSampler;\\nuniform float radius;\\nuniform float angle;\\nuniform vec2 offset;\\n\\nvoid main(void)\\n{\\n   vec2 coord = vTextureCoord - offset;\\n   float dist = length(coord);\\n\\n   if (dist < radius)\\n   {\\n       float ratio = (radius - dist) / radius;\\n       float angleMod = ratio * ratio * angle;\\n       float s = sin(angleMod);\\n       float c = cos(angleMod);\\n       coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);\\n   }\\n\\n   gl_FragColor = texture2D(uSampler, coord+offset);\\n}\\n\",\n        // custom uniforms\n        {\n            radius:     { type: '1f', value: 0.5 },\n            angle:      { type: '1f', value: 5 },\n            offset:     { type: 'v2', value: { x: 0.5, y: 0.5 } }\n        }\n    );\n}\n\nTwistFilter.prototype = Object.create(core.AbstractFilter.prototype);\nTwistFilter.prototype.constructor = TwistFilter;\nmodule.exports = TwistFilter;\n\nObject.defineProperties(TwistFilter.prototype, {\n    /**\n     * This point describes the the offset of the twist.\n     *\n     * @member {PIXI.Point}\n     * @memberof PIXI.filters.TwistFilter#\n     */\n    offset: {\n        get: function ()\n        {\n            return this.uniforms.offset.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.offset.value = value;\n        }\n    },\n\n    /**\n     * This radius of the twist.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TwistFilter#\n     */\n    radius: {\n        get: function ()\n        {\n            return this.uniforms.radius.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.radius.value = value;\n        }\n    },\n\n    /**\n     * This angle of the twist.\n     *\n     * @member {number}\n     * @memberof PIXI.filters.TwistFilter#\n     */\n    angle: {\n        get: function ()\n        {\n            return this.uniforms.angle.value;\n        },\n        set: function (value)\n        {\n            this.uniforms.angle.value = value;\n        }\n    }\n});\n\n},{\"../../core\":29}],115:[function(require,module,exports){\n(function (global){\n// run the polyfills\nrequire('./polyfill');\n\nvar core = module.exports = require('./core');\n\n// add core plugins.\ncore.extras         = require('./extras');\ncore.filters        = require('./filters');\ncore.interaction    = require('./interaction');\ncore.loaders        = require('./loaders');\ncore.mesh           = require('./mesh');\ncore.accessibility  = require('./accessibility');\n\n// export a premade loader instance\n/**\n * A premade instance of the loader that can be used to loader resources.\n *\n * @name loader\n * @memberof PIXI\n * @property {PIXI.loaders.Loader}\n */\ncore.loader = new core.loaders.Loader();\n\n// mixin the deprecation features.\nObject.assign(core, require('./deprecation'));\n\n// Always export pixi globally.\nglobal.PIXI = core;\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./accessibility\":21,\"./core\":29,\"./deprecation\":79,\"./extras\":86,\"./filters\":103,\"./interaction\":118,\"./loaders\":121,\"./mesh\":128,\"./polyfill\":133}],116:[function(require,module,exports){\nvar core = require('../core');\n\n/**\n * Holds all information related to an Interaction event\n *\n * @class\n * @memberof PIXI.interaction\n */\nfunction InteractionData()\n{\n    /**\n     * This point stores the global coords of where the touch/mouse event happened\n     *\n     * @member {PIXI.Point}\n     */\n    this.global = new core.Point();\n\n    /**\n     * The target Sprite that was interacted with\n     *\n     * @member {PIXI.Sprite}\n     */\n    this.target = null;\n\n    /**\n     * When passed to an event handler, this will be the original DOM Event that was captured\n     *\n     * @member {Event}\n     */\n    this.originalEvent = null;\n}\n\nInteractionData.prototype.constructor = InteractionData;\nmodule.exports = InteractionData;\n\n/**\n * This will return the local coordinates of the specified displayObject for this InteractionData\n *\n * @param displayObject {PIXI.DisplayObject} The DisplayObject that you would like the local coords off\n * @param [point] {PIXI.Point} A Point object in which to store the value, optional (otherwise will create a new point)\n * @param [globalPos] {PIXI.Point} A Point object containing your custom global coords, optional (otherwise will use the current global coords)\n * @return {PIXI.Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject\n */\nInteractionData.prototype.getLocalPosition = function (displayObject, point, globalPos)\n{\n    return displayObject.worldTransform.applyInverse(globalPos || this.global, point);\n};\n\n},{\"../core\":29}],117:[function(require,module,exports){\nvar core = require('../core'),\n    InteractionData = require('./InteractionData');\n\n// Mix interactiveTarget into core.DisplayObject.prototype\nObject.assign(\n    core.DisplayObject.prototype,\n    require('./interactiveTarget')\n);\n\n/**\n * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive\n * if its interactive parameter is set to true\n * This manager also supports multitouch.\n *\n * @class\n * @memberof PIXI.interaction\n * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} A reference to the current renderer\n * @param [options] {object}\n * @param [options.autoPreventDefault=true] {boolean} Should the manager automatically prevent default browser actions.\n * @param [options.interactionFrequency=10] {number} Frequency increases the interaction events will be checked.\n */\nfunction InteractionManager(renderer, options)\n{\n    options = options || {};\n\n    /**\n     * The renderer this interaction manager works for.\n     *\n     * @member {PIXI.SystemRenderer}\n     */\n    this.renderer = renderer;\n\n    /**\n     * Should default browser actions automatically be prevented.\n     *\n     * @member {boolean}\n     * @default true\n     */\n    this.autoPreventDefault = options.autoPreventDefault !== undefined ? options.autoPreventDefault : true;\n\n    /**\n     * As this frequency increases the interaction events will be checked more often.\n     *\n     * @member {number}\n     * @default 10\n     */\n    this.interactionFrequency = options.interactionFrequency || 10;\n\n    /**\n     * The mouse data\n     *\n     * @member {PIXI.interaction.InteractionData}\n     */\n    this.mouse = new InteractionData();\n\n    /**\n     * An event data object to handle all the event tracking/dispatching\n     *\n     * @member {object}\n     */\n    this.eventData = {\n        stopped: false,\n        target: null,\n        type: null,\n        data: this.mouse,\n        stopPropagation:function(){\n            this.stopped = true;\n        }\n    };\n\n    /**\n     * Tiny little interactiveData pool !\n     *\n     * @member {PIXI.interaction.InteractionData[]}\n     */\n    this.interactiveDataPool = [];\n\n    /**\n     * The DOM element to bind to.\n     *\n     * @member {HTMLElement}\n     * @private\n     */\n    this.interactionDOMElement = null;\n\n    /**\n     * This property determins if mousemove and touchmove events are fired only when the cursror is over the object\n     * Setting to true will make things work more in line with how the DOM verison works.\n     * Setting to false can make things easier for things like dragging\n     * It is currently set to false as this is how pixi used to work. This will be set to true in future versions of pixi.\n     * @member {boolean}\n     * @private\n     */\n    this.moveWhenInside = false;\n    \n    /**\n     * Have events been attached to the dom element?\n     *\n     * @member {boolean}\n     * @private\n     */\n    this.eventsAdded = false;\n\n    //this will make it so that you don't have to call bind all the time\n\n    /**\n     * @member {Function}\n     */\n    this.onMouseUp = this.onMouseUp.bind(this);\n    this.processMouseUp = this.processMouseUp.bind( this );\n\n\n    /**\n     * @member {Function}\n     */\n    this.onMouseDown = this.onMouseDown.bind(this);\n    this.processMouseDown = this.processMouseDown.bind( this );\n\n    /**\n     * @member {Function}\n     */\n    this.onMouseMove = this.onMouseMove.bind( this );\n    this.processMouseMove = this.processMouseMove.bind( this );\n\n    /**\n     * @member {Function}\n     */\n    this.onMouseOut = this.onMouseOut.bind(this);\n    this.processMouseOverOut = this.processMouseOverOut.bind( this );\n\n\n    /**\n     * @member {Function}\n     */\n    this.onTouchStart = this.onTouchStart.bind(this);\n    this.processTouchStart = this.processTouchStart.bind(this);\n\n    /**\n     * @member {Function}\n     */\n    this.onTouchEnd = this.onTouchEnd.bind(this);\n    this.processTouchEnd = this.processTouchEnd.bind(this);\n\n    /**\n     * @member {Function}\n     */\n    this.onTouchMove = this.onTouchMove.bind(this);\n    this.processTouchMove = this.processTouchMove.bind(this);\n\n    /**\n     * @member {number}\n     */\n    this.last = 0;\n\n    /**\n     * The css style of the cursor that is being used\n     * @member {string}\n     */\n    this.currentCursorStyle = 'inherit';\n\n    /**\n     * Internal cached var\n     * @member {PIXI.Point}\n     * @private\n     */\n    this._tempPoint = new core.Point();\n    \n\n    /**\n     * The current resolution\n     * @member {number}\n     */\n    this.resolution = 1;\n\n    this.setTargetElement(this.renderer.view, this.renderer.resolution);\n}\n\nInteractionManager.prototype.constructor = InteractionManager;\nmodule.exports = InteractionManager;\n\n/**\n * Sets the DOM element which will receive mouse/touch events. This is useful for when you have\n * other DOM elements on top of the renderers Canvas element. With this you'll be bale to deletegate\n * another DOM element to receive those events.\n *\n * @param element {HTMLElement} the DOM element which will receive mouse and touch events.\n * @param [resolution=1] {number} THe resolution of the new element (relative to the canvas).\n * @private\n */\nInteractionManager.prototype.setTargetElement = function (element, resolution)\n{\n    this.removeEvents();\n\n    this.interactionDOMElement = element;\n\n    this.resolution = resolution || 1;\n\n    this.addEvents();\n};\n\n/**\n * Registers all the DOM events\n *\n * @private\n */\nInteractionManager.prototype.addEvents = function ()\n{\n    if (!this.interactionDOMElement)\n    {\n        return;\n    }\n\n    core.ticker.shared.add(this.update, this);\n\n    if (window.navigator.msPointerEnabled)\n    {\n        this.interactionDOMElement.style['-ms-content-zooming'] = 'none';\n        this.interactionDOMElement.style['-ms-touch-action'] = 'none';\n    }\n\n    window.document.addEventListener('mousemove',    this.onMouseMove, true);\n    this.interactionDOMElement.addEventListener('mousedown',    this.onMouseDown, true);\n    this.interactionDOMElement.addEventListener('mouseout',     this.onMouseOut, true);\n\n    this.interactionDOMElement.addEventListener('touchstart',   this.onTouchStart, true);\n    this.interactionDOMElement.addEventListener('touchend',     this.onTouchEnd, true);\n    this.interactionDOMElement.addEventListener('touchmove',    this.onTouchMove, true);\n\n    window.addEventListener('mouseup',  this.onMouseUp, true);\n\n    this.eventsAdded = true;\n};\n\n/**\n * Removes all the DOM events that were previously registered\n *\n * @private\n */\nInteractionManager.prototype.removeEvents = function ()\n{\n    if (!this.interactionDOMElement)\n    {\n        return;\n    }\n\n    core.ticker.shared.remove(this.update);\n\n    if (window.navigator.msPointerEnabled)\n    {\n        this.interactionDOMElement.style['-ms-content-zooming'] = '';\n        this.interactionDOMElement.style['-ms-touch-action'] = '';\n    }\n\n    window.document.removeEventListener('mousemove', this.onMouseMove, true);\n    this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true);\n    this.interactionDOMElement.removeEventListener('mouseout',  this.onMouseOut, true);\n\n    this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true);\n    this.interactionDOMElement.removeEventListener('touchend',  this.onTouchEnd, true);\n    this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true);\n\n    this.interactionDOMElement = null;\n\n    window.removeEventListener('mouseup',  this.onMouseUp, true);\n\n    this.eventsAdded = false;\n};\n\n/**\n * Updates the state of interactive objects.\n * Invoked by a throttled ticker update from\n * {@link PIXI.ticker.shared}.\n *\n * @param deltaTime {number}\n */\nInteractionManager.prototype.update = function (deltaTime)\n{\n    this._deltaTime += deltaTime;\n\n    if (this._deltaTime < this.interactionFrequency)\n    {\n        return;\n    }\n\n    this._deltaTime = 0;\n\n    if (!this.interactionDOMElement)\n    {\n        return;\n    }\n\n    // if the user move the mouse this check has already been dfone using the mouse move!\n    if(this.didMove)\n    {\n        this.didMove = false;\n        return;\n    }\n\n    this.cursor = 'inherit';\n\n    this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseOverOut, true );\n\n    if (this.currentCursorStyle !== this.cursor)\n    {\n        this.currentCursorStyle = this.cursor;\n        this.interactionDOMElement.style.cursor = this.cursor;\n    }\n\n    //TODO\n};\n\n/**\n * Dispatches an event on the display object that was interacted with\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} the display object in question\n * @param eventString {string} the name of the event (e.g, mousedown)\n * @param eventData {object} the event data object\n * @private\n */\nInteractionManager.prototype.dispatchEvent = function ( displayObject, eventString, eventData )\n{\n    if(!eventData.stopped)\n    {\n        eventData.target = displayObject;\n        eventData.type = eventString;\n\n        displayObject.emit( eventString, eventData );\n\n        if( displayObject[eventString] )\n        {\n            displayObject[eventString]( eventData );\n        }\n    }\n};\n\n/**\n * Maps x and y coords from a DOM object and maps them correctly to the pixi view. The resulting value is stored in the point.\n * This takes into account the fact that the DOM element could be scaled and positioned anywhere on the screen.\n *\n * @param  {PIXI.Point} point the point that the result will be stored in\n * @param  {number} x     the x coord of the position to map\n * @param  {number} y     the y coord of the position to map\n */\nInteractionManager.prototype.mapPositionToPoint = function ( point, x, y )\n{\n    var rect = this.interactionDOMElement.getBoundingClientRect();\n    point.x = ( ( x - rect.left ) * (this.interactionDOMElement.width  / rect.width  ) ) / this.resolution;\n    point.y = ( ( y - rect.top  ) * (this.interactionDOMElement.height / rect.height ) ) / this.resolution;\n};\n\n/**\n * This function is provides a neat way of crawling through the scene graph and running a specified function on all interactive objects it finds.\n * It will also take care of hit testing the interactive objects and passes the hit across in the function.\n *\n * @param  {PIXI.Point} point the point that is tested for collision\n * @param  {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} displayObject the displayObject that will be hit test (recurcsivly crawls its children)\n * @param  {Function} func the function that will be called on each interactive object. The displayObject and hit will be passed to the function\n * @param  {boolean} hitTest this indicates if the objects inside should be hit test against the point\n * @return {boolean} returns true if the displayObject hit the point\n */\nInteractionManager.prototype.processInteractive = function (point, displayObject, func, hitTest, interactive)\n{\n    if(!displayObject || !displayObject.visible)\n    {\n        return false;\n    }\n\n    // Took a little while to rework this function correctly! But now it is done and nice and optimised. ^_^\n    // \n    // This function will now loop through all objects and then only hit test the objects it HAS to, not all of them. MUCH faster..\n    // An object will be hit test if the following is true:\n    // \n    // 1: It is interactive.\n    // 2: It belongs to a parent that is interactive AND one of the parents children have not already been hit.\n    // \n    // As another little optimisation once an interactive object has been hit we can carry on through the scenegraph, but we know that there will be no more hits! So we can avoid extra hit tests\n    // A final optimisation is that an object is not hit test directly if a child has already been hit.\n    \n    var hit = false,\n        interactiveParent = interactive = displayObject.interactive || interactive;\n\n    // if the displayobject has a hitArea, then it does not need to hitTest children.\n    if(displayObject.hitArea)\n    {\n        interactiveParent = false;\n    }\n\n    // ** FREE TIP **! If an object is not interacttive or has no buttons in it (such as a game scene!) set interactiveChildren to false for that displayObject.\n    // This will allow pixi to completly ignore and bypass checking the displayObjects children.\n    if(displayObject.interactiveChildren)\n    {       \n        var children = displayObject.children;\n        \n        for (var i = children.length-1; i >= 0; i--)\n        {\n            var child = children[i];\n\n            // time to get recursive.. if this function will return if somthing is hit..\n            if(this.processInteractive(point, child, func, hitTest, interactiveParent))\n            {\n                // its a good idea to check if a child has lost its parent.\n                // this means it has been removed whilst looping so its best\n                if(!child.parent)\n                {\n                    continue;\n                }\n\n                hit = true;\n\n                // we no longer need to hit test any more objects in this container as we we now know the parent has been hit\n                interactiveParent = false;\n                \n                // If the child is interactive , that means that the object hit was actually interactive and not just the child of an interactive object. \n                // This means we no longer need to hit test anything else. We still need to run through all objects, but we don't need to perform any hit tests.\n                //if(child.interactive)\n                //{\n                hitTest = false;\n                //}\n\n                // we can break now as we have hit an object.\n                //break;\n            }\n        }\n    }\n\n    // no point running this if the item is not interactive or does not have an interactive parent.\n    if(interactive)\n    {\n        // if we are hit testing (as in we have no hit any objects yet)\n        // We also don't need to worry about hit testing if once of the displayObjects children has already been hit!\n        if(hitTest && !hit)\n        {  \n            if(displayObject.hitArea)\n            {\n                displayObject.worldTransform.applyInverse(point,  this._tempPoint);\n                hit = displayObject.hitArea.contains( this._tempPoint.x, this._tempPoint.y );\n            }\n            else if(displayObject.containsPoint)\n            {\n                hit = displayObject.containsPoint(point);\n            }\n        }\n\n        if(displayObject.interactive)\n        {\n            func(displayObject, hit); \n        }\n    }\n\n    return hit;\n  \n};\n\n\n/**\n * Is called when the mouse button is pressed down on the renderer element\n *\n * @param event {Event} The DOM event of a mouse button being pressed down\n * @private\n */\nInteractionManager.prototype.onMouseDown = function (event)\n{\n    this.mouse.originalEvent = event;\n    this.eventData.data = this.mouse;\n    this.eventData.stopped = false;\n\n    // Update internal mouse reference\n    this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);\n\n    if (this.autoPreventDefault)\n    {\n        this.mouse.originalEvent.preventDefault();\n    }\n\n    this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseDown, true );\n};\n\n/**\n * Processes the result of the mouse down check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the dispay object\n * @private\n */\nInteractionManager.prototype.processMouseDown = function ( displayObject, hit )\n{\n    var e = this.mouse.originalEvent;\n    \n    var isRightButton = e.button === 2 || e.which === 3;\n\n    if(hit)\n    {\n        displayObject[ isRightButton ? '_isRightDown' : '_isLeftDown' ] = true;\n        this.dispatchEvent( displayObject, isRightButton ? 'rightdown' : 'mousedown', this.eventData );\n    }\n};\n\n\n\n/**\n * Is called when the mouse button is released on the renderer element\n *\n * @param event {Event} The DOM event of a mouse button being released\n * @private\n */\nInteractionManager.prototype.onMouseUp = function (event)\n{\n    this.mouse.originalEvent = event;\n    this.eventData.data = this.mouse;\n    this.eventData.stopped = false;\n\n    // Update internal mouse reference\n    this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);\n\n    this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseUp, true );\n};\n\n/**\n * Processes the result of the mouse up check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processMouseUp = function ( displayObject, hit )\n{\n    var e = this.mouse.originalEvent;\n\n    var isRightButton = e.button === 2 || e.which === 3;\n    var isDown =  isRightButton ? '_isRightDown' : '_isLeftDown';\n\n    if(hit)\n    {\n        this.dispatchEvent( displayObject, isRightButton ? 'rightup' : 'mouseup', this.eventData );\n\n        if( displayObject[ isDown ] )\n        {\n            displayObject[ isDown ] = false;\n            this.dispatchEvent( displayObject, isRightButton ? 'rightclick' : 'click', this.eventData );\n        }\n    }\n    else\n    {\n        if( displayObject[ isDown ] )\n        {\n            displayObject[ isDown ] = false;\n            this.dispatchEvent( displayObject, isRightButton ? 'rightupoutside' : 'mouseupoutside', this.eventData );\n        }\n    }\n};\n\n\n/**\n * Is called when the mouse moves across the renderer element\n *\n * @param event {Event} The DOM event of the mouse moving\n * @private\n */\nInteractionManager.prototype.onMouseMove = function (event)\n{\n    this.mouse.originalEvent = event;\n    this.eventData.data = this.mouse;\n    this.eventData.stopped = false;\n\n    this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);\n\n    this.didMove = true;\n\n    this.cursor = 'inherit';\n\n    this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseMove, true );\n\n    if (this.currentCursorStyle !== this.cursor)\n    {\n        this.currentCursorStyle = this.cursor;\n        this.interactionDOMElement.style.cursor = this.cursor;\n    }\n\n    //TODO BUG for parents ineractive object (border order issue)\n};\n\n/**\n * Processes the result of the mouse move check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processMouseMove = function ( displayObject, hit )\n{\n    this.processMouseOverOut(displayObject, hit);\n    \n    // only display on mouse over\n    if(!this.moveWhenInside || hit)\n    {\n        this.dispatchEvent( displayObject, 'mousemove', this.eventData);\n    }\n};\n\n\n/**\n * Is called when the mouse is moved out of the renderer element\n *\n * @param event {Event} The DOM event of a mouse being moved out\n * @private\n */\nInteractionManager.prototype.onMouseOut = function (event)\n{\n    this.mouse.originalEvent = event;\n    this.eventData.stopped = false;\n\n    // Update internal mouse reference\n    this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);\n\n    this.interactionDOMElement.style.cursor = 'inherit';\n\n    // TODO optimize by not check EVERY TIME! maybe half as often? //\n    this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY );\n\n    this.processInteractive( this.mouse.global, this.renderer._lastObjectRendered, this.processMouseOverOut, false );\n};\n\n/**\n * Processes the result of the mouse over/out check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processMouseOverOut = function ( displayObject, hit )\n{\n    if(hit)\n    {\n        if(!displayObject._over)\n        {\n            displayObject._over = true;\n            this.dispatchEvent( displayObject, 'mouseover', this.eventData );\n        }\n\n        if (displayObject.buttonMode)\n        {\n            this.cursor = displayObject.defaultCursor;\n        }\n    }\n    else\n    {\n        if(displayObject._over)\n        {\n            displayObject._over = false;\n            this.dispatchEvent( displayObject, 'mouseout', this.eventData);\n        }\n    }\n};\n\n\n/**\n * Is called when a touch is started on the renderer element\n *\n * @param event {Event} The DOM event of a touch starting on the renderer view\n * @private\n */\nInteractionManager.prototype.onTouchStart = function (event)\n{\n    if (this.autoPreventDefault)\n    {\n        event.preventDefault();\n    }\n\n    var changedTouches = event.changedTouches;\n    var cLength = changedTouches.length;\n\n    for (var i=0; i < cLength; i++)\n    {\n        var touchEvent = changedTouches[i];\n        //TODO POOL\n        var touchData = this.getTouchData( touchEvent );\n\n        touchData.originalEvent = event;\n\n        this.eventData.data = touchData;\n        this.eventData.stopped = false;\n\n        this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchStart, true );\n\n        this.returnTouchData( touchData );\n    }\n};\n\n/**\n * Processes the result of a touch check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processTouchStart = function ( displayObject, hit )\n{\n    if(hit)\n    {\n        displayObject._touchDown = true;\n        this.dispatchEvent( displayObject, 'touchstart', this.eventData );\n    }\n};\n\n\n/**\n * Is called when a touch ends on the renderer element\n *\n * @param event {Event} The DOM event of a touch ending on the renderer view\n */\nInteractionManager.prototype.onTouchEnd = function (event)\n{\n    if (this.autoPreventDefault)\n    {\n        event.preventDefault();\n    }\n\n    var changedTouches = event.changedTouches;\n    var cLength = changedTouches.length;\n\n    for (var i=0; i < cLength; i++)\n    {\n        var touchEvent = changedTouches[i];\n\n        var touchData = this.getTouchData( touchEvent );\n\n        touchData.originalEvent = event;\n\n        //TODO this should be passed along.. no set\n        this.eventData.data = touchData;\n        this.eventData.stopped = false;\n\n\n        this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchEnd, true );\n\n        this.returnTouchData( touchData );\n    }\n};\n\n/**\n * Processes the result of the end of a touch and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processTouchEnd = function ( displayObject, hit )\n{\n    if(hit)\n    {\n        this.dispatchEvent( displayObject, 'touchend', this.eventData );\n\n        if( displayObject._touchDown )\n        {\n            displayObject._touchDown = false;\n            this.dispatchEvent( displayObject, 'tap', this.eventData );\n        }\n    }\n    else\n    {\n        if( displayObject._touchDown )\n        {\n            displayObject._touchDown = false;\n            this.dispatchEvent( displayObject, 'touchendoutside', this.eventData );\n        }\n    }\n};\n\n/**\n * Is called when a touch is moved across the renderer element\n *\n * @param event {Event} The DOM event of a touch moving across the renderer view\n * @private\n */\nInteractionManager.prototype.onTouchMove = function (event)\n{\n    if (this.autoPreventDefault)\n    {\n        event.preventDefault();\n    }\n\n    var changedTouches = event.changedTouches;\n    var cLength = changedTouches.length;\n\n    for (var i=0; i < cLength; i++)\n    {\n        var touchEvent = changedTouches[i];\n\n        var touchData = this.getTouchData( touchEvent );\n\n        touchData.originalEvent = event;\n\n        this.eventData.data = touchData;\n        this.eventData.stopped = false;\n\n        this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchMove, this.moveWhenInside );\n\n        this.returnTouchData( touchData );\n    }\n};\n\n/**\n * Processes the result of a touch move check and dispatches the event if need be\n *\n * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested\n * @param hit {boolean} the result of the hit test on the display object\n * @private\n */\nInteractionManager.prototype.processTouchMove = function ( displayObject, hit )\n{\n    if(!this.moveWhenInside || hit)\n    {\n        this.dispatchEvent( displayObject, 'touchmove', this.eventData);\n    }\n};\n\n/**\n * Grabs an interaction data object from the internal pool\n *\n * @param touchEvent {EventData} The touch event we need to pair with an interactionData object\n *\n * @private\n */\nInteractionManager.prototype.getTouchData = function (touchEvent)\n{\n    var touchData = this.interactiveDataPool.pop();\n\n    if(!touchData)\n    {\n        touchData = new InteractionData();\n    }\n\n    touchData.identifier = touchEvent.identifier;\n    this.mapPositionToPoint( touchData.global, touchEvent.clientX, touchEvent.clientY );\n\n    if(navigator.isCocoonJS)\n    {\n        touchData.global.x = touchData.global.x / this.resolution;\n        touchData.global.y = touchData.global.y / this.resolution;\n    }\n\n    touchEvent.globalX = touchData.global.x;\n    touchEvent.globalY = touchData.global.y;\n\n    return touchData;\n};\n\n/**\n * Returns an interaction data object to the internal pool\n *\n * @param touchData {PIXI.interaction.InteractionData} The touch data object we want to return to the pool\n *\n * @private\n */\nInteractionManager.prototype.returnTouchData = function ( touchData )\n{\n    this.interactiveDataPool.push( touchData );\n};\n\n/**\n * Destroys the interaction manager\n *\n */\nInteractionManager.prototype.destroy = function () {\n    this.removeEvents();\n\n    this.renderer = null;\n\n    this.mouse = null;\n\n    this.eventData = null;\n\n    this.interactiveDataPool = null;\n\n    this.interactionDOMElement = null;\n\n    this.onMouseUp = null;\n    this.processMouseUp = null;\n\n\n    this.onMouseDown = null;\n    this.processMouseDown = null;\n\n    this.onMouseMove = null;\n    this.processMouseMove = null;\n\n    this.onMouseOut = null;\n    this.processMouseOverOut = null;\n\n\n    this.onTouchStart = null;\n    this.processTouchStart = null;\n\n    this.onTouchEnd = null;\n    this.processTouchEnd = null;\n\n    this.onTouchMove = null;\n    this.processTouchMove = null;\n\n    this._tempPoint = null;\n};\n\ncore.WebGLRenderer.registerPlugin('interaction', InteractionManager);\ncore.CanvasRenderer.registerPlugin('interaction', InteractionManager);\n\n},{\"../core\":29,\"./InteractionData\":116,\"./interactiveTarget\":119}],118:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI interactions library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI.interaction\n */\nmodule.exports = {\n    InteractionData:    require('./InteractionData'),\n    InteractionManager: require('./InteractionManager'),\n    interactiveTarget:  require('./interactiveTarget')\n};\n\n},{\"./InteractionData\":116,\"./InteractionManager\":117,\"./interactiveTarget\":119}],119:[function(require,module,exports){\n/**\n * Default property values of interactive objects\n * used by {@link PIXI.interaction.InteractionManager}.\n *\n * @mixin\n * @memberof PIXI.interaction\n * @example\n *      function MyObject() {}\n *\n *      Object.assign(\n *          MyObject.prototype,\n *          PIXI.interaction.interactiveTarget\n *      );\n */\nvar interactiveTarget = {\n    /**\n     * @todo Needs docs.\n     */\n    interactive: false,\n    /**\n     * @todo Needs docs.\n     */\n    buttonMode: false,\n    /**\n     * @todo Needs docs.\n     */\n    interactiveChildren: true,\n    /**\n     * @todo Needs docs.\n     */\n    defaultCursor: 'pointer',\n\n    // some internal checks..\n\n    /**\n     * @todo Needs docs.\n     * @private\n     */\n    _over: false,\n    /**\n     * @todo Needs docs.\n     * @private\n     */\n    _touchDown: false\n};\n\nmodule.exports = interactiveTarget;\n\n},{}],120:[function(require,module,exports){\nvar Resource = require('resource-loader').Resource,\n    core = require('../core'),\n    extras = require('../extras'),\n    path = require('path');\n\n\nfunction parse(resource, texture) {\n    var data = {};\n    var info = resource.data.getElementsByTagName('info')[0];\n    var common = resource.data.getElementsByTagName('common')[0];\n\n    data.font = info.getAttribute('face');\n    data.size = parseInt(info.getAttribute('size'), 10);\n    data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10);\n    data.chars = {};\n\n    //parse letters\n    var letters = resource.data.getElementsByTagName('char');\n\n    for (var i = 0; i < letters.length; i++)\n    {\n        var charCode = parseInt(letters[i].getAttribute('id'), 10);\n\n        var textureRect = new core.Rectangle(\n            parseInt(letters[i].getAttribute('x'), 10) + texture.frame.x,\n            parseInt(letters[i].getAttribute('y'), 10) + texture.frame.y,\n            parseInt(letters[i].getAttribute('width'), 10),\n            parseInt(letters[i].getAttribute('height'), 10)\n        );\n\n        data.chars[charCode] = {\n            xOffset: parseInt(letters[i].getAttribute('xoffset'), 10),\n            yOffset: parseInt(letters[i].getAttribute('yoffset'), 10),\n            xAdvance: parseInt(letters[i].getAttribute('xadvance'), 10),\n            kerning: {},\n            texture: new core.Texture(texture.baseTexture, textureRect)\n\n        };\n    }\n\n    //parse kernings\n    var kernings = resource.data.getElementsByTagName('kerning');\n    for (i = 0; i < kernings.length; i++)\n    {\n        var first = parseInt(kernings[i].getAttribute('first'), 10);\n        var second = parseInt(kernings[i].getAttribute('second'), 10);\n        var amount = parseInt(kernings[i].getAttribute('amount'), 10);\n\n        if(data.chars[second])\n        {\n            data.chars[second].kerning[first] = amount;\n        }\n    }\n\n    resource.bitmapFont = data;\n\n    // I'm leaving this as a temporary fix so we can test the bitmap fonts in v3\n    // but it's very likely to change\n    extras.BitmapText.fonts[data.font] = data;\n}\n\n\nmodule.exports = function ()\n{\n    return function (resource, next)\n    {\n        // skip if no data or not xml data\n        if (!resource.data || !resource.isXml)\n        {\n            return next();\n        }\n\n        // skip if not bitmap font data, using some silly duck-typing\n        if (\n            resource.data.getElementsByTagName('page').length === 0 ||\n            resource.data.getElementsByTagName('info').length === 0 ||\n            resource.data.getElementsByTagName('info')[0].getAttribute('face') === null\n            )\n        {\n            return next();\n        }\n\n        var xmlUrl = path.dirname(resource.url);\n\n        if (xmlUrl === '.') {\n            xmlUrl = '';\n        }\n\n        if (this.baseUrl && xmlUrl) {\n            // if baseurl has a trailing slash then add one to xmlUrl so the replace works below\n            if (this.baseUrl.charAt(this.baseUrl.length - 1) === '/') {\n                xmlUrl += '/';\n            }\n\n            // remove baseUrl from xmlUrl\n            xmlUrl = xmlUrl.replace(this.baseUrl, '');\n        }\n\n        // if there is an xmlUrl now, it needs a trailing slash. Ensure that it does if the string isn't empty.\n        if (xmlUrl && xmlUrl.charAt(xmlUrl.length - 1) !== '/') {\n            xmlUrl += '/';\n        }\n        var textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');\n        if (core.utils.TextureCache[textureUrl]) {\n            //reuse existing texture\n            parse(resource, core.utils.TextureCache[textureUrl]);\n            next();\n        }\n        else {\n            var loadOptions = {\n                crossOrigin: resource.crossOrigin,\n                loadType: Resource.LOAD_TYPE.IMAGE,\n                metadata: resource.metadata.imageMetadata\n            };\n            // load the texture for the font\n            this.add(resource.name + '_image', textureUrl, loadOptions, function (res) {\n                parse(resource, res.texture);\n                next();\n            });\n        }\n    };\n};\n\n},{\"../core\":29,\"../extras\":86,\"path\":2,\"resource-loader\":16}],121:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI loaders library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI.loaders\n */\nmodule.exports = {\n    Loader:             require('./loader'),\n\n    // parsers\n    bitmapFontParser:   require('./bitmapFontParser'),\n    spritesheetParser:  require('./spritesheetParser'),\n    textureParser:      require('./textureParser'),\n    Resource:           require('resource-loader').Resource\n};\n\n},{\"./bitmapFontParser\":120,\"./loader\":122,\"./spritesheetParser\":123,\"./textureParser\":124,\"resource-loader\":16}],122:[function(require,module,exports){\nvar ResourceLoader = require('resource-loader'),\n    textureParser = require('./textureParser'),\n    spritesheetParser = require('./spritesheetParser'),\n    bitmapFontParser = require('./bitmapFontParser');\n\n/**\n *\n * The new loader, extends Resource Loader by Chad Engler : https://github.com/englercj/resource-loader\n *\n * ```js\n * var loader = PIXI.loader; // pixi exposes a premade instance for you to use.\n * //or\n * var loader = new PIXI.loaders.Loader(); // you can also create your own if you want\n *\n * loader.add('bunny',\"data/bunny.png\");\n *\n * loader.once('complete',onAssetsLoaded);\n *\n * loader.load();\n * ```\n *\n * @class\n * @extends PIXI.ResourceLoader\n * @memberof PIXI.loaders\n * @param [baseUrl=''] {string} The base url for all resources loaded by this loader.\n * @param [concurrency=10] {number} The number of resources to load concurrently.\n */\nfunction Loader(baseUrl, concurrency)\n{\n    ResourceLoader.call(this, baseUrl, concurrency);\n\n    for (var i = 0; i < Loader._pixiMiddleware.length; ++i) {\n        this.use(Loader._pixiMiddleware[i]());\n    }\n}\n\nLoader.prototype = Object.create(ResourceLoader.prototype);\nLoader.prototype.constructor = Loader;\n\nmodule.exports = Loader;\n\nLoader._pixiMiddleware = [\n    // parse any blob into more usable objects (e.g. Image)\n    ResourceLoader.middleware.parsing.blob,\n    // parse any Image objects into textures\n    textureParser,\n    // parse any spritesheet data into multiple textures\n    spritesheetParser,\n    // parse any spritesheet data into multiple textures\n    bitmapFontParser\n];\n\nLoader.addPixiMiddleware = function (fn) {\n    Loader._pixiMiddleware.push(fn);\n};\n\n// Add custom extentions\nvar Resource = ResourceLoader.Resource;\n\nResource.setExtensionXhrType('fnt', Resource.XHR_RESPONSE_TYPE.DOCUMENT);\n\n},{\"./bitmapFontParser\":120,\"./spritesheetParser\":123,\"./textureParser\":124,\"resource-loader\":16}],123:[function(require,module,exports){\nvar Resource = require('resource-loader').Resource,\n    path = require('path'),\n    core = require('../core'),\n    async = require('async');\n\nvar BATCH_SIZE = 1000;\n\nmodule.exports = function ()\n{\n    return function (resource, next)\n    {\n        var imageResourceName = resource.name + '_image';\n\n        // skip if no data, its not json, it isn't spritesheet data, or the image resource already exists\n        if (!resource.data || !resource.isJson || !resource.data.frames || this.resources[imageResourceName])\n        {\n            return next();\n        }\n\n        var loadOptions = {\n            crossOrigin: resource.crossOrigin,\n            loadType: Resource.LOAD_TYPE.IMAGE,\n            metadata: resource.metadata.imageMetadata\n        };\n\n        var route = path.dirname(resource.url.replace(this.baseUrl, ''));\n\n        // load the image for this sheet\n        this.add(imageResourceName, route + '/' + resource.data.meta.image, loadOptions, function (res)\n        {\n            resource.textures = {};\n\n            var frames = resource.data.frames;\n            var frameKeys = Object.keys(frames);\n            var resolution = core.utils.getResolutionOfUrl(resource.url);\n            var batchIndex = 0;\n\n            function processFrames(initialFrameIndex, maxFrames)\n            {\n                var frameIndex = initialFrameIndex;\n\n                while (frameIndex - initialFrameIndex < maxFrames && frameIndex < frameKeys.length)\n                {\n                    var frame = frames[frameKeys[frameIndex]];\n                    var rect = frame.frame;\n\n                    if (rect)\n                    {\n                        var size = null;\n                        var trim = null;\n\n                        if (frame.rotated)\n                        {\n                            size = new core.Rectangle(rect.x, rect.y, rect.h, rect.w);\n                        }\n                        else\n                        {\n                            size = new core.Rectangle(rect.x, rect.y, rect.w, rect.h);\n                        }\n\n                        //  Check to see if the sprite is trimmed\n                        if (frame.trimmed)\n                        {\n                            trim = new core.Rectangle(\n                                frame.spriteSourceSize.x / resolution,\n                                frame.spriteSourceSize.y / resolution,\n                                frame.sourceSize.w / resolution,\n                                frame.sourceSize.h / resolution\n                            );\n                        }\n\n                        // flip the width and height!\n                        if (frame.rotated)\n                        {\n                            var temp = size.width;\n                            size.width = size.height;\n                            size.height = temp;\n                        }\n\n                        size.x /= resolution;\n                        size.y /= resolution;\n                        size.width /= resolution;\n                        size.height /= resolution;\n\n                        resource.textures[frameKeys[frameIndex]] = new core.Texture(res.texture.baseTexture, size, size.clone(), trim, frame.rotated);\n\n                        // lets also add the frame to pixi's global cache for fromFrame and fromImage functions\n                        core.utils.TextureCache[frameKeys[frameIndex]] = resource.textures[frameKeys[frameIndex]];\n                    }\n                    frameIndex++;\n                }\n            }\n\n            function shouldProcessNextBatch()\n            {\n                return batchIndex * BATCH_SIZE < frameKeys.length;\n            }\n\n            function processNextBatch(done)\n            {\n                processFrames(batchIndex * BATCH_SIZE, BATCH_SIZE);\n                batchIndex++;\n                setTimeout(done, 0);\n            }\n\n            if (frameKeys.length <= BATCH_SIZE)\n            {\n                processFrames(0, BATCH_SIZE);\n                next();\n            }\n            else\n            {\n                async.whilst(shouldProcessNextBatch, processNextBatch, next);\n            }\n        });\n    };\n};\n\n},{\"../core\":29,\"async\":1,\"path\":2,\"resource-loader\":16}],124:[function(require,module,exports){\nvar core = require('../core');\n\nmodule.exports = function ()\n{\n    return function (resource, next)\n    {\n        // create a new texture if the data is an Image object\n        if (resource.data && resource.isImage)\n        {\n            var baseTexture = new core.BaseTexture(resource.data, null, core.utils.getResolutionOfUrl(resource.url));\n            baseTexture.imageUrl = resource.url;\n            resource.texture = new core.Texture(baseTexture);\n            // lets also add the frame to pixi's global cache for fromFrame and fromImage fucntions\n            core.utils.BaseTextureCache[resource.url] = baseTexture;\n            core.utils.TextureCache[resource.url] = resource.texture;\n        }\n\n        next();\n    };\n};\n\n},{\"../core\":29}],125:[function(require,module,exports){\nvar core = require('../core'),\n    tempPoint = new core.Point(),\n    tempPolygon = new core.Polygon();\n\n/**\n * Base mesh class\n * @class\n * @extends PIXI.Container\n * @memberof PIXI.mesh\n * @param texture {PIXI.Texture} The texture to use\n * @param [vertices] {Float32Array} if you want to specify the vertices\n * @param [uvs] {Float32Array} if you want to specify the uvs\n * @param [indices] {Uint16Array} if you want to specify the indices\n * @param [drawMode] {number} the drawMode, can be any of the Mesh.DRAW_MODES consts\n */\nfunction Mesh(texture, vertices, uvs, indices, drawMode)\n{\n    core.Container.call(this);\n\n    /**\n     * The texture of the Mesh\n     *\n     * @member {PIXI.Texture}\n     * @private\n     */\n    this._texture = null;\n\n    /**\n     * The Uvs of the Mesh\n     *\n     * @member {Float32Array}\n     */\n    this.uvs = uvs || new Float32Array([0, 0,\n        1, 0,\n        1, 1,\n        0, 1]);\n\n    /**\n     * An array of vertices\n     *\n     * @member {Float32Array}\n     */\n    this.vertices = vertices || new Float32Array([0, 0,\n        100, 0,\n        100, 100,\n        0, 100]);\n\n    /*\n     * @member {Uint16Array} An array containing the indices of the vertices\n     */\n    //  TODO auto generate this based on draw mode!\n    this.indices = indices || new Uint16Array([0, 1, 3, 2]);\n\n    /**\n     * Whether the Mesh is dirty or not\n     *\n     * @member {boolean}\n     */\n    this.dirty = true;\n\n    /**\n     * The blend mode to be applied to the sprite. Set to `PIXI.BLEND_MODES.NORMAL` to remove any blend mode.\n     *\n     * @member {number}\n     * @default PIXI.BLEND_MODES.NORMAL\n     * @see PIXI.BLEND_MODES\n     */\n    this.blendMode = core.BLEND_MODES.NORMAL;\n\n    /**\n     * Triangles in canvas mode are automatically antialiased, use this value to force triangles to overlap a bit with each other.\n     *\n     * @member {number}\n     */\n    this.canvasPadding = 0;\n\n    /**\n     * The way the Mesh should be drawn, can be any of the {@link PIXI.mesh.Mesh.DRAW_MODES} consts\n     *\n     * @member {number}\n     * @see PIXI.mesh.Mesh.DRAW_MODES\n     */\n    this.drawMode = drawMode || Mesh.DRAW_MODES.TRIANGLE_MESH;\n\n    // run texture setter;\n    this.texture = texture;\n\n     /**\n     * The default shader that is used if a mesh doesn't have a more specific one.\n     *\n     * @member {PIXI.Shader}\n     */\n    this.shader = null;\n}\n\n// constructor\nMesh.prototype = Object.create(core.Container.prototype);\nMesh.prototype.constructor = Mesh;\nmodule.exports = Mesh;\n\nObject.defineProperties(Mesh.prototype, {\n    /**\n     * The texture that the sprite is using\n     *\n     * @member {PIXI.Texture}\n     * @memberof PIXI.mesh.Mesh#\n     */\n    texture: {\n        get: function ()\n        {\n            return  this._texture;\n        },\n        set: function (value)\n        {\n            if (this._texture === value)\n            {\n                return;\n            }\n\n            this._texture = value;\n\n            if (value)\n            {\n                // wait for the texture to load\n                if (value.baseTexture.hasLoaded)\n                {\n                    this._onTextureUpdate();\n                }\n                else\n                {\n                    value.once('update', this._onTextureUpdate, this);\n                }\n            }\n        }\n    }\n});\n\n/**\n * Renders the object using the WebGL renderer\n *\n * @param renderer {PIXI.WebGLRenderer} a reference to the WebGL renderer\n * @private\n */\nMesh.prototype._renderWebGL = function (renderer)\n{\n    renderer.setObjectRenderer(renderer.plugins.mesh);\n    renderer.plugins.mesh.render(this);\n};\n\n/**\n * Renders the object using the Canvas renderer\n *\n * @param renderer {PIXI.CanvasRenderer}\n * @private\n */\nMesh.prototype._renderCanvas = function (renderer)\n{\n    var context = renderer.context;\n\n    var transform = this.worldTransform;\n    var res = renderer.resolution;\n\n    if (renderer.roundPixels)\n    {\n        context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, (transform.tx * res) | 0, (transform.ty * res) | 0);\n    }\n    else\n    {\n        context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, transform.tx * res, transform.ty * res);\n    }\n\n    if (this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH)\n    {\n        this._renderCanvasTriangleMesh(context);\n    }\n    else\n    {\n        this._renderCanvasTriangles(context);\n    }\n};\n\n/**\n * Draws the object in Triangle Mesh mode using canvas\n *\n * @param context {CanvasRenderingContext2D} the current drawing context\n * @private\n */\nMesh.prototype._renderCanvasTriangleMesh = function (context)\n{\n    // draw triangles!!\n    var vertices = this.vertices;\n    var uvs = this.uvs;\n\n    var length = vertices.length / 2;\n    // this.count++;\n\n    for (var i = 0; i < length - 2; i++)\n    {\n        // draw some triangles!\n        var index = i * 2;\n        this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4));\n    }\n};\n\n/**\n * Draws the object in triangle mode using canvas\n *\n * @param context {CanvasRenderingContext2D} the current drawing context\n * @private\n */\nMesh.prototype._renderCanvasTriangles = function (context)\n{\n    // draw triangles!!\n    var vertices = this.vertices;\n    var uvs = this.uvs;\n    var indices = this.indices;\n\n    var length = indices.length;\n    // this.count++;\n\n    for (var i = 0; i < length; i += 3)\n    {\n        // draw some triangles!\n        var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2;\n        this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2);\n    }\n};\n\n/**\n * Draws one of the triangles that form this Mesh\n *\n * @param context {CanvasRenderingContext2D} the current drawing context\n * @param vertices {Float32Array} a reference to the vertices of the Mesh\n * @param uvs {Float32Array} a reference to the uvs of the Mesh\n * @param index0 {number} the index of the first vertex\n * @param index1 {number} the index of the second vertex\n * @param index2 {number} the index of the third vertex\n * @private\n */\nMesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2)\n{\n    var base = this._texture.baseTexture;\n    var textureSource = base.source;\n    var textureWidth = base.width;\n    var textureHeight = base.height;\n\n    var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2];\n    var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1];\n\n    var u0 = uvs[index0] * base.width, u1 = uvs[index1] * base.width, u2 = uvs[index2] * base.width;\n    var v0 = uvs[index0 + 1] * base.height, v1 = uvs[index1 + 1] * base.height, v2 = uvs[index2 + 1] * base.height;\n\n    if (this.canvasPadding > 0)\n    {\n        var paddingX = this.canvasPadding / this.worldTransform.a;\n        var paddingY = this.canvasPadding / this.worldTransform.d;\n        var centerX = (x0 + x1 + x2) / 3;\n        var centerY = (y0 + y1 + y2) / 3;\n\n        var normX = x0 - centerX;\n        var normY = y0 - centerY;\n\n        var dist = Math.sqrt(normX * normX + normY * normY);\n        x0 = centerX + (normX / dist) * (dist + paddingX);\n        y0 = centerY + (normY / dist) * (dist + paddingY);\n\n        //\n\n        normX = x1 - centerX;\n        normY = y1 - centerY;\n\n        dist = Math.sqrt(normX * normX + normY * normY);\n        x1 = centerX + (normX / dist) * (dist + paddingX);\n        y1 = centerY + (normY / dist) * (dist + paddingY);\n\n        normX = x2 - centerX;\n        normY = y2 - centerY;\n\n        dist = Math.sqrt(normX * normX + normY * normY);\n        x2 = centerX + (normX / dist) * (dist + paddingX);\n        y2 = centerY + (normY / dist) * (dist + paddingY);\n    }\n\n    context.save();\n    context.beginPath();\n\n\n    context.moveTo(x0, y0);\n    context.lineTo(x1, y1);\n    context.lineTo(x2, y2);\n\n    context.closePath();\n\n    context.clip();\n\n    // Compute matrix transform\n    var delta =  (u0 * v1)      + (v0 * u2)      + (u1 * v2)      - (v1 * u2)      - (v0 * u1)      - (u0 * v2);\n    var deltaA = (x0 * v1)      + (v0 * x2)      + (x1 * v2)      - (v1 * x2)      - (v0 * x1)      - (x0 * v2);\n    var deltaB = (u0 * x1)      + (x0 * u2)      + (u1 * x2)      - (x1 * u2)      - (x0 * u1)      - (u0 * x2);\n    var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2);\n    var deltaD = (y0 * v1)      + (v0 * y2)      + (y1 * v2)      - (v1 * y2)      - (v0 * y1)      - (y0 * v2);\n    var deltaE = (u0 * y1)      + (y0 * u2)      + (u1 * y2)      - (y1 * u2)      - (y0 * u1)      - (u0 * y2);\n    var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2);\n\n    context.transform(deltaA / delta, deltaD / delta,\n        deltaB / delta, deltaE / delta,\n        deltaC / delta, deltaF / delta);\n\n    context.drawImage(textureSource, 0, 0, textureWidth * base.resolution, textureHeight * base.resolution, 0, 0, textureWidth, textureHeight);\n    context.restore();\n};\n\n\n\n/**\n * Renders a flat Mesh\n *\n * @param Mesh {PIXI.mesh.Mesh} The Mesh to render\n * @private\n */\nMesh.prototype.renderMeshFlat = function (Mesh)\n{\n    var context = this.context;\n    var vertices = Mesh.vertices;\n\n    var length = vertices.length/2;\n    // this.count++;\n\n    context.beginPath();\n    for (var i=1; i < length-2; i++)\n    {\n        // draw some triangles!\n        var index = i*2;\n\n        var x0 = vertices[index],   x1 = vertices[index+2], x2 = vertices[index+4];\n        var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5];\n\n        context.moveTo(x0, y0);\n        context.lineTo(x1, y1);\n        context.lineTo(x2, y2);\n    }\n\n    context.fillStyle = '#FF0000';\n    context.fill();\n    context.closePath();\n};\n\n/**\n * When the texture is updated, this event will fire to update the scale and frame\n *\n * @param event\n * @private\n */\nMesh.prototype._onTextureUpdate = function ()\n{\n    this.updateFrame = true;\n};\n\n/**\n * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account.\n *\n * @param matrix {PIXI.Matrix} the transformation matrix of the sprite\n * @return {PIXI.Rectangle} the framing rectangle\n */\nMesh.prototype.getBounds = function (matrix)\n{\n    if (!this._currentBounds) {\n        var worldTransform = matrix || this.worldTransform;\n\n        var a = worldTransform.a;\n        var b = worldTransform.b;\n        var c = worldTransform.c;\n        var d = worldTransform.d;\n        var tx = worldTransform.tx;\n        var ty = worldTransform.ty;\n\n        var maxX = -Infinity;\n        var maxY = -Infinity;\n\n        var minX = Infinity;\n        var minY = Infinity;\n\n        var vertices = this.vertices;\n        for (var i = 0, n = vertices.length; i < n; i += 2) {\n            var rawX = vertices[i], rawY = vertices[i + 1];\n            var x = (a * rawX) + (c * rawY) + tx;\n            var y = (d * rawY) + (b * rawX) + ty;\n\n            minX = x < minX ? x : minX;\n            minY = y < minY ? y : minY;\n\n            maxX = x > maxX ? x : maxX;\n            maxY = y > maxY ? y : maxY;\n        }\n\n        if (minX === -Infinity || maxY === Infinity) {\n            return core.Rectangle.EMPTY;\n        }\n\n        var bounds = this._bounds;\n\n        bounds.x = minX;\n        bounds.width = maxX - minX;\n\n        bounds.y = minY;\n        bounds.height = maxY - minY;\n\n        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate\n        this._currentBounds = bounds;\n    }\n\n    return this._currentBounds;\n};\n\n/**\n * Tests if a point is inside this mesh. Works only for TRIANGLE_MESH\n *\n * @param point {PIXI.Point} the point to test\n * @return {boolean} the result of the test\n */\nMesh.prototype.containsPoint = function( point ) {\n    if (!this.getBounds().contains(point.x, point.y)) {\n        return false;\n    }\n    this.worldTransform.applyInverse(point,  tempPoint);\n\n    var vertices = this.vertices;\n    var points = tempPolygon.points;\n    var i, len;\n\n    if (this.drawMode === Mesh.DRAW_MODES.TRIANGLES) {\n        var indices = this.indices;\n        len = this.indices.length;\n        //TODO: inline this.\n        for (i=0;i<len;i+=3) {\n            var ind0 = indices[i]*2, ind1 = indices[i+1]*2, ind2 = indices[i+2]*2;\n            points[0] = vertices[ind0];\n            points[1] = vertices[ind0+1];\n            points[2] = vertices[ind1];\n            points[3] = vertices[ind1+1];\n            points[4] = vertices[ind2];\n            points[5] = vertices[ind2+1];\n            if (tempPolygon.contains(tempPoint.x, tempPoint.y)) {\n                return true;\n            }\n        }\n    } else {\n        len = vertices.length;\n        for (i=0;i<len;i+=6) {\n            points[0] = vertices[i];\n            points[1] = vertices[i+1];\n            points[2] = vertices[i+2];\n            points[3] = vertices[i+3];\n            points[4] = vertices[i+4];\n            points[5] = vertices[i+5];\n            if (tempPolygon.contains(tempPoint.x, tempPoint.y)) {\n                return true;\n            }\n        }\n    }\n    return false;\n};\n\n/**\n * Different drawing buffer modes supported\n *\n * @static\n * @constant\n * @property {object} DRAW_MODES\n * @property {number} DRAW_MODES.TRIANGLE_MESH\n * @property {number} DRAW_MODES.TRIANGLES\n */\nMesh.DRAW_MODES = {\n    TRIANGLE_MESH: 0,\n    TRIANGLES: 1\n};\n\n},{\"../core\":29}],126:[function(require,module,exports){\nvar Mesh = require('./Mesh');\n\n/**\n * The Plane allows you to draw a texture across several points and them manipulate these points\n *\n *```js\n * for (var i = 0; i < 20; i++) {\n *     points.push(new PIXI.Point(i * 50, 0));\n * };\n * var Plane = new PIXI.Plane(PIXI.Texture.fromImage(\"snake.png\"), points);\n *  ```\n *\n * @class\n * @extends PIXI.mesh.Mesh\n * @memberof PIXI.mesh\n * @param {PIXI.Texture} texture - The texture to use on the Plane.\n * @param {int} segmentsX - The number ox x segments\n * @param {int} segmentsY - The number of y segments\n *\n */\nfunction Plane(texture, segmentsX, segmentsY)\n{\n    Mesh.call(this, texture);\n\n    /**\n     * Tracker for if the Plane is ready to be drawn. Needed because Mesh ctor can\n     * call _onTextureUpdated which could call refresh too early.\n     *\n     * @member {boolean}\n     * @private\n     */\n    this._ready = true;\n\n    this.segmentsX =  segmentsX || 10;\n    this.segmentsY = segmentsY || 10;\n\n    this.drawMode = Mesh.DRAW_MODES.TRIANGLES;\n    this.refresh();\n\n}\n\n\n// constructor\nPlane.prototype = Object.create( Mesh.prototype );\nPlane.prototype.constructor = Plane;\nmodule.exports = Plane;\n\n/**\n * Refreshes\n *\n */\nPlane.prototype.refresh = function()\n{\n    var total = this.segmentsX * this.segmentsY;\n    var verts = [];\n    var colors = [];\n    var uvs = [];\n    var indices = [];\n    var texture = this.texture;\n\n  //  texture.width = 800 texture.width || 800;\n //   texture.height = 800//texture.height || 800;\n\n    var segmentsXSub = this.segmentsX - 1;\n    var segmentsYSub = this.segmentsY - 1;\n    var i = 0;\n\n    var sizeX = texture.width / segmentsXSub;\n    var sizeY = texture.height / segmentsYSub;\n\n    for (i = 0; i < total; i++) {\n\n        var x = (i % this.segmentsX);\n        var y = ( (i / this.segmentsX ) | 0 );\n\n\n        verts.push((x * sizeX),\n                   (y * sizeY));\n\n        // this works for rectangular textures. \n        uvs.push(texture._uvs.x0 + (texture._uvs.x1 - texture._uvs.x0) * (x / (this.segmentsX-1)), texture._uvs.y0 + (texture._uvs.y3-texture._uvs.y0) * (y/ (this.segmentsY-1)));\n      }\n\n    //  cons\n\n    var totalSub = segmentsXSub * segmentsYSub;\n\n    for (i = 0; i < totalSub; i++) {\n\n        var xpos = i % segmentsXSub;\n        var ypos = (i / segmentsXSub ) | 0;\n\n\n        var  value = (ypos * this.segmentsX) + xpos;\n        var  value2 = (ypos * this.segmentsX) + xpos + 1;\n        var  value3 = ((ypos+1) * this.segmentsX) + xpos;\n        var  value4 = ((ypos+1) * this.segmentsX) + xpos + 1;\n\n        indices.push(value, value2, value3);\n        indices.push(value2, value4, value3);\n    }\n\n\n    //console.log(indices)\n    this.vertices = new Float32Array(verts);\n    this.uvs = new Float32Array(uvs);\n    this.colors = new Float32Array(colors);\n    this.indices = new Uint16Array(indices);\n};\n\n/**\n * Clear texture UVs when new texture is set\n *\n * @private\n */\nPlane.prototype._onTextureUpdate = function ()\n{\n    Mesh.prototype._onTextureUpdate.call(this);\n\n    // wait for the Plane ctor to finish before calling refresh\n    if (this._ready) {\n        this.refresh();\n    }\n};\n\n},{\"./Mesh\":125}],127:[function(require,module,exports){\nvar Mesh = require('./Mesh');\nvar core = require('../core');\n\n/**\n * The rope allows you to draw a texture across several points and them manipulate these points\n *\n *```js\n * for (var i = 0; i < 20; i++) {\n *     points.push(new PIXI.Point(i * 50, 0));\n * };\n * var rope = new PIXI.Rope(PIXI.Texture.fromImage(\"snake.png\"), points);\n *  ```\n *\n * @class\n * @extends PIXI.mesh.Mesh\n * @memberof PIXI.mesh\n * @param {PIXI.Texture} texture - The texture to use on the rope.\n * @param {PIXI.Point[]} points - An array of {@link PIXI.Point} objects to construct this rope.\n *\n */\nfunction Rope(texture, points)\n{\n    Mesh.call(this, texture);\n\n    /*\n     * @member {PIXI.Point[]} An array of points that determine the rope\n     */\n    this.points = points;\n\n    /*\n     * @member {Float32Array} An array of vertices used to construct this rope.\n     */\n    this.vertices = new Float32Array(points.length * 4);\n\n    /*\n     * @member {Float32Array} The WebGL Uvs of the rope.\n     */\n    this.uvs = new Float32Array(points.length * 4);\n\n    /*\n     * @member {Float32Array} An array containing the color components\n     */\n    this.colors = new Float32Array(points.length * 2);\n\n    /*\n     * @member {Uint16Array} An array containing the indices of the vertices\n     */\n    this.indices = new Uint16Array(points.length * 2);\n\n    /**\n     * Tracker for if the rope is ready to be drawn. Needed because Mesh ctor can\n     * call _onTextureUpdated which could call refresh too early.\n     *\n     * @member {boolean}\n     * @private\n     */\n     this._ready = true;\n\n     this.refresh();\n}\n\n\n// constructor\nRope.prototype = Object.create(Mesh.prototype);\nRope.prototype.constructor = Rope;\nmodule.exports = Rope;\n\n/**\n * Refreshes\n *\n */\nRope.prototype.refresh = function ()\n{\n    var points = this.points;\n\n    // if too little points, or texture hasn't got UVs set yet just move on.\n    if (points.length < 1 || !this._texture._uvs)\n    {\n        return;\n    }\n\n    var uvs = this.uvs;\n\n    var indices = this.indices;\n    var colors = this.colors;\n\n    var textureUvs = this._texture._uvs;\n    var offset = new core.Point(textureUvs.x0, textureUvs.y0);\n    var factor = new core.Point(textureUvs.x2 - textureUvs.x0, textureUvs.y2 - textureUvs.y0);\n\n    uvs[0] = 0 + offset.x;\n    uvs[1] = 0 + offset.y;\n    uvs[2] = 0 + offset.x;\n    uvs[3] = 1 * factor.y + offset.y;\n\n    colors[0] = 1;\n    colors[1] = 1;\n\n    indices[0] = 0;\n    indices[1] = 1;\n\n    var total = points.length,\n        point, index, amount;\n\n    for (var i = 1; i < total; i++)\n    {\n        point = points[i];\n        index = i * 4;\n        // time to do some smart drawing!\n        amount = i / (total-1);\n\n        uvs[index] = amount * factor.x + offset.x;\n        uvs[index+1] = 0 + offset.y;\n\n        uvs[index+2] = amount * factor.x + offset.x;\n        uvs[index+3] = 1 * factor.y + offset.y;\n\n        index = i * 2;\n        colors[index] = 1;\n        colors[index+1] = 1;\n\n        index = i * 2;\n        indices[index] = index;\n        indices[index + 1] = index + 1;\n    }\n\n    this.dirty = true;\n};\n\n/**\n * Clear texture UVs when new texture is set\n *\n * @private\n */\nRope.prototype._onTextureUpdate = function ()\n{\n    Mesh.prototype._onTextureUpdate.call(this);\n\n    // wait for the Rope ctor to finish before calling refresh\n    if (this._ready) {\n        this.refresh();\n    }\n};\n\n/**\n * Updates the object transform for rendering\n *\n * @private\n */\nRope.prototype.updateTransform = function ()\n{\n    var points = this.points;\n\n    if (points.length < 1)\n    {\n        return;\n    }\n\n    var lastPoint = points[0];\n    var nextPoint;\n    var perpX = 0;\n    var perpY = 0;\n\n    // this.count -= 0.2;\n\n    var vertices = this.vertices;\n    var total = points.length,\n        point, index, ratio, perpLength, num;\n\n    for (var i = 0; i < total; i++)\n    {\n        point = points[i];\n        index = i * 4;\n\n        if (i < points.length-1)\n        {\n            nextPoint = points[i+1];\n        }\n        else\n        {\n            nextPoint = point;\n        }\n\n        perpY = -(nextPoint.x - lastPoint.x);\n        perpX = nextPoint.y - lastPoint.y;\n\n        ratio = (1 - (i / (total-1))) * 10;\n\n        if (ratio > 1)\n        {\n            ratio = 1;\n        }\n\n        perpLength = Math.sqrt(perpX * perpX + perpY * perpY);\n        num = this._texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;\n        perpX /= perpLength;\n        perpY /= perpLength;\n\n        perpX *= num;\n        perpY *= num;\n\n        vertices[index] = point.x + perpX;\n        vertices[index+1] = point.y + perpY;\n        vertices[index+2] = point.x - perpX;\n        vertices[index+3] = point.y - perpY;\n\n        lastPoint = point;\n    }\n\n    this.containerUpdateTransform();\n};\n\n},{\"../core\":29,\"./Mesh\":125}],128:[function(require,module,exports){\n/**\n * @file        Main export of the PIXI extras library\n * @author      Mat Groves <mat@goodboydigital.com>\n * @copyright   2013-2015 GoodBoyDigital\n * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}\n */\n\n/**\n * @namespace PIXI.mesh\n */\nmodule.exports = {\n    Mesh:           require('./Mesh'),\n    Plane:           require('./Plane'),\n    Rope:           require('./Rope'),\n    MeshRenderer:   require('./webgl/MeshRenderer'),\n    MeshShader:     require('./webgl/MeshShader')\n};\n\n},{\"./Mesh\":125,\"./Plane\":126,\"./Rope\":127,\"./webgl/MeshRenderer\":129,\"./webgl/MeshShader\":130}],129:[function(require,module,exports){\nvar core = require('../../core'),\n    Mesh = require('../Mesh');\n\n/**\n * @author Mat Groves\n *\n * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/\n * for creating the original pixi version!\n * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer\n *\n * Heavily inspired by LibGDX's MeshRenderer:\n * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/MeshRenderer.java\n */\n\n/**\n *\n * @class\n * @private\n * @memberof PIXI.mesh\n * @extends PIXI.ObjectRenderer\n * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for.\n */\nfunction MeshRenderer(renderer)\n{\n    core.ObjectRenderer.call(this, renderer);\n\n\n    /**\n     * Holds the indices\n     *\n     * @member {Uint16Array}\n     */\n    \n    this.indices = new Uint16Array(15000);\n\n    //TODO this could be a single buffer shared amongst all renderers as we reuse this set up in most renderers\n    for (var i=0, j=0; i < 15000; i += 6, j += 4)\n    {\n        this.indices[i + 0] = j + 0;\n        this.indices[i + 1] = j + 1;\n        this.indices[i + 2] = j + 2;\n        this.indices[i + 3] = j + 0;\n        this.indices[i + 4] = j + 2;\n        this.indices[i + 5] = j + 3;\n    }\n\n    this.currentShader = null;\n}\n\nMeshRenderer.prototype = Object.create(core.ObjectRenderer.prototype);\nMeshRenderer.prototype.constructor = MeshRenderer;\nmodule.exports = MeshRenderer;\n\ncore.WebGLRenderer.registerPlugin('mesh', MeshRenderer);\n\n/**\n * Sets up the renderer context and necessary buffers.\n *\n * @private\n * @param gl {WebGLRenderingContext} the current WebGL drawing context\n */\nMeshRenderer.prototype.onContextChange = function ()\n{\n\n};\n\n/**\n * Renders the sprite object.\n *\n * @param mesh {PIXI.mesh.Mesh} the mesh to render\n */\nMeshRenderer.prototype.render = function (mesh)\n{\n    if(!mesh._vertexBuffer)\n    {\n        this._initWebGL(mesh);\n    }\n\n    var renderer = this.renderer,\n        gl = renderer.gl,\n        texture = mesh._texture.baseTexture,\n        shader = mesh.shader;// || renderer.shaderManager.plugins.meshShader;\n\n    var drawMode = mesh.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES;\n\n    renderer.blendModeManager.setBlendMode(mesh.blendMode);\n\n    //TODO cache custom state..\n    if (!shader)\n    {\n        shader = renderer.shaderManager.plugins.meshShader;\n    }\n    else\n    {\n        shader = shader.shaders[gl.id] || shader.getShader(renderer);// : shader;\n    }\n\n    this.renderer.shaderManager.setShader(shader);\n\n    shader.uniforms.translationMatrix.value = mesh.worldTransform.toArray(true);\n    shader.uniforms.projectionMatrix.value = renderer.currentRenderTarget.projectionMatrix.toArray(true);\n    shader.uniforms.alpha.value = mesh.worldAlpha;\n\n    shader.syncUniforms();\n\n    if (!mesh.dirty)\n    {\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer);\n        gl.bufferSubData(gl.ARRAY_BUFFER, 0, mesh.vertices);\n        gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0);\n\n        // update the uvs\n        gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer);\n        gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0);\n\n\n        gl.activeTexture(gl.TEXTURE0);\n\n       if (!texture._glTextures[gl.id])\n        {\n            this.renderer.updateTexture(texture);\n        }\n        else\n        {\n            // bind the current texture\n            gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);\n        }\n\n        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer);\n        gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, mesh.indices);\n    }\n    else\n    {\n\n        mesh.dirty = false;\n        gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0);\n\n        // update the uvs\n        gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, mesh.uvs, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0);\n\n         gl.activeTexture(gl.TEXTURE0);\n\n        if (!texture._glTextures[gl.id])\n        {\n            this.renderer.updateTexture(texture);\n        }\n        else\n        {\n            // bind the current texture\n            gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);\n        }\n\n        // dont need to upload!\n        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer);\n        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW);\n\n    }\n\n    gl.drawElements(drawMode, mesh.indices.length, gl.UNSIGNED_SHORT, 0);\n\n};\n\n/**\n * Prepares all the buffers to render this mesh\n * @param mesh {PIXI.mesh.Mesh} the mesh to render\n */\nMeshRenderer.prototype._initWebGL = function (mesh)\n{\n    // build the strip!\n    var gl = this.renderer.gl;\n\n    mesh._vertexBuffer = gl.createBuffer();\n    mesh._indexBuffer = gl.createBuffer();\n    mesh._uvBuffer = gl.createBuffer();\n\n\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.DYNAMIC_DRAW);\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER,  mesh.uvs, gl.STATIC_DRAW);\n\n    if(mesh.colors){\n        mesh._colorBuffer = gl.createBuffer();\n        gl.bindBuffer(gl.ARRAY_BUFFER, mesh._colorBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, mesh.colors, gl.STATIC_DRAW);\n    }\n\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW);\n};\n\n\n/**\n * Empties the current batch.\n *\n */\nMeshRenderer.prototype.flush = function ()\n{\n\n};\n\n/**\n * Starts a new mesh renderer.\n *\n */\nMeshRenderer.prototype.start = function ()\n{\n    \n\n    this.currentShader = null;\n};\n\n/**\n * Destroys the Mesh renderer\n *\n */\nMeshRenderer.prototype.destroy = function ()\n{\n    core.ObjectRenderer.prototype.destroy.call(this);\n};\n\n},{\"../../core\":29,\"../Mesh\":125}],130:[function(require,module,exports){\nvar core = require('../../core');\n\n/**\n * @class\n * @extends PIXI.Shader\n * @memberof PIXI.mesh\n * @param shaderManager {PIXI.ShaderManager} The WebGL shader manager this shader works for.\n */\nfunction MeshShader(shaderManager)\n{\n    core.Shader.call(this,\n        shaderManager,\n        // vertex shader\n        [\n            'precision lowp float;',\n            'attribute vec2 aVertexPosition;',\n            'attribute vec2 aTextureCoord;',\n\n            'uniform mat3 translationMatrix;',\n            'uniform mat3 projectionMatrix;',\n\n            'varying vec2 vTextureCoord;',\n\n            'void main(void){',\n            '   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',\n            '   vTextureCoord = aTextureCoord;',\n            '}'\n        ].join('\\n'),\n        [\n            'precision lowp float;',\n\n            'varying vec2 vTextureCoord;',\n            'uniform float alpha;',\n\n            'uniform sampler2D uSampler;',\n\n            'void main(void){',\n            '   gl_FragColor = texture2D(uSampler, vTextureCoord) * alpha ;',\n            '}'\n        ].join('\\n'),\n        // custom uniforms\n        {\n            alpha:  { type: '1f', value: 0 },\n            translationMatrix: { type: 'mat3', value: new Float32Array(9) },\n            projectionMatrix: { type: 'mat3', value: new Float32Array(9) }\n        },\n        // custom attributes\n        {\n            aVertexPosition:0,\n            aTextureCoord:0\n        }\n    );\n}\n\nMeshShader.prototype = Object.create(core.Shader.prototype);\nMeshShader.prototype.constructor = MeshShader;\nmodule.exports = MeshShader;\n\ncore.ShaderManager.registerPlugin('meshShader', MeshShader);\n\n},{\"../../core\":29}],131:[function(require,module,exports){\n// References:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\nif (!Math.sign)\n{\n    Math.sign = function (x) {\n        x = +x;\n        if (x === 0 || isNaN(x))\n        {\n            return x;\n        }\n        return x > 0 ? 1 : -1;\n    };\n}\n\n},{}],132:[function(require,module,exports){\n// References:\n// https://github.com/sindresorhus/object-assign\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\nif (!Object.assign)\n{\n    Object.assign = require('object-assign');\n}\n\n},{\"object-assign\":11}],133:[function(require,module,exports){\nrequire('./Object.assign');\nrequire('./requestAnimationFrame');\nrequire('./Math.sign');\n\n},{\"./Math.sign\":131,\"./Object.assign\":132,\"./requestAnimationFrame\":134}],134:[function(require,module,exports){\n(function (global){\n// References:\n// http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n// https://gist.github.com/1579671\n// http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision\n// https://gist.github.com/timhall/4078614\n// https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame\n\n// Expected to be used with Browserfiy\n// Browserify automatically detects the use of `global` and passes the\n// correct reference of `global`, `self`, and finally `window`\n\n// Date.now\nif (!(Date.now && Date.prototype.getTime)) {\n    Date.now = function now() {\n        return new Date().getTime();\n    };\n}\n\n// performance.now\nif (!(global.performance && global.performance.now)) {\n    var startTime = Date.now();\n    if (!global.performance) {\n        global.performance = {};\n    }\n    global.performance.now = function () {\n        return Date.now() - startTime;\n    };\n}\n\n// requestAnimationFrame\nvar lastTime = Date.now();\nvar vendors = ['ms', 'moz', 'webkit', 'o'];\n\nfor(var x = 0; x < vendors.length && !global.requestAnimationFrame; ++x) {\n    global.requestAnimationFrame = global[vendors[x] + 'RequestAnimationFrame'];\n    global.cancelAnimationFrame = global[vendors[x] + 'CancelAnimationFrame'] ||\n        global[vendors[x] + 'CancelRequestAnimationFrame'];\n}\n\nif (!global.requestAnimationFrame) {\n    global.requestAnimationFrame = function (callback) {\n        if (typeof callback !== 'function') {\n            throw new TypeError(callback + 'is not a function');\n        }\n\n        var currentTime = Date.now(),\n            delay = 16 + lastTime - currentTime;\n\n        if (delay < 0) {\n            delay = 0;\n        }\n\n        lastTime = currentTime;\n\n        return setTimeout(function () {\n            lastTime = Date.now();\n            callback(performance.now());\n        }, delay);\n    };\n}\n\nif (!global.cancelAnimationFrame) {\n    global.cancelAnimationFrame = function(id) {\n        clearTimeout(id);\n    };\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}]},{},[115])(115)\n});\n//# sourceMappingURL=pixi.js.map\n\n/*\n  html2canvas 0.5.0-alpha2 <http://html2canvas.hertzen.com>\n  Copyright (c) 2015 Niklas von Hertzen\n\n  Released under MIT License\n*/\n\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.html2canvas = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/*!\n * @overview es6-promise - a tiny implementation of Promises/A+.\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)\n * @license   Licensed under MIT license\n *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE\n * @version   2.3.0\n */\n\n(function() {\n    \"use strict\";\n    function lib$es6$promise$utils$$objectOrFunction(x) {\n      return typeof x === 'function' || (typeof x === 'object' && x !== null);\n    }\n\n    function lib$es6$promise$utils$$isFunction(x) {\n      return typeof x === 'function';\n    }\n\n    function lib$es6$promise$utils$$isMaybeThenable(x) {\n      return typeof x === 'object' && x !== null;\n    }\n\n    var lib$es6$promise$utils$$_isArray;\n    if (!Array.isArray) {\n      lib$es6$promise$utils$$_isArray = function (x) {\n        return Object.prototype.toString.call(x) === '[object Array]';\n      };\n    } else {\n      lib$es6$promise$utils$$_isArray = Array.isArray;\n    }\n\n    var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;\n    var lib$es6$promise$asap$$len = 0;\n    var lib$es6$promise$asap$$toString = {}.toString;\n    var lib$es6$promise$asap$$vertxNext;\n    var lib$es6$promise$asap$$customSchedulerFn;\n\n    var lib$es6$promise$asap$$asap = function asap(callback, arg) {\n      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;\n      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;\n      lib$es6$promise$asap$$len += 2;\n      if (lib$es6$promise$asap$$len === 2) {\n        // If len is 2, that means that we need to schedule an async flush.\n        // If additional callbacks are queued before the queue is flushed, they\n        // will be processed by this flush that we are scheduling.\n        if (lib$es6$promise$asap$$customSchedulerFn) {\n          lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);\n        } else {\n          lib$es6$promise$asap$$scheduleFlush();\n        }\n      }\n    }\n\n    function lib$es6$promise$asap$$setScheduler(scheduleFn) {\n      lib$es6$promise$asap$$customSchedulerFn = scheduleFn;\n    }\n\n    function lib$es6$promise$asap$$setAsap(asapFn) {\n      lib$es6$promise$asap$$asap = asapFn;\n    }\n\n    var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;\n    var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};\n    var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;\n    var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';\n\n    // test for web worker but not in IE10\n    var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&\n      typeof importScripts !== 'undefined' &&\n      typeof MessageChannel !== 'undefined';\n\n    // node\n    function lib$es6$promise$asap$$useNextTick() {\n      var nextTick = process.nextTick;\n      // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n      // setImmediate should be used instead instead\n      var version = process.versions.node.match(/^(?:(\\d+)\\.)?(?:(\\d+)\\.)?(\\*|\\d+)$/);\n      if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {\n        nextTick = setImmediate;\n      }\n      return function() {\n        nextTick(lib$es6$promise$asap$$flush);\n      };\n    }\n\n    // vertx\n    function lib$es6$promise$asap$$useVertxTimer() {\n      return function() {\n        lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);\n      };\n    }\n\n    function lib$es6$promise$asap$$useMutationObserver() {\n      var iterations = 0;\n      var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);\n      var node = document.createTextNode('');\n      observer.observe(node, { characterData: true });\n\n      return function() {\n        node.data = (iterations = ++iterations % 2);\n      };\n    }\n\n    // web worker\n    function lib$es6$promise$asap$$useMessageChannel() {\n      var channel = new MessageChannel();\n      channel.port1.onmessage = lib$es6$promise$asap$$flush;\n      return function () {\n        channel.port2.postMessage(0);\n      };\n    }\n\n    function lib$es6$promise$asap$$useSetTimeout() {\n      return function() {\n        setTimeout(lib$es6$promise$asap$$flush, 1);\n      };\n    }\n\n    var lib$es6$promise$asap$$queue = new Array(1000);\n    function lib$es6$promise$asap$$flush() {\n      for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {\n        var callback = lib$es6$promise$asap$$queue[i];\n        var arg = lib$es6$promise$asap$$queue[i+1];\n\n        callback(arg);\n\n        lib$es6$promise$asap$$queue[i] = undefined;\n        lib$es6$promise$asap$$queue[i+1] = undefined;\n      }\n\n      lib$es6$promise$asap$$len = 0;\n    }\n\n    function lib$es6$promise$asap$$attemptVertex() {\n      try {\n        var r = require;\n        var vertx = r('vertx');\n        lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;\n        return lib$es6$promise$asap$$useVertxTimer();\n      } catch(e) {\n        return lib$es6$promise$asap$$useSetTimeout();\n      }\n    }\n\n    var lib$es6$promise$asap$$scheduleFlush;\n    // Decide what async method to use to triggering processing of queued callbacks:\n    if (lib$es6$promise$asap$$isNode) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();\n    } else if (lib$es6$promise$asap$$BrowserMutationObserver) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();\n    } else if (lib$es6$promise$asap$$isWorker) {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();\n    } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();\n    } else {\n      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();\n    }\n\n    function lib$es6$promise$$internal$$noop() {}\n\n    var lib$es6$promise$$internal$$PENDING   = void 0;\n    var lib$es6$promise$$internal$$FULFILLED = 1;\n    var lib$es6$promise$$internal$$REJECTED  = 2;\n\n    var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n    function lib$es6$promise$$internal$$selfFullfillment() {\n      return new TypeError(\"You cannot resolve a promise with itself\");\n    }\n\n    function lib$es6$promise$$internal$$cannotReturnOwn() {\n      return new TypeError('A promises callback cannot return that same promise.');\n    }\n\n    function lib$es6$promise$$internal$$getThen(promise) {\n      try {\n        return promise.then;\n      } catch(error) {\n        lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;\n        return lib$es6$promise$$internal$$GET_THEN_ERROR;\n      }\n    }\n\n    function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {\n      try {\n        then.call(value, fulfillmentHandler, rejectionHandler);\n      } catch(e) {\n        return e;\n      }\n    }\n\n    function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {\n       lib$es6$promise$asap$$asap(function(promise) {\n        var sealed = false;\n        var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {\n          if (sealed) { return; }\n          sealed = true;\n          if (thenable !== value) {\n            lib$es6$promise$$internal$$resolve(promise, value);\n          } else {\n            lib$es6$promise$$internal$$fulfill(promise, value);\n          }\n        }, function(reason) {\n          if (sealed) { return; }\n          sealed = true;\n\n          lib$es6$promise$$internal$$reject(promise, reason);\n        }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n        if (!sealed && error) {\n          sealed = true;\n          lib$es6$promise$$internal$$reject(promise, error);\n        }\n      }, promise);\n    }\n\n    function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {\n      if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {\n        lib$es6$promise$$internal$$fulfill(promise, thenable._result);\n      } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {\n        lib$es6$promise$$internal$$reject(promise, thenable._result);\n      } else {\n        lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {\n          lib$es6$promise$$internal$$resolve(promise, value);\n        }, function(reason) {\n          lib$es6$promise$$internal$$reject(promise, reason);\n        });\n      }\n    }\n\n    function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {\n      if (maybeThenable.constructor === promise.constructor) {\n        lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);\n      } else {\n        var then = lib$es6$promise$$internal$$getThen(maybeThenable);\n\n        if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {\n          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);\n        } else if (then === undefined) {\n          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n        } else if (lib$es6$promise$utils$$isFunction(then)) {\n          lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);\n        } else {\n          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n        }\n      }\n    }\n\n    function lib$es6$promise$$internal$$resolve(promise, value) {\n      if (promise === value) {\n        lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());\n      } else if (lib$es6$promise$utils$$objectOrFunction(value)) {\n        lib$es6$promise$$internal$$handleMaybeThenable(promise, value);\n      } else {\n        lib$es6$promise$$internal$$fulfill(promise, value);\n      }\n    }\n\n    function lib$es6$promise$$internal$$publishRejection(promise) {\n      if (promise._onerror) {\n        promise._onerror(promise._result);\n      }\n\n      lib$es6$promise$$internal$$publish(promise);\n    }\n\n    function lib$es6$promise$$internal$$fulfill(promise, value) {\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n\n      promise._result = value;\n      promise._state = lib$es6$promise$$internal$$FULFILLED;\n\n      if (promise._subscribers.length !== 0) {\n        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);\n      }\n    }\n\n    function lib$es6$promise$$internal$$reject(promise, reason) {\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n      promise._state = lib$es6$promise$$internal$$REJECTED;\n      promise._result = reason;\n\n      lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);\n    }\n\n    function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {\n      var subscribers = parent._subscribers;\n      var length = subscribers.length;\n\n      parent._onerror = null;\n\n      subscribers[length] = child;\n      subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;\n      subscribers[length + lib$es6$promise$$internal$$REJECTED]  = onRejection;\n\n      if (length === 0 && parent._state) {\n        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);\n      }\n    }\n\n    function lib$es6$promise$$internal$$publish(promise) {\n      var subscribers = promise._subscribers;\n      var settled = promise._state;\n\n      if (subscribers.length === 0) { return; }\n\n      var child, callback, detail = promise._result;\n\n      for (var i = 0; i < subscribers.length; i += 3) {\n        child = subscribers[i];\n        callback = subscribers[i + settled];\n\n        if (child) {\n          lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);\n        } else {\n          callback(detail);\n        }\n      }\n\n      promise._subscribers.length = 0;\n    }\n\n    function lib$es6$promise$$internal$$ErrorObject() {\n      this.error = null;\n    }\n\n    var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n    function lib$es6$promise$$internal$$tryCatch(callback, detail) {\n      try {\n        return callback(detail);\n      } catch(e) {\n        lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;\n        return lib$es6$promise$$internal$$TRY_CATCH_ERROR;\n      }\n    }\n\n    function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {\n      var hasCallback = lib$es6$promise$utils$$isFunction(callback),\n          value, error, succeeded, failed;\n\n      if (hasCallback) {\n        value = lib$es6$promise$$internal$$tryCatch(callback, detail);\n\n        if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {\n          failed = true;\n          error = value.error;\n          value = null;\n        } else {\n          succeeded = true;\n        }\n\n        if (promise === value) {\n          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());\n          return;\n        }\n\n      } else {\n        value = detail;\n        succeeded = true;\n      }\n\n      if (promise._state !== lib$es6$promise$$internal$$PENDING) {\n        // noop\n      } else if (hasCallback && succeeded) {\n        lib$es6$promise$$internal$$resolve(promise, value);\n      } else if (failed) {\n        lib$es6$promise$$internal$$reject(promise, error);\n      } else if (settled === lib$es6$promise$$internal$$FULFILLED) {\n        lib$es6$promise$$internal$$fulfill(promise, value);\n      } else if (settled === lib$es6$promise$$internal$$REJECTED) {\n        lib$es6$promise$$internal$$reject(promise, value);\n      }\n    }\n\n    function lib$es6$promise$$internal$$initializePromise(promise, resolver) {\n      try {\n        resolver(function resolvePromise(value){\n          lib$es6$promise$$internal$$resolve(promise, value);\n        }, function rejectPromise(reason) {\n          lib$es6$promise$$internal$$reject(promise, reason);\n        });\n      } catch(e) {\n        lib$es6$promise$$internal$$reject(promise, e);\n      }\n    }\n\n    function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {\n      var enumerator = this;\n\n      enumerator._instanceConstructor = Constructor;\n      enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n      if (enumerator._validateInput(input)) {\n        enumerator._input     = input;\n        enumerator.length     = input.length;\n        enumerator._remaining = input.length;\n\n        enumerator._init();\n\n        if (enumerator.length === 0) {\n          lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n        } else {\n          enumerator.length = enumerator.length || 0;\n          enumerator._enumerate();\n          if (enumerator._remaining === 0) {\n            lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n          }\n        }\n      } else {\n        lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());\n      }\n    }\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {\n      return lib$es6$promise$utils$$isArray(input);\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {\n      return new Error('Array Methods must be provided an Array');\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {\n      this._result = new Array(this.length);\n    };\n\n    var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {\n      var enumerator = this;\n\n      var length  = enumerator.length;\n      var promise = enumerator.promise;\n      var input   = enumerator._input;\n\n      for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n        enumerator._eachEntry(input[i], i);\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {\n      var enumerator = this;\n      var c = enumerator._instanceConstructor;\n\n      if (lib$es6$promise$utils$$isMaybeThenable(entry)) {\n        if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {\n          entry._onerror = null;\n          enumerator._settledAt(entry._state, i, entry._result);\n        } else {\n          enumerator._willSettleAt(c.resolve(entry), i);\n        }\n      } else {\n        enumerator._remaining--;\n        enumerator._result[i] = entry;\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {\n      var enumerator = this;\n      var promise = enumerator.promise;\n\n      if (promise._state === lib$es6$promise$$internal$$PENDING) {\n        enumerator._remaining--;\n\n        if (state === lib$es6$promise$$internal$$REJECTED) {\n          lib$es6$promise$$internal$$reject(promise, value);\n        } else {\n          enumerator._result[i] = value;\n        }\n      }\n\n      if (enumerator._remaining === 0) {\n        lib$es6$promise$$internal$$fulfill(promise, enumerator._result);\n      }\n    };\n\n    lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {\n      var enumerator = this;\n\n      lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {\n        enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);\n      }, function(reason) {\n        enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);\n      });\n    };\n    function lib$es6$promise$promise$all$$all(entries) {\n      return new lib$es6$promise$enumerator$$default(this, entries).promise;\n    }\n    var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;\n    function lib$es6$promise$promise$race$$race(entries) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n      if (!lib$es6$promise$utils$$isArray(entries)) {\n        lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));\n        return promise;\n      }\n\n      var length = entries.length;\n\n      function onFulfillment(value) {\n        lib$es6$promise$$internal$$resolve(promise, value);\n      }\n\n      function onRejection(reason) {\n        lib$es6$promise$$internal$$reject(promise, reason);\n      }\n\n      for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n        lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);\n      }\n\n      return promise;\n    }\n    var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;\n    function lib$es6$promise$promise$resolve$$resolve(object) {\n      /*jshint validthis:true */\n      var Constructor = this;\n\n      if (object && typeof object === 'object' && object.constructor === Constructor) {\n        return object;\n      }\n\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n      lib$es6$promise$$internal$$resolve(promise, object);\n      return promise;\n    }\n    var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;\n    function lib$es6$promise$promise$reject$$reject(reason) {\n      /*jshint validthis:true */\n      var Constructor = this;\n      var promise = new Constructor(lib$es6$promise$$internal$$noop);\n      lib$es6$promise$$internal$$reject(promise, reason);\n      return promise;\n    }\n    var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;\n\n    var lib$es6$promise$promise$$counter = 0;\n\n    function lib$es6$promise$promise$$needsResolver() {\n      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n    }\n\n    function lib$es6$promise$promise$$needsNew() {\n      throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n    }\n\n    var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;\n    /**\n      Promise objects represent the eventual result of an asynchronous operation. The\n      primary way of interacting with a promise is through its `then` method, which\n      registers callbacks to receive either a promise's eventual value or the reason\n      why the promise cannot be fulfilled.\n\n      Terminology\n      -----------\n\n      - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n      - `thenable` is an object or function that defines a `then` method.\n      - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n      - `exception` is a value that is thrown using the throw statement.\n      - `reason` is a value that indicates why a promise was rejected.\n      - `settled` the final resting state of a promise, fulfilled or rejected.\n\n      A promise can be in one of three states: pending, fulfilled, or rejected.\n\n      Promises that are fulfilled have a fulfillment value and are in the fulfilled\n      state.  Promises that are rejected have a rejection reason and are in the\n      rejected state.  A fulfillment value is never a thenable.\n\n      Promises can also be said to *resolve* a value.  If this value is also a\n      promise, then the original promise's settled state will match the value's\n      settled state.  So a promise that *resolves* a promise that rejects will\n      itself reject, and a promise that *resolves* a promise that fulfills will\n      itself fulfill.\n\n\n      Basic Usage:\n      ------------\n\n      ```js\n      var promise = new Promise(function(resolve, reject) {\n        // on success\n        resolve(value);\n\n        // on failure\n        reject(reason);\n      });\n\n      promise.then(function(value) {\n        // on fulfillment\n      }, function(reason) {\n        // on rejection\n      });\n      ```\n\n      Advanced Usage:\n      ---------------\n\n      Promises shine when abstracting away asynchronous interactions such as\n      `XMLHttpRequest`s.\n\n      ```js\n      function getJSON(url) {\n        return new Promise(function(resolve, reject){\n          var xhr = new XMLHttpRequest();\n\n          xhr.open('GET', url);\n          xhr.onreadystatechange = handler;\n          xhr.responseType = 'json';\n          xhr.setRequestHeader('Accept', 'application/json');\n          xhr.send();\n\n          function handler() {\n            if (this.readyState === this.DONE) {\n              if (this.status === 200) {\n                resolve(this.response);\n              } else {\n                reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));\n              }\n            }\n          };\n        });\n      }\n\n      getJSON('/posts.json').then(function(json) {\n        // on fulfillment\n      }, function(reason) {\n        // on rejection\n      });\n      ```\n\n      Unlike callbacks, promises are great composable primitives.\n\n      ```js\n      Promise.all([\n        getJSON('/posts'),\n        getJSON('/comments')\n      ]).then(function(values){\n        values[0] // => postsJSON\n        values[1] // => commentsJSON\n\n        return values;\n      });\n      ```\n\n      @class Promise\n      @param {function} resolver\n      Useful for tooling.\n      @constructor\n    */\n    function lib$es6$promise$promise$$Promise(resolver) {\n      this._id = lib$es6$promise$promise$$counter++;\n      this._state = undefined;\n      this._result = undefined;\n      this._subscribers = [];\n\n      if (lib$es6$promise$$internal$$noop !== resolver) {\n        if (!lib$es6$promise$utils$$isFunction(resolver)) {\n          lib$es6$promise$promise$$needsResolver();\n        }\n\n        if (!(this instanceof lib$es6$promise$promise$$Promise)) {\n          lib$es6$promise$promise$$needsNew();\n        }\n\n        lib$es6$promise$$internal$$initializePromise(this, resolver);\n      }\n    }\n\n    lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;\n    lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;\n    lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;\n    lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;\n    lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;\n    lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;\n    lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;\n\n    lib$es6$promise$promise$$Promise.prototype = {\n      constructor: lib$es6$promise$promise$$Promise,\n\n    /**\n      The primary way of interacting with a promise is through its `then` method,\n      which registers callbacks to receive either a promise's eventual value or the\n      reason why the promise cannot be fulfilled.\n\n      ```js\n      findUser().then(function(user){\n        // user is available\n      }, function(reason){\n        // user is unavailable, and you are given the reason why\n      });\n      ```\n\n      Chaining\n      --------\n\n      The return value of `then` is itself a promise.  This second, 'downstream'\n      promise is resolved with the return value of the first promise's fulfillment\n      or rejection handler, or rejected if the handler throws an exception.\n\n      ```js\n      findUser().then(function (user) {\n        return user.name;\n      }, function (reason) {\n        return 'default name';\n      }).then(function (userName) {\n        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n        // will be `'default name'`\n      });\n\n      findUser().then(function (user) {\n        throw new Error('Found user, but still unhappy');\n      }, function (reason) {\n        throw new Error('`findUser` rejected and we're unhappy');\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n      });\n      ```\n      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n\n      ```js\n      findUser().then(function (user) {\n        throw new PedagogicalException('Upstream error');\n      }).then(function (value) {\n        // never reached\n      }).then(function (value) {\n        // never reached\n      }, function (reason) {\n        // The `PedgagocialException` is propagated all the way down to here\n      });\n      ```\n\n      Assimilation\n      ------------\n\n      Sometimes the value you want to propagate to a downstream promise can only be\n      retrieved asynchronously. This can be achieved by returning a promise in the\n      fulfillment or rejection handler. The downstream promise will then be pending\n      until the returned promise is settled. This is called *assimilation*.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // The user's comments are now available\n      });\n      ```\n\n      If the assimliated promise rejects, then the downstream promise will also reject.\n\n      ```js\n      findUser().then(function (user) {\n        return findCommentsByAuthor(user);\n      }).then(function (comments) {\n        // If `findCommentsByAuthor` fulfills, we'll have the value here\n      }, function (reason) {\n        // If `findCommentsByAuthor` rejects, we'll have the reason here\n      });\n      ```\n\n      Simple Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var result;\n\n      try {\n        result = findResult();\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n      findResult(function(result, err){\n        if (err) {\n          // failure\n        } else {\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findResult().then(function(result){\n        // success\n      }, function(reason){\n        // failure\n      });\n      ```\n\n      Advanced Example\n      --------------\n\n      Synchronous Example\n\n      ```javascript\n      var author, books;\n\n      try {\n        author = findAuthor();\n        books  = findBooksByAuthor(author);\n        // success\n      } catch(reason) {\n        // failure\n      }\n      ```\n\n      Errback Example\n\n      ```js\n\n      function foundBooks(books) {\n\n      }\n\n      function failure(reason) {\n\n      }\n\n      findAuthor(function(author, err){\n        if (err) {\n          failure(err);\n          // failure\n        } else {\n          try {\n            findBoooksByAuthor(author, function(books, err) {\n              if (err) {\n                failure(err);\n              } else {\n                try {\n                  foundBooks(books);\n                } catch(reason) {\n                  failure(reason);\n                }\n              }\n            });\n          } catch(error) {\n            failure(err);\n          }\n          // success\n        }\n      });\n      ```\n\n      Promise Example;\n\n      ```javascript\n      findAuthor().\n        then(findBooksByAuthor).\n        then(function(books){\n          // found books\n      }).catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method then\n      @param {Function} onFulfilled\n      @param {Function} onRejected\n      Useful for tooling.\n      @return {Promise}\n    */\n      then: function(onFulfillment, onRejection) {\n        var parent = this;\n        var state = parent._state;\n\n        if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {\n          return this;\n        }\n\n        var child = new this.constructor(lib$es6$promise$$internal$$noop);\n        var result = parent._result;\n\n        if (state) {\n          var callback = arguments[state - 1];\n          lib$es6$promise$asap$$asap(function(){\n            lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);\n          });\n        } else {\n          lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);\n        }\n\n        return child;\n      },\n\n    /**\n      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n      as the catch block of a try/catch statement.\n\n      ```js\n      function findAuthor(){\n        throw new Error('couldn't find that author');\n      }\n\n      // synchronous\n      try {\n        findAuthor();\n      } catch(reason) {\n        // something went wrong\n      }\n\n      // async with promises\n      findAuthor().catch(function(reason){\n        // something went wrong\n      });\n      ```\n\n      @method catch\n      @param {Function} onRejection\n      Useful for tooling.\n      @return {Promise}\n    */\n      'catch': function(onRejection) {\n        return this.then(null, onRejection);\n      }\n    };\n    function lib$es6$promise$polyfill$$polyfill() {\n      var local;\n\n      if (typeof global !== 'undefined') {\n          local = global;\n      } else if (typeof self !== 'undefined') {\n          local = self;\n      } else {\n          try {\n              local = Function('return this')();\n          } catch (e) {\n              throw new Error('polyfill failed because global object is unavailable in this environment');\n          }\n      }\n\n      var P = local.Promise;\n\n      if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {\n        return;\n      }\n\n      local.Promise = lib$es6$promise$promise$$default;\n    }\n    var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;\n\n    var lib$es6$promise$umd$$ES6Promise = {\n      'Promise': lib$es6$promise$promise$$default,\n      'polyfill': lib$es6$promise$polyfill$$default\n    };\n\n    /* global define:true module:true window: true */\n    if (typeof define === 'function' && define['amd']) {\n      define(function() { return lib$es6$promise$umd$$ES6Promise; });\n    } else if (typeof module !== 'undefined' && module['exports']) {\n      module['exports'] = lib$es6$promise$umd$$ES6Promise;\n    } else if (typeof this !== 'undefined') {\n      this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;\n    }\n\n    lib$es6$promise$polyfill$$default();\n}).call(this);\n\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"_process\":2}],2:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            currentQueue[queueIndex].run();\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],3:[function(require,module,exports){\n(function (global){\n/*! https://mths.be/punycode v1.3.2 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t    counter = 0,\n\t\t    length = string.length,\n\t\t    value,\n\t\t    extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t//  0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * http://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t    inputLength = input.length,\n\t\t    out,\n\t\t    i = 0,\n\t\t    n = initialN,\n\t\t    bias = initialBias,\n\t\t    basic,\n\t\t    j,\n\t\t    index,\n\t\t    oldi,\n\t\t    w,\n\t\t    k,\n\t\t    digit,\n\t\t    t,\n\t\t    /** Cached calculation results */\n\t\t    baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols (e.g. a domain name label) to a\n\t * Punycode string of ASCII-only symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t    delta,\n\t\t    handledCPCount,\n\t\t    basicLength,\n\t\t    bias,\n\t\t    j,\n\t\t    m,\n\t\t    q,\n\t\t    k,\n\t\t    t,\n\t\t    currentValue,\n\t\t    output = [],\n\t\t    /** `inputLength` will hold the number of code points in `input`. */\n\t\t    inputLength,\n\t\t    /** Cached calculation results */\n\t\t    handledCPCountPlusOne,\n\t\t    baseMinusT,\n\t\t    qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name or an email address\n\t * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n\t * it doesn't matter if you call it on a string that has already been\n\t * converted to Unicode.\n\t * @memberOf punycode\n\t * @param {String} input The Punycoded domain name or email address to\n\t * convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name or an email address to\n\t * Punycode. Only the non-ASCII parts of the domain name will be converted,\n\t * i.e. it doesn't matter if you call it with a domain that's already in\n\t * ASCII.\n\t * @memberOf punycode\n\t * @param {String} input The domain name or email address to convert, as a\n\t * Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name or\n\t * email address.\n\t */\n\tfunction toASCII(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.3.2',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine('punycode', function() {\n\t\t\treturn punycode;\n\t\t});\n\t} else if (freeExports && freeModule) {\n\t\tif (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = punycode;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (key in punycode) {\n\t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.punycode = punycode;\n\t}\n\n}(this));\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],4:[function(require,module,exports){\nvar log = require('./log');\nvar Promise = require('./promise');\n\nfunction restoreOwnerScroll(ownerDocument, x, y) {\n    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {\n        ownerDocument.defaultView.scrollTo(x, y);\n    }\n}\n\nfunction cloneCanvasContents(canvas, clonedCanvas) {\n    try {\n        if (clonedCanvas) {\n            clonedCanvas.width = canvas.width;\n            clonedCanvas.height = canvas.height;\n            clonedCanvas.getContext(\"2d\").putImageData(canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height), 0, 0);\n        }\n    } catch(e) {\n        log(\"Unable to copy canvas content from\", canvas, e);\n    }\n}\n\nfunction cloneNode(node, javascriptEnabled) {\n    var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);\n\n    var child = node.firstChild;\n    while(child) {\n        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {\n            clone.appendChild(cloneNode(child, javascriptEnabled));\n        }\n        child = child.nextSibling;\n    }\n\n    if (node.nodeType === 1 && node.tagName !== 'BODY') {\n        clone._scrollTop = node.scrollTop;\n        clone._scrollLeft = node.scrollLeft;\n        if (node.nodeName === \"CANVAS\") {\n            cloneCanvasContents(node, clone);\n        } else if (node.nodeName === \"TEXTAREA\" || node.nodeName === \"SELECT\") {\n            clone.value = node.value;\n        }\n    }\n\n    return clone;\n}\n\nfunction initNode(node) {\n    if (node.nodeType === 1) {\n        node.scrollTop = node._scrollTop;\n        node.scrollLeft = node._scrollLeft;\n\n        var child = node.firstChild;\n        while(child) {\n            initNode(child);\n            child = child.nextSibling;\n        }\n    }\n}\n\nmodule.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {\n    var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);\n    var container = containerDocument.createElement(\"iframe\");\n\n    container.className = \"html2canvas-container\";\n    container.style.visibility = \"hidden\";\n    container.style.position = \"fixed\";\n    container.style.left = \"-10000px\";\n    container.style.top = \"0px\";\n    container.style.border = \"0\";\n    container.style.border = \"0\";\n    container.width = width;\n    container.height = height;\n    container.scrolling = \"no\"; // ios won't scroll without it\n    containerDocument.body.appendChild(container);\n\n    return new Promise(function(resolve) {\n        var documentClone = container.contentWindow.document;\n\n        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle\n         if window url is about:blank, we can assign the url to current by writing onto the document\n         */\n        container.contentWindow.onload = container.onload = function() {\n            var interval = setInterval(function() {\n                if (documentClone.body.childNodes.length > 0) {\n                    initNode(documentClone.documentElement);\n                    clearInterval(interval);\n                    if (options.type === \"view\") {\n                        container.contentWindow.scrollTo(x, y);\n                        if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {\n                            documentClone.documentElement.style.top = (-y) + \"px\";\n                            documentClone.documentElement.style.left = (-x) + \"px\";\n                            documentClone.documentElement.style.position = 'absolute';\n                        }\n                    }\n                    resolve(container);\n                }\n            }, 50);\n        };\n\n        documentClone.open();\n        documentClone.write(\"<!DOCTYPE html><html></html>\");\n        // Chrome scrolls the parent document for some reason after the write to the cloned window???\n        restoreOwnerScroll(ownerDocument, x, y);\n        documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);\n        documentClone.close();\n    });\n};\n\n},{\"./log\":15,\"./promise\":18}],5:[function(require,module,exports){\n// http://dev.w3.org/csswg/css-color/\n\nfunction Color(value) {\n    this.r = 0;\n    this.g = 0;\n    this.b = 0;\n    this.a = null;\n    var result = this.fromArray(value) ||\n        this.namedColor(value) ||\n        this.rgb(value) ||\n        this.rgba(value) ||\n        this.hex6(value) ||\n        this.hex3(value);\n}\n\nColor.prototype.darken = function(amount) {\n    var a = 1 - amount;\n    return  new Color([\n        Math.round(this.r * a),\n        Math.round(this.g * a),\n        Math.round(this.b * a),\n        this.a\n    ]);\n};\n\nColor.prototype.isTransparent = function() {\n    return this.a === 0;\n};\n\nColor.prototype.isBlack = function() {\n    return this.r === 0 && this.g === 0 && this.b === 0;\n};\n\nColor.prototype.fromArray = function(array) {\n    if (Array.isArray(array)) {\n        this.r = Math.min(array[0], 255);\n        this.g = Math.min(array[1], 255);\n        this.b = Math.min(array[2], 255);\n        if (array.length > 3) {\n            this.a = array[3];\n        }\n    }\n\n    return (Array.isArray(array));\n};\n\nvar _hex3 = /^#([a-f0-9]{3})$/i;\n\nColor.prototype.hex3 = function(value) {\n    var match = null;\n    if ((match = value.match(_hex3)) !== null) {\n        this.r = parseInt(match[1][0] + match[1][0], 16);\n        this.g = parseInt(match[1][1] + match[1][1], 16);\n        this.b = parseInt(match[1][2] + match[1][2], 16);\n    }\n    return match !== null;\n};\n\nvar _hex6 = /^#([a-f0-9]{6})$/i;\n\nColor.prototype.hex6 = function(value) {\n    var match = null;\n    if ((match = value.match(_hex6)) !== null) {\n        this.r = parseInt(match[1].substring(0, 2), 16);\n        this.g = parseInt(match[1].substring(2, 4), 16);\n        this.b = parseInt(match[1].substring(4, 6), 16);\n    }\n    return match !== null;\n};\n\n\nvar _rgb = /^rgb\\((\\d{1,3}) *, *(\\d{1,3}) *, *(\\d{1,3})\\)$/;\n\nColor.prototype.rgb = function(value) {\n    var match = null;\n    if ((match = value.match(_rgb)) !== null) {\n        this.r = Number(match[1]);\n        this.g = Number(match[2]);\n        this.b = Number(match[3]);\n    }\n    return match !== null;\n};\n\nvar _rgba = /^rgba\\((\\d{1,3}) *, *(\\d{1,3}) *, *(\\d{1,3}) *, *(\\d+\\.?\\d*)\\)$/;\n\nColor.prototype.rgba = function(value) {\n    var match = null;\n    if ((match = value.match(_rgba)) !== null) {\n        this.r = Number(match[1]);\n        this.g = Number(match[2]);\n        this.b = Number(match[3]);\n        this.a = Number(match[4]);\n    }\n    return match !== null;\n};\n\nColor.prototype.toString = function() {\n    return this.a !== null && this.a !== 1 ?\n    \"rgba(\" + [this.r, this.g, this.b, this.a].join(\",\") + \")\" :\n    \"rgb(\" + [this.r, this.g, this.b].join(\",\") + \")\";\n};\n\nColor.prototype.namedColor = function(value) {\n    var color = colors[value.toLowerCase()];\n    if (color) {\n        this.r = color[0];\n        this.g = color[1];\n        this.b = color[2];\n    } else if (value.toLowerCase() === \"transparent\") {\n        this.r = this.g = this.b = this.a = 0;\n        return true;\n    }\n\n    return !!color;\n};\n\nColor.prototype.isColor = true;\n\n// JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(\",\").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))\nvar colors = {\n    \"aliceblue\": [240, 248, 255],\n    \"antiquewhite\": [250, 235, 215],\n    \"aqua\": [0, 255, 255],\n    \"aquamarine\": [127, 255, 212],\n    \"azure\": [240, 255, 255],\n    \"beige\": [245, 245, 220],\n    \"bisque\": [255, 228, 196],\n    \"black\": [0, 0, 0],\n    \"blanchedalmond\": [255, 235, 205],\n    \"blue\": [0, 0, 255],\n    \"blueviolet\": [138, 43, 226],\n    \"brown\": [165, 42, 42],\n    \"burlywood\": [222, 184, 135],\n    \"cadetblue\": [95, 158, 160],\n    \"chartreuse\": [127, 255, 0],\n    \"chocolate\": [210, 105, 30],\n    \"coral\": [255, 127, 80],\n    \"cornflowerblue\": [100, 149, 237],\n    \"cornsilk\": [255, 248, 220],\n    \"crimson\": [220, 20, 60],\n    \"cyan\": [0, 255, 255],\n    \"darkblue\": [0, 0, 139],\n    \"darkcyan\": [0, 139, 139],\n    \"darkgoldenrod\": [184, 134, 11],\n    \"darkgray\": [169, 169, 169],\n    \"darkgreen\": [0, 100, 0],\n    \"darkgrey\": [169, 169, 169],\n    \"darkkhaki\": [189, 183, 107],\n    \"darkmagenta\": [139, 0, 139],\n    \"darkolivegreen\": [85, 107, 47],\n    \"darkorange\": [255, 140, 0],\n    \"darkorchid\": [153, 50, 204],\n    \"darkred\": [139, 0, 0],\n    \"darksalmon\": [233, 150, 122],\n    \"darkseagreen\": [143, 188, 143],\n    \"darkslateblue\": [72, 61, 139],\n    \"darkslategray\": [47, 79, 79],\n    \"darkslategrey\": [47, 79, 79],\n    \"darkturquoise\": [0, 206, 209],\n    \"darkviolet\": [148, 0, 211],\n    \"deeppink\": [255, 20, 147],\n    \"deepskyblue\": [0, 191, 255],\n    \"dimgray\": [105, 105, 105],\n    \"dimgrey\": [105, 105, 105],\n    \"dodgerblue\": [30, 144, 255],\n    \"firebrick\": [178, 34, 34],\n    \"floralwhite\": [255, 250, 240],\n    \"forestgreen\": [34, 139, 34],\n    \"fuchsia\": [255, 0, 255],\n    \"gainsboro\": [220, 220, 220],\n    \"ghostwhite\": [248, 248, 255],\n    \"gold\": [255, 215, 0],\n    \"goldenrod\": [218, 165, 32],\n    \"gray\": [128, 128, 128],\n    \"green\": [0, 128, 0],\n    \"greenyellow\": [173, 255, 47],\n    \"grey\": [128, 128, 128],\n    \"honeydew\": [240, 255, 240],\n    \"hotpink\": [255, 105, 180],\n    \"indianred\": [205, 92, 92],\n    \"indigo\": [75, 0, 130],\n    \"ivory\": [255, 255, 240],\n    \"khaki\": [240, 230, 140],\n    \"lavender\": [230, 230, 250],\n    \"lavenderblush\": [255, 240, 245],\n    \"lawngreen\": [124, 252, 0],\n    \"lemonchiffon\": [255, 250, 205],\n    \"lightblue\": [173, 216, 230],\n    \"lightcoral\": [240, 128, 128],\n    \"lightcyan\": [224, 255, 255],\n    \"lightgoldenrodyellow\": [250, 250, 210],\n    \"lightgray\": [211, 211, 211],\n    \"lightgreen\": [144, 238, 144],\n    \"lightgrey\": [211, 211, 211],\n    \"lightpink\": [255, 182, 193],\n    \"lightsalmon\": [255, 160, 122],\n    \"lightseagreen\": [32, 178, 170],\n    \"lightskyblue\": [135, 206, 250],\n    \"lightslategray\": [119, 136, 153],\n    \"lightslategrey\": [119, 136, 153],\n    \"lightsteelblue\": [176, 196, 222],\n    \"lightyellow\": [255, 255, 224],\n    \"lime\": [0, 255, 0],\n    \"limegreen\": [50, 205, 50],\n    \"linen\": [250, 240, 230],\n    \"magenta\": [255, 0, 255],\n    \"maroon\": [128, 0, 0],\n    \"mediumaquamarine\": [102, 205, 170],\n    \"mediumblue\": [0, 0, 205],\n    \"mediumorchid\": [186, 85, 211],\n    \"mediumpurple\": [147, 112, 219],\n    \"mediumseagreen\": [60, 179, 113],\n    \"mediumslateblue\": [123, 104, 238],\n    \"mediumspringgreen\": [0, 250, 154],\n    \"mediumturquoise\": [72, 209, 204],\n    \"mediumvioletred\": [199, 21, 133],\n    \"midnightblue\": [25, 25, 112],\n    \"mintcream\": [245, 255, 250],\n    \"mistyrose\": [255, 228, 225],\n    \"moccasin\": [255, 228, 181],\n    \"navajowhite\": [255, 222, 173],\n    \"navy\": [0, 0, 128],\n    \"oldlace\": [253, 245, 230],\n    \"olive\": [128, 128, 0],\n    \"olivedrab\": [107, 142, 35],\n    \"orange\": [255, 165, 0],\n    \"orangered\": [255, 69, 0],\n    \"orchid\": [218, 112, 214],\n    \"palegoldenrod\": [238, 232, 170],\n    \"palegreen\": [152, 251, 152],\n    \"paleturquoise\": [175, 238, 238],\n    \"palevioletred\": [219, 112, 147],\n    \"papayawhip\": [255, 239, 213],\n    \"peachpuff\": [255, 218, 185],\n    \"peru\": [205, 133, 63],\n    \"pink\": [255, 192, 203],\n    \"plum\": [221, 160, 221],\n    \"powderblue\": [176, 224, 230],\n    \"purple\": [128, 0, 128],\n    \"rebeccapurple\": [102, 51, 153],\n    \"red\": [255, 0, 0],\n    \"rosybrown\": [188, 143, 143],\n    \"royalblue\": [65, 105, 225],\n    \"saddlebrown\": [139, 69, 19],\n    \"salmon\": [250, 128, 114],\n    \"sandybrown\": [244, 164, 96],\n    \"seagreen\": [46, 139, 87],\n    \"seashell\": [255, 245, 238],\n    \"sienna\": [160, 82, 45],\n    \"silver\": [192, 192, 192],\n    \"skyblue\": [135, 206, 235],\n    \"slateblue\": [106, 90, 205],\n    \"slategray\": [112, 128, 144],\n    \"slategrey\": [112, 128, 144],\n    \"snow\": [255, 250, 250],\n    \"springgreen\": [0, 255, 127],\n    \"steelblue\": [70, 130, 180],\n    \"tan\": [210, 180, 140],\n    \"teal\": [0, 128, 128],\n    \"thistle\": [216, 191, 216],\n    \"tomato\": [255, 99, 71],\n    \"turquoise\": [64, 224, 208],\n    \"violet\": [238, 130, 238],\n    \"wheat\": [245, 222, 179],\n    \"white\": [255, 255, 255],\n    \"whitesmoke\": [245, 245, 245],\n    \"yellow\": [255, 255, 0],\n    \"yellowgreen\": [154, 205, 50]\n};\n\nmodule.exports = Color;\n\n},{}],6:[function(require,module,exports){\nvar Promise = require('./promise');\nvar Support = require('./support');\nvar CanvasRenderer = require('./renderers/canvas');\nvar ImageLoader = require('./imageloader');\nvar NodeParser = require('./nodeparser');\nvar NodeContainer = require('./nodecontainer');\nvar log = require('./log');\nvar utils = require('./utils');\nvar createWindowClone = require('./clone');\nvar loadUrlDocument = require('./proxy').loadUrlDocument;\nvar getBounds = utils.getBounds;\n\nvar html2canvasNodeAttribute = \"data-html2canvas-node\";\nvar html2canvasCloneIndex = 0;\n\nfunction html2canvas(nodeList, options) {\n    var index = html2canvasCloneIndex++;\n    options = options || {};\n    if (options.logging) {\n        window.html2canvas.logging = true;\n        window.html2canvas.start = Date.now();\n    }\n\n    options.async = typeof(options.async) === \"undefined\" ? true : options.async;\n    options.allowTaint = typeof(options.allowTaint) === \"undefined\" ? false : options.allowTaint;\n    options.removeContainer = typeof(options.removeContainer) === \"undefined\" ? true : options.removeContainer;\n    options.javascriptEnabled = typeof(options.javascriptEnabled) === \"undefined\" ? false : options.javascriptEnabled;\n    options.imageTimeout = typeof(options.imageTimeout) === \"undefined\" ? 10000 : options.imageTimeout;\n    options.renderer = typeof(options.renderer) === \"function\" ? options.renderer : CanvasRenderer;\n    options.strict = !!options.strict;\n\n    if (typeof(nodeList) === \"string\") {\n        if (typeof(options.proxy) !== \"string\") {\n            return Promise.reject(\"Proxy must be used when rendering url\");\n        }\n        var width = options.width != null ? options.width : window.innerWidth;\n        var height = options.height != null ? options.height : window.innerHeight;\n        return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {\n            return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);\n        });\n    }\n\n    var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];\n    node.setAttribute(html2canvasNodeAttribute + index, index);\n    return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {\n        if (typeof(options.onrendered) === \"function\") {\n            log(\"options.onrendered is deprecated, html2canvas returns a Promise containing the canvas\");\n            options.onrendered(canvas);\n        }\n        return canvas;\n    });\n}\n\nhtml2canvas.Promise = Promise;\nhtml2canvas.CanvasRenderer = CanvasRenderer;\nhtml2canvas.NodeContainer = NodeContainer;\nhtml2canvas.log = log;\nhtml2canvas.utils = utils;\n\nmodule.exports = (typeof(document) === \"undefined\" || typeof(Object.create) !== \"function\" || typeof(document.createElement(\"canvas\").getContext) !== \"function\") ? function() {\n    return Promise.reject(\"No canvas support\");\n} : html2canvas;\n\nfunction renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {\n    return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {\n        log(\"Document cloned\");\n\n        var attributeName = html2canvasNodeAttribute + html2canvasIndex;\n        var selector = \"[\" + attributeName + \"='\" + html2canvasIndex + \"']\";\n        document.querySelector(selector).removeAttribute(attributeName);\n        var clonedWindow = container.contentWindow;\n        var node = clonedWindow.document.querySelector(selector);\n        node.style.opacity === \"0\" && node.getAttribute('renderer') === \"webgl\" ? node.style.opacity = 1 : null;\n        var oncloneHandler = (typeof(options.onclone) === \"function\") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);\n        return oncloneHandler.then(function() {\n            return renderWindow(node, container, options, windowWidth, windowHeight);\n        });\n    });\n}\n\nfunction renderWindow(node, container, options, windowWidth, windowHeight) {\n    var clonedWindow = container.contentWindow;\n    var support = new Support(clonedWindow.document);\n    var imageLoader = new ImageLoader(options, support);\n    var bounds = getBounds(node);\n    var width = options.type === \"view\" ? windowWidth : documentWidth(clonedWindow.document);\n    var height = options.type === \"view\" ? windowHeight : documentHeight(clonedWindow.document);\n    var renderer = new options.renderer(width, height, imageLoader, options, document);\n    var parser = new NodeParser(node, renderer, support, imageLoader, options);\n    return parser.ready.then(function() {\n        log(\"Finished rendering\");\n        var canvas;\n\n        if (options.type === \"view\") {\n            canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});\n        } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {\n            canvas = renderer.canvas;\n        } else {\n            //If retina - increase bounds by two since we ve got 2x canvas from renderer\n            if (window.devicePixelRatio !== 1) {\n                bounds.top = bounds.top * window.devicePixelRatio;\n                bounds.left = bounds.left * window.devicePixelRatio;\n                bounds.right = bounds.right * window.devicePixelRatio;\n                bounds.bottom = bounds.bottom * window.devicePixelRatio;\n            }\n\n            canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: clonedWindow.pageXOffset, y: clonedWindow.pageYOffset});\n        }\n\n        cleanupContainer(container, options);\n        return canvas;\n    });\n}\n\nfunction cleanupContainer(container, options) {\n    if (options.removeContainer) {\n        container.parentNode.removeChild(container);\n        log(\"Cleaned up container\");\n    }\n}\n\nfunction crop(canvas, bounds) {\n    var croppedCanvas = document.createElement(\"canvas\");\n    var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));\n    var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));\n    var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));\n    var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));\n    croppedCanvas.width = bounds.width;\n    croppedCanvas.height =  bounds.height;\n    log(\"Cropping canvas at:\", \"left:\", bounds.left, \"top:\", bounds.top, \"width:\", (x2-x1), \"height:\", (y2-y1));\n    log(\"Resulting crop with width\", bounds.width, \"and height\", bounds.height, \" with x\", x1, \"and y\", y1);\n    croppedCanvas.getContext(\"2d\").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1);\n    return croppedCanvas;\n}\n\nfunction documentWidth (doc) {\n    return Math.max(\n        Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),\n        Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),\n        Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)\n    );\n}\n\nfunction documentHeight (doc) {\n    return Math.max(\n        Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),\n        Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),\n        Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)\n    );\n}\n\nfunction absoluteUrl(url) {\n    var link = document.createElement(\"a\");\n    link.href = url;\n    link.href = link.href;\n    return link;\n}\n\n},{\"./clone\":4,\"./imageloader\":13,\"./log\":15,\"./nodecontainer\":16,\"./nodeparser\":17,\"./promise\":18,\"./proxy\":19,\"./renderers/canvas\":23,\"./support\":25,\"./utils\":29}],7:[function(require,module,exports){\nvar Promise = require('./promise');\nvar log = require('./log');\nvar smallImage = require('./utils').smallImage;\n\nfunction DummyImageContainer(src) {\n    this.src = src;\n    log(\"DummyImageContainer for\", src);\n    if (!this.promise || !this.image) {\n        log(\"Initiating DummyImageContainer\");\n        DummyImageContainer.prototype.image = new Image();\n        var image = this.image;\n        DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {\n            image.onload = resolve;\n            image.onerror = reject;\n            image.src = smallImage();\n            if (image.complete === true) {\n                resolve(image);\n            }\n        });\n    }\n}\n\nmodule.exports = DummyImageContainer;\n\n},{\"./log\":15,\"./promise\":18,\"./utils\":29}],8:[function(require,module,exports){\nvar smallImage = require('./utils').smallImage;\n\nfunction Font(family, size) {\n    var container = document.createElement('div'),\n        img = document.createElement('img'),\n        span = document.createElement('span'),\n        sampleText = 'Hidden Text',\n        baseline,\n        middle;\n\n    container.style.visibility = \"hidden\";\n    container.style.fontFamily = family;\n    container.style.fontSize = size;\n    container.style.margin = 0;\n    container.style.padding = 0;\n\n    document.body.appendChild(container);\n\n    img.src = smallImage();\n    img.width = 1;\n    img.height = 1;\n\n    img.style.margin = 0;\n    img.style.padding = 0;\n    img.style.verticalAlign = \"baseline\";\n\n    span.style.fontFamily = family;\n    span.style.fontSize = size;\n    span.style.margin = 0;\n    span.style.padding = 0;\n\n    span.appendChild(document.createTextNode(sampleText));\n    container.appendChild(span);\n    container.appendChild(img);\n    baseline = (img.offsetTop - span.offsetTop) + 1;\n\n    container.removeChild(span);\n    container.appendChild(document.createTextNode(sampleText));\n\n    container.style.lineHeight = \"normal\";\n    img.style.verticalAlign = \"super\";\n\n    middle = (img.offsetTop-container.offsetTop) + 1;\n\n    document.body.removeChild(container);\n\n    this.baseline = baseline;\n    this.lineWidth = 1;\n    this.middle = middle;\n}\n\nmodule.exports = Font;\n\n},{\"./utils\":29}],9:[function(require,module,exports){\nvar Font = require('./font');\n\nfunction FontMetrics() {\n    this.data = {};\n}\n\nFontMetrics.prototype.getMetrics = function(family, size) {\n    if (this.data[family + \"-\" + size] === undefined) {\n        this.data[family + \"-\" + size] = new Font(family, size);\n    }\n    return this.data[family + \"-\" + size];\n};\n\nmodule.exports = FontMetrics;\n\n},{\"./font\":8}],10:[function(require,module,exports){\nvar utils = require('./utils');\nvar Promise = require('./promise');\nvar getBounds = utils.getBounds;\nvar loadUrlDocument = require('./proxy').loadUrlDocument;\n\nfunction FrameContainer(container, sameOrigin, options) {\n    this.image = null;\n    this.src = container;\n    var self = this;\n    var bounds = getBounds(container);\n    this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {\n        if (container.contentWindow.document.URL === \"about:blank\" || container.contentWindow.document.documentElement == null) {\n            container.contentWindow.onload = container.onload = function() {\n                resolve(container);\n            };\n        } else {\n            resolve(container);\n        }\n    })).then(function(container) {\n        var html2canvas = require('./core');\n        return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});\n    }).then(function(canvas) {\n        return self.image = canvas;\n    });\n}\n\nFrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {\n    var container = this.src;\n    return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);\n};\n\nmodule.exports = FrameContainer;\n\n},{\"./core\":6,\"./promise\":18,\"./proxy\":19,\"./utils\":29}],11:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction GradientContainer(imageData) {\n    this.src = imageData.value;\n    this.colorStops = [];\n    this.type = null;\n    this.x0 = 0.5;\n    this.y0 = 0.5;\n    this.x1 = 0.5;\n    this.y1 = 0.5;\n    this.promise = Promise.resolve(true);\n}\n\nGradientContainer.prototype.TYPES = {\n    LINEAR: 1,\n    RADIAL: 2\n};\n\nmodule.exports = GradientContainer;\n\n},{\"./promise\":18}],12:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction ImageContainer(src, cors) {\n    this.src = src;\n    this.image = new Image();\n    var self = this;\n    this.tainted = null;\n    this.promise = new Promise(function(resolve, reject) {\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n        if (cors) {\n            self.image.crossOrigin = \"anonymous\";\n        }\n        self.image.src = src;\n        if (self.image.complete === true) {\n            resolve(self.image);\n        }\n    });\n}\n\nmodule.exports = ImageContainer;\n\n},{\"./promise\":18}],13:[function(require,module,exports){\nvar Promise = require('./promise');\nvar log = require('./log');\nvar ImageContainer = require('./imagecontainer');\nvar DummyImageContainer = require('./dummyimagecontainer');\nvar ProxyImageContainer = require('./proxyimagecontainer');\nvar FrameContainer = require('./framecontainer');\nvar SVGContainer = require('./svgcontainer');\nvar SVGNodeContainer = require('./svgnodecontainer');\nvar LinearGradientContainer = require('./lineargradientcontainer');\nvar WebkitGradientContainer = require('./webkitgradientcontainer');\nvar bind = require('./utils').bind;\n\nfunction ImageLoader(options, support) {\n    this.link = null;\n    this.options = options;\n    this.support = support;\n    this.origin = this.getOrigin(window.location.href);\n}\n\nImageLoader.prototype.findImages = function(nodes) {\n    var images = [];\n    nodes.reduce(function(imageNodes, container) {\n        switch(container.node.nodeName) {\n        case \"IMG\":\n            return imageNodes.concat([{\n                args: [container.node.src],\n                method: \"url\"\n            }]);\n        case \"svg\":\n        case \"IFRAME\":\n            return imageNodes.concat([{\n                args: [container.node],\n                method: container.node.nodeName\n            }]);\n        }\n        return imageNodes;\n    }, []).forEach(this.addImage(images, this.loadImage), this);\n    return images;\n};\n\nImageLoader.prototype.findBackgroundImage = function(images, container) {\n    container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);\n    return images;\n};\n\nImageLoader.prototype.addImage = function(images, callback) {\n    return function(newImage) {\n        newImage.args.forEach(function(image) {\n            if (!this.imageExists(images, image)) {\n                images.splice(0, 0, callback.call(this, newImage));\n                log('Added image #' + (images.length), typeof(image) === \"string\" ? image.substring(0, 100) : image);\n            }\n        }, this);\n    };\n};\n\nImageLoader.prototype.hasImageBackground = function(imageData) {\n    return imageData.method !== \"none\";\n};\n\nImageLoader.prototype.loadImage = function(imageData) {\n    if (imageData.method === \"url\") {\n        var src = imageData.args[0];\n        if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {\n            return new SVGContainer(src);\n        } else if (src.match(/data:image\\/.*;base64,/i)) {\n            return new ImageContainer(src.replace(/url\\(['\"]{0,}|['\"]{0,}\\)$/ig, ''), false);\n        } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {\n            return new ImageContainer(src, false);\n        } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {\n            return new ImageContainer(src, true);\n        } else if (this.options.proxy) {\n            return new ProxyImageContainer(src, this.options.proxy);\n        } else {\n            return new DummyImageContainer(src);\n        }\n    } else if (imageData.method === \"linear-gradient\") {\n        return new LinearGradientContainer(imageData);\n    } else if (imageData.method === \"gradient\") {\n        return new WebkitGradientContainer(imageData);\n    } else if (imageData.method === \"svg\") {\n        return new SVGNodeContainer(imageData.args[0], this.support.svg);\n    } else if (imageData.method === \"IFRAME\") {\n        return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);\n    } else {\n        return new DummyImageContainer(imageData);\n    }\n};\n\nImageLoader.prototype.isSVG = function(src) {\n    return src.substring(src.length - 3).toLowerCase() === \"svg\" || SVGContainer.prototype.isInline(src);\n};\n\nImageLoader.prototype.imageExists = function(images, src) {\n    return images.some(function(image) {\n        return image.src === src;\n    });\n};\n\nImageLoader.prototype.isSameOrigin = function(url) {\n    return (this.getOrigin(url) === this.origin);\n};\n\nImageLoader.prototype.getOrigin = function(url) {\n    var link = this.link || (this.link = document.createElement(\"a\"));\n    link.href = url;\n    link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/\n    return link.protocol + link.hostname + link.port;\n};\n\nImageLoader.prototype.getPromise = function(container) {\n    return this.timeout(container, this.options.imageTimeout)['catch'](function() {\n        var dummy = new DummyImageContainer(container.src);\n        return dummy.promise.then(function(image) {\n            container.image = image;\n        });\n    });\n};\n\nImageLoader.prototype.get = function(src) {\n    var found = null;\n    return this.images.some(function(img) {\n        return (found = img).src === src;\n    }) ? found : null;\n};\n\nImageLoader.prototype.fetch = function(nodes) {\n    this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));\n    this.images.forEach(function(image, index) {\n        image.promise.then(function() {\n            log(\"Succesfully loaded image #\"+ (index+1), image);\n        }, function(e) {\n            log(\"Failed loading image #\"+ (index+1), image, e);\n        });\n    });\n    this.ready = Promise.all(this.images.map(this.getPromise, this));\n    log(\"Finished searching images\");\n    return this;\n};\n\nImageLoader.prototype.timeout = function(container, timeout) {\n    var timer;\n    var promise = Promise.race([container.promise, new Promise(function(res, reject) {\n        timer = setTimeout(function() {\n            log(\"Timed out loading image\", container);\n            reject(container);\n        }, timeout);\n    })]).then(function(container) {\n        clearTimeout(timer);\n        return container;\n    });\n    promise['catch'](function() {\n        clearTimeout(timer);\n    });\n    return promise;\n};\n\nmodule.exports = ImageLoader;\n\n},{\"./dummyimagecontainer\":7,\"./framecontainer\":10,\"./imagecontainer\":12,\"./lineargradientcontainer\":14,\"./log\":15,\"./promise\":18,\"./proxyimagecontainer\":20,\"./svgcontainer\":26,\"./svgnodecontainer\":27,\"./utils\":29,\"./webkitgradientcontainer\":30}],14:[function(require,module,exports){\nvar GradientContainer = require('./gradientcontainer');\nvar Color = require('./color');\n\nfunction LinearGradientContainer(imageData) {\n    GradientContainer.apply(this, arguments);\n    this.type = this.TYPES.LINEAR;\n\n    var hasDirection = imageData.args[0].match(this.stepRegExp) === null;\n\n    if (hasDirection) {\n        imageData.args[0].split(\" \").reverse().forEach(function(position) {\n            switch(position) {\n            case \"left\":\n                this.x0 = 0;\n                this.x1 = 1;\n                break;\n            case \"top\":\n                this.y0 = 0;\n                this.y1 = 1;\n                break;\n            case \"right\":\n                this.x0 = 1;\n                this.x1 = 0;\n                break;\n            case \"bottom\":\n                this.y0 = 1;\n                this.y1 = 0;\n                break;\n            case \"to\":\n                var y0 = this.y0;\n                var x0 = this.x0;\n                this.y0 = this.y1;\n                this.x0 = this.x1;\n                this.x1 = x0;\n                this.y1 = y0;\n                break;\n            }\n        }, this);\n    } else {\n        this.y0 = 0;\n        this.y1 = 1;\n    }\n\n    this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {\n        var colorStopMatch = colorStop.match(/((?:rgb|rgba)\\(\\d{1,3},\\s\\d{1,3},\\s\\d{1,3}(?:,\\s[0-9\\.]+)?\\)|\\w+)\\s*(\\d{1,3})?(%|px)?/);\n        return {\n            color: new Color(colorStopMatch[1]),\n            stop: colorStopMatch[3] === \"%\" ? colorStopMatch[2] / 100 : null\n        };\n    }, this);\n\n    if (this.colorStops[0].stop === null) {\n        this.colorStops[0].stop = 0;\n    }\n\n    if (this.colorStops[this.colorStops.length - 1].stop === null) {\n        this.colorStops[this.colorStops.length - 1].stop = 1;\n    }\n\n    this.colorStops.forEach(function(colorStop, index) {\n        if (colorStop.stop === null) {\n            this.colorStops.slice(index).some(function(find, count) {\n                if (find.stop !== null) {\n                    colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;\n                    return true;\n                } else {\n                    return false;\n                }\n            }, this);\n        }\n    }, this);\n}\n\nLinearGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\nLinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\\(\\d{1,3},\\s\\d{1,3},\\s\\d{1,3}(?:,\\s[0-9\\.]+)?\\))\\s*(\\d{1,3})?(%|px)?/;\n\nmodule.exports = LinearGradientContainer;\n\n},{\"./color\":5,\"./gradientcontainer\":11}],15:[function(require,module,exports){\nmodule.exports = function() {\n    if (window.html2canvas.logging && window.console && window.console.log) {\n        Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + \"ms\", \"html2canvas:\"].concat([].slice.call(arguments, 0)));\n    }\n};\n\n},{}],16:[function(require,module,exports){\nvar Color = require('./color');\nvar utils = require('./utils');\nvar getBounds = utils.getBounds;\nvar parseBackgrounds = utils.parseBackgrounds;\nvar offsetBounds = utils.offsetBounds;\n\nfunction NodeContainer(node, parent) {\n    this.node = node;\n    this.parent = parent;\n    this.stack = null;\n    this.bounds = null;\n    this.borders = null;\n    this.clip = [];\n    this.backgroundClip = [];\n    this.offsetBounds = null;\n    this.visible = null;\n    this.computedStyles = null;\n    this.colors = {};\n    this.styles = {};\n    this.backgroundImages = null;\n    this.transformData = null;\n    this.transformMatrix = null;\n    this.isPseudoElement = false;\n    this.opacity = null;\n}\n\nNodeContainer.prototype.cloneTo = function(stack) {\n    stack.visible = this.visible;\n    stack.borders = this.borders;\n    stack.bounds = this.bounds;\n    stack.clip = this.clip;\n    stack.backgroundClip = this.backgroundClip;\n    stack.computedStyles = this.computedStyles;\n    stack.styles = this.styles;\n    stack.backgroundImages = this.backgroundImages;\n    stack.opacity = this.opacity;\n};\n\nNodeContainer.prototype.getOpacity = function() {\n    return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;\n};\n\nNodeContainer.prototype.assignStack = function(stack) {\n    this.stack = stack;\n    stack.children.push(this);\n};\n\nNodeContainer.prototype.isElementVisible = function() {\n    return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (\n        this.css('display') !== \"none\" &&\n        this.css('visibility') !== \"hidden\" &&\n        !this.node.hasAttribute(\"data-html2canvas-ignore\") &&\n        (this.node.nodeName !== \"INPUT\" || this.node.getAttribute(\"type\") !== \"hidden\")\n    );\n};\n\nNodeContainer.prototype.css = function(attribute) {\n    if (!this.computedStyles) {\n        this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? \":before\" : \":after\") : this.computedStyle(null);\n    }\n\n    return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);\n};\n\nNodeContainer.prototype.prefixedCss = function(attribute) {\n    var prefixes = [\"webkit\", \"moz\", \"ms\", \"o\"];\n    var value = this.css(attribute);\n    if (value === undefined) {\n        prefixes.some(function(prefix) {\n            value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));\n            return value !== undefined;\n        }, this);\n    }\n    return value === undefined ? null : value;\n};\n\nNodeContainer.prototype.computedStyle = function(type) {\n    return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);\n};\n\nNodeContainer.prototype.cssInt = function(attribute) {\n    var value = parseInt(this.css(attribute), 10);\n    return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html\n};\n\nNodeContainer.prototype.color = function(attribute) {\n    return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));\n};\n\nNodeContainer.prototype.cssFloat = function(attribute) {\n    var value = parseFloat(this.css(attribute));\n    return (isNaN(value)) ? 0 : value;\n};\n\nNodeContainer.prototype.fontWeight = function() {\n    var weight = this.css(\"fontWeight\");\n    switch(parseInt(weight, 10)){\n    case 401:\n        weight = \"bold\";\n        break;\n    case 400:\n        weight = \"normal\";\n        break;\n    }\n    return weight;\n};\n\nNodeContainer.prototype.parseClip = function() {\n    var matches = this.css('clip').match(this.CLIP);\n    if (matches) {\n        return {\n            top: parseInt(matches[1], 10),\n            right: parseInt(matches[2], 10),\n            bottom: parseInt(matches[3], 10),\n            left: parseInt(matches[4], 10)\n        };\n    }\n    return null;\n};\n\nNodeContainer.prototype.parseBackgroundImages = function() {\n    return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css(\"backgroundImage\")));\n};\n\nNodeContainer.prototype.cssList = function(property, index) {\n    var value = (this.css(property) || '').split(',');\n    value = value[index || 0] || value[0] || 'auto';\n    value = value.trim().split(' ');\n    if (value.length === 1) {\n        value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];\n    }\n    return value;\n};\n\nNodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {\n    var size = this.cssList(\"backgroundSize\", index);\n    var width, height;\n\n    if (isPercentage(size[0])) {\n        width = bounds.width * parseFloat(size[0]) / 100;\n    } else if (/contain|cover/.test(size[0])) {\n        var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;\n        return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};\n    } else {\n        width = parseInt(size[0], 10);\n    }\n\n    if (size[0] === 'auto' && size[1] === 'auto') {\n        height = image.height;\n    } else if (size[1] === 'auto') {\n        height = width / image.width * image.height;\n    } else if (isPercentage(size[1])) {\n        height =  bounds.height * parseFloat(size[1]) / 100;\n    } else {\n        height = parseInt(size[1], 10);\n    }\n\n    if (size[0] === 'auto') {\n        width = height / image.height * image.width;\n    }\n\n    return {width: width, height: height};\n};\n\nNodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {\n    var position = this.cssList('backgroundPosition', index);\n    var left, top;\n\n    if (isPercentage(position[0])){\n        left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);\n    } else {\n        left = parseInt(position[0], 10);\n    }\n\n    if (position[1] === 'auto') {\n        top = left / image.width * image.height;\n    } else if (isPercentage(position[1])){\n        top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;\n    } else {\n        top = parseInt(position[1], 10);\n    }\n\n    if (position[0] === 'auto') {\n        left = top / image.height * image.width;\n    }\n\n    return {left: left, top: top};\n};\n\nNodeContainer.prototype.parseBackgroundRepeat = function(index) {\n    return this.cssList(\"backgroundRepeat\", index)[0];\n};\n\nNodeContainer.prototype.parseTextShadows = function() {\n    var textShadow = this.css(\"textShadow\");\n    var results = [];\n\n    if (textShadow && textShadow !== 'none') {\n        var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);\n        for (var i = 0; shadows && (i < shadows.length); i++) {\n            var s = shadows[i].match(this.TEXT_SHADOW_VALUES);\n            results.push({\n                color: new Color(s[0]),\n                offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,\n                offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,\n                blur: s[3] ? s[3].replace('px', '') : 0\n            });\n        }\n    }\n    return results;\n};\n\nNodeContainer.prototype.parseTransform = function() {\n    if (!this.transformData) {\n        if (this.hasTransform()) {\n            var offset = this.parseBounds();\n            var origin = this.prefixedCss(\"transformOrigin\").split(\" \").map(removePx).map(asFloat);\n            origin[0] += offset.left;\n            origin[1] += offset.top;\n            this.transformData = {\n                origin: origin,\n                matrix: this.parseTransformMatrix()\n            };\n        } else {\n            this.transformData = {\n                origin: [0, 0],\n                matrix: [1, 0, 0, 1, 0, 0]\n            };\n        }\n    }\n    return this.transformData;\n};\n\nNodeContainer.prototype.parseTransformMatrix = function() {\n    if (!this.transformMatrix) {\n        var transform = this.prefixedCss(\"transform\");\n        var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;\n        this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];\n    }\n    return this.transformMatrix;\n};\n\nNodeContainer.prototype.parseBounds = function() {\n    return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));\n};\n\nNodeContainer.prototype.hasTransform = function() {\n    return this.parseTransformMatrix().join(\",\") !== \"1,0,0,1,0,0\" || (this.parent && this.parent.hasTransform());\n};\n\nNodeContainer.prototype.getValue = function() {\n    var value = this.node.value || \"\";\n    if (this.node.tagName === \"SELECT\") {\n        value = selectionValue(this.node);\n    } else if (this.node.type === \"password\") {\n        value = Array(value.length + 1).join('\\u2022'); // jshint ignore:line\n    }\n    return value.length === 0 ? (this.node.placeholder || \"\") : value;\n};\n\nNodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\\((.+)\\)/;\nNodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\\([^\\)]+\\)(\\s-?\\d+px){0,})/g;\nNodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\\d+px)|(#.+)|(rgb\\(.+\\))|(rgba\\(.+\\))/g;\nNodeContainer.prototype.CLIP = /^rect\\((\\d+)px,? (\\d+)px,? (\\d+)px,? (\\d+)px\\)$/;\n\nfunction selectionValue(node) {\n    var option = node.options[node.selectedIndex || 0];\n    return option ? (option.text || \"\") : \"\";\n}\n\nfunction parseMatrix(match) {\n    if (match && match[1] === \"matrix\") {\n        return match[2].split(\",\").map(function(s) {\n            return parseFloat(s.trim());\n        });\n    } else if (match && match[1] === \"matrix3d\") {\n        var matrix3d = match[2].split(\",\").map(function(s) {\n          return parseFloat(s.trim());\n        });\n        return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];\n    }\n}\n\nfunction isPercentage(value) {\n    return value.toString().indexOf(\"%\") !== -1;\n}\n\nfunction removePx(str) {\n    return str.replace(\"px\", \"\");\n}\n\nfunction asFloat(str) {\n    return parseFloat(str);\n}\n\nmodule.exports = NodeContainer;\n\n},{\"./color\":5,\"./utils\":29}],17:[function(require,module,exports){\nvar log = require('./log');\nvar punycode = require('punycode');\nvar NodeContainer = require('./nodecontainer');\nvar TextContainer = require('./textcontainer');\nvar PseudoElementContainer = require('./pseudoelementcontainer');\nvar FontMetrics = require('./fontmetrics');\nvar Color = require('./color');\nvar Promise = require('./promise');\nvar StackingContext = require('./stackingcontext');\nvar utils = require('./utils');\nvar bind = utils.bind;\nvar getBounds = utils.getBounds;\nvar parseBackgrounds = utils.parseBackgrounds;\nvar offsetBounds = utils.offsetBounds;\n\nfunction NodeParser(element, renderer, support, imageLoader, options) {\n    log(\"Starting NodeParser\");\n    this.renderer = renderer;\n    this.options = options;\n    this.range = null;\n    this.support = support;\n    this.renderQueue = [];\n    this.stack = new StackingContext(true, 1, element.ownerDocument, null);\n    var parent = new NodeContainer(element, null);\n    if (options.background) {\n        renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));\n    }\n    if (element === element.ownerDocument.documentElement) {\n        // http://www.w3.org/TR/css3-background/#special-backgrounds\n        var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);\n        renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));\n    }\n    parent.visibile = parent.isElementVisible();\n    this.createPseudoHideStyles(element.ownerDocument);\n    this.disableAnimations(element.ownerDocument);\n    this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {\n        return container.visible = container.isElementVisible();\n    }).map(this.getPseudoElements, this));\n    this.fontMetrics = new FontMetrics();\n    log(\"Fetched nodes, total:\", this.nodes.length);\n    log(\"Calculate overflow clips\");\n    this.calculateOverflowClips();\n    log(\"Start fetching images\");\n    this.images = imageLoader.fetch(this.nodes.filter(isElement));\n    this.ready = this.images.ready.then(bind(function() {\n        log(\"Images loaded, starting parsing\");\n        log(\"Creating stacking contexts\");\n        this.createStackingContexts();\n        log(\"Sorting stacking contexts\");\n        this.sortStackingContexts(this.stack);\n        this.parse(this.stack);\n        log(\"Render queue created with \" + this.renderQueue.length + \" items\");\n        return new Promise(bind(function(resolve) {\n            if (!options.async) {\n                this.renderQueue.forEach(this.paint, this);\n                resolve();\n            } else if (typeof(options.async) === \"function\") {\n                options.async.call(this, this.renderQueue, resolve);\n            } else if (this.renderQueue.length > 0){\n                this.renderIndex = 0;\n                this.asyncRenderer(this.renderQueue, resolve);\n            } else {\n                resolve();\n            }\n        }, this));\n    }, this));\n}\n\nNodeParser.prototype.calculateOverflowClips = function() {\n    this.nodes.forEach(function(container) {\n        if (isElement(container)) {\n            if (isPseudoElement(container)) {\n                container.appendToDOM();\n            }\n            container.borders = this.parseBorders(container);\n            var clip = (container.css('overflow') === \"hidden\") ? [container.borders.clip] : [];\n            var cssClip = container.parseClip();\n            if (cssClip && [\"absolute\", \"fixed\"].indexOf(container.css('position')) !== -1) {\n                clip.push([[\"rect\",\n                        container.bounds.left + cssClip.left,\n                        container.bounds.top + cssClip.top,\n                        cssClip.right - cssClip.left,\n                        cssClip.bottom - cssClip.top\n                ]]);\n            }\n            container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;\n            container.backgroundClip = (container.css('overflow') !== \"hidden\") ? container.clip.concat([container.borders.clip]) : container.clip;\n            if (isPseudoElement(container)) {\n                container.cleanDOM();\n            }\n        } else if (isTextNode(container)) {\n            container.clip = hasParentClip(container) ? container.parent.clip : [];\n        }\n        if (!isPseudoElement(container)) {\n            container.bounds = null;\n        }\n    }, this);\n};\n\nfunction hasParentClip(container) {\n    return container.parent && container.parent.clip.length;\n}\n\nNodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {\n    asyncTimer = asyncTimer || Date.now();\n    this.paint(queue[this.renderIndex++]);\n    if (queue.length === this.renderIndex) {\n        resolve();\n    } else if (asyncTimer + 20 > Date.now()) {\n        this.asyncRenderer(queue, resolve, asyncTimer);\n    } else {\n        setTimeout(bind(function() {\n            this.asyncRenderer(queue, resolve);\n        }, this), 0);\n    }\n};\n\nNodeParser.prototype.createPseudoHideStyles = function(document) {\n    this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: \"\" !important; display: none !important; }' +\n        '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: \"\" !important; display: none !important; }');\n};\n\nNodeParser.prototype.disableAnimations = function(document) {\n    this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +\n        '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');\n};\n\nNodeParser.prototype.createStyles = function(document, styles) {\n    var hidePseudoElements = document.createElement('style');\n    hidePseudoElements.innerHTML = styles;\n    document.body.appendChild(hidePseudoElements);\n};\n\nNodeParser.prototype.getPseudoElements = function(container) {\n    var nodes = [[container]];\n    if (container.node.nodeType === Node.ELEMENT_NODE) {\n        var before = this.getPseudoElement(container, \":before\");\n        var after = this.getPseudoElement(container, \":after\");\n\n        if (before) {\n            nodes.push(before);\n        }\n\n        if (after) {\n            nodes.push(after);\n        }\n    }\n    return flatten(nodes);\n};\n\nfunction toCamelCase(str) {\n    return str.replace(/(\\-[a-z])/g, function(match){\n        return match.toUpperCase().replace('-','');\n    });\n}\n\nNodeParser.prototype.getPseudoElement = function(container, type) {\n    var style = container.computedStyle(type);\n    if(!style || !style.content || style.content === \"none\" || style.content === \"-moz-alt-content\" || style.display === \"none\") {\n        return null;\n    }\n\n    var content = stripQuotes(style.content);\n    var isImage = content.substr(0, 3) === 'url';\n    var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');\n    var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);\n\n    for (var i = style.length-1; i >= 0; i--) {\n        var property = toCamelCase(style.item(i));\n        pseudoNode.style[property] = style[property];\n    }\n\n    pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + \" \" + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;\n\n    if (isImage) {\n        pseudoNode.src = parseBackgrounds(content)[0].args[0];\n        return [pseudoContainer];\n    } else {\n        var text = document.createTextNode(content);\n        pseudoNode.appendChild(text);\n        return [pseudoContainer, new TextContainer(text, pseudoContainer)];\n    }\n};\n\n\nNodeParser.prototype.getChildren = function(parentContainer) {\n    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {\n        var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);\n        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== \"TEXTAREA\" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;\n    }, this));\n};\n\nNodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {\n    var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);\n    container.cloneTo(stack);\n    var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;\n    parentStack.contexts.push(stack);\n    container.stack = stack;\n};\n\nNodeParser.prototype.createStackingContexts = function() {\n    this.nodes.forEach(function(container) {\n        if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {\n            this.newStackingContext(container, true);\n        } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {\n            this.newStackingContext(container, false);\n        } else {\n            container.assignStack(container.parent.stack);\n        }\n    }, this);\n};\n\nNodeParser.prototype.isBodyWithTransparentRoot = function(container) {\n    return container.node.nodeName === \"BODY\" && container.parent.color('backgroundColor').isTransparent();\n};\n\nNodeParser.prototype.isRootElement = function(container) {\n    return container.parent === null;\n};\n\nNodeParser.prototype.sortStackingContexts = function(stack) {\n    stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));\n    stack.contexts.forEach(this.sortStackingContexts, this);\n};\n\nNodeParser.prototype.parseTextBounds = function(container) {\n    return function(text, index, textList) {\n        if (container.parent.css(\"textDecoration\").substr(0, 4) !== \"none\" || text.trim().length !== 0) {\n            if (this.support.rangeBounds && !container.parent.hasTransform()) {\n                var offset = textList.slice(0, index).join(\"\").length;\n                return this.getRangeBounds(container.node, offset, text.length);\n            } else if (container.node && typeof(container.node.data) === \"string\") {\n                var replacementNode = container.node.splitText(text.length);\n                var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());\n                container.node = replacementNode;\n                return bounds;\n            }\n        } else if(!this.support.rangeBounds || container.parent.hasTransform()){\n            container.node = container.node.splitText(text.length);\n        }\n        return {};\n    };\n};\n\nNodeParser.prototype.getWrapperBounds = function(node, transform) {\n    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');\n    var parent = node.parentNode,\n        backupText = node.cloneNode(true);\n\n    wrapper.appendChild(node.cloneNode(true));\n    parent.replaceChild(wrapper, node);\n    var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);\n    parent.replaceChild(backupText, wrapper);\n    return bounds;\n};\n\nNodeParser.prototype.getRangeBounds = function(node, offset, length) {\n    var range = this.range || (this.range = node.ownerDocument.createRange());\n    range.setStart(node, offset);\n    range.setEnd(node, offset + length);\n    return range.getBoundingClientRect();\n};\n\nfunction ClearTransform() {}\n\nNodeParser.prototype.parse = function(stack) {\n    // http://www.w3.org/TR/CSS21/visuren.html#z-index\n    var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).\n    var descendantElements = stack.children.filter(isElement);\n    var descendantNonFloats = descendantElements.filter(not(isFloating));\n    var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.\n    var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.\n    var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.\n    var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.\n    var text = stack.children.filter(isTextNode).filter(hasText);\n    var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).\n    negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)\n        .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {\n            this.renderQueue.push(container);\n            if (isStackingContext(container)) {\n                this.parse(container);\n                this.renderQueue.push(new ClearTransform());\n            }\n        }, this);\n};\n\nNodeParser.prototype.paint = function(container) {\n    try {\n        if (container instanceof ClearTransform) {\n            this.renderer.ctx.restore();\n        } else if (isTextNode(container)) {\n            if (isPseudoElement(container.parent)) {\n                container.parent.appendToDOM();\n            }\n            this.paintText(container);\n            if (isPseudoElement(container.parent)) {\n                container.parent.cleanDOM();\n            }\n        } else {\n            this.paintNode(container);\n        }\n    } catch(e) {\n        log(e);\n        if (this.options.strict) {\n            throw e;\n        }\n    }\n};\n\nNodeParser.prototype.paintNode = function(container) {\n    if (isStackingContext(container)) {\n        this.renderer.setOpacity(container.opacity);\n        this.renderer.ctx.save();\n        if (container.hasTransform()) {\n            this.renderer.setTransform(container.parseTransform());\n        }\n    }\n\n    if (container.node.nodeName === \"INPUT\" && container.node.type === \"checkbox\") {\n        this.paintCheckbox(container);\n    } else if (container.node.nodeName === \"INPUT\" && container.node.type === \"radio\") {\n        this.paintRadio(container);\n    } else {\n        this.paintElement(container);\n    }\n};\n\nNodeParser.prototype.paintElement = function(container) {\n    var bounds = container.parseBounds();\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));\n    }, this);\n\n    this.renderer.clip(container.clip, function() {\n        this.renderer.renderBorders(container.borders.borders);\n    }, this);\n\n    this.renderer.clip(container.backgroundClip, function() {\n        switch (container.node.nodeName) {\n        case \"svg\":\n        case \"IFRAME\":\n            var imgContainer = this.images.get(container.node);\n            if (imgContainer) {\n                this.renderer.renderImage(container, bounds, container.borders, imgContainer);\n            } else {\n                log(\"Error loading <\" + container.node.nodeName + \">\", container.node);\n            }\n            break;\n        case \"IMG\":\n            var imageContainer = this.images.get(container.node.src);\n            if (imageContainer) {\n                this.renderer.renderImage(container, bounds, container.borders, imageContainer);\n            } else {\n                log(\"Error loading <img>\", container.node.src);\n            }\n            break;\n        case \"CANVAS\":\n            this.renderer.renderImage(container, bounds, container.borders, {image: container.node});\n            break;\n        case \"SELECT\":\n        case \"INPUT\":\n        case \"TEXTAREA\":\n            this.paintFormValue(container);\n            break;\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintCheckbox = function(container) {\n    var b = container.parseBounds();\n\n    var size = Math.min(b.width, b.height);\n    var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};\n    var r = [3, 3];\n    var radius = [r, r, r, r];\n    var borders = [1,1,1,1].map(function(w) {\n        return {color: new Color('#A5A5A5'), width: w};\n    });\n\n    var borderPoints = calculateCurvePoints(bounds, radius, borders);\n\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color(\"#DEDEDE\"));\n        this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));\n        if (container.node.checked) {\n            this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + \"px\", 'arial');\n            this.renderer.text(\"\\u2714\", bounds.left + size / 6, bounds.top + size - 1);\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintRadio = function(container) {\n    var bounds = container.parseBounds();\n\n    var size = Math.min(bounds.width, bounds.height) - 2;\n\n    this.renderer.clip(container.backgroundClip, function() {\n        this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));\n        if (container.node.checked) {\n            this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));\n        }\n    }, this);\n};\n\nNodeParser.prototype.paintFormValue = function(container) {\n    var value = container.getValue();\n    if (value.length > 0) {\n        var document = container.node.ownerDocument;\n        var wrapper = document.createElement('html2canvaswrapper');\n        var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',\n            'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',\n            'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',\n            'boxSizing', 'whiteSpace', 'wordWrap'];\n\n        properties.forEach(function(property) {\n            try {\n                wrapper.style[property] = container.css(property);\n            } catch(e) {\n                // Older IE has issues with \"border\"\n                log(\"html2canvas: Parse: Exception caught in renderFormValue: \" + e.message);\n            }\n        });\n        var bounds = container.parseBounds();\n        wrapper.style.position = \"fixed\";\n        wrapper.style.left = bounds.left + \"px\";\n        wrapper.style.top = bounds.top + \"px\";\n        wrapper.textContent = value;\n        document.body.appendChild(wrapper);\n        this.paintText(new TextContainer(wrapper.firstChild, container));\n        document.body.removeChild(wrapper);\n    }\n};\n\nNodeParser.prototype.paintText = function(container) {\n    container.applyTextTransform();\n    var characters = punycode.ucs2.decode(container.node.data);\n    var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {\n        return punycode.ucs2.encode([character]);\n    });\n\n    var weight = container.parent.fontWeight();\n    var size = container.parent.css('fontSize');\n    var family = container.parent.css('fontFamily');\n    var shadows = container.parent.parseTextShadows();\n\n    this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);\n    if (shadows.length) {\n        // TODO: support multiple text shadows\n        this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);\n    } else {\n        this.renderer.clearShadow();\n    }\n\n    this.renderer.clip(container.parent.clip, function() {\n        textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {\n            if (bounds) {\n                this.renderer.text(textList[index], bounds.left, bounds.bottom);\n                this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));\n            }\n        }, this);\n    }, this);\n};\n\nNodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {\n    switch(container.css(\"textDecoration\").split(\" \")[0]) {\n    case \"underline\":\n        // Draws a line at the baseline of the font\n        // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size\n        this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n        break;\n    case \"overline\":\n        this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color(\"color\"));\n        break;\n    case \"line-through\":\n        // TODO try and find exact position for line-through\n        this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n        break;\n    }\n};\n\nvar borderColorTransforms = {\n    inset: [\n        [\"darken\", 0.60],\n        [\"darken\", 0.10],\n        [\"darken\", 0.10],\n        [\"darken\", 0.60]\n    ]\n};\n\nNodeParser.prototype.parseBorders = function(container) {\n    var nodeBounds = container.parseBounds();\n    var radius = getBorderRadiusData(container);\n    var borders = [\"Top\", \"Right\", \"Bottom\", \"Left\"].map(function(side, index) {\n        var style = container.css('border' + side + 'Style');\n        var color = container.color('border' + side + 'Color');\n        if (style === \"inset\" && color.isBlack()) {\n            color = new Color([255, 255, 255, color.a]); // this is wrong, but\n        }\n        var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;\n        return {\n            width: container.cssInt('border' + side + 'Width'),\n            color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,\n            args: null\n        };\n    });\n    var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);\n\n    return {\n        clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),\n        borders: calculateBorders(borders, nodeBounds, borderPoints, radius)\n    };\n};\n\nfunction calculateBorders(borders, nodeBounds, borderPoints, radius) {\n    return borders.map(function(border, borderSide) {\n        if (border.width > 0) {\n            var bx = nodeBounds.left;\n            var by = nodeBounds.top;\n            var bw = nodeBounds.width;\n            var bh = nodeBounds.height - (borders[2].width);\n\n            switch(borderSide) {\n            case 0:\n                // top border\n                bh = borders[0].width;\n                border.args = drawSide({\n                        c1: [bx, by],\n                        c2: [bx + bw, by],\n                        c3: [bx + bw - borders[1].width, by + bh],\n                        c4: [bx + borders[3].width, by + bh]\n                    }, radius[0], radius[1],\n                    borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);\n                break;\n            case 1:\n                // right border\n                bx = nodeBounds.left + nodeBounds.width - (borders[1].width);\n                bw = borders[1].width;\n\n                border.args = drawSide({\n                        c1: [bx + bw, by],\n                        c2: [bx + bw, by + bh + borders[2].width],\n                        c3: [bx, by + bh],\n                        c4: [bx, by + borders[0].width]\n                    }, radius[1], radius[2],\n                    borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);\n                break;\n            case 2:\n                // bottom border\n                by = (by + nodeBounds.height) - (borders[2].width);\n                bh = borders[2].width;\n                border.args = drawSide({\n                        c1: [bx + bw, by + bh],\n                        c2: [bx, by + bh],\n                        c3: [bx + borders[3].width, by],\n                        c4: [bx + bw - borders[3].width, by]\n                    }, radius[2], radius[3],\n                    borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);\n                break;\n            case 3:\n                // left border\n                bw = borders[3].width;\n                border.args = drawSide({\n                        c1: [bx, by + bh + borders[2].width],\n                        c2: [bx, by],\n                        c3: [bx + bw, by + borders[0].width],\n                        c4: [bx + bw, by + bh]\n                    }, radius[3], radius[0],\n                    borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);\n                break;\n            }\n        }\n        return border;\n    });\n}\n\nNodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {\n    var backgroundClip = container.css('backgroundClip'),\n        borderArgs = [];\n\n    switch(backgroundClip) {\n    case \"content-box\":\n    case \"padding-box\":\n        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);\n        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);\n        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);\n        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);\n        break;\n\n    default:\n        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);\n        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);\n        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);\n        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);\n        break;\n    }\n\n    return borderArgs;\n};\n\nfunction getCurvePoints(x, y, r1, r2) {\n    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);\n    var ox = (r1) * kappa, // control point offset horizontal\n        oy = (r2) * kappa, // control point offset vertical\n        xm = x + r1, // x-middle\n        ym = y + r2; // y-middle\n    return {\n        topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),\n        topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),\n        bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),\n        bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})\n    };\n}\n\nfunction calculateCurvePoints(bounds, borderRadius, borders) {\n    var x = bounds.left,\n        y = bounds.top,\n        width = bounds.width,\n        height = bounds.height,\n\n        tlh = borderRadius[0][0],\n        tlv = borderRadius[0][1],\n        trh = borderRadius[1][0],\n        trv = borderRadius[1][1],\n        brh = borderRadius[2][0],\n        brv = borderRadius[2][1],\n        blh = borderRadius[3][0],\n        blv = borderRadius[3][1];\n\n        var halfHeight = Math.floor(height / 2);\n        tlh = tlh > halfHeight ? halfHeight : tlh;\n        tlv = tlv > halfHeight ? halfHeight : tlv;\n        trh = trh > halfHeight ? halfHeight : trh;\n        trv = trv > halfHeight ? halfHeight : trv;\n        brh = brh > halfHeight ? halfHeight : brh;\n        brv = brv > halfHeight ? halfHeight : brv;\n        blh = blh > halfHeight ? halfHeight : blh;\n        blv = blv > halfHeight ? halfHeight : blv;\n\n        var topWidth = width - trh,\n        rightHeight = height - brv,\n        bottomWidth = width - brh,\n        leftHeight = height - blv;\n\n    return {\n        topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),\n        topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),\n        topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),\n        topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),\n        bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),\n        bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),\n        bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),\n        bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)\n    };\n}\n\nfunction bezierCurve(start, startControl, endControl, end) {\n    var lerp = function (a, b, t) {\n        return {\n            x: a.x + (b.x - a.x) * t,\n            y: a.y + (b.y - a.y) * t\n        };\n    };\n\n    return {\n        start: start,\n        startControl: startControl,\n        endControl: endControl,\n        end: end,\n        subdivide: function(t) {\n            var ab = lerp(start, startControl, t),\n                bc = lerp(startControl, endControl, t),\n                cd = lerp(endControl, end, t),\n                abbc = lerp(ab, bc, t),\n                bccd = lerp(bc, cd, t),\n                dest = lerp(abbc, bccd, t);\n            return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];\n        },\n        curveTo: function(borderArgs) {\n            borderArgs.push([\"bezierCurve\", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);\n        },\n        curveToReversed: function(borderArgs) {\n            borderArgs.push([\"bezierCurve\", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);\n        }\n    };\n}\n\nfunction drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {\n    var borderArgs = [];\n\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", outer1[1].start.x, outer1[1].start.y]);\n        outer1[1].curveTo(borderArgs);\n    } else {\n        borderArgs.push([ \"line\", borderData.c1[0], borderData.c1[1]]);\n    }\n\n    if (radius2[0] > 0 || radius2[1] > 0) {\n        borderArgs.push([\"line\", outer2[0].start.x, outer2[0].start.y]);\n        outer2[0].curveTo(borderArgs);\n        borderArgs.push([\"line\", inner2[0].end.x, inner2[0].end.y]);\n        inner2[0].curveToReversed(borderArgs);\n    } else {\n        borderArgs.push([\"line\", borderData.c2[0], borderData.c2[1]]);\n        borderArgs.push([\"line\", borderData.c3[0], borderData.c3[1]]);\n    }\n\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", inner1[1].end.x, inner1[1].end.y]);\n        inner1[1].curveToReversed(borderArgs);\n    } else {\n        borderArgs.push([\"line\", borderData.c4[0], borderData.c4[1]]);\n    }\n\n    return borderArgs;\n}\n\nfunction parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {\n    if (radius1[0] > 0 || radius1[1] > 0) {\n        borderArgs.push([\"line\", corner1[0].start.x, corner1[0].start.y]);\n        corner1[0].curveTo(borderArgs);\n        corner1[1].curveTo(borderArgs);\n    } else {\n        borderArgs.push([\"line\", x, y]);\n    }\n\n    if (radius2[0] > 0 || radius2[1] > 0) {\n        borderArgs.push([\"line\", corner2[0].start.x, corner2[0].start.y]);\n    }\n}\n\nfunction negativeZIndex(container) {\n    return container.cssInt(\"zIndex\") < 0;\n}\n\nfunction positiveZIndex(container) {\n    return container.cssInt(\"zIndex\") > 0;\n}\n\nfunction zIndex0(container) {\n    return container.cssInt(\"zIndex\") === 0;\n}\n\nfunction inlineLevel(container) {\n    return [\"inline\", \"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n}\n\nfunction isStackingContext(container) {\n    return (container instanceof StackingContext);\n}\n\nfunction hasText(container) {\n    return container.node.data.trim().length > 0;\n}\n\nfunction noLetterSpacing(container) {\n    return (/^(normal|none|0px)$/.test(container.parent.css(\"letterSpacing\")));\n}\n\nfunction getBorderRadiusData(container) {\n    return [\"TopLeft\", \"TopRight\", \"BottomRight\", \"BottomLeft\"].map(function(side) {\n        var value = container.css('border' + side + 'Radius');\n        var arr = value.split(\" \");\n        if (arr.length <= 1) {\n            arr[1] = arr[0];\n        }\n        return arr.map(asInt);\n    });\n}\n\nfunction renderableNode(node) {\n    return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);\n}\n\nfunction isPositionedForStacking(container) {\n    var position = container.css(\"position\");\n    var zIndex = ([\"absolute\", \"relative\", \"fixed\"].indexOf(position) !== -1) ? container.css(\"zIndex\") : \"auto\";\n    return zIndex !== \"auto\";\n}\n\nfunction isPositioned(container) {\n    return container.css(\"position\") !== \"static\";\n}\n\nfunction isFloating(container) {\n    return container.css(\"float\") !== \"none\";\n}\n\nfunction isInlineBlock(container) {\n    return [\"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n}\n\nfunction not(callback) {\n    var context = this;\n    return function() {\n        return !callback.apply(context, arguments);\n    };\n}\n\nfunction isElement(container) {\n    return container.node.nodeType === Node.ELEMENT_NODE;\n}\n\nfunction isPseudoElement(container) {\n    return container.isPseudoElement === true;\n}\n\nfunction isTextNode(container) {\n    return container.node.nodeType === Node.TEXT_NODE;\n}\n\nfunction zIndexSort(contexts) {\n    return function(a, b) {\n        return (a.cssInt(\"zIndex\") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt(\"zIndex\") + (contexts.indexOf(b) / contexts.length));\n    };\n}\n\nfunction hasOpacity(container) {\n    return container.getOpacity() < 1;\n}\n\nfunction asInt(value) {\n    return parseInt(value, 10);\n}\n\nfunction getWidth(border) {\n    return border.width;\n}\n\nfunction nonIgnoredElement(nodeContainer) {\n    return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || [\"SCRIPT\", \"HEAD\", \"TITLE\", \"OBJECT\", \"BR\", \"OPTION\"].indexOf(nodeContainer.node.nodeName) === -1);\n}\n\nfunction flatten(arrays) {\n    return [].concat.apply([], arrays);\n}\n\nfunction stripQuotes(content) {\n    var first = content.substr(0, 1);\n    return (first === content.substr(content.length - 1) && first.match(/'|\"/)) ? content.substr(1, content.length - 2) : content;\n}\n\nfunction getWords(characters) {\n    var words = [], i = 0, onWordBoundary = false, word;\n    while(characters.length) {\n        if (isWordBoundary(characters[i]) === onWordBoundary) {\n            word = characters.splice(0, i);\n            if (word.length) {\n                words.push(punycode.ucs2.encode(word));\n            }\n            onWordBoundary =! onWordBoundary;\n            i = 0;\n        } else {\n            i++;\n        }\n\n        if (i >= characters.length) {\n            word = characters.splice(0, i);\n            if (word.length) {\n                words.push(punycode.ucs2.encode(word));\n            }\n        }\n    }\n    return words;\n}\n\nfunction isWordBoundary(characterCode) {\n    return [\n        32, // <space>\n        13, // \\r\n        10, // \\n\n        9, // \\t\n        45 // -\n    ].indexOf(characterCode) !== -1;\n}\n\nfunction hasUnicode(string) {\n    return (/[^\\u0000-\\u00ff]/).test(string);\n}\n\nmodule.exports = NodeParser;\n\n},{\"./color\":5,\"./fontmetrics\":9,\"./log\":15,\"./nodecontainer\":16,\"./promise\":18,\"./pseudoelementcontainer\":21,\"./stackingcontext\":24,\"./textcontainer\":28,\"./utils\":29,\"punycode\":3}],18:[function(require,module,exports){\nmodule.exports = require('es6-promise').Promise;\n\n},{\"es6-promise\":1}],19:[function(require,module,exports){\nvar Promise = require('./promise');\nvar XHR = require('./xhr');\nvar utils = require('./utils');\nvar log = require('./log');\nvar createWindowClone = require('./clone');\nvar decode64 = utils.decode64;\n\nfunction Proxy(src, proxyUrl, document) {\n    var supportsCORS = ('withCredentials' in new XMLHttpRequest());\n    if (!proxyUrl) {\n        return Promise.reject(\"No proxy configured\");\n    }\n    var callback = createCallback(supportsCORS);\n    var url = createProxyUrl(proxyUrl, src, callback);\n\n    return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {\n        return decode64(response.content);\n    }));\n}\nvar proxyCount = 0;\n\nfunction ProxyURL(src, proxyUrl, document) {\n    var supportsCORSImage = ('crossOrigin' in new Image());\n    var callback = createCallback(supportsCORSImage);\n    var url = createProxyUrl(proxyUrl, src, callback);\n    return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {\n        return \"data:\" + response.type + \";base64,\" + response.content;\n    }));\n}\n\nfunction jsonp(document, url, callback) {\n    return new Promise(function(resolve, reject) {\n        var s = document.createElement(\"script\");\n        var cleanup = function() {\n            delete window.html2canvas.proxy[callback];\n            document.body.removeChild(s);\n        };\n        window.html2canvas.proxy[callback] = function(response) {\n            cleanup();\n            resolve(response);\n        };\n        s.src = url;\n        s.onerror = function(e) {\n            cleanup();\n            reject(e);\n        };\n        document.body.appendChild(s);\n    });\n}\n\nfunction createCallback(useCORS) {\n    return !useCORS ? \"html2canvas_\" + Date.now() + \"_\" + (++proxyCount) + \"_\" + Math.round(Math.random() * 100000) : \"\";\n}\n\nfunction createProxyUrl(proxyUrl, src, callback) {\n    return proxyUrl + \"?url=\" + encodeURIComponent(src) + (callback.length ? \"&callback=html2canvas.proxy.\" + callback : \"\");\n}\n\nfunction documentFromHTML(src) {\n    return function(html) {\n        var parser = new DOMParser(), doc;\n        try {\n            doc = parser.parseFromString(html, \"text/html\");\n        } catch(e) {\n            log(\"DOMParser not supported, falling back to createHTMLDocument\");\n            doc = document.implementation.createHTMLDocument(\"\");\n            try {\n                doc.open();\n                doc.write(html);\n                doc.close();\n            } catch(ee) {\n                log(\"createHTMLDocument write not supported, falling back to document.body.innerHTML\");\n                doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement\n            }\n        }\n\n        var b = doc.querySelector(\"base\");\n        if (!b || !b.href.host) {\n            var base = doc.createElement(\"base\");\n            base.href = src;\n            doc.head.insertBefore(base, doc.head.firstChild);\n        }\n\n        return doc;\n    };\n}\n\nfunction loadUrlDocument(src, proxy, document, width, height, options) {\n    return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {\n        return createWindowClone(doc, document, width, height, options, 0, 0);\n    });\n}\n\nexports.Proxy = Proxy;\nexports.ProxyURL = ProxyURL;\nexports.loadUrlDocument = loadUrlDocument;\n\n},{\"./clone\":4,\"./log\":15,\"./promise\":18,\"./utils\":29,\"./xhr\":31}],20:[function(require,module,exports){\nvar ProxyURL = require('./proxy').ProxyURL;\nvar Promise = require('./promise');\n\nfunction ProxyImageContainer(src, proxy) {\n    var link = document.createElement(\"a\");\n    link.href = src;\n    src = link.href;\n    this.src = src;\n    this.image = new Image();\n    var self = this;\n    this.promise = new Promise(function(resolve, reject) {\n        self.image.crossOrigin = \"Anonymous\";\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n\n        new ProxyURL(src, proxy, document).then(function(url) {\n            self.image.src = url;\n        })['catch'](reject);\n    });\n}\n\nmodule.exports = ProxyImageContainer;\n\n},{\"./promise\":18,\"./proxy\":19}],21:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction PseudoElementContainer(node, parent, type) {\n    NodeContainer.call(this, node, parent);\n    this.isPseudoElement = true;\n    this.before = type === \":before\";\n}\n\nPseudoElementContainer.prototype.cloneTo = function(stack) {\n    PseudoElementContainer.prototype.cloneTo.call(this, stack);\n    stack.isPseudoElement = true;\n    stack.before = this.before;\n};\n\nPseudoElementContainer.prototype = Object.create(NodeContainer.prototype);\n\nPseudoElementContainer.prototype.appendToDOM = function() {\n    if (this.before) {\n        this.parent.node.insertBefore(this.node, this.parent.node.firstChild);\n    } else {\n        this.parent.node.appendChild(this.node);\n    }\n    this.parent.node.className += \" \" + this.getHideClass();\n};\n\nPseudoElementContainer.prototype.cleanDOM = function() {\n    this.node.parentNode.removeChild(this.node);\n    this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), \"\");\n};\n\nPseudoElementContainer.prototype.getHideClass = function() {\n    return this[\"PSEUDO_HIDE_ELEMENT_CLASS_\" + (this.before ? \"BEFORE\" : \"AFTER\")];\n};\n\nPseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = \"___html2canvas___pseudoelement_before\";\nPseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = \"___html2canvas___pseudoelement_after\";\n\nmodule.exports = PseudoElementContainer;\n\n},{\"./nodecontainer\":16}],22:[function(require,module,exports){\nvar log = require('./log');\n\nfunction Renderer(width, height, images, options, document) {\n    this.width = width;\n    this.height = height;\n    this.images = images;\n    this.options = options;\n    this.document = document;\n}\n\nRenderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {\n    var paddingLeft = container.cssInt('paddingLeft'),\n        paddingTop = container.cssInt('paddingTop'),\n        paddingRight = container.cssInt('paddingRight'),\n        paddingBottom = container.cssInt('paddingBottom'),\n        borders = borderData.borders;\n\n    var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);\n    var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);\n    this.drawImage(\n        imageContainer,\n        0,\n        0,\n        imageContainer.image.width || width,\n        imageContainer.image.height || height,\n        bounds.left + paddingLeft + borders[3].width,\n        bounds.top + paddingTop + borders[0].width,\n        width,\n        height\n    );\n};\n\nRenderer.prototype.renderBackground = function(container, bounds, borderData) {\n    if (bounds.height > 0 && bounds.width > 0) {\n        this.renderBackgroundColor(container, bounds);\n        this.renderBackgroundImage(container, bounds, borderData);\n    }\n};\n\nRenderer.prototype.renderBackgroundColor = function(container, bounds) {\n    var color = container.color(\"backgroundColor\");\n    if (!color.isTransparent()) {\n        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);\n    }\n};\n\nRenderer.prototype.renderBorders = function(borders) {\n    borders.forEach(this.renderBorder, this);\n};\n\nRenderer.prototype.renderBorder = function(data) {\n    if (!data.color.isTransparent() && data.args !== null) {\n        this.drawShape(data.args, data.color);\n    }\n};\n\nRenderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {\n    var backgroundImages = container.parseBackgroundImages();\n    backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {\n        switch(backgroundImage.method) {\n        case \"url\":\n            var image = this.images.get(backgroundImage.args[0]);\n            if (image) {\n                this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);\n            } else {\n                log(\"Error loading background-image\", backgroundImage.args[0]);\n            }\n            break;\n        case \"linear-gradient\":\n        case \"gradient\":\n            var gradientImage = this.images.get(backgroundImage.value);\n            if (gradientImage) {\n                this.renderBackgroundGradient(gradientImage, bounds, borderData);\n            } else {\n                log(\"Error loading background-image\", backgroundImage.args[0]);\n            }\n            break;\n        case \"none\":\n            break;\n        default:\n            log(\"Unknown background-image type\", backgroundImage.args[0]);\n        }\n    }, this);\n};\n\nRenderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {\n    var size = container.parseBackgroundSize(bounds, imageContainer.image, index);\n    var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);\n    var repeat = container.parseBackgroundRepeat(index);\n    switch (repeat) {\n    case \"repeat-x\":\n    case \"repeat no-repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);\n        break;\n    case \"repeat-y\":\n    case \"no-repeat repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);\n        break;\n    case \"no-repeat\":\n        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);\n        break;\n    default:\n        this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);\n        break;\n    }\n};\n\nmodule.exports = Renderer;\n\n},{\"./log\":15}],23:[function(require,module,exports){\nvar Renderer = require('../renderer');\nvar LinearGradientContainer = require('../lineargradientcontainer');\nvar Utils = require('../utils');\nvar log = require('../log');\n\nfunction CanvasRenderer(width, height) {\n    this.ratio = Utils.getDeviceRatio();\n\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    Renderer.apply(this, arguments);\n    this.canvas = this.options.canvas || this.document.createElement(\"canvas\");\n    if (!this.options.canvas) {\n        this.canvas.width = width;\n        this.canvas.height = height;\n\n        if (this.ratio !== 1) {\n            var scale = 1 / this.ratio;\n            this.canvas.style.transform = 'scaleX(' + scale + ') scaleY(' + scale + ')';\n            this.canvas.style.transformOrigin = '0 0';\n        }\n    }\n\n    this.ctx = this.canvas.getContext(\"2d\");\n    this.taintCtx = this.document.createElement(\"canvas\").getContext(\"2d\");\n    this.ctx.textBaseline = \"bottom\";\n    this.variables = {};\n    log(\"Initialized CanvasRenderer with size\", width, \"x\", height);\n}\n\nCanvasRenderer.prototype = Object.create(Renderer.prototype);\n\nCanvasRenderer.prototype.setFillStyle = function(fillStyle) {\n    this.ctx.fillStyle = typeof(fillStyle) === \"object\" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;\n    return this.ctx;\n};\n\nCanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    this.setFillStyle(color).fillRect(left, top, width, height);\n};\n\nCanvasRenderer.prototype.circle = function(left, top, size, color) {\n    this.setFillStyle(color);\n    this.ctx.beginPath();\n    this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);\n    this.ctx.closePath();\n    this.ctx.fill();\n};\n\nCanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    size = Utils.applyRatio(size);\n\n    this.circle(left, top, size, color);\n    this.ctx.strokeStyle = strokeColor.toString();\n    this.ctx.stroke();\n};\n\nCanvasRenderer.prototype.drawShape = function(shape, color) {\n    shape = Utils.applyRatioToShape(shape);\n\n    this.shape(shape);\n    this.setFillStyle(color).fill();\n};\n\nCanvasRenderer.prototype.taints = function(imageContainer) {\n    if (imageContainer.tainted === null) {\n        this.taintCtx.drawImage(imageContainer.image, 0, 0);\n        try {\n            this.taintCtx.getImageData(0, 0, 1, 1);\n            imageContainer.tainted = false;\n        } catch(e) {\n            this.taintCtx = document.createElement(\"canvas\").getContext(\"2d\");\n            imageContainer.tainted = true;\n        }\n    }\n\n    return imageContainer.tainted;\n};\n\nCanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {\n    //Do not scale source coordinates\n    //sx = Utils.applyRatio(sx);\n    //sy = Utils.applyRatio(sy);\n    //sw = Utils.applyRatio(sw);\n    //sh = Utils.applyRatio(sh);\n\n    dx = Utils.applyRatio(dx);\n    dy = Utils.applyRatio(dy);\n    dw = Utils.applyRatio(dw);\n    dh = Utils.applyRatio(dh);\n\n    if (!this.taints(imageContainer) || this.options.allowTaint) {\n        this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);\n    }\n};\n\nCanvasRenderer.prototype.clip = function(shapes, callback, context) {\n    this.ctx.save();\n    shapes.filter(hasEntries).forEach(function(shape) {\n        shape = Utils.applyRatioToShape(shape);\n        this.shape(shape)//.clip();\n    }, this);\n    callback.call(context);\n    this.ctx.restore();\n};\n\nCanvasRenderer.prototype.shape = function(shape) {\n    this.ctx.beginPath();\n    shape.forEach(function(point, index) {\n        if (point[0] === \"rect\") {\n            this.ctx.rect.apply(this.ctx, point.slice(1));\n        } else {\n            this.ctx[(index === 0) ? \"moveTo\" : point[0] + \"To\" ].apply(this.ctx, point.slice(1));\n        }\n    }, this);\n    this.ctx.closePath();\n    return this.ctx;\n};\n\nCanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {\n    size = Utils.applyRatioToFontSize(size);\n    this.setFillStyle(color).font = [style, variant, weight, size, family].join(\" \").split(\",\")[0];\n};\n\nCanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {\n    offsetX = Utils.applyRatio(offsetX);\n    offsetY = Utils.applyRatio(offsetY);\n\n    this.setVariable(\"shadowColor\", color.toString())\n        .setVariable(\"shadowOffsetY\", offsetX)\n        .setVariable(\"shadowOffsetX\", offsetY)\n        .setVariable(\"shadowBlur\", blur);\n};\n\nCanvasRenderer.prototype.clearShadow = function() {\n    this.setVariable(\"shadowColor\", \"rgba(0,0,0,0)\");\n};\n\nCanvasRenderer.prototype.setOpacity = function(opacity) {\n    this.ctx.globalAlpha = opacity;\n};\n\nCanvasRenderer.prototype.setTransform = function(transform) {\n    debugger;\n    this.ctx.translate(transform.origin[0], transform.origin[1]);\n    this.ctx.transform.apply(this.ctx, transform.matrix);\n    this.ctx.translate(-transform.origin[0], -transform.origin[1]);\n};\n\nCanvasRenderer.prototype.setVariable = function(property, value) {\n    if (this.variables[property] !== value) {\n        this.variables[property] = this.ctx[property] = value;\n    }\n\n    return this;\n};\n\nCanvasRenderer.prototype.text = function(text, left, bottom) {\n    left = Utils.applyRatio(left);\n    bottom = Utils.applyRatio(bottom);\n\n    this.ctx.fillText(text, left, bottom);\n};\n\nCanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {\n    debugger;\n    size = Utils.applyRatio(size);\n    bounds = Utils.applyRatioToBounds(bounds);\n    left = Utils.applyRatio(left);\n    top = Utils.applyRatio(top);\n    width = Utils.applyRatio(width);\n    height = Utils.applyRatio(height);\n\n    var shape = [\n        [\"line\", Math.round(left), Math.round(top)],\n        [\"line\", Math.round(left + width), Math.round(top)],\n        [\"line\", Math.round(left + width), Math.round(height + top)],\n        [\"line\", Math.round(left), Math.round(height + top)]\n    ];\n    this.clip([shape], function() {\n        this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);\n    }, this);\n};\n\nCanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {\n    debugger;\n    bounds = Utils.applyRatioToBounds(bounds);\n    size = Utils.applyRatioToBounds(size);\n    backgroundPosition = Utils.applyRatioToBounds(backgroundPosition);\n    borderLeft = Utils.applyRatio(borderLeft);\n    borderTop = Utils.applyRatio(borderTop);\n\n    var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);\n    this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), \"repeat\"));\n    this.ctx.translate(offsetX, offsetY);\n    this.ctx.fill();\n    this.ctx.translate(-offsetX, -offsetY);\n};\n\nCanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {\n    debugger;\n    bounds = Utils.applyRatioToBounds(bounds);\n\n    if (gradientImage instanceof LinearGradientContainer) {\n        var gradient = this.ctx.createLinearGradient(\n            bounds.left + bounds.width * gradientImage.x0,\n            bounds.top + bounds.height * gradientImage.y0,\n            bounds.left +  bounds.width * gradientImage.x1,\n            bounds.top +  bounds.height * gradientImage.y1);\n        gradientImage.colorStops.forEach(function(colorStop) {\n            gradient.addColorStop(colorStop.stop, colorStop.color.toString());\n        });\n        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);\n    }\n};\n\nCanvasRenderer.prototype.resizeImage = function(imageContainer, size) {\n    size = Utils.applyRatioToBounds(size);\n\n    var image = imageContainer.image;\n    if(image.width === size.width && image.height === size.height) {\n        return image;\n    }\n\n    var ctx, canvas = document.createElement('canvas');\n    canvas.width = size.width;\n    canvas.height = size.height;\n    ctx = canvas.getContext(\"2d\");\n    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );\n    return canvas;\n};\n\nfunction hasEntries(array) {\n    return array.length > 0;\n}\n\nmodule.exports = CanvasRenderer;\n\n},{\"../lineargradientcontainer\":14,\"../log\":15,\"../renderer\":22,\"../utils\":29}],24:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction StackingContext(hasOwnStacking, opacity, element, parent) {\n    NodeContainer.call(this, element, parent);\n    this.ownStacking = hasOwnStacking;\n    this.contexts = [];\n    this.children = [];\n    this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;\n}\n\nStackingContext.prototype = Object.create(NodeContainer.prototype);\n\nStackingContext.prototype.getParentStack = function(context) {\n    var parentStack = (this.parent) ? this.parent.stack : null;\n    return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;\n};\n\nmodule.exports = StackingContext;\n\n},{\"./nodecontainer\":16}],25:[function(require,module,exports){\nfunction Support(document) {\n    this.rangeBounds = this.testRangeBounds(document);\n    this.cors = this.testCORS();\n    this.svg = this.testSVG();\n}\n\nSupport.prototype.testRangeBounds = function(document) {\n    var range, testElement, rangeBounds, rangeHeight, support = false;\n\n    if (document.createRange) {\n        range = document.createRange();\n        if (range.getBoundingClientRect) {\n            testElement = document.createElement('boundtest');\n            testElement.style.height = \"123px\";\n            testElement.style.display = \"block\";\n            document.body.appendChild(testElement);\n\n            range.selectNode(testElement);\n            rangeBounds = range.getBoundingClientRect();\n            rangeHeight = rangeBounds.height;\n\n            if (rangeHeight === 123) {\n                support = true;\n            }\n            document.body.removeChild(testElement);\n        }\n    }\n\n    return support;\n};\n\nSupport.prototype.testCORS = function() {\n    return typeof((new Image()).crossOrigin) !== \"undefined\";\n};\n\nSupport.prototype.testSVG = function() {\n    var img = new Image();\n    var canvas = document.createElement(\"canvas\");\n    var ctx =  canvas.getContext(\"2d\");\n    img.src = \"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>\";\n\n    try {\n        ctx.drawImage(img, 0, 0);\n        canvas.toDataURL();\n    } catch(e) {\n        return false;\n    }\n    return true;\n};\n\nmodule.exports = Support;\n\n},{}],26:[function(require,module,exports){\nvar Promise = require('./promise');\nvar XHR = require('./xhr');\nvar decode64 = require('./utils').decode64;\n\nfunction SVGContainer(src) {\n    this.src = src;\n    this.image = null;\n    var self = this;\n\n    this.promise = this.hasFabric().then(function() {\n        return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));\n    }).then(function(svg) {\n        return new Promise(function(resolve) {\n            window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));\n        });\n    });\n}\n\nSVGContainer.prototype.hasFabric = function() {\n    return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error(\"html2canvas.svg.js is not loaded, cannot render svg\")) : Promise.resolve();\n};\n\nSVGContainer.prototype.inlineFormatting = function(src) {\n    return (/^data:image\\/svg\\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);\n};\n\nSVGContainer.prototype.removeContentType = function(src) {\n    return src.replace(/^data:image\\/svg\\+xml(;base64)?,/,'');\n};\n\nSVGContainer.prototype.isInline = function(src) {\n    return (/^data:image\\/svg\\+xml/i.test(src));\n};\n\nSVGContainer.prototype.createCanvas = function(resolve) {\n    var self = this;\n    return function (objects, options) {\n        var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');\n        self.image = canvas.lowerCanvasEl;\n        canvas\n            .setWidth(options.width)\n            .setHeight(options.height)\n            .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))\n            .renderAll();\n        resolve(canvas.lowerCanvasEl);\n    };\n};\n\nSVGContainer.prototype.decode64 = function(str) {\n    return (typeof(window.atob) === \"function\") ? window.atob(str) : decode64(str);\n};\n\nmodule.exports = SVGContainer;\n\n},{\"./promise\":18,\"./utils\":29,\"./xhr\":31}],27:[function(require,module,exports){\nvar SVGContainer = require('./svgcontainer');\nvar Promise = require('./promise');\n\nfunction SVGNodeContainer(node, _native) {\n    this.src = node;\n    this.image = null;\n    var self = this;\n\n    this.promise = _native ? new Promise(function(resolve, reject) {\n        self.image = new Image();\n        self.image.onload = resolve;\n        self.image.onerror = reject;\n        self.image.src = \"data:image/svg+xml,\" + (new XMLSerializer()).serializeToString(node);\n        if (self.image.complete === true) {\n            resolve(self.image);\n        }\n    }) : this.hasFabric().then(function() {\n        return new Promise(function(resolve) {\n            window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));\n        });\n    });\n}\n\nSVGNodeContainer.prototype = Object.create(SVGContainer.prototype);\n\nmodule.exports = SVGNodeContainer;\n\n},{\"./promise\":18,\"./svgcontainer\":26}],28:[function(require,module,exports){\nvar NodeContainer = require('./nodecontainer');\n\nfunction TextContainer(node, parent) {\n    NodeContainer.call(this, node, parent);\n}\n\nTextContainer.prototype = Object.create(NodeContainer.prototype);\n\nTextContainer.prototype.applyTextTransform = function() {\n    this.node.data = this.transform(this.parent.css(\"textTransform\"));\n};\n\nTextContainer.prototype.transform = function(transform) {\n    var text = this.node.data;\n    switch(transform){\n        case \"lowercase\":\n            return text.toLowerCase();\n        case \"capitalize\":\n            return text.replace(/(^|\\s|:|-|\\(|\\))([a-z])/g, capitalize);\n        case \"uppercase\":\n            return text.toUpperCase();\n        default:\n            return text;\n    }\n};\n\nfunction capitalize(m, p1, p2) {\n    if (m.length > 0) {\n        return p1 + p2.toUpperCase();\n    }\n}\n\nmodule.exports = TextContainer;\n\n},{\"./nodecontainer\":16}],29:[function(require,module,exports){\nexports.smallImage = function smallImage() {\n    return \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n};\n\nexports.bind = function(callback, context) {\n    return function() {\n        return callback.apply(context, arguments);\n    };\n};\n\n/*\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n\nexports.decode64 = function(base64) {\n    var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n    var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;\n\n    var output = \"\";\n\n    for (i = 0; i < len; i+=4) {\n        encoded1 = chars.indexOf(base64[i]);\n        encoded2 = chars.indexOf(base64[i+1]);\n        encoded3 = chars.indexOf(base64[i+2]);\n        encoded4 = chars.indexOf(base64[i+3]);\n\n        byte1 = (encoded1 << 2) | (encoded2 >> 4);\n        byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        byte3 = ((encoded3 & 3) << 6) | encoded4;\n        if (encoded3 === 64) {\n            output += String.fromCharCode(byte1);\n        } else if (encoded4 === 64 || encoded4 === -1) {\n            output += String.fromCharCode(byte1, byte2);\n        } else{\n            output += String.fromCharCode(byte1, byte2, byte3);\n        }\n    }\n\n    return output;\n};\n\nexports.getBounds = function(node) {\n    if (node.getBoundingClientRect) {\n        var clientRect = node.getBoundingClientRect();\n        var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;\n        return {\n            top: clientRect.top,\n            bottom: clientRect.bottom || (clientRect.top + clientRect.height),\n            right: clientRect.left + width,\n            left: clientRect.left,\n            width:  width,\n            height: node.offsetHeight == null ? clientRect.height : node.offsetHeight\n        };\n    }\n    return {};\n};\n\nexports.offsetBounds = function(node) {\n    var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};\n\n    return {\n        top: node.offsetTop + parent.top,\n        bottom: node.offsetTop + node.offsetHeight + parent.top,\n        right: node.offsetLeft + parent.left + node.offsetWidth,\n        left: node.offsetLeft + parent.left,\n        width: node.offsetWidth,\n        height: node.offsetHeight\n    };\n};\n\nexports.parseBackgrounds = function(backgroundImage) {\n    var whitespace = ' \\r\\n\\t',\n        method, definition, prefix, prefix_i, block, results = [],\n        mode = 0, numParen = 0, quote, args;\n    var appendResult = function() {\n        if(method) {\n            if (definition.substr(0, 1) === '\"') {\n                definition = definition.substr(1, definition.length - 2);\n            }\n            if (definition) {\n                args.push(definition);\n            }\n            if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {\n                prefix = method.substr(0, prefix_i);\n                method = method.substr(prefix_i);\n            }\n            results.push({\n                prefix: prefix,\n                method: method.toLowerCase(),\n                value: block,\n                args: args,\n                image: null\n            });\n        }\n        args = [];\n        method = prefix = definition = block = '';\n    };\n    args = [];\n    method = prefix = definition = block = '';\n    backgroundImage.split(\"\").forEach(function(c) {\n        if (mode === 0 && whitespace.indexOf(c) > -1) {\n            return;\n        }\n        switch(c) {\n        case '\"':\n            if(!quote) {\n                quote = c;\n            } else if(quote === c) {\n                quote = null;\n            }\n            break;\n        case '(':\n            if(quote) {\n                break;\n            } else if(mode === 0) {\n                mode = 1;\n                block += c;\n                return;\n            } else {\n                numParen++;\n            }\n            break;\n        case ')':\n            if (quote) {\n                break;\n            } else if(mode === 1) {\n                if(numParen === 0) {\n                    mode = 0;\n                    block += c;\n                    appendResult();\n                    return;\n                } else {\n                    numParen--;\n                }\n            }\n            break;\n\n        case ',':\n            if (quote) {\n                break;\n            } else if(mode === 0) {\n                appendResult();\n                return;\n            } else if (mode === 1) {\n                if (numParen === 0 && !method.match(/^url$/i)) {\n                    args.push(definition);\n                    definition = '';\n                    block += c;\n                    return;\n                }\n            }\n            break;\n        }\n\n        block += c;\n        if (mode === 0) {\n            method += c;\n        } else {\n            definition += c;\n        }\n    });\n\n    appendResult();\n    return results;\n};\n\nexports.getDeviceRatio = function() {\n    return window.devicePixelRatio;\n};\n\nexports.applyRatio = function(value) {\n    return value * exports.getDeviceRatio();\n}\n\nexports.applyRatioToBounds = function(bounds) {\n    bounds.width = bounds.width * exports.getDeviceRatio();\n    bounds.top = bounds.top * exports.getDeviceRatio();\n\n    //In case this is a size\n    try {\n        bounds.left = bounds.left * exports.getDeviceRatio();\n        bounds.height = bounds.height * exports.getDeviceRatio();\n    } catch (e) {\n\n    }\n\n    return bounds;\n}\n\nexports.applyRatioToPosition = function(position) {\n    position.left = position.left * exports.getDeviceRatio();\n    position.height = position.height * exports.getDeviceRatio();\n\n    return bounds;\n}\n\nexports.applyRatioToShape = function(shape) {\n    for (var i = 0; i < shape.length; i++) {\n        if (shape[i] instanceof Array) {\n            for (var k = 1; k < shape[i].length; k++) {\n                shape[i][k] = this.applyRatio(shape[i][k]);\n            }\n        }\n    }\n    return shape;\n}\n\nexports.applyRatioToFontSize = function(fontSize) {\n    var numericPart = parseFloat(fontSize) * exports.getDeviceRatio();\n    var stringPart = fontSize.replace(/[0-9]/g, '');\n\n    fontSize = numericPart + stringPart;\n\n    return fontSize;\n}\n\n\n\n},{}],30:[function(require,module,exports){\nvar GradientContainer = require('./gradientcontainer');\n\nfunction WebkitGradientContainer(imageData) {\n    GradientContainer.apply(this, arguments);\n    this.type = (imageData.args[0] === \"linear\") ? this.TYPES.LINEAR : this.TYPES.RADIAL;\n}\n\nWebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\nmodule.exports = WebkitGradientContainer;\n\n},{\"./gradientcontainer\":11}],31:[function(require,module,exports){\nvar Promise = require('./promise');\n\nfunction XHR(url) {\n    return new Promise(function(resolve, reject) {\n        var xhr = new XMLHttpRequest();\n        xhr.open('GET', url);\n\n        xhr.onload = function() {\n            if (xhr.status === 200) {\n                resolve(xhr.responseText);\n            } else {\n                reject(new Error(xhr.statusText));\n            }\n        };\n\n        xhr.onerror = function() {\n            reject(new Error(\"Network Error\"));\n        };\n\n        xhr.send();\n    });\n}\n\nmodule.exports = XHR;\n\n},{\"./promise\":18}]},{},[6])(6)\n});\n/*! VelocityJS.org (1.2.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */\n\n/*************************\n   Velocity jQuery Shim\n*************************/\n\n/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */\n\n/* This file contains the jQuery functions that Velocity relies on, thereby removing Velocity's dependency on a full copy of jQuery, and allowing it to work in any environment. */\n/* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */\n/* Browser support: Using this shim instead of jQuery proper removes support for IE8. */\n\n;(function (window) {\n    /***************\n         Setup\n    ***************/\n\n    /* If jQuery is already loaded, there's no point in loading this shim. */\n    if (window.jQuery) {\n        return;\n    }\n\n    /* jQuery base. */\n    var $ = function (selector, context) {\n        return new $.fn.init(selector, context);\n    };\n\n    /********************\n       Private Methods\n    ********************/\n\n    /* jQuery */\n    $.isWindow = function (obj) {\n        /* jshint eqeqeq: false */\n        return obj != null && obj == obj.window;\n    };\n\n    /* jQuery */\n    $.type = function (obj) {\n        if (obj == null) {\n            return obj + \"\";\n        }\n\n        return typeof obj === \"object\" || typeof obj === \"function\" ?\n            class2type[toString.call(obj)] || \"object\" :\n            typeof obj;\n    };\n\n    /* jQuery */\n    $.isArray = Array.isArray || function (obj) {\n        return $.type(obj) === \"array\";\n    };\n\n    /* jQuery */\n    function isArraylike (obj) {\n        var length = obj.length,\n            type = $.type(obj);\n\n        if (type === \"function\" || $.isWindow(obj)) {\n            return false;\n        }\n\n        if (obj.nodeType === 1 && length) {\n            return true;\n        }\n\n        return type === \"array\" || length === 0 || typeof length === \"number\" && length > 0 && (length - 1) in obj;\n    }\n\n    /***************\n       $ Methods\n    ***************/\n\n    /* jQuery: Support removed for IE<9. */\n    $.isPlainObject = function (obj) {\n        var key;\n\n        if (!obj || $.type(obj) !== \"object\" || obj.nodeType || $.isWindow(obj)) {\n            return false;\n        }\n\n        try {\n            if (obj.constructor &&\n                !hasOwn.call(obj, \"constructor\") &&\n                !hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\")) {\n                return false;\n            }\n        } catch (e) {\n            return false;\n        }\n\n        for (key in obj) {}\n\n        return key === undefined || hasOwn.call(obj, key);\n    };\n\n    /* jQuery */\n    $.each = function(obj, callback, args) {\n        var value,\n            i = 0,\n            length = obj.length,\n            isArray = isArraylike(obj);\n\n        if (args) {\n            if (isArray) {\n                for (; i < length; i++) {\n                    value = callback.apply(obj[i], args);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            } else {\n                for (i in obj) {\n                    value = callback.apply(obj[i], args);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            }\n\n        } else {\n            if (isArray) {\n                for (; i < length; i++) {\n                    value = callback.call(obj[i], i, obj[i]);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            } else {\n                for (i in obj) {\n                    value = callback.call(obj[i], i, obj[i]);\n\n                    if (value === false) {\n                        break;\n                    }\n                }\n            }\n        }\n\n        return obj;\n    };\n\n    /* Custom */\n    $.data = function (node, key, value) {\n        /* $.getData() */\n        if (value === undefined) {\n            var id = node[$.expando],\n                store = id && cache[id];\n\n            if (key === undefined) {\n                return store;\n            } else if (store) {\n                if (key in store) {\n                    return store[key];\n                }\n            }\n        /* $.setData() */\n        } else if (key !== undefined) {\n            var id = node[$.expando] || (node[$.expando] = ++$.uuid);\n\n            cache[id] = cache[id] || {};\n            cache[id][key] = value;\n\n            return value;\n        }\n    };\n\n    /* Custom */\n    $.removeData = function (node, keys) {\n        var id = node[$.expando],\n            store = id && cache[id];\n\n        if (store) {\n            $.each(keys, function(_, key) {\n                delete store[key];\n            });\n        }\n    };\n\n    /* jQuery */\n    $.extend = function () {\n        var src, copyIsArray, copy, name, options, clone,\n            target = arguments[0] || {},\n            i = 1,\n            length = arguments.length,\n            deep = false;\n\n        if (typeof target === \"boolean\") {\n            deep = target;\n\n            target = arguments[i] || {};\n            i++;\n        }\n\n        if (typeof target !== \"object\" && $.type(target) !== \"function\") {\n            target = {};\n        }\n\n        if (i === length) {\n            target = this;\n            i--;\n        }\n\n        for (; i < length; i++) {\n            if ((options = arguments[i]) != null) {\n                for (name in options) {\n                    src = target[name];\n                    copy = options[name];\n\n                    if (target === copy) {\n                        continue;\n                    }\n\n                    if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {\n                        if (copyIsArray) {\n                            copyIsArray = false;\n                            clone = src && $.isArray(src) ? src : [];\n\n                        } else {\n                            clone = src && $.isPlainObject(src) ? src : {};\n                        }\n\n                        target[name] = $.extend(deep, clone, copy);\n\n                    } else if (copy !== undefined) {\n                        target[name] = copy;\n                    }\n                }\n            }\n        }\n\n        return target;\n    };\n\n    /* jQuery 1.4.3 */\n    $.queue = function (elem, type, data) {\n        function $makeArray (arr, results) {\n            var ret = results || [];\n\n            if (arr != null) {\n                if (isArraylike(Object(arr))) {\n                    /* $.merge */\n                    (function(first, second) {\n                        var len = +second.length,\n                            j = 0,\n                            i = first.length;\n\n                        while (j < len) {\n                            first[i++] = second[j++];\n                        }\n\n                        if (len !== len) {\n                            while (second[j] !== undefined) {\n                                first[i++] = second[j++];\n                            }\n                        }\n\n                        first.length = i;\n\n                        return first;\n                    })(ret, typeof arr === \"string\" ? [arr] : arr);\n                } else {\n                    [].push.call(ret, arr);\n                }\n            }\n\n            return ret;\n        }\n\n        if (!elem) {\n            return;\n        }\n\n        type = (type || \"fx\") + \"queue\";\n\n        var q = $.data(elem, type);\n\n        if (!data) {\n            return q || [];\n        }\n\n        if (!q || $.isArray(data)) {\n            q = $.data(elem, type, $makeArray(data));\n        } else {\n            q.push(data);\n        }\n\n        return q;\n    };\n\n    /* jQuery 1.4.3 */\n    $.dequeue = function (elems, type) {\n        /* Custom: Embed element iteration. */\n        $.each(elems.nodeType ? [ elems ] : elems, function(i, elem) {\n            type = type || \"fx\";\n\n            var queue = $.queue(elem, type),\n                fn = queue.shift();\n\n            if (fn === \"inprogress\") {\n                fn = queue.shift();\n            }\n\n            if (fn) {\n                if (type === \"fx\") {\n                    queue.unshift(\"inprogress\");\n                }\n\n                fn.call(elem, function() {\n                    $.dequeue(elem, type);\n                });\n            }\n        });\n    };\n\n    /******************\n       $.fn Methods\n    ******************/\n\n    /* jQuery */\n    $.fn = $.prototype = {\n        init: function (selector) {\n            /* Just return the element wrapped inside an array; don't proceed with the actual jQuery node wrapping process. */\n            if (selector.nodeType) {\n                this[0] = selector;\n\n                return this;\n            } else {\n                throw new Error(\"Not a DOM node.\");\n            }\n        },\n\n        offset: function () {\n            /* jQuery altered code: Dropped disconnected DOM node checking. */\n            var box = this[0].getBoundingClientRect ? this[0].getBoundingClientRect() : { top: 0, left: 0 };\n\n            return {\n                top: box.top + (window.pageYOffset || document.scrollTop  || 0)  - (document.clientTop  || 0),\n                left: box.left + (window.pageXOffset || document.scrollLeft  || 0) - (document.clientLeft || 0)\n            };\n        },\n\n        position: function () {\n            /* jQuery */\n            function offsetParent() {\n                var offsetParent = this.offsetParent || document;\n\n                while (offsetParent && (!offsetParent.nodeType.toLowerCase === \"html\" && offsetParent.style.position === \"static\")) {\n                    offsetParent = offsetParent.offsetParent;\n                }\n\n                return offsetParent || document;\n            }\n\n            /* Zepto */\n            var elem = this[0],\n                offsetParent = offsetParent.apply(elem),\n                offset = this.offset(),\n                parentOffset = /^(?:body|html)$/i.test(offsetParent.nodeName) ? { top: 0, left: 0 } : $(offsetParent).offset()\n\n            offset.top -= parseFloat(elem.style.marginTop) || 0;\n            offset.left -= parseFloat(elem.style.marginLeft) || 0;\n\n            if (offsetParent.style) {\n                parentOffset.top += parseFloat(offsetParent.style.borderTopWidth) || 0\n                parentOffset.left += parseFloat(offsetParent.style.borderLeftWidth) || 0\n            }\n\n            return {\n                top: offset.top - parentOffset.top,\n                left: offset.left - parentOffset.left\n            };\n        }\n    };\n\n    /**********************\n       Private Variables\n    **********************/\n\n    /* For $.data() */\n    var cache = {};\n    $.expando = \"velocity\" + (new Date().getTime());\n    $.uuid = 0;\n\n    /* For $.queue() */\n    var class2type = {},\n        hasOwn = class2type.hasOwnProperty,\n        toString = class2type.toString;\n\n    var types = \"Boolean Number String Function Array Date RegExp Object Error\".split(\" \");\n    for (var i = 0; i < types.length; i++) {\n        class2type[\"[object \" + types[i] + \"]\"] = types[i].toLowerCase();\n    }\n\n    /* Makes $(node) possible, without having to call init. */\n    $.fn.init.prototype = $.fn;\n\n    /* Globalize Velocity onto the window, and assign its Utilities property. */\n    window.Velocity = { Utilities: $ };\n})(window);\n\n/******************\n    Velocity.js\n******************/\n\n;(function (factory) {\n    /* CommonJS module. */\n    if (typeof module === \"object\" && typeof module.exports === \"object\") {\n        module.exports = factory();\n    /* AMD module. */\n    } else if (typeof define === \"function\" && define.amd) {\n        define(factory);\n    /* Browser globals. */\n    } else {\n        factory();\n    }\n}(function() {\nreturn function (global, window, document, undefined) {\n\n    /***************\n        Summary\n    ***************/\n\n    /*\n    - CSS: CSS stack that works independently from the rest of Velocity.\n    - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually.\n      - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options.\n      - Queueing: The logic that runs once the call has reached its point of execution in the element's $.queue() stack.\n                  Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed).\n      - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.\n    - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls.\n    - completeCall(): Handles the cleanup process for each Velocity call.\n    */\n\n    /*********************\n       Helper Functions\n    *********************/\n\n    /* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */\n    var IE = (function() {\n        if (document.documentMode) {\n            return document.documentMode;\n        } else {\n            for (var i = 7; i > 4; i--) {\n                var div = document.createElement(\"div\");\n\n                div.innerHTML = \"<!--[if IE \" + i + \"]><span></span><![endif]-->\";\n\n                if (div.getElementsByTagName(\"span\").length) {\n                    div = null;\n\n                    return i;\n                }\n            }\n        }\n\n        return undefined;\n    })();\n\n    /* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */\n    var rAFShim = (function() {\n        var timeLast = 0;\n\n        return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {\n            var timeCurrent = (new Date()).getTime(),\n                timeDelta;\n\n            /* Dynamically set delay on a per-tick basis to match 60fps. */\n            /* Technique by Erik Moller. MIT license: https://gist.github.com/paulirish/1579671 */\n            timeDelta = Math.max(0, 16 - (timeCurrent - timeLast));\n            timeLast = timeCurrent + timeDelta;\n\n            return setTimeout(function() { callback(timeCurrent + timeDelta); }, timeDelta);\n        };\n    })();\n\n    /* Array compacting. Copyright Lo-Dash. MIT License: https://github.com/lodash/lodash/blob/master/LICENSE.txt */\n    function compactSparseArray (array) {\n        var index = -1,\n            length = array ? array.length : 0,\n            result = [];\n\n        while (++index < length) {\n            var value = array[index];\n\n            if (value) {\n                result.push(value);\n            }\n        }\n\n        return result;\n    }\n\n    function sanitizeElements (elements) {\n        /* Unwrap jQuery/Zepto objects. */\n        if (Type.isWrapped(elements)) {\n            elements = [].slice.call(elements);\n        /* Wrap a single element in an array so that $.each() can iterate with the element instead of its node's children. */\n        } else if (Type.isNode(elements)) {\n            elements = [ elements ];\n        }\n\n        return elements;\n    }\n\n    var Type = {\n        isString: function (variable) {\n            return (typeof variable === \"string\");\n        },\n        isArray: Array.isArray || function (variable) {\n            return Object.prototype.toString.call(variable) === \"[object Array]\";\n        },\n        isFunction: function (variable) {\n            return Object.prototype.toString.call(variable) === \"[object Function]\";\n        },\n        isNode: function (variable) {\n            return variable && variable.nodeType;\n        },\n        /* Copyright Martin Bohm. MIT License: https://gist.github.com/Tomalak/818a78a226a0738eaade */\n        isNodeList: function (variable) {\n            return typeof variable === \"object\" &&\n                /^\\[object (HTMLCollection|NodeList|Object)\\]$/.test(Object.prototype.toString.call(variable)) &&\n                variable.length !== undefined &&\n                (variable.length === 0 || (typeof variable[0] === \"object\" && variable[0].nodeType > 0));\n        },\n        /* Determine if variable is a wrapped jQuery or Zepto element. */\n        isWrapped: function (variable) {\n            return variable && (variable.jquery || (window.Zepto && window.Zepto.zepto.isZ(variable)));\n        },\n        isSVG: function (variable) {\n            return window.SVGElement && (variable instanceof window.SVGElement);\n        },\n        isEmptyObject: function (variable) {\n            for (var name in variable) {\n                return false;\n            }\n\n            return true;\n        }\n    };\n\n    /*****************\n       Dependencies\n    *****************/\n\n    var $,\n        isJQuery = false;\n\n    if (global.fn && global.fn.jquery) {\n        $ = global;\n        isJQuery = true;\n    } else {\n        $ = window.Velocity.Utilities;\n    }\n\n    if (IE <= 8 && !isJQuery) {\n        throw new Error(\"Velocity: IE8 and below require jQuery to be loaded before Velocity.\");\n    } else if (IE <= 7) {\n        /* Revert to jQuery's $.animate(), and lose Velocity's extra features. */\n        jQuery.fn.velocity = jQuery.fn.animate;\n\n        /* Now that $.fn.velocity is aliased, abort this Velocity declaration. */\n        return;\n    }\n\n    /*****************\n        Constants\n    *****************/\n\n    var DURATION_DEFAULT = 400,\n        EASING_DEFAULT = \"swing\";\n\n    /*************\n        State\n    *************/\n\n    var Velocity = {\n        /* Container for page-wide Velocity state data. */\n        State: {\n            /* Detect mobile devices to determine if mobileHA should be turned on. */\n            isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),\n            /* The mobileHA option's behavior changes on older Android devices (Gingerbread, versions 2.3.3-2.3.7). */\n            isAndroid: /Android/i.test(navigator.userAgent),\n            isGingerbread: /Android 2\\.3\\.[3-7]/i.test(navigator.userAgent),\n            isChrome: window.chrome,\n            isFirefox: /Firefox/i.test(navigator.userAgent),\n            /* Create a cached element for re-use when checking for CSS property prefixes. */\n            prefixElement: document.createElement(\"div\"),\n            /* Cache every prefix match to avoid repeating lookups. */\n            prefixMatches: {},\n            /* Cache the anchor used for animating window scrolling. */\n            scrollAnchor: null,\n            /* Cache the browser-specific property names associated with the scroll anchor. */\n            scrollPropertyLeft: null,\n            scrollPropertyTop: null,\n            /* Keep track of whether our RAF tick is running. */\n            isTicking: false,\n            /* Container for every in-progress call to Velocity. */\n            calls: []\n        },\n        /* Velocity's custom CSS stack. Made global for unit testing. */\n        CSS: { /* Defined below. */ },\n        /* A shim of the jQuery utility functions used by Velocity -- provided by Velocity's optional jQuery shim. */\n        Utilities: $,\n        /* Container for the user's custom animation redirects that are referenced by name in place of the properties map argument. */\n        Redirects: { /* Manually registered by the user. */ },\n        Easings: { /* Defined below. */ },\n        /* Attempt to use ES6 Promises by default. Users can override this with a third-party promises library. */\n        Promise: window.Promise,\n        /* Velocity option defaults, which can be overriden by the user. */\n        defaults: {\n            queue: \"\",\n            duration: DURATION_DEFAULT,\n            easing: EASING_DEFAULT,\n            begin: undefined,\n            complete: undefined,\n            progress: undefined,\n            display: undefined,\n            visibility: undefined,\n            loop: false,\n            delay: false,\n            mobileHA: true,\n            /* Advanced: Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */\n            _cacheValues: true\n        },\n        /* A design goal of Velocity is to cache data wherever possible in order to avoid DOM requerying. Accordingly, each element has a data cache. */\n        init: function (element) {\n            $.data(element, \"velocity\", {\n                /* Store whether this is an SVG element, since its properties are retrieved and updated differently than standard HTML elements. */\n                isSVG: Type.isSVG(element),\n                /* Keep track of whether the element is currently being animated by Velocity.\n                   This is used to ensure that property values are not transferred between non-consecutive (stale) calls. */\n                isAnimating: false,\n                /* A reference to the element's live computedStyle object. Learn more here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */\n                computedStyle: null,\n                /* Tween data is cached for each animation on the element so that data can be passed across calls --\n                   in particular, end values are used as subsequent start values in consecutive Velocity calls. */\n                tweensContainer: null,\n                /* The full root property values of each CSS hook being animated on this element are cached so that:\n                   1) Concurrently-animating hooks sharing the same root can have their root values' merged into one while tweening.\n                   2) Post-hook-injection root values can be transferred over to consecutively chained Velocity calls as starting root values. */\n                rootPropertyValueCache: {},\n                /* A cache for transform updates, which must be manually flushed via CSS.flushTransformCache(). */\n                transformCache: {}\n            });\n        },\n        /* A parallel to jQuery's $.css(), used for getting/setting Velocity's hooked CSS properties. */\n        hook: null, /* Defined below. */\n        /* Velocity-wide animation time remapping for testing purposes. */\n        mock: false,\n        version: { major: 1, minor: 2, patch: 2 },\n        /* Set to 1 or 2 (most verbose) to output debug info to console. */\n        debug: false\n    };\n\n    /* Retrieve the appropriate scroll anchor and property name for the browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY */\n    if (window.pageYOffset !== undefined) {\n        Velocity.State.scrollAnchor = window;\n        Velocity.State.scrollPropertyLeft = \"pageXOffset\";\n        Velocity.State.scrollPropertyTop = \"pageYOffset\";\n    } else {\n        Velocity.State.scrollAnchor = document.documentElement || document.body.parentNode || document.body;\n        Velocity.State.scrollPropertyLeft = \"scrollLeft\";\n        Velocity.State.scrollPropertyTop = \"scrollTop\";\n    }\n\n    /* Shorthand alias for jQuery's $.data() utility. */\n    function Data (element) {\n        /* Hardcode a reference to the plugin name. */\n        var response = $.data(element, \"velocity\");\n\n        /* jQuery <=1.4.2 returns null instead of undefined when no match is found. We normalize this behavior. */\n        return response === null ? undefined : response;\n    };\n\n    /**************\n        Easing\n    **************/\n\n    /* Step easing generator. */\n    function generateStep (steps) {\n        return function (p) {\n            return Math.round(p * steps) * (1 / steps);\n        };\n    }\n\n    /* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n    function generateBezier (mX1, mY1, mX2, mY2) {\n        var NEWTON_ITERATIONS = 4,\n            NEWTON_MIN_SLOPE = 0.001,\n            SUBDIVISION_PRECISION = 0.0000001,\n            SUBDIVISION_MAX_ITERATIONS = 10,\n            kSplineTableSize = 11,\n            kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),\n            float32ArraySupported = \"Float32Array\" in window;\n\n        /* Must contain four arguments. */\n        if (arguments.length !== 4) {\n            return false;\n        }\n\n        /* Arguments must be numbers. */\n        for (var i = 0; i < 4; ++i) {\n            if (typeof arguments[i] !== \"number\" || isNaN(arguments[i]) || !isFinite(arguments[i])) {\n                return false;\n            }\n        }\n\n        /* X values must be in the [0, 1] range. */\n        mX1 = Math.min(mX1, 1);\n        mX2 = Math.min(mX2, 1);\n        mX1 = Math.max(mX1, 0);\n        mX2 = Math.max(mX2, 0);\n\n        var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);\n\n        function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }\n        function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }\n        function C (aA1)      { return 3.0 * aA1; }\n\n        function calcBezier (aT, aA1, aA2) {\n            return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;\n        }\n\n        function getSlope (aT, aA1, aA2) {\n            return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);\n        }\n\n        function newtonRaphsonIterate (aX, aGuessT) {\n            for (var i = 0; i < NEWTON_ITERATIONS; ++i) {\n                var currentSlope = getSlope(aGuessT, mX1, mX2);\n\n                if (currentSlope === 0.0) return aGuessT;\n\n                var currentX = calcBezier(aGuessT, mX1, mX2) - aX;\n                aGuessT -= currentX / currentSlope;\n            }\n\n            return aGuessT;\n        }\n\n        function calcSampleValues () {\n            for (var i = 0; i < kSplineTableSize; ++i) {\n                mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);\n            }\n        }\n\n        function binarySubdivide (aX, aA, aB) {\n            var currentX, currentT, i = 0;\n\n            do {\n                currentT = aA + (aB - aA) / 2.0;\n                currentX = calcBezier(currentT, mX1, mX2) - aX;\n                if (currentX > 0.0) {\n                  aB = currentT;\n                } else {\n                  aA = currentT;\n                }\n            } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);\n\n            return currentT;\n        }\n\n        function getTForX (aX) {\n            var intervalStart = 0.0,\n                currentSample = 1,\n                lastSample = kSplineTableSize - 1;\n\n            for (; currentSample != lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {\n                intervalStart += kSampleStepSize;\n            }\n\n            --currentSample;\n\n            var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]),\n                guessForT = intervalStart + dist * kSampleStepSize,\n                initialSlope = getSlope(guessForT, mX1, mX2);\n\n            if (initialSlope >= NEWTON_MIN_SLOPE) {\n                return newtonRaphsonIterate(aX, guessForT);\n            } else if (initialSlope == 0.0) {\n                return guessForT;\n            } else {\n                return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);\n            }\n        }\n\n        var _precomputed = false;\n\n        function precompute() {\n            _precomputed = true;\n            if (mX1 != mY1 || mX2 != mY2) calcSampleValues();\n        }\n\n        var f = function (aX) {\n            if (!_precomputed) precompute();\n            if (mX1 === mY1 && mX2 === mY2) return aX;\n            if (aX === 0) return 0;\n            if (aX === 1) return 1;\n\n            return calcBezier(getTForX(aX), mY1, mY2);\n        };\n\n        f.getControlPoints = function() { return [{ x: mX1, y: mY1 }, { x: mX2, y: mY2 }]; };\n\n        var str = \"generateBezier(\" + [mX1, mY1, mX2, mY2] + \")\";\n        f.toString = function () { return str; };\n\n        return f;\n    }\n\n    /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n    /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass\n       then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */\n    var generateSpringRK4 = (function () {\n        function springAccelerationForState (state) {\n            return (-state.tension * state.x) - (state.friction * state.v);\n        }\n\n        function springEvaluateStateWithDerivative (initialState, dt, derivative) {\n            var state = {\n                x: initialState.x + derivative.dx * dt,\n                v: initialState.v + derivative.dv * dt,\n                tension: initialState.tension,\n                friction: initialState.friction\n            };\n\n            return { dx: state.v, dv: springAccelerationForState(state) };\n        }\n\n        function springIntegrateState (state, dt) {\n            var a = {\n                    dx: state.v,\n                    dv: springAccelerationForState(state)\n                },\n                b = springEvaluateStateWithDerivative(state, dt * 0.5, a),\n                c = springEvaluateStateWithDerivative(state, dt * 0.5, b),\n                d = springEvaluateStateWithDerivative(state, dt, c),\n                dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),\n                dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);\n\n            state.x = state.x + dxdt * dt;\n            state.v = state.v + dvdt * dt;\n\n            return state;\n        }\n\n        return function springRK4Factory (tension, friction, duration) {\n\n            var initState = {\n                    x: -1,\n                    v: 0,\n                    tension: null,\n                    friction: null\n                },\n                path = [0],\n                time_lapsed = 0,\n                tolerance = 1 / 10000,\n                DT = 16 / 1000,\n                have_duration, dt, last_state;\n\n            tension = parseFloat(tension) || 500;\n            friction = parseFloat(friction) || 20;\n            duration = duration || null;\n\n            initState.tension = tension;\n            initState.friction = friction;\n\n            have_duration = duration !== null;\n\n            /* Calculate the actual time it takes for this animation to complete with the provided conditions. */\n            if (have_duration) {\n                /* Run the simulation without a duration. */\n                time_lapsed = springRK4Factory(tension, friction);\n                /* Compute the adjusted time delta. */\n                dt = time_lapsed / duration * DT;\n            } else {\n                dt = DT;\n            }\n\n            while (true) {\n                /* Next/step function .*/\n                last_state = springIntegrateState(last_state || initState, dt);\n                /* Store the position. */\n                path.push(1 + last_state.x);\n                time_lapsed += 16;\n                /* If the change threshold is reached, break. */\n                if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {\n                    break;\n                }\n            }\n\n            /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the\n               computed path and returns a snapshot of the position according to a given percentComplete. */\n            return !have_duration ? time_lapsed : function(percentComplete) { return path[ (percentComplete * (path.length - 1)) | 0 ]; };\n        };\n    }());\n\n    /* jQuery easings. */\n    Velocity.Easings = {\n        linear: function(p) { return p; },\n        swing: function(p) { return 0.5 - Math.cos( p * Math.PI ) / 2 },\n        /* Bonus \"spring\" easing, which is a less exaggerated version of easeInOutElastic. */\n        spring: function(p) { return 1 - (Math.cos(p * 4.5 * Math.PI) * Math.exp(-p * 6)); }\n    };\n\n    /* CSS3 and Robert Penner easings. */\n    $.each(\n        [\n            [ \"ease\", [ 0.25, 0.1, 0.25, 1.0 ] ],\n            [ \"ease-in\", [ 0.42, 0.0, 1.00, 1.0 ] ],\n            [ \"ease-out\", [ 0.00, 0.0, 0.58, 1.0 ] ],\n            [ \"ease-in-out\", [ 0.42, 0.0, 0.58, 1.0 ] ],\n            [ \"easeInSine\", [ 0.47, 0, 0.745, 0.715 ] ],\n            [ \"easeOutSine\", [ 0.39, 0.575, 0.565, 1 ] ],\n            [ \"easeInOutSine\", [ 0.445, 0.05, 0.55, 0.95 ] ],\n            [ \"easeInQuad\", [ 0.55, 0.085, 0.68, 0.53 ] ],\n            [ \"easeOutQuad\", [ 0.25, 0.46, 0.45, 0.94 ] ],\n            [ \"easeInOutQuad\", [ 0.455, 0.03, 0.515, 0.955 ] ],\n            [ \"easeInCubic\", [ 0.55, 0.055, 0.675, 0.19 ] ],\n            [ \"easeOutCubic\", [ 0.215, 0.61, 0.355, 1 ] ],\n            [ \"easeInOutCubic\", [ 0.645, 0.045, 0.355, 1 ] ],\n            [ \"easeInQuart\", [ 0.895, 0.03, 0.685, 0.22 ] ],\n            [ \"easeOutQuart\", [ 0.165, 0.84, 0.44, 1 ] ],\n            [ \"easeInOutQuart\", [ 0.77, 0, 0.175, 1 ] ],\n            [ \"easeInQuint\", [ 0.755, 0.05, 0.855, 0.06 ] ],\n            [ \"easeOutQuint\", [ 0.23, 1, 0.32, 1 ] ],\n            [ \"easeInOutQuint\", [ 0.86, 0, 0.07, 1 ] ],\n            [ \"easeInExpo\", [ 0.95, 0.05, 0.795, 0.035 ] ],\n            [ \"easeOutExpo\", [ 0.19, 1, 0.22, 1 ] ],\n            [ \"easeInOutExpo\", [ 1, 0, 0, 1 ] ],\n            [ \"easeInCirc\", [ 0.6, 0.04, 0.98, 0.335 ] ],\n            [ \"easeOutCirc\", [ 0.075, 0.82, 0.165, 1 ] ],\n            [ \"easeInOutCirc\", [ 0.785, 0.135, 0.15, 0.86 ] ]\n        ], function(i, easingArray) {\n            Velocity.Easings[easingArray[0]] = generateBezier.apply(null, easingArray[1]);\n        });\n\n    /* Determine the appropriate easing type given an easing input. */\n    function getEasing(value, duration) {\n        var easing = value;\n\n        /* The easing option can either be a string that references a pre-registered easing,\n           or it can be a two-/four-item array of integers to be converted into a bezier/spring function. */\n        if (Type.isString(value)) {\n            /* Ensure that the easing has been assigned to jQuery's Velocity.Easings object. */\n            if (!Velocity.Easings[value]) {\n                easing = false;\n            }\n        } else if (Type.isArray(value) && value.length === 1) {\n            easing = generateStep.apply(null, value);\n        } else if (Type.isArray(value) && value.length === 2) {\n            /* springRK4 must be passed the animation's duration. */\n            /* Note: If the springRK4 array contains non-numbers, generateSpringRK4() returns an easing\n               function generated with default tension and friction values. */\n            easing = generateSpringRK4.apply(null, value.concat([ duration ]));\n        } else if (Type.isArray(value) && value.length === 4) {\n            /* Note: If the bezier array contains non-numbers, generateBezier() returns false. */\n            easing = generateBezier.apply(null, value);\n        } else {\n            easing = false;\n        }\n\n        /* Revert to the Velocity-wide default easing type, or fall back to \"swing\" (which is also jQuery's default)\n           if the Velocity-wide default has been incorrectly modified. */\n        if (easing === false) {\n            if (Velocity.Easings[Velocity.defaults.easing]) {\n                easing = Velocity.defaults.easing;\n            } else {\n                easing = EASING_DEFAULT;\n            }\n        }\n\n        return easing;\n    }\n\n    /*****************\n        CSS Stack\n    *****************/\n\n    /* The CSS object is a highly condensed and performant CSS stack that fully replaces jQuery's.\n       It handles the validation, getting, and setting of both standard CSS properties and CSS property hooks. */\n    /* Note: A \"CSS\" shorthand is aliased so that our code is easier to read. */\n    var CSS = Velocity.CSS = {\n\n        /*************\n            RegEx\n        *************/\n\n        RegEx: {\n            isHex: /^#([A-f\\d]{3}){1,2}$/i,\n            /* Unwrap a property value's surrounding text, e.g. \"rgba(4, 3, 2, 1)\" ==> \"4, 3, 2, 1\" and \"rect(4px 3px 2px 1px)\" ==> \"4px 3px 2px 1px\". */\n            valueUnwrap: /^[A-z]+\\((.*)\\)$/i,\n            wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,\n            /* Split a multi-value property into an array of subvalues, e.g. \"rgba(4, 3, 2, 1) 4px 3px 2px 1px\" ==> [ \"rgba(4, 3, 2, 1)\", \"4px\", \"3px\", \"2px\", \"1px\" ]. */\n            valueSplit: /([A-z]+\\(.+\\))|(([A-z0-9#-.]+?)(?=\\s|$))/ig\n        },\n\n        /************\n            Lists\n        ************/\n\n        Lists: {\n            colors: [ \"fill\", \"stroke\", \"stopColor\", \"color\", \"backgroundColor\", \"borderColor\", \"borderTopColor\", \"borderRightColor\", \"borderBottomColor\", \"borderLeftColor\", \"outlineColor\" ],\n            transformsBase: [ \"translateX\", \"translateY\", \"scale\", \"scaleX\", \"scaleY\", \"skewX\", \"skewY\", \"rotateZ\" ],\n            transforms3D: [ \"transformPerspective\", \"translateZ\", \"scaleZ\", \"rotateX\", \"rotateY\" ]\n        },\n\n        /************\n            Hooks\n        ************/\n\n        /* Hooks allow a subproperty (e.g. \"boxShadowBlur\") of a compound-value CSS property\n           (e.g. \"boxShadow: X Y Blur Spread Color\") to be animated as if it were a discrete property. */\n        /* Note: Beyond enabling fine-grained property animation, hooking is necessary since Velocity only\n           tweens properties with single numeric values; unlike CSS transitions, Velocity does not interpolate compound-values. */\n        Hooks: {\n            /********************\n                Registration\n            ********************/\n\n            /* Templates are a concise way of indicating which subproperties must be individually registered for each compound-value CSS property. */\n            /* Each template consists of the compound-value's base name, its constituent subproperty names, and those subproperties' default values. */\n            templates: {\n                \"textShadow\": [ \"Color X Y Blur\", \"black 0px 0px 0px\" ],\n                \"boxShadow\": [ \"Color X Y Blur Spread\", \"black 0px 0px 0px 0px\" ],\n                \"clip\": [ \"Top Right Bottom Left\", \"0px 0px 0px 0px\" ],\n                \"backgroundPosition\": [ \"X Y\", \"0% 0%\" ],\n                \"transformOrigin\": [ \"X Y Z\", \"50% 50% 0px\" ],\n                \"perspectiveOrigin\": [ \"X Y\", \"50% 50%\" ]\n            },\n\n            /* A \"registered\" hook is one that has been converted from its template form into a live,\n               tweenable property. It contains data to associate it with its root property. */\n            registered: {\n                /* Note: A registered hook looks like this ==> textShadowBlur: [ \"textShadow\", 3 ],\n                   which consists of the subproperty's name, the associated root property's name,\n                   and the subproperty's position in the root's value. */\n            },\n            /* Convert the templates into individual hooks then append them to the registered object above. */\n            register: function () {\n                /* Color hooks registration: Colors are defaulted to white -- as opposed to black -- since colors that are\n                   currently set to \"transparent\" default to their respective template below when color-animated,\n                   and white is typically a closer match to transparent than black is. An exception is made for text (\"color\"),\n                   which is almost always set closer to black than white. */\n                for (var i = 0; i < CSS.Lists.colors.length; i++) {\n                    var rgbComponents = (CSS.Lists.colors[i] === \"color\") ? \"0 0 0 1\" : \"255 255 255 1\";\n                    CSS.Hooks.templates[CSS.Lists.colors[i]] = [ \"Red Green Blue Alpha\", rgbComponents ];\n                }\n\n                var rootProperty,\n                    hookTemplate,\n                    hookNames;\n\n                /* In IE, color values inside compound-value properties are positioned at the end the value instead of at the beginning.\n                   Thus, we re-arrange the templates accordingly. */\n                if (IE) {\n                    for (rootProperty in CSS.Hooks.templates) {\n                        hookTemplate = CSS.Hooks.templates[rootProperty];\n                        hookNames = hookTemplate[0].split(\" \");\n\n                        var defaultValues = hookTemplate[1].match(CSS.RegEx.valueSplit);\n\n                        if (hookNames[0] === \"Color\") {\n                            /* Reposition both the hook's name and its default value to the end of their respective strings. */\n                            hookNames.push(hookNames.shift());\n                            defaultValues.push(defaultValues.shift());\n\n                            /* Replace the existing template for the hook's root property. */\n                            CSS.Hooks.templates[rootProperty] = [ hookNames.join(\" \"), defaultValues.join(\" \") ];\n                        }\n                    }\n                }\n\n                /* Hook registration. */\n                for (rootProperty in CSS.Hooks.templates) {\n                    hookTemplate = CSS.Hooks.templates[rootProperty];\n                    hookNames = hookTemplate[0].split(\" \");\n\n                    for (var i in hookNames) {\n                        var fullHookName = rootProperty + hookNames[i],\n                            hookPosition = i;\n\n                        /* For each hook, register its full name (e.g. textShadowBlur) with its root property (e.g. textShadow)\n                           and the hook's position in its template's default value string. */\n                        CSS.Hooks.registered[fullHookName] = [ rootProperty, hookPosition ];\n                    }\n                }\n            },\n\n            /*****************************\n               Injection and Extraction\n            *****************************/\n\n            /* Look up the root property associated with the hook (e.g. return \"textShadow\" for \"textShadowBlur\"). */\n            /* Since a hook cannot be set directly (the browser won't recognize it), style updating for hooks is routed through the hook's root property. */\n            getRoot: function (property) {\n                var hookData = CSS.Hooks.registered[property];\n\n                if (hookData) {\n                    return hookData[0];\n                } else {\n                    /* If there was no hook match, return the property name untouched. */\n                    return property;\n                }\n            },\n            /* Convert any rootPropertyValue, null or otherwise, into a space-delimited list of hook values so that\n               the targeted hook can be injected or extracted at its standard position. */\n            cleanRootPropertyValue: function(rootProperty, rootPropertyValue) {\n                /* If the rootPropertyValue is wrapped with \"rgb()\", \"clip()\", etc., remove the wrapping to normalize the value before manipulation. */\n                if (CSS.RegEx.valueUnwrap.test(rootPropertyValue)) {\n                    rootPropertyValue = rootPropertyValue.match(CSS.RegEx.valueUnwrap)[1];\n                }\n\n                /* If rootPropertyValue is a CSS null-value (from which there's inherently no hook value to extract),\n                   default to the root's default value as defined in CSS.Hooks.templates. */\n                /* Note: CSS null-values include \"none\", \"auto\", and \"transparent\". They must be converted into their\n                   zero-values (e.g. textShadow: \"none\" ==> textShadow: \"0px 0px 0px black\") for hook manipulation to proceed. */\n                if (CSS.Values.isCSSNullValue(rootPropertyValue)) {\n                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];\n                }\n\n                return rootPropertyValue;\n            },\n            /* Extracted the hook's value from its root property's value. This is used to get the starting value of an animating hook. */\n            extractValue: function (fullHookName, rootPropertyValue) {\n                var hookData = CSS.Hooks.registered[fullHookName];\n\n                if (hookData) {\n                    var hookRoot = hookData[0],\n                        hookPosition = hookData[1];\n\n                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);\n\n                    /* Split rootPropertyValue into its constituent hook values then grab the desired hook at its standard position. */\n                    return rootPropertyValue.toString().match(CSS.RegEx.valueSplit)[hookPosition];\n                } else {\n                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */\n                    return rootPropertyValue;\n                }\n            },\n            /* Inject the hook's value into its root property's value. This is used to piece back together the root property\n               once Velocity has updated one of its individually hooked values through tweening. */\n            injectValue: function (fullHookName, hookValue, rootPropertyValue) {\n                var hookData = CSS.Hooks.registered[fullHookName];\n\n                if (hookData) {\n                    var hookRoot = hookData[0],\n                        hookPosition = hookData[1],\n                        rootPropertyValueParts,\n                        rootPropertyValueUpdated;\n\n                    rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);\n\n                    /* Split rootPropertyValue into its individual hook values, replace the targeted value with hookValue,\n                       then reconstruct the rootPropertyValue string. */\n                    rootPropertyValueParts = rootPropertyValue.toString().match(CSS.RegEx.valueSplit);\n                    rootPropertyValueParts[hookPosition] = hookValue;\n                    rootPropertyValueUpdated = rootPropertyValueParts.join(\" \");\n\n                    return rootPropertyValueUpdated;\n                } else {\n                    /* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */\n                    return rootPropertyValue;\n                }\n            }\n        },\n\n        /*******************\n           Normalizations\n        *******************/\n\n        /* Normalizations standardize CSS property manipulation by pollyfilling browser-specific implementations (e.g. opacity)\n           and reformatting special properties (e.g. clip, rgba) to look like standard ones. */\n        Normalizations: {\n            /* Normalizations are passed a normalization target (either the property's name, its extracted value, or its injected value),\n               the targeted element (which may need to be queried), and the targeted property value. */\n            registered: {\n                clip: function (type, element, propertyValue) {\n                    switch (type) {\n                        case \"name\":\n                            return \"clip\";\n                        /* Clip needs to be unwrapped and stripped of its commas during extraction. */\n                        case \"extract\":\n                            var extracted;\n\n                            /* If Velocity also extracted this value, skip extraction. */\n                            if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {\n                                extracted = propertyValue;\n                            } else {\n                                /* Remove the \"rect()\" wrapper. */\n                                extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap);\n\n                                /* Strip off commas. */\n                                extracted = extracted ? extracted[1].replace(/,(\\s+)?/g, \" \") : propertyValue;\n                            }\n\n                            return extracted;\n                        /* Clip needs to be re-wrapped during injection. */\n                        case \"inject\":\n                            return \"rect(\" + propertyValue + \")\";\n                    }\n                },\n\n                blur: function(type, element, propertyValue) {\n                    switch (type) {\n                        case \"name\":\n                            return Velocity.State.isFirefox ? \"filter\" : \"-webkit-filter\";\n                        case \"extract\":\n                            var extracted = parseFloat(propertyValue);\n\n                            /* If extracted is NaN, meaning the value isn't already extracted. */\n                            if (!(extracted || extracted === 0)) {\n                                var blurComponent = propertyValue.toString().match(/blur\\(([0-9]+[A-z]+)\\)/i);\n\n                                /* If the filter string had a blur component, return just the blur value and unit type. */\n                                if (blurComponent) {\n                                    extracted = blurComponent[1];\n                                /* If the component doesn't exist, default blur to 0. */\n                                } else {\n                                    extracted = 0;\n                                }\n                            }\n\n                            return extracted;\n                        /* Blur needs to be re-wrapped during injection. */\n                        case \"inject\":\n                            /* For the blur effect to be fully de-applied, it needs to be set to \"none\" instead of 0. */\n                            if (!parseFloat(propertyValue)) {\n                                return \"none\";\n                            } else {\n                                return \"blur(\" + propertyValue + \")\";\n                            }\n                    }\n                },\n\n                /* <=IE8 do not support the standard opacity property. They use filter:alpha(opacity=INT) instead. */\n                opacity: function (type, element, propertyValue) {\n                    if (IE <= 8) {\n                        switch (type) {\n                            case \"name\":\n                                return \"filter\";\n                            case \"extract\":\n                                /* <=IE8 return a \"filter\" value of \"alpha(opacity=\\d{1,3})\".\n                                   Extract the value and convert it to a decimal value to match the standard CSS opacity property's formatting. */\n                                var extracted = propertyValue.toString().match(/alpha\\(opacity=(.*)\\)/i);\n\n                                if (extracted) {\n                                    /* Convert to decimal value. */\n                                    propertyValue = extracted[1] / 100;\n                                } else {\n                                    /* When extracting opacity, default to 1 since a null value means opacity hasn't been set. */\n                                    propertyValue = 1;\n                                }\n\n                                return propertyValue;\n                            case \"inject\":\n                                /* Opacified elements are required to have their zoom property set to a non-zero value. */\n                                element.style.zoom = 1;\n\n                                /* Setting the filter property on elements with certain font property combinations can result in a\n                                   highly unappealing ultra-bolding effect. There's no way to remedy this throughout a tween, but dropping the\n                                   value altogether (when opacity hits 1) at leasts ensures that the glitch is gone post-tweening. */\n                                if (parseFloat(propertyValue) >= 1) {\n                                    return \"\";\n                                } else {\n                                  /* As per the filter property's spec, convert the decimal value to a whole number and wrap the value. */\n                                  return \"alpha(opacity=\" + parseInt(parseFloat(propertyValue) * 100, 10) + \")\";\n                                }\n                        }\n                    /* With all other browsers, normalization is not required; return the same values that were passed in. */\n                    } else {\n                        switch (type) {\n                            case \"name\":\n                                return \"opacity\";\n                            case \"extract\":\n                                return propertyValue;\n                            case \"inject\":\n                                return propertyValue;\n                        }\n                    }\n                }\n            },\n\n            /*****************************\n                Batched Registrations\n            *****************************/\n\n            /* Note: Batched normalizations extend the CSS.Normalizations.registered object. */\n            register: function () {\n\n                /*****************\n                    Transforms\n                *****************/\n\n                /* Transforms are the subproperties contained by the CSS \"transform\" property. Transforms must undergo normalization\n                   so that they can be referenced in a properties map by their individual names. */\n                /* Note: When transforms are \"set\", they are actually assigned to a per-element transformCache. When all transform\n                   setting is complete complete, CSS.flushTransformCache() must be manually called to flush the values to the DOM.\n                   Transform setting is batched in this way to improve performance: the transform style only needs to be updated\n                   once when multiple transform subproperties are being animated simultaneously. */\n                /* Note: IE9 and Android Gingerbread have support for 2D -- but not 3D -- transforms. Since animating unsupported\n                   transform properties results in the browser ignoring the *entire* transform string, we prevent these 3D values\n                   from being normalized for these browsers so that tweening skips these properties altogether\n                   (since it will ignore them as being unsupported by the browser.) */\n                if (!(IE <= 9) && !Velocity.State.isGingerbread) {\n                    /* Note: Since the standalone CSS \"perspective\" property and the CSS transform \"perspective\" subproperty\n                    share the same name, the latter is given a unique token within Velocity: \"transformPerspective\". */\n                    CSS.Lists.transformsBase = CSS.Lists.transformsBase.concat(CSS.Lists.transforms3D);\n                }\n\n                for (var i = 0; i < CSS.Lists.transformsBase.length; i++) {\n                    /* Wrap the dynamically generated normalization function in a new scope so that transformName's value is\n                    paired with its respective function. (Otherwise, all functions would take the final for loop's transformName.) */\n                    (function() {\n                        var transformName = CSS.Lists.transformsBase[i];\n\n                        CSS.Normalizations.registered[transformName] = function (type, element, propertyValue) {\n                            switch (type) {\n                                /* The normalized property name is the parent \"transform\" property -- the property that is actually set in CSS. */\n                                case \"name\":\n                                    return \"transform\";\n                                /* Transform values are cached onto a per-element transformCache object. */\n                                case \"extract\":\n                                    /* If this transform has yet to be assigned a value, return its null value. */\n                                    if (Data(element) === undefined || Data(element).transformCache[transformName] === undefined) {\n                                        /* Scale CSS.Lists.transformsBase default to 1 whereas all other transform properties default to 0. */\n                                        return /^scale/i.test(transformName) ? 1 : 0;\n                                    /* When transform values are set, they are wrapped in parentheses as per the CSS spec.\n                                       Thus, when extracting their values (for tween calculations), we strip off the parentheses. */\n                                    } else {\n                                        return Data(element).transformCache[transformName].replace(/[()]/g, \"\");\n                                    }\n                                case \"inject\":\n                                    var invalid = false;\n\n                                    /* If an individual transform property contains an unsupported unit type, the browser ignores the *entire* transform property.\n                                       Thus, protect users from themselves by skipping setting for transform values supplied with invalid unit types. */\n                                    /* Switch on the base transform type; ignore the axis by removing the last letter from the transform's name. */\n                                    switch (transformName.substr(0, transformName.length - 1)) {\n                                        /* Whitelist unit types for each transform. */\n                                        case \"translate\":\n                                            invalid = !/(%|px|em|rem|vw|vh|\\d)$/i.test(propertyValue);\n                                            break;\n                                        /* Since an axis-free \"scale\" property is supported as well, a little hack is used here to detect it by chopping off its last letter. */\n                                        case \"scal\":\n                                        case \"scale\":\n                                            /* Chrome on Android has a bug in which scaled elements blur if their initial scale\n                                               value is below 1 (which can happen with forcefeeding). Thus, we detect a yet-unset scale property\n                                               and ensure that its first value is always 1. More info: http://stackoverflow.com/questions/10417890/css3-animations-with-transform-causes-blurred-elements-on-webkit/10417962#10417962 */\n                                            if (Velocity.State.isAndroid && Data(element).transformCache[transformName] === undefined && propertyValue < 1) {\n                                                propertyValue = 1;\n                                            }\n\n                                            invalid = !/(\\d)$/i.test(propertyValue);\n                                            break;\n                                        case \"skew\":\n                                            invalid = !/(deg|\\d)$/i.test(propertyValue);\n                                            break;\n                                        case \"rotate\":\n                                            invalid = !/(deg|\\d)$/i.test(propertyValue);\n                                            break;\n                                    }\n\n                                    if (!invalid) {\n                                        /* As per the CSS spec, wrap the value in parentheses. */\n                                        Data(element).transformCache[transformName] = \"(\" + propertyValue + \")\";\n                                    }\n\n                                    /* Although the value is set on the transformCache object, return the newly-updated value for the calling code to process as normal. */\n                                    return Data(element).transformCache[transformName];\n                            }\n                        };\n                    })();\n                }\n\n                /*************\n                    Colors\n                *************/\n\n                /* Since Velocity only animates a single numeric value per property, color animation is achieved by hooking the individual RGBA components of CSS color properties.\n                   Accordingly, color values must be normalized (e.g. \"#ff0000\", \"red\", and \"rgb(255, 0, 0)\" ==> \"255 0 0 1\") so that their components can be injected/extracted by CSS.Hooks logic. */\n                for (var i = 0; i < CSS.Lists.colors.length; i++) {\n                    /* Wrap the dynamically generated normalization function in a new scope so that colorName's value is paired with its respective function.\n                       (Otherwise, all functions would take the final for loop's colorName.) */\n                    (function () {\n                        var colorName = CSS.Lists.colors[i];\n\n                        /* Note: In IE<=8, which support rgb but not rgba, color properties are reverted to rgb by stripping off the alpha component. */\n                        CSS.Normalizations.registered[colorName] = function(type, element, propertyValue) {\n                            switch (type) {\n                                case \"name\":\n                                    return colorName;\n                                /* Convert all color values into the rgb format. (Old IE can return hex values and color names instead of rgb/rgba.) */\n                                case \"extract\":\n                                    var extracted;\n\n                                    /* If the color is already in its hookable form (e.g. \"255 255 255 1\") due to having been previously extracted, skip extraction. */\n                                    if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {\n                                        extracted = propertyValue;\n                                    } else {\n                                        var converted,\n                                            colorNames = {\n                                                black: \"rgb(0, 0, 0)\",\n                                                blue: \"rgb(0, 0, 255)\",\n                                                gray: \"rgb(128, 128, 128)\",\n                                                green: \"rgb(0, 128, 0)\",\n                                                red: \"rgb(255, 0, 0)\",\n                                                white: \"rgb(255, 255, 255)\"\n                                            };\n\n                                        /* Convert color names to rgb. */\n                                        if (/^[A-z]+$/i.test(propertyValue)) {\n                                            if (colorNames[propertyValue] !== undefined) {\n                                                converted = colorNames[propertyValue]\n                                            } else {\n                                                /* If an unmatched color name is provided, default to black. */\n                                                converted = colorNames.black;\n                                            }\n                                        /* Convert hex values to rgb. */\n                                        } else if (CSS.RegEx.isHex.test(propertyValue)) {\n                                            converted = \"rgb(\" + CSS.Values.hexToRgb(propertyValue).join(\" \") + \")\";\n                                        /* If the provided color doesn't match any of the accepted color formats, default to black. */\n                                        } else if (!(/^rgba?\\(/i.test(propertyValue))) {\n                                            converted = colorNames.black;\n                                        }\n\n                                        /* Remove the surrounding \"rgb/rgba()\" string then replace commas with spaces and strip\n                                           repeated spaces (in case the value included spaces to begin with). */\n                                        extracted = (converted || propertyValue).toString().match(CSS.RegEx.valueUnwrap)[1].replace(/,(\\s+)?/g, \" \");\n                                    }\n\n                                    /* So long as this isn't <=IE8, add a fourth (alpha) component if it's missing and default it to 1 (visible). */\n                                    if (!(IE <= 8) && extracted.split(\" \").length === 3) {\n                                        extracted += \" 1\";\n                                    }\n\n                                    return extracted;\n                                case \"inject\":\n                                    /* If this is IE<=8 and an alpha component exists, strip it off. */\n                                    if (IE <= 8) {\n                                        if (propertyValue.split(\" \").length === 4) {\n                                            propertyValue = propertyValue.split(/\\s+/).slice(0, 3).join(\" \");\n                                        }\n                                    /* Otherwise, add a fourth (alpha) component if it's missing and default it to 1 (visible). */\n                                    } else if (propertyValue.split(\" \").length === 3) {\n                                        propertyValue += \" 1\";\n                                    }\n\n                                    /* Re-insert the browser-appropriate wrapper(\"rgb/rgba()\"), insert commas, and strip off decimal units\n                                       on all values but the fourth (R, G, and B only accept whole numbers). */\n                                    return (IE <= 8 ? \"rgb\" : \"rgba\") + \"(\" + propertyValue.replace(/\\s+/g, \",\").replace(/\\.(\\d)+(?=,)/g, \"\") + \")\";\n                            }\n                        };\n                    })();\n                }\n            }\n        },\n\n        /************************\n           CSS Property Names\n        ************************/\n\n        Names: {\n            /* Camelcase a property name into its JavaScript notation (e.g. \"background-color\" ==> \"backgroundColor\").\n               Camelcasing is used to normalize property names between and across calls. */\n            camelCase: function (property) {\n                return property.replace(/-(\\w)/g, function (match, subMatch) {\n                    return subMatch.toUpperCase();\n                });\n            },\n\n            /* For SVG elements, some properties (namely, dimensional ones) are GET/SET via the element's HTML attributes (instead of via CSS styles). */\n            SVGAttribute: function (property) {\n                var SVGAttributes = \"width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2\";\n\n                /* Certain browsers require an SVG transform to be applied as an attribute. (Otherwise, application via CSS is preferable due to 3D support.) */\n                if (IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) {\n                    SVGAttributes += \"|transform\";\n                }\n\n                return new RegExp(\"^(\" + SVGAttributes + \")$\", \"i\").test(property);\n            },\n\n            /* Determine whether a property should be set with a vendor prefix. */\n            /* If a prefixed version of the property exists, return it. Otherwise, return the original property name.\n               If the property is not at all supported by the browser, return a false flag. */\n            prefixCheck: function (property) {\n                /* If this property has already been checked, return the cached value. */\n                if (Velocity.State.prefixMatches[property]) {\n                    return [ Velocity.State.prefixMatches[property], true ];\n                } else {\n                    var vendors = [ \"\", \"Webkit\", \"Moz\", \"ms\", \"O\" ];\n\n                    for (var i = 0, vendorsLength = vendors.length; i < vendorsLength; i++) {\n                        var propertyPrefixed;\n\n                        if (i === 0) {\n                            propertyPrefixed = property;\n                        } else {\n                            /* Capitalize the first letter of the property to conform to JavaScript vendor prefix notation (e.g. webkitFilter). */\n                            propertyPrefixed = vendors[i] + property.replace(/^\\w/, function(match) { return match.toUpperCase(); });\n                        }\n\n                        /* Check if the browser supports this property as prefixed. */\n                        if (Type.isString(Velocity.State.prefixElement.style[propertyPrefixed])) {\n                            /* Cache the match. */\n                            Velocity.State.prefixMatches[property] = propertyPrefixed;\n\n                            return [ propertyPrefixed, true ];\n                        }\n                    }\n\n                    /* If the browser doesn't support this property in any form, include a false flag so that the caller can decide how to proceed. */\n                    return [ property, false ];\n                }\n            }\n        },\n\n        /************************\n           CSS Property Values\n        ************************/\n\n        Values: {\n            /* Hex to RGB conversion. Copyright Tim Down: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */\n            hexToRgb: function (hex) {\n                var shortformRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n                    longformRegex = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i,\n                    rgbParts;\n\n                hex = hex.replace(shortformRegex, function (m, r, g, b) {\n                    return r + r + g + g + b + b;\n                });\n\n                rgbParts = longformRegex.exec(hex);\n\n                return rgbParts ? [ parseInt(rgbParts[1], 16), parseInt(rgbParts[2], 16), parseInt(rgbParts[3], 16) ] : [ 0, 0, 0 ];\n            },\n\n            isCSSNullValue: function (value) {\n                /* The browser defaults CSS values that have not been set to either 0 or one of several possible null-value strings.\n                   Thus, we check for both falsiness and these special strings. */\n                /* Null-value checking is performed to default the special strings to 0 (for the sake of tweening) or their hook\n                   templates as defined as CSS.Hooks (for the sake of hook injection/extraction). */\n                /* Note: Chrome returns \"rgba(0, 0, 0, 0)\" for an undefined color whereas IE returns \"transparent\". */\n                return (value == 0 || /^(none|auto|transparent|(rgba\\(0, ?0, ?0, ?0\\)))$/i.test(value));\n            },\n\n            /* Retrieve a property's default unit type. Used for assigning a unit type when one is not supplied by the user. */\n            getUnitType: function (property) {\n                if (/^(rotate|skew)/i.test(property)) {\n                    return \"deg\";\n                } else if (/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(property)) {\n                    /* The above properties are unitless. */\n                    return \"\";\n                } else {\n                    /* Default to px for all other properties. */\n                    return \"px\";\n                }\n            },\n\n            /* HTML elements default to an associated display type when they're not set to display:none. */\n            /* Note: This function is used for correctly setting the non-\"none\" display value in certain Velocity redirects, such as fadeIn/Out. */\n            getDisplayType: function (element) {\n                var tagName = element && element.tagName.toString().toLowerCase();\n\n                if (/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(tagName)) {\n                    return \"inline\";\n                } else if (/^(li)$/i.test(tagName)) {\n                    return \"list-item\";\n                } else if (/^(tr)$/i.test(tagName)) {\n                    return \"table-row\";\n                } else if (/^(table)$/i.test(tagName)) {\n                    return \"table\";\n                } else if (/^(tbody)$/i.test(tagName)) {\n                    return \"table-row-group\";\n                /* Default to \"block\" when no match is found. */\n                } else {\n                    return \"block\";\n                }\n            },\n\n            /* The class add/remove functions are used to temporarily apply a \"velocity-animating\" class to elements while they're animating. */\n            addClass: function (element, className) {\n                if (element.classList) {\n                    element.classList.add(className);\n                } else {\n                    element.className += (element.className.length ? \" \" : \"\") + className;\n                }\n            },\n\n            removeClass: function (element, className) {\n                if (element.classList) {\n                    element.classList.remove(className);\n                } else {\n                    element.className = element.className.toString().replace(new RegExp(\"(^|\\\\s)\" + className.split(\" \").join(\"|\") + \"(\\\\s|$)\", \"gi\"), \" \");\n                }\n            }\n        },\n\n        /****************************\n           Style Getting & Setting\n        ****************************/\n\n        /* The singular getPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */\n        getPropertyValue: function (element, property, rootPropertyValue, forceStyleLookup) {\n            /* Get an element's computed property value. */\n            /* Note: Retrieving the value of a CSS property cannot simply be performed by checking an element's\n               style attribute (which only reflects user-defined values). Instead, the browser must be queried for a property's\n               *computed* value. You can read more about getComputedStyle here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */\n            function computePropertyValue (element, property) {\n                /* When box-sizing isn't set to border-box, height and width style values are incorrectly computed when an\n                   element's scrollbars are visible (which expands the element's dimensions). Thus, we defer to the more accurate\n                   offsetHeight/Width property, which includes the total dimensions for interior, border, padding, and scrollbar.\n                   We subtract border and padding to get the sum of interior + scrollbar. */\n                var computedValue = 0;\n\n                /* IE<=8 doesn't support window.getComputedStyle, thus we defer to jQuery, which has an extensive array\n                   of hacks to accurately retrieve IE8 property values. Re-implementing that logic here is not worth bloating the\n                   codebase for a dying browser. The performance repercussions of using jQuery here are minimal since\n                   Velocity is optimized to rarely (and sometimes never) query the DOM. Further, the $.css() codepath isn't that slow. */\n                if (IE <= 8) {\n                    computedValue = $.css(element, property); /* GET */\n                /* All other browsers support getComputedStyle. The returned live object reference is cached onto its\n                   associated element so that it does not need to be refetched upon every GET. */\n                } else {\n                    /* Browsers do not return height and width values for elements that are set to display:\"none\". Thus, we temporarily\n                       toggle display to the element type's default value. */\n                    var toggleDisplay = false;\n\n                    if (/^(width|height)$/.test(property) && CSS.getPropertyValue(element, \"display\") === 0) {\n                        toggleDisplay = true;\n                        CSS.setPropertyValue(element, \"display\", CSS.Values.getDisplayType(element));\n                    }\n\n                    function revertDisplay () {\n                        if (toggleDisplay) {\n                            CSS.setPropertyValue(element, \"display\", \"none\");\n                        }\n                    }\n\n                    if (!forceStyleLookup) {\n                        if (property === \"height\" && CSS.getPropertyValue(element, \"boxSizing\").toString().toLowerCase() !== \"border-box\") {\n                            var contentBoxHeight = element.offsetHeight - (parseFloat(CSS.getPropertyValue(element, \"borderTopWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"borderBottomWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingTop\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingBottom\")) || 0);\n                            revertDisplay();\n\n                            return contentBoxHeight;\n                        } else if (property === \"width\" && CSS.getPropertyValue(element, \"boxSizing\").toString().toLowerCase() !== \"border-box\") {\n                            var contentBoxWidth = element.offsetWidth - (parseFloat(CSS.getPropertyValue(element, \"borderLeftWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"borderRightWidth\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingLeft\")) || 0) - (parseFloat(CSS.getPropertyValue(element, \"paddingRight\")) || 0);\n                            revertDisplay();\n\n                            return contentBoxWidth;\n                        }\n                    }\n\n                    var computedStyle;\n\n                    /* For elements that Velocity hasn't been called on directly (e.g. when Velocity queries the DOM on behalf\n                       of a parent of an element its animating), perform a direct getComputedStyle lookup since the object isn't cached. */\n                    if (Data(element) === undefined) {\n                        computedStyle = window.getComputedStyle(element, null); /* GET */\n                    /* If the computedStyle object has yet to be cached, do so now. */\n                    } else if (!Data(element).computedStyle) {\n                        computedStyle = Data(element).computedStyle = window.getComputedStyle(element, null); /* GET */\n                    /* If computedStyle is cached, use it. */\n                    } else {\n                        computedStyle = Data(element).computedStyle;\n                    }\n\n                    /* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color.\n                       Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse.\n                       So, as a polyfill for querying individual border side colors, we just return the top border's color and animate all borders from that value. */\n                    if (property === \"borderColor\") {\n                        property = \"borderTopColor\";\n                    }\n\n                    /* IE9 has a bug in which the \"filter\" property must be accessed from computedStyle using the getPropertyValue method\n                       instead of a direct property lookup. The getPropertyValue method is slower than a direct lookup, which is why we avoid it by default. */\n                    if (IE === 9 && property === \"filter\") {\n                        computedValue = computedStyle.getPropertyValue(property); /* GET */\n                    } else {\n                        computedValue = computedStyle[property];\n                    }\n\n                    /* Fall back to the property's style value (if defined) when computedValue returns nothing,\n                       which can happen when the element hasn't been painted. */\n                    if (computedValue === \"\" || computedValue === null) {\n                        computedValue = element.style[property];\n                    }\n\n                    revertDisplay();\n                }\n\n                /* For top, right, bottom, and left (TRBL) values that are set to \"auto\" on elements of \"fixed\" or \"absolute\" position,\n                   defer to jQuery for converting \"auto\" to a numeric value. (For elements with a \"static\" or \"relative\" position, \"auto\" has the same\n                   effect as being set to 0, so no conversion is necessary.) */\n                /* An example of why numeric conversion is necessary: When an element with \"position:absolute\" has an untouched \"left\"\n                   property, which reverts to \"auto\", left's value is 0 relative to its parent element, but is often non-zero relative\n                   to its *containing* (not parent) element, which is the nearest \"position:relative\" ancestor or the viewport (and always the viewport in the case of \"position:fixed\"). */\n                if (computedValue === \"auto\" && /^(top|right|bottom|left)$/i.test(property)) {\n                    var position = computePropertyValue(element, \"position\"); /* GET */\n\n                    /* For absolute positioning, jQuery's $.position() only returns values for top and left;\n                       right and bottom will have their \"auto\" value reverted to 0. */\n                    /* Note: A jQuery object must be created here since jQuery doesn't have a low-level alias for $.position().\n                       Not a big deal since we're currently in a GET batch anyway. */\n                    if (position === \"fixed\" || (position === \"absolute\" && /top|left/i.test(property))) {\n                        /* Note: jQuery strips the pixel unit from its returned values; we re-add it here to conform with computePropertyValue's behavior. */\n                        computedValue = $(element).position()[property] + \"px\"; /* GET */\n                    }\n                }\n\n                return computedValue;\n            }\n\n            var propertyValue;\n\n            /* If this is a hooked property (e.g. \"clipLeft\" instead of the root property of \"clip\"),\n               extract the hook's value from a normalized rootPropertyValue using CSS.Hooks.extractValue(). */\n            if (CSS.Hooks.registered[property]) {\n                var hook = property,\n                    hookRoot = CSS.Hooks.getRoot(hook);\n\n                /* If a cached rootPropertyValue wasn't passed in (which Velocity always attempts to do in order to avoid requerying the DOM),\n                   query the DOM for the root property's value. */\n                if (rootPropertyValue === undefined) {\n                    /* Since the browser is now being directly queried, use the official post-prefixing property name for this lookup. */\n                    rootPropertyValue = CSS.getPropertyValue(element, CSS.Names.prefixCheck(hookRoot)[0]); /* GET */\n                }\n\n                /* If this root has a normalization registered, peform the associated normalization extraction. */\n                if (CSS.Normalizations.registered[hookRoot]) {\n                    rootPropertyValue = CSS.Normalizations.registered[hookRoot](\"extract\", element, rootPropertyValue);\n                }\n\n                /* Extract the hook's value. */\n                propertyValue = CSS.Hooks.extractValue(hook, rootPropertyValue);\n\n            /* If this is a normalized property (e.g. \"opacity\" becomes \"filter\" in <=IE8) or \"translateX\" becomes \"transform\"),\n               normalize the property's name and value, and handle the special case of transforms. */\n            /* Note: Normalizing a property is mutually exclusive from hooking a property since hook-extracted values are strictly\n               numerical and therefore do not require normalization extraction. */\n            } else if (CSS.Normalizations.registered[property]) {\n                var normalizedPropertyName,\n                    normalizedPropertyValue;\n\n                normalizedPropertyName = CSS.Normalizations.registered[property](\"name\", element);\n\n                /* Transform values are calculated via normalization extraction (see below), which checks against the element's transformCache.\n                   At no point do transform GETs ever actually query the DOM; initial stylesheet values are never processed.\n                   This is because parsing 3D transform matrices is not always accurate and would bloat our codebase;\n                   thus, normalization extraction defaults initial transform values to their zero-values (e.g. 1 for scaleX and 0 for translateX). */\n                if (normalizedPropertyName !== \"transform\") {\n                    normalizedPropertyValue = computePropertyValue(element, CSS.Names.prefixCheck(normalizedPropertyName)[0]); /* GET */\n\n                    /* If the value is a CSS null-value and this property has a hook template, use that zero-value template so that hooks can be extracted from it. */\n                    if (CSS.Values.isCSSNullValue(normalizedPropertyValue) && CSS.Hooks.templates[property]) {\n                        normalizedPropertyValue = CSS.Hooks.templates[property][1];\n                    }\n                }\n\n                propertyValue = CSS.Normalizations.registered[property](\"extract\", element, normalizedPropertyValue);\n            }\n\n            /* If a (numeric) value wasn't produced via hook extraction or normalization, query the DOM. */\n            if (!/^[\\d-]/.test(propertyValue)) {\n                /* For SVG elements, dimensional properties (which SVGAttribute() detects) are tweened via\n                   their HTML attribute values instead of their CSS style values. */\n                if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {\n                    /* Since the height/width attribute values must be set manually, they don't reflect computed values.\n                       Thus, we use use getBBox() to ensure we always get values for elements with undefined height/width attributes. */\n                    if (/^(height|width)$/i.test(property)) {\n                        /* Firefox throws an error if .getBBox() is called on an SVG that isn't attached to the DOM. */\n                        try {\n                            propertyValue = element.getBBox()[property];\n                        } catch (error) {\n                            propertyValue = 0;\n                        }\n                    /* Otherwise, access the attribute value directly. */\n                    } else {\n                        propertyValue = element.getAttribute(property);\n                    }\n                } else {\n                    propertyValue = computePropertyValue(element, CSS.Names.prefixCheck(property)[0]); /* GET */\n                }\n            }\n\n            /* Since property lookups are for animation purposes (which entails computing the numeric delta between start and end values),\n               convert CSS null-values to an integer of value 0. */\n            if (CSS.Values.isCSSNullValue(propertyValue)) {\n                propertyValue = 0;\n            }\n\n            if (Velocity.debug >= 2) console.log(\"Get \" + property + \": \" + propertyValue);\n\n            return propertyValue;\n        },\n\n        /* The singular setPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */\n        setPropertyValue: function(element, property, propertyValue, rootPropertyValue, scrollData) {\n            var propertyName = property;\n\n            /* In order to be subjected to call options and element queueing, scroll animation is routed through Velocity as if it were a standard CSS property. */\n            if (property === \"scroll\") {\n                /* If a container option is present, scroll the container instead of the browser window. */\n                if (scrollData.container) {\n                    scrollData.container[\"scroll\" + scrollData.direction] = propertyValue;\n                /* Otherwise, Velocity defaults to scrolling the browser window. */\n                } else {\n                    if (scrollData.direction === \"Left\") {\n                        window.scrollTo(propertyValue, scrollData.alternateValue);\n                    } else {\n                        window.scrollTo(scrollData.alternateValue, propertyValue);\n                    }\n                }\n            } else {\n                /* Transforms (translateX, rotateZ, etc.) are applied to a per-element transformCache object, which is manually flushed via flushTransformCache().\n                   Thus, for now, we merely cache transforms being SET. */\n                if (CSS.Normalizations.registered[property] && CSS.Normalizations.registered[property](\"name\", element) === \"transform\") {\n                    /* Perform a normalization injection. */\n                    /* Note: The normalization logic handles the transformCache updating. */\n                    CSS.Normalizations.registered[property](\"inject\", element, propertyValue);\n\n                    propertyName = \"transform\";\n                    propertyValue = Data(element).transformCache[property];\n                } else {\n                    /* Inject hooks. */\n                    if (CSS.Hooks.registered[property]) {\n                        var hookName = property,\n                            hookRoot = CSS.Hooks.getRoot(property);\n\n                        /* If a cached rootPropertyValue was not provided, query the DOM for the hookRoot's current value. */\n                        rootPropertyValue = rootPropertyValue || CSS.getPropertyValue(element, hookRoot); /* GET */\n\n                        propertyValue = CSS.Hooks.injectValue(hookName, propertyValue, rootPropertyValue);\n                        property = hookRoot;\n                    }\n\n                    /* Normalize names and values. */\n                    if (CSS.Normalizations.registered[property]) {\n                        propertyValue = CSS.Normalizations.registered[property](\"inject\", element, propertyValue);\n                        property = CSS.Normalizations.registered[property](\"name\", element);\n                    }\n\n                    /* Assign the appropriate vendor prefix before performing an official style update. */\n                    propertyName = CSS.Names.prefixCheck(property)[0];\n\n                    /* A try/catch is used for IE<=8, which throws an error when \"invalid\" CSS values are set, e.g. a negative width.\n                       Try/catch is avoided for other browsers since it incurs a performance overhead. */\n                    if (IE <= 8) {\n                        try {\n                            element.style[propertyName] = propertyValue;\n                        } catch (error) { if (Velocity.debug) console.log(\"Browser does not support [\" + propertyValue + \"] for [\" + propertyName + \"]\"); }\n                    /* SVG elements have their dimensional properties (width, height, x, y, cx, etc.) applied directly as attributes instead of as styles. */\n                    /* Note: IE8 does not support SVG elements, so it's okay that we skip it for SVG animation. */\n                    } else if (Data(element) && Data(element).isSVG && CSS.Names.SVGAttribute(property)) {\n                        /* Note: For SVG attributes, vendor-prefixed property names are never used. */\n                        /* Note: Not all CSS properties can be animated via attributes, but the browser won't throw an error for unsupported properties. */\n                        element.setAttribute(property, propertyValue);\n                    } else {\n                        var style = element.renderer === \"webgl\" ? element.styleGL : element.style;\n                        style[propertyName] = propertyValue;\n                    }\n\n                    if (Velocity.debug >= 2) console.log(\"Set \" + property + \" (\" + propertyName + \"): \" + propertyValue);\n                }\n            }\n\n            /* Return the normalized property name and value in case the caller wants to know how these values were modified before being applied to the DOM. */\n            return [ propertyName, propertyValue ];\n        },\n\n        /* To increase performance by batching transform updates into a single SET, transforms are not directly applied to an element until flushTransformCache() is called. */\n        /* Note: Velocity applies transform properties in the same order that they are chronogically introduced to the element's CSS styles. */\n        flushTransformCache: function(element) {\n            var transformString = \"\";\n\n            /* Certain browsers require that SVG transforms be applied as an attribute. However, the SVG transform attribute takes a modified version of CSS's transform string\n               (units are dropped and, except for skewX/Y, subproperties are merged into their master property -- e.g. scaleX and scaleY are merged into scale(X Y). */\n            if ((IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) && Data(element).isSVG) {\n                /* Since transform values are stored in their parentheses-wrapped form, we use a helper function to strip out their numeric values.\n                   Further, SVG transform properties only take unitless (representing pixels) values, so it's okay that parseFloat() strips the unit suffixed to the float value. */\n                function getTransformFloat (transformProperty) {\n                    return parseFloat(CSS.getPropertyValue(element, transformProperty));\n                }\n\n                /* Create an object to organize all the transforms that we'll apply to the SVG element. To keep the logic simple,\n                   we process *all* transform properties -- even those that may not be explicitly applied (since they default to their zero-values anyway). */\n                var SVGTransforms = {\n                    translate: [ getTransformFloat(\"translateX\"), getTransformFloat(\"translateY\") ],\n                    skewX: [ getTransformFloat(\"skewX\") ], skewY: [ getTransformFloat(\"skewY\") ],\n                    /* If the scale property is set (non-1), use that value for the scaleX and scaleY values\n                       (this behavior mimics the result of animating all these properties at once on HTML elements). */\n                    scale: getTransformFloat(\"scale\") !== 1 ? [ getTransformFloat(\"scale\"), getTransformFloat(\"scale\") ] : [ getTransformFloat(\"scaleX\"), getTransformFloat(\"scaleY\") ],\n                    /* Note: SVG's rotate transform takes three values: rotation degrees followed by the X and Y values\n                       defining the rotation's origin point. We ignore the origin values (default them to 0). */\n                    rotate: [ getTransformFloat(\"rotateZ\"), 0, 0 ]\n                };\n\n                /* Iterate through the transform properties in the user-defined property map order.\n                   (This mimics the behavior of non-SVG transform animation.) */\n                $.each(Data(element).transformCache, function(transformName) {\n                    /* Except for with skewX/Y, revert the axis-specific transform subproperties to their axis-free master\n                       properties so that they match up with SVG's accepted transform properties. */\n                    if (/^translate/i.test(transformName)) {\n                        transformName = \"translate\";\n                    } else if (/^scale/i.test(transformName)) {\n                        transformName = \"scale\";\n                    } else if (/^rotate/i.test(transformName)) {\n                        transformName = \"rotate\";\n                    }\n\n                    /* Check that we haven't yet deleted the property from the SVGTransforms container. */\n                    if (SVGTransforms[transformName]) {\n                        /* Append the transform property in the SVG-supported transform format. As per the spec, surround the space-delimited values in parentheses. */\n                        transformString += transformName + \"(\" + SVGTransforms[transformName].join(\" \") + \")\" + \" \";\n\n                        /* After processing an SVG transform property, delete it from the SVGTransforms container so we don't\n                           re-insert the same master property if we encounter another one of its axis-specific properties. */\n                        delete SVGTransforms[transformName];\n                    }\n                });\n            } else {\n                var transformValue,\n                    perspective;\n\n                /* Transform properties are stored as members of the transformCache object. Concatenate all the members into a string. */\n                $.each(Data(element).transformCache, function(transformName) {\n                    transformValue = Data(element).transformCache[transformName];\n\n                    /* Transform's perspective subproperty must be set first in order to take effect. Store it temporarily. */\n                    if (transformName === \"transformPerspective\") {\n                        perspective = transformValue;\n                        return true;\n                    }\n\n                    /* IE9 only supports one rotation type, rotateZ, which it refers to as \"rotate\". */\n                    if (IE === 9 && transformName === \"rotateZ\") {\n                        transformName = \"rotate\";\n                    }\n\n                    transformString += transformName + transformValue + \" \";\n                });\n\n                /* If present, set the perspective subproperty first. */\n                if (perspective) {\n                    transformString = \"perspective\" + perspective + \" \" + transformString;\n                }\n            }\n\n            CSS.setPropertyValue(element, \"transform\", transformString);\n        }\n    };\n\n    /* Register hooks and normalizations. */\n    CSS.Hooks.register();\n    CSS.Normalizations.register();\n\n    /* Allow hook setting in the same fashion as jQuery's $.css(). */\n    Velocity.hook = function (elements, arg2, arg3) {\n        var value = undefined;\n\n        elements = sanitizeElements(elements);\n\n        $.each(elements, function(i, element) {\n            /* Initialize Velocity's per-element data cache if this element hasn't previously been animated. */\n            if (Data(element) === undefined) {\n                Velocity.init(element);\n            }\n\n            /* Get property value. If an element set was passed in, only return the value for the first element. */\n            if (arg3 === undefined) {\n                if (value === undefined) {\n                    value = Velocity.CSS.getPropertyValue(element, arg2);\n                }\n            /* Set property value. */\n            } else {\n                /* sPV returns an array of the normalized propertyName/propertyValue pair used to update the DOM. */\n                var adjustedSet = Velocity.CSS.setPropertyValue(element, arg2, arg3);\n\n                /* Transform properties don't automatically set. They have to be flushed to the DOM. */\n                if (adjustedSet[0] === \"transform\") {\n                    Velocity.CSS.flushTransformCache(element);\n                }\n\n                value = adjustedSet;\n            }\n        });\n\n        return value;\n    };\n\n    /*****************\n        Animation\n    *****************/\n\n    var animate = function() {\n\n        /******************\n            Call Chain\n        ******************/\n\n        /* Logic for determining what to return to the call stack when exiting out of Velocity. */\n        function getChain () {\n            /* If we are using the utility function, attempt to return this call's promise. If no promise library was detected,\n               default to null instead of returning the targeted elements so that utility function's return value is standardized. */\n            if (isUtility) {\n                return promiseData.promise || null;\n            /* Otherwise, if we're using $.fn, return the jQuery-/Zepto-wrapped element set. */\n            } else {\n                return elementsWrapped;\n            }\n        }\n\n        /*************************\n           Arguments Assignment\n        *************************/\n\n        /* To allow for expressive CoffeeScript code, Velocity supports an alternative syntax in which \"elements\" (or \"e\"), \"properties\" (or \"p\"), and \"options\" (or \"o\")\n           objects are defined on a container object that's passed in as Velocity's sole argument. */\n        /* Note: Some browsers automatically populate arguments with a \"properties\" object. We detect it by checking for its default \"names\" property. */\n        var syntacticSugar = (arguments[0] && (arguments[0].p || (($.isPlainObject(arguments[0].properties) && !arguments[0].properties.names) || Type.isString(arguments[0].properties)))),\n            /* Whether Velocity was called via the utility function (as opposed to on a jQuery/Zepto object). */\n            isUtility,\n            /* When Velocity is called via the utility function ($.Velocity()/Velocity()), elements are explicitly\n               passed in as the first parameter. Thus, argument positioning varies. We normalize them here. */\n            elementsWrapped,\n            argumentIndex;\n\n        var elements,\n            propertiesMap,\n            options;\n\n        /* Detect jQuery/Zepto elements being animated via the $.fn method. */\n        if (Type.isWrapped(this)) {\n            isUtility = false;\n\n            argumentIndex = 0;\n            elements = this;\n            elementsWrapped = this;\n        /* Otherwise, raw elements are being animated via the utility function. */\n        } else {\n            isUtility = true;\n\n            argumentIndex = 1;\n            elements = syntacticSugar ? (arguments[0].elements || arguments[0].e) : arguments[0];\n        }\n\n        elements = sanitizeElements(elements);\n\n        if (!elements) {\n            return;\n        }\n\n        if (syntacticSugar) {\n            propertiesMap = arguments[0].properties || arguments[0].p;\n            options = arguments[0].options || arguments[0].o;\n        } else {\n            propertiesMap = arguments[argumentIndex];\n            options = arguments[argumentIndex + 1];\n        }\n\n        /* The length of the element set (in the form of a nodeList or an array of elements) is defaulted to 1 in case a\n           single raw DOM element is passed in (which doesn't contain a length property). */\n        var elementsLength = elements.length,\n            elementsIndex = 0;\n\n        /***************************\n            Argument Overloading\n        ***************************/\n\n        /* Support is included for jQuery's argument overloading: $.animate(propertyMap [, duration] [, easing] [, complete]).\n           Overloading is detected by checking for the absence of an object being passed into options. */\n        /* Note: The stop and finish actions do not accept animation options, and are therefore excluded from this check. */\n        if (!/^(stop|finish)$/i.test(propertiesMap) && !$.isPlainObject(options)) {\n            /* The utility function shifts all arguments one position to the right, so we adjust for that offset. */\n            var startingArgumentPosition = argumentIndex + 1;\n\n            options = {};\n\n            /* Iterate through all options arguments */\n            for (var i = startingArgumentPosition; i < arguments.length; i++) {\n                /* Treat a number as a duration. Parse it out. */\n                /* Note: The following RegEx will return true if passed an array with a number as its first item.\n                   Thus, arrays are skipped from this check. */\n                if (!Type.isArray(arguments[i]) && (/^(fast|normal|slow)$/i.test(arguments[i]) || /^\\d/.test(arguments[i]))) {\n                    options.duration = arguments[i];\n                /* Treat strings and arrays as easings. */\n                } else if (Type.isString(arguments[i]) || Type.isArray(arguments[i])) {\n                    options.easing = arguments[i];\n                /* Treat a function as a complete callback. */\n                } else if (Type.isFunction(arguments[i])) {\n                    options.complete = arguments[i];\n                }\n            }\n        }\n\n        /***************\n            Promises\n        ***************/\n\n        var promiseData = {\n                promise: null,\n                resolver: null,\n                rejecter: null\n            };\n\n        /* If this call was made via the utility function (which is the default method of invocation when jQuery/Zepto are not being used), and if\n           promise support was detected, create a promise object for this call and store references to its resolver and rejecter methods. The resolve\n           method is used when a call completes naturally or is prematurely stopped by the user. In both cases, completeCall() handles the associated\n           call cleanup and promise resolving logic. The reject method is used when an invalid set of arguments is passed into a Velocity call. */\n        /* Note: Velocity employs a call-based queueing architecture, which means that stopping an animating element actually stops the full call that\n           triggered it -- not that one element exclusively. Similarly, there is one promise per call, and all elements targeted by a Velocity call are\n           grouped together for the purposes of resolving and rejecting a promise. */\n        if (isUtility && Velocity.Promise) {\n            promiseData.promise = new Velocity.Promise(function (resolve, reject) {\n                promiseData.resolver = resolve;\n                promiseData.rejecter = reject;\n            });\n        }\n\n        /*********************\n           Action Detection\n        *********************/\n\n        /* Velocity's behavior is categorized into \"actions\": Elements can either be specially scrolled into view,\n           or they can be started, stopped, or reversed. If a literal or referenced properties map is passed in as Velocity's\n           first argument, the associated action is \"start\". Alternatively, \"scroll\", \"reverse\", or \"stop\" can be passed in instead of a properties map. */\n        var action;\n\n        switch (propertiesMap) {\n            case \"scroll\":\n                action = \"scroll\";\n                break;\n\n            case \"reverse\":\n                action = \"reverse\";\n                break;\n\n            case \"finish\":\n            case \"stop\":\n                /*******************\n                    Action: Stop\n                *******************/\n\n                /* Clear the currently-active delay on each targeted element. */\n                $.each(elements, function(i, element) {\n                    if (Data(element) && Data(element).delayTimer) {\n                        /* Stop the timer from triggering its cached next() function. */\n                        clearTimeout(Data(element).delayTimer.setTimeout);\n\n                        /* Manually call the next() function so that the subsequent queue items can progress. */\n                        if (Data(element).delayTimer.next) {\n                            Data(element).delayTimer.next();\n                        }\n\n                        delete Data(element).delayTimer;\n                    }\n                });\n\n                var callsToStop = [];\n\n                /* When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have\n                   been applied to multiple elements, in which case all of the call's elements will be stopped. When an element\n                   is stopped, the next item in its animation queue is immediately triggered. */\n                /* An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the \"fx\" queue)\n                   or a custom queue string can be passed in. */\n                /* Note: The stop command runs prior to Velocity's Queueing phase since its behavior is intended to take effect *immediately*,\n                   regardless of the element's current queue state. */\n\n                /* Iterate through every active call. */\n                $.each(Velocity.State.calls, function(i, activeCall) {\n                    /* Inactive calls are set to false by the logic inside completeCall(). Skip them. */\n                    if (activeCall) {\n                        /* Iterate through the active call's targeted elements. */\n                        $.each(activeCall[1], function(k, activeElement) {\n                            /* If true was passed in as a secondary argument, clear absolutely all calls on this element. Otherwise, only\n                               clear calls associated with the relevant queue. */\n                            /* Call stopping logic works as follows:\n                               - options === true --> stop current default queue calls (and queue:false calls), including remaining queued ones.\n                               - options === undefined --> stop current queue:\"\" call and all queue:false calls.\n                               - options === false --> stop only queue:false calls.\n                               - options === \"custom\" --> stop current queue:\"custom\" call, including remaining queued ones (there is no functionality to only clear the currently-running queue:\"custom\" call). */\n                            var queueName = (options === undefined) ? \"\" : options;\n\n                            if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {\n                                return true;\n                            }\n\n                            /* Iterate through the calls targeted by the stop command. */\n                            $.each(elements, function(l, element) {                                \n                                /* Check that this call was applied to the target element. */\n                                if (element === activeElement) {\n                                    /* Optionally clear the remaining queued calls. */\n                                    if (options === true || Type.isString(options)) {\n                                        /* Iterate through the items in the element's queue. */\n                                        $.each($.queue(element, Type.isString(options) ? options : \"\"), function(_, item) {\n                                            /* The queue array can contain an \"inprogress\" string, which we skip. */\n                                            if (Type.isFunction(item)) {\n                                                /* Pass the item's callback a flag indicating that we want to abort from the queue call.\n                                                   (Specifically, the queue will resolve the call's associated promise then abort.)  */\n                                                item(null, true);\n                                            }\n                                        });\n\n                                        /* Clearing the $.queue() array is achieved by resetting it to []. */\n                                        $.queue(element, Type.isString(options) ? options : \"\", []);\n                                    }\n\n                                    if (propertiesMap === \"stop\") {\n                                        /* Since \"reverse\" uses cached start values (the previous call's endValues), these values must be\n                                           changed to reflect the final value that the elements were actually tweened to. */\n                                        /* Note: If only queue:false animations are currently running on an element, it won't have a tweensContainer\n                                           object. Also, queue:false animations can't be reversed. */\n                                        if (Data(element) && Data(element).tweensContainer && queueName !== false) {\n                                            $.each(Data(element).tweensContainer, function(m, activeTween) {\n                                                activeTween.endValue = activeTween.currentValue;\n                                            });\n                                        }\n\n                                        callsToStop.push(i);\n                                    } else if (propertiesMap === \"finish\") {\n                                        /* To get active tweens to finish immediately, we forcefully shorten their durations to 1ms so that\n                                        they finish upon the next rAf tick then proceed with normal call completion logic. */\n                                        activeCall[2].duration = 1;\n                                    }\n                                }\n                            });\n                        });\n                    }\n                });\n\n                /* Prematurely call completeCall() on each matched active call. Pass an additional flag for \"stop\" to indicate\n                   that the complete callback and display:none setting should be skipped since we're completing prematurely. */\n                if (propertiesMap === \"stop\") {\n                    $.each(callsToStop, function(i, j) {\n                        completeCall(j, true);\n                    });\n\n                    if (promiseData.promise) {\n                        /* Immediately resolve the promise associated with this stop call since stop runs synchronously. */\n                        promiseData.resolver(elements);\n                    }\n                }\n\n                /* Since we're stopping, and not proceeding with queueing, exit out of Velocity. */\n                return getChain();\n\n            default:\n                /* Treat a non-empty plain object as a literal properties map. */\n                if ($.isPlainObject(propertiesMap) && !Type.isEmptyObject(propertiesMap)) {\n                    action = \"start\";\n\n                /****************\n                    Redirects\n                ****************/\n\n                /* Check if a string matches a registered redirect (see Redirects above). */\n                } else if (Type.isString(propertiesMap) && Velocity.Redirects[propertiesMap]) {\n                    var opts = $.extend({}, options),\n                        durationOriginal = opts.duration,\n                        delayOriginal = opts.delay || 0;\n\n                    /* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */\n                    if (opts.backwards === true) {\n                        elements = $.extend(true, [], elements).reverse();\n                    }\n\n                    /* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */\n                    $.each(elements, function(elementIndex, element) {\n                        /* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */\n                        if (parseFloat(opts.stagger)) {\n                            opts.delay = delayOriginal + (parseFloat(opts.stagger) * elementIndex);\n                        } else if (Type.isFunction(opts.stagger)) {\n                            opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elementsLength);\n                        }\n\n                        /* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards)\n                           the duration of each element's animation, using floors to prevent producing very short durations. */\n                        if (opts.drag) {\n                            /* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */\n                            opts.duration = parseFloat(durationOriginal) || (/^(callout|transition)/.test(propertiesMap) ? 1000 : DURATION_DEFAULT);\n\n                            /* For each element, take the greater duration of: A) animation completion percentage relative to the original duration,\n                               B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value).\n                               The end result is a baseline of 75% of the redirect's duration that increases/decreases as the end of the element set is approached. */\n                            opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex/elementsLength : (elementIndex + 1) / elementsLength), opts.duration * 0.75, 200);\n                        }\n\n                        /* Pass in the call's opts object so that the redirect can optionally extend it. It defaults to an empty object instead of null to\n                           reduce the opts checking logic required inside the redirect. */\n                        Velocity.Redirects[propertiesMap].call(element, element, opts || {}, elementIndex, elementsLength, elements, promiseData.promise ? promiseData : undefined);\n                    });\n\n                    /* Since the animation logic resides within the redirect's own code, abort the remainder of this call.\n                       (The performance overhead up to this point is virtually non-existant.) */\n                    /* Note: The jQuery call chain is kept intact by returning the complete element set. */\n                    return getChain();\n                } else {\n                    var abortError = \"Velocity: First argument (\" + propertiesMap + \") was not a property map, a known action, or a registered redirect. Aborting.\";\n\n                    if (promiseData.promise) {\n                        promiseData.rejecter(new Error(abortError));\n                    } else {\n                        console.log(abortError);\n                    }\n\n                    return getChain();\n                }\n        }\n\n        /**************************\n            Call-Wide Variables\n        **************************/\n\n        /* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements\n           being animated in a single Velocity call. Calculating unit ratios necessitates DOM querying and updating, and is therefore\n           avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale\n           conversion metrics across Velocity animations that are not immediately consecutively chained. */\n        var callUnitConversionData = {\n                lastParent: null,\n                lastPosition: null,\n                lastFontSize: null,\n                lastPercentToPxWidth: null,\n                lastPercentToPxHeight: null,\n                lastEmToPx: null,\n                remToPx: null,\n                vwToPx: null,\n                vhToPx: null\n            };\n\n        /* A container for all the ensuing tween data and metadata associated with this call. This container gets pushed to the page-wide\n           Velocity.State.calls array that is processed during animation ticking. */\n        var call = [];\n\n        /************************\n           Element Processing\n        ************************/\n\n        /* Element processing consists of three parts -- data processing that cannot go stale and data processing that *can* go stale (i.e. third-party style modifications):\n           1) Pre-Queueing: Element-wide variables, including the element's data storage, are instantiated. Call options are prepared. If triggered, the Stop action is executed.\n           2) Queueing: The logic that runs once this call has reached its point of execution in the element's $.queue() stack. Most logic is placed here to avoid risking it becoming stale.\n           3) Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.\n        */\n\n        function processElement () {\n\n            /*************************\n               Part I: Pre-Queueing\n            *************************/\n\n            /***************************\n               Element-Wide Variables\n            ***************************/\n\n            var element = this,\n                /* The runtime opts object is the extension of the current call's options and Velocity's page-wide option defaults. */\n                opts = $.extend({}, Velocity.defaults, options),\n                /* A container for the processed data associated with each property in the propertyMap.\n                   (Each property in the map produces its own \"tween\".) */\n                tweensContainer = {},\n                elementUnitConversionData;\n\n            /******************\n               Element Init\n            ******************/\n\n            if (Data(element) === undefined) {\n                Velocity.init(element);\n            }\n\n            /******************\n               Option: Delay\n            ******************/\n\n            /* Since queue:false doesn't respect the item's existing queue, we avoid injecting its delay here (it's set later on). */\n            /* Note: Velocity rolls its own delay function since jQuery doesn't have a utility alias for $.fn.delay()\n               (and thus requires jQuery element creation, which we avoid since its overhead includes DOM querying). */\n            if (parseFloat(opts.delay) && opts.queue !== false) {\n                $.queue(element, opts.queue, function(next) {\n                    /* This is a flag used to indicate to the upcoming completeCall() function that this queue entry was initiated by Velocity. See completeCall() for further details. */\n                    Velocity.velocityQueueEntryFlag = true;\n\n                    /* The ensuing queue item (which is assigned to the \"next\" argument that $.queue() automatically passes in) will be triggered after a setTimeout delay.\n                       The setTimeout is stored so that it can be subjected to clearTimeout() if this animation is prematurely stopped via Velocity's \"stop\" command. */\n                    Data(element).delayTimer = {\n                        setTimeout: setTimeout(next, parseFloat(opts.delay)),\n                        next: next\n                    };\n                });\n            }\n\n            /*********************\n               Option: Duration\n            *********************/\n\n            /* Support for jQuery's named durations. */\n            switch (opts.duration.toString().toLowerCase()) {\n                case \"fast\":\n                    opts.duration = 200;\n                    break;\n\n                case \"normal\":\n                    opts.duration = DURATION_DEFAULT;\n                    break;\n\n                case \"slow\":\n                    opts.duration = 600;\n                    break;\n\n                default:\n                    /* Remove the potential \"ms\" suffix and default to 1 if the user is attempting to set a duration of 0 (in order to produce an immediate style change). */\n                    opts.duration = parseFloat(opts.duration) || 1;\n            }\n\n            /************************\n               Global Option: Mock\n            ************************/\n\n            if (Velocity.mock !== false) {\n                /* In mock mode, all animations are forced to 1ms so that they occur immediately upon the next rAF tick.\n                   Alternatively, a multiplier can be passed in to time remap all delays and durations. */\n                if (Velocity.mock === true) {\n                    opts.duration = opts.delay = 1;\n                } else {\n                    opts.duration *= parseFloat(Velocity.mock) || 1;\n                    opts.delay *= parseFloat(Velocity.mock) || 1;\n                }\n            }\n\n            /*******************\n               Option: Easing\n            *******************/\n\n            opts.easing = getEasing(opts.easing, opts.duration);\n\n            /**********************\n               Option: Callbacks\n            **********************/\n\n            /* Callbacks must functions. Otherwise, default to null. */\n            if (opts.begin && !Type.isFunction(opts.begin)) {\n                opts.begin = null;\n            }\n\n            if (opts.progress && !Type.isFunction(opts.progress)) {\n                opts.progress = null;\n            }\n\n            if (opts.complete && !Type.isFunction(opts.complete)) {\n                opts.complete = null;\n            }\n\n            /*********************************\n               Option: Display & Visibility\n            *********************************/\n\n            /* Refer to Velocity's documentation (VelocityJS.org/#displayAndVisibility) for a description of the display and visibility options' behavior. */\n            /* Note: We strictly check for undefined instead of falsiness because display accepts an empty string value. */\n            if (opts.display !== undefined && opts.display !== null) {\n                opts.display = opts.display.toString().toLowerCase();\n\n                /* Users can pass in a special \"auto\" value to instruct Velocity to set the element to its default display value. */\n                if (opts.display === \"auto\") {\n                    opts.display = Velocity.CSS.Values.getDisplayType(element);\n                }\n            }\n\n            if (opts.visibility !== undefined && opts.visibility !== null) {\n                opts.visibility = opts.visibility.toString().toLowerCase();\n            }\n\n            /**********************\n               Option: mobileHA\n            **********************/\n\n            /* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack)\n               on animating elements. HA is removed from the element at the completion of its animation. */\n            /* Note: Android Gingerbread doesn't support HA. If a null transform hack (mobileHA) is in fact set, it will prevent other tranform subproperties from taking effect. */\n            /* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */\n            opts.mobileHA = (opts.mobileHA && Velocity.State.isMobile && !Velocity.State.isGingerbread);\n\n            /***********************\n               Part II: Queueing\n            ***********************/\n\n            /* When a set of elements is targeted by a Velocity call, the set is broken up and each element has the current Velocity call individually queued onto it.\n               In this way, each element's existing queue is respected; some elements may already be animating and accordingly should not have this current Velocity call triggered immediately. */\n            /* In each queue, tween data is processed for each animating property then pushed onto the call-wide calls array. When the last element in the set has had its tweens processed,\n               the call array is pushed to Velocity.State.calls for live processing by the requestAnimationFrame tick. */\n            function buildQueue (next) {\n\n                /*******************\n                   Option: Begin\n                *******************/\n\n                /* The begin callback is fired once per call -- not once per elemenet -- and is passed the full raw DOM element set as both its context and its first argument. */\n                if (opts.begin && elementsIndex === 0) {\n                    /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */\n                    try {\n                        opts.begin.call(elements, elements);\n                    } catch (error) {\n                        setTimeout(function() { throw error; }, 1);\n                    }\n                }\n\n                /*****************************************\n                   Tween Data Construction (for Scroll)\n                *****************************************/\n\n                /* Note: In order to be subjected to chaining and animation options, scroll's tweening is routed through Velocity as if it were a standard CSS property animation. */\n                if (action === \"scroll\") {\n                    /* The scroll action uniquely takes an optional \"offset\" option -- specified in pixels -- that offsets the targeted scroll position. */\n                    var scrollDirection = (/^x$/i.test(opts.axis) ? \"Left\" : \"Top\"),\n                        scrollOffset = parseFloat(opts.offset) || 0,\n                        scrollPositionCurrent,\n                        scrollPositionCurrentAlternate,\n                        scrollPositionEnd;\n\n                    /* Scroll also uniquely takes an optional \"container\" option, which indicates the parent element that should be scrolled --\n                       as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */\n                    if (opts.container) {\n                        /* Ensure that either a jQuery object or a raw DOM element was passed in. */\n                        if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) {\n                            /* Extract the raw DOM element from the jQuery wrapper. */\n                            opts.container = opts.container[0] || opts.container;\n                            /* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes\n                               (due to the user's natural interaction with the page). */\n                            scrollPositionCurrent = opts.container[\"scroll\" + scrollDirection]; /* GET */\n\n                            /* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions\n                               -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and*\n                               the scroll container's current scroll position. */\n                            scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; /* GET */\n                        /* If a value other than a jQuery object or a raw DOM element was passed in, default to null so that this option is ignored. */\n                        } else {\n                            opts.container = null;\n                        }\n                    } else {\n                        /* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using\n                           the appropriate cached property names (which differ based on browser type). */\n                        scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State[\"scrollProperty\" + scrollDirection]]; /* GET */\n                        /* When scrolling the browser window, cache the alternate axis's current value since window.scrollTo() doesn't let us change only one value at a time. */\n                        scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State[\"scrollProperty\" + (scrollDirection === \"Left\" ? \"Top\" : \"Left\")]]; /* GET */\n\n                        /* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area --\n                           and therefore end values do not need to be compounded onto current values. */\n                        scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */\n                    }\n\n                    /* Since there's only one format that scroll's associated tweensContainer can take, we create it manually. */\n                    tweensContainer = {\n                        scroll: {\n                            rootPropertyValue: false,\n                            startValue: scrollPositionCurrent,\n                            currentValue: scrollPositionCurrent,\n                            endValue: scrollPositionEnd,\n                            unitType: \"\",\n                            easing: opts.easing,\n                            scrollData: {\n                                container: opts.container,\n                                direction: scrollDirection,\n                                alternateValue: scrollPositionCurrentAlternate\n                            }\n                        },\n                        element: element\n                    };\n\n                    if (Velocity.debug) console.log(\"tweensContainer (scroll): \", tweensContainer.scroll, element);\n\n                /******************************************\n                   Tween Data Construction (for Reverse)\n                ******************************************/\n\n                /* Reverse acts like a \"start\" action in that a property map is animated toward. The only difference is\n                   that the property map used for reverse is the inverse of the map used in the previous call. Thus, we manipulate\n                   the previous call to construct our new map: use the previous map's end values as our new map's start values. Copy over all other data. */\n                /* Note: Reverse can be directly called via the \"reverse\" parameter, or it can be indirectly triggered via the loop option. (Loops are composed of multiple reverses.) */\n                /* Note: Reverse calls do not need to be consecutively chained onto a currently-animating element in order to operate on cached values;\n                   there is no harm to reverse being called on a potentially stale data cache since reverse's behavior is simply defined\n                   as reverting to the element's values as they were prior to the previous *Velocity* call. */\n                } else if (action === \"reverse\") {\n                    /* Abort if there is no prior animation data to reverse to. */\n                    if (!Data(element).tweensContainer) {\n                        /* Dequeue the element so that this queue entry releases itself immediately, allowing subsequent queue entries to run. */\n                        $.dequeue(element, opts.queue);\n\n                        return;\n                    } else {\n                        /*********************\n                           Options Parsing\n                        *********************/\n\n                        /* If the element was hidden via the display option in the previous call,\n                           revert display to \"auto\" prior to reversal so that the element is visible again. */\n                        if (Data(element).opts.display === \"none\") {\n                            Data(element).opts.display = \"auto\";\n                        }\n\n                        if (Data(element).opts.visibility === \"hidden\") {\n                            Data(element).opts.visibility = \"visible\";\n                        }\n\n                        /* If the loop option was set in the previous call, disable it so that \"reverse\" calls aren't recursively generated.\n                           Further, remove the previous call's callback options; typically, users do not want these to be refired. */\n                        Data(element).opts.loop = false;\n                        Data(element).opts.begin = null;\n                        Data(element).opts.complete = null;\n\n                        /* Since we're extending an opts object that has already been extended with the defaults options object,\n                           we remove non-explicitly-defined properties that are auto-assigned values. */\n                        if (!options.easing) {\n                            delete opts.easing;\n                        }\n\n                        if (!options.duration) {\n                            delete opts.duration;\n                        }\n\n                        /* The opts object used for reversal is an extension of the options object optionally passed into this\n                           reverse call plus the options used in the previous Velocity call. */\n                        opts = $.extend({}, Data(element).opts, opts);\n\n                        /*************************************\n                           Tweens Container Reconstruction\n                        *************************************/\n\n                        /* Create a deepy copy (indicated via the true flag) of the previous call's tweensContainer. */\n                        var lastTweensContainer = $.extend(true, {}, Data(element).tweensContainer);\n\n                        /* Manipulate the previous tweensContainer by replacing its end values and currentValues with its start values. */\n                        for (var lastTween in lastTweensContainer) {\n                            /* In addition to tween data, tweensContainers contain an element property that we ignore here. */\n                            if (lastTween !== \"element\") {\n                                var lastStartValue = lastTweensContainer[lastTween].startValue;\n\n                                lastTweensContainer[lastTween].startValue = lastTweensContainer[lastTween].currentValue = lastTweensContainer[lastTween].endValue;\n                                lastTweensContainer[lastTween].endValue = lastStartValue;\n\n                                /* Easing is the only option that embeds into the individual tween data (since it can be defined on a per-property basis).\n                                   Accordingly, every property's easing value must be updated when an options object is passed in with a reverse call.\n                                   The side effect of this extensibility is that all per-property easing values are forcefully reset to the new value. */\n                                if (!Type.isEmptyObject(options)) {\n                                    lastTweensContainer[lastTween].easing = opts.easing;\n                                }\n\n                                if (Velocity.debug) console.log(\"reverse tweensContainer (\" + lastTween + \"): \" + JSON.stringify(lastTweensContainer[lastTween]), element);\n                            }\n                        }\n\n                        tweensContainer = lastTweensContainer;\n                    }\n\n                /*****************************************\n                   Tween Data Construction (for Start)\n                *****************************************/\n\n                } else if (action === \"start\") {\n\n                    /*************************\n                        Value Transferring\n                    *************************/\n\n                    /* If this queue entry follows a previous Velocity-initiated queue entry *and* if this entry was created\n                       while the element was in the process of being animated by Velocity, then this current call is safe to use\n                       the end values from the prior call as its start values. Velocity attempts to perform this value transfer\n                       process whenever possible in order to avoid requerying the DOM. */\n                    /* If values aren't transferred from a prior call and start values were not forcefed by the user (more on this below),\n                       then the DOM is queried for the element's current values as a last resort. */\n                    /* Note: Conversely, animation reversal (and looping) *always* perform inter-call value transfers; they never requery the DOM. */\n                    var lastTweensContainer;\n\n                    /* The per-element isAnimating flag is used to indicate whether it's safe (i.e. the data isn't stale)\n                       to transfer over end values to use as start values. If it's set to true and there is a previous\n                       Velocity call to pull values from, do so. */\n                    if (Data(element).tweensContainer && Data(element).isAnimating === true) {\n                        lastTweensContainer = Data(element).tweensContainer;\n                    }\n\n                    /***************************\n                       Tween Data Calculation\n                    ***************************/\n\n                    /* This function parses property data and defaults endValue, easing, and startValue as appropriate. */\n                    /* Property map values can either take the form of 1) a single value representing the end value,\n                       or 2) an array in the form of [ endValue, [, easing] [, startValue] ].\n                       The optional third parameter is a forcefed startValue to be used instead of querying the DOM for\n                       the element's current value. Read Velocity's docmentation to learn more about forcefeeding: VelocityJS.org/#forcefeeding */\n                    function parsePropertyValue (valueData, skipResolvingEasing) {\n                        var endValue = undefined,\n                            easing = undefined,\n                            startValue = undefined;\n\n                        /* Handle the array format, which can be structured as one of three potential overloads:\n                           A) [ endValue, easing, startValue ], B) [ endValue, easing ], or C) [ endValue, startValue ] */\n                        if (Type.isArray(valueData)) {\n                            /* endValue is always the first item in the array. Don't bother validating endValue's value now\n                               since the ensuing property cycling logic does that. */\n                            endValue = valueData[0];\n\n                            /* Two-item array format: If the second item is a number, function, or hex string, treat it as a\n                               start value since easings can only be non-hex strings or arrays. */\n                            if ((!Type.isArray(valueData[1]) && /^[\\d-]/.test(valueData[1])) || Type.isFunction(valueData[1]) || CSS.RegEx.isHex.test(valueData[1])) {\n                                startValue = valueData[1];\n                            /* Two or three-item array: If the second item is a non-hex string or an array, treat it as an easing. */\n                            } else if ((Type.isString(valueData[1]) && !CSS.RegEx.isHex.test(valueData[1])) || Type.isArray(valueData[1])) {\n                                easing = skipResolvingEasing ? valueData[1] : getEasing(valueData[1], opts.duration);\n\n                                /* Don't bother validating startValue's value now since the ensuing property cycling logic inherently does that. */\n                                if (valueData[2] !== undefined) {\n                                    startValue = valueData[2];\n                                }\n                            }\n                        /* Handle the single-value format. */\n                        } else {\n                            endValue = valueData;\n                        }\n\n                        /* Default to the call's easing if a per-property easing type was not defined. */\n                        if (!skipResolvingEasing) {\n                            easing = easing || opts.easing;\n                        }\n\n                        /* If functions were passed in as values, pass the function the current element as its context,\n                           plus the element's index and the element set's size as arguments. Then, assign the returned value. */\n                        if (Type.isFunction(endValue)) {\n                            endValue = endValue.call(element, elementsIndex, elementsLength);\n                        }\n\n                        if (Type.isFunction(startValue)) {\n                            startValue = startValue.call(element, elementsIndex, elementsLength);\n                        }\n\n                        /* Allow startValue to be left as undefined to indicate to the ensuing code that its value was not forcefed. */\n                        return [ endValue || 0, easing, startValue ];\n                    }\n\n                    /* Cycle through each property in the map, looking for shorthand color properties (e.g. \"color\" as opposed to \"colorRed\"). Inject the corresponding\n                       colorRed, colorGreen, and colorBlue RGB component tweens into the propertiesMap (which Velocity understands) and remove the shorthand property. */\n                    $.each(propertiesMap, function(property, value) {\n                        /* Find shorthand color properties that have been passed a hex string. */\n                        if (RegExp(\"^\" + CSS.Lists.colors.join(\"$|^\") + \"$\").test(property)) {\n                            /* Parse the value data for each shorthand. */\n                            var valueData = parsePropertyValue(value, true),\n                                endValue = valueData[0],\n                                easing = valueData[1],\n                                startValue = valueData[2];\n\n                            if (CSS.RegEx.isHex.test(endValue)) {\n                                /* Convert the hex strings into their RGB component arrays. */\n                                var colorComponents = [ \"Red\", \"Green\", \"Blue\" ],\n                                    endValueRGB = CSS.Values.hexToRgb(endValue),\n                                    startValueRGB = startValue ? CSS.Values.hexToRgb(startValue) : undefined;\n\n                                /* Inject the RGB component tweens into propertiesMap. */\n                                for (var i = 0; i < colorComponents.length; i++) {\n                                    var dataArray = [ endValueRGB[i] ];\n\n                                    if (easing) {\n                                        dataArray.push(easing);\n                                    }\n\n                                    if (startValueRGB !== undefined) {\n                                        dataArray.push(startValueRGB[i]);\n                                    }\n\n                                    propertiesMap[property + colorComponents[i]] = dataArray;\n                                }\n\n                                /* Remove the intermediary shorthand property entry now that we've processed it. */\n                                delete propertiesMap[property];\n                            }\n                        }\n                    });\n\n                    /* Create a tween out of each property, and append its associated data to tweensContainer. */\n                    for (var property in propertiesMap) {\n\n                        /**************************\n                           Start Value Sourcing\n                        **************************/\n\n                        /* Parse out endValue, easing, and startValue from the property's data. */\n                        var valueData = parsePropertyValue(propertiesMap[property]),\n                            endValue = valueData[0],\n                            easing = valueData[1],\n                            startValue = valueData[2];\n\n                        /* Now that the original property name's format has been used for the parsePropertyValue() lookup above,\n                           we force the property to its camelCase styling to normalize it for manipulation. */\n                        property = CSS.Names.camelCase(property);\n\n                        /* In case this property is a hook, there are circumstances where we will intend to work on the hook's root property and not the hooked subproperty. */\n                        var rootProperty = CSS.Hooks.getRoot(property),\n                            rootPropertyValue = false;\n\n                        /* Other than for the dummy tween property, properties that are not supported by the browser (and do not have an associated normalization) will\n                           inherently produce no style changes when set, so they are skipped in order to decrease animation tick overhead.\n                           Property support is determined via prefixCheck(), which returns a false flag when no supported is detected. */\n                        /* Note: Since SVG elements have some of their properties directly applied as HTML attributes,\n                           there is no way to check for their explicit browser support, and so we skip skip this check for them. */\n                        if (!Data(element).isSVG && rootProperty !== \"tween\" && CSS.Names.prefixCheck(rootProperty)[1] === false && CSS.Normalizations.registered[rootProperty] === undefined) {\n                            if (Velocity.debug) console.log(\"Skipping [\" + rootProperty + \"] due to a lack of browser support.\");\n\n                            continue;\n                        }\n\n                        /* If the display option is being set to a non-\"none\" (e.g. \"block\") and opacity (filter on IE<=8) is being\n                           animated to an endValue of non-zero, the user's intention is to fade in from invisible, thus we forcefeed opacity\n                           a startValue of 0 if its startValue hasn't already been sourced by value transferring or prior forcefeeding. */\n                        if (((opts.display !== undefined && opts.display !== null && opts.display !== \"none\") || (opts.visibility !== undefined && opts.visibility !== \"hidden\")) && /opacity|filter/.test(property) && !startValue && endValue !== 0) {\n                            startValue = 0;\n                        }\n\n                        /* If values have been transferred from the previous Velocity call, extract the endValue and rootPropertyValue\n                           for all of the current call's properties that were *also* animated in the previous call. */\n                        /* Note: Value transferring can optionally be disabled by the user via the _cacheValues option. */\n                        if (opts._cacheValues && lastTweensContainer && lastTweensContainer[property]) {\n                            if (startValue === undefined) {\n                                startValue = lastTweensContainer[property].endValue + lastTweensContainer[property].unitType;\n                            }\n\n                            /* The previous call's rootPropertyValue is extracted from the element's data cache since that's the\n                               instance of rootPropertyValue that gets freshly updated by the tweening process, whereas the rootPropertyValue\n                               attached to the incoming lastTweensContainer is equal to the root property's value prior to any tweening. */\n                            rootPropertyValue = Data(element).rootPropertyValueCache[rootProperty];\n                        /* If values were not transferred from a previous Velocity call, query the DOM as needed. */\n                        } else {\n                            /* Handle hooked properties. */\n                            if (CSS.Hooks.registered[property]) {\n                               if (startValue === undefined) {\n                                    rootPropertyValue = CSS.getPropertyValue(element, rootProperty); /* GET */\n                                    /* Note: The following getPropertyValue() call does not actually trigger a DOM query;\n                                       getPropertyValue() will extract the hook from rootPropertyValue. */\n                                    startValue = CSS.getPropertyValue(element, property, rootPropertyValue);\n                                /* If startValue is already defined via forcefeeding, do not query the DOM for the root property's value;\n                                   just grab rootProperty's zero-value template from CSS.Hooks. This overwrites the element's actual\n                                   root property value (if one is set), but this is acceptable since the primary reason users forcefeed is\n                                   to avoid DOM queries, and thus we likewise avoid querying the DOM for the root property's value. */\n                                } else {\n                                    /* Grab this hook's zero-value template, e.g. \"0px 0px 0px black\". */\n                                    rootPropertyValue = CSS.Hooks.templates[rootProperty][1];\n                                }\n                            /* Handle non-hooked properties that haven't already been defined via forcefeeding. */\n                            } else if (startValue === undefined) {\n                                startValue = CSS.getPropertyValue(element, property); /* GET */\n                            }\n                        }\n\n                        /**************************\n                           Value Data Extraction\n                        **************************/\n\n                        var separatedValue,\n                            endValueUnitType,\n                            startValueUnitType,\n                            operator = false;\n\n                        /* Separates a property value into its numeric value and its unit type. */\n                        function separateValue (property, value) {\n                            var unitType,\n                                numericValue;\n\n                            numericValue = (value || \"0\")\n                                .toString()\n                                .toLowerCase()\n                                /* Match the unit type at the end of the value. */\n                                .replace(/[%A-z]+$/, function(match) {\n                                    /* Grab the unit type. */\n                                    unitType = match;\n\n                                    /* Strip the unit type off of value. */\n                                    return \"\";\n                                });\n\n                            /* If no unit type was supplied, assign one that is appropriate for this property (e.g. \"deg\" for rotateZ or \"px\" for width). */\n                            if (!unitType) {\n                                unitType = CSS.Values.getUnitType(property);\n                            }\n\n                            return [ numericValue, unitType ];\n                        }\n\n                        /* Separate startValue. */\n                        separatedValue = separateValue(property, startValue);\n                        startValue = separatedValue[0];\n                        startValueUnitType = separatedValue[1];\n\n                        /* Separate endValue, and extract a value operator (e.g. \"+=\", \"-=\") if one exists. */\n                        separatedValue = separateValue(property, endValue);\n                        endValue = separatedValue[0].replace(/^([+-\\/*])=/, function(match, subMatch) {\n                            operator = subMatch;\n\n                            /* Strip the operator off of the value. */\n                            return \"\";\n                        });\n                        endValueUnitType = separatedValue[1];\n\n                        /* Parse float values from endValue and startValue. Default to 0 if NaN is returned. */\n                        startValue = parseFloat(startValue) || 0;\n                        endValue = parseFloat(endValue) || 0;\n\n                        /***************************************\n                           Property-Specific Value Conversion\n                        ***************************************/\n\n                        /* Custom support for properties that don't actually accept the % unit type, but where pollyfilling is trivial and relatively foolproof. */\n                        if (endValueUnitType === \"%\") {\n                            /* A %-value fontSize/lineHeight is relative to the parent's fontSize (as opposed to the parent's dimensions),\n                               which is identical to the em unit's behavior, so we piggyback off of that. */\n                            if (/^(fontSize|lineHeight)$/.test(property)) {\n                                /* Convert % into an em decimal value. */\n                                endValue = endValue / 100;\n                                endValueUnitType = \"em\";\n                            /* For scaleX and scaleY, convert the value into its decimal format and strip off the unit type. */\n                            } else if (/^scale/.test(property)) {\n                                endValue = endValue / 100;\n                                endValueUnitType = \"\";\n                            /* For RGB components, take the defined percentage of 255 and strip off the unit type. */\n                            } else if (/(Red|Green|Blue)$/i.test(property)) {\n                                endValue = (endValue / 100) * 255;\n                                endValueUnitType = \"\";\n                            }\n                        }\n\n                        /***************************\n                           Unit Ratio Calculation\n                        ***************************/\n\n                        /* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of\n                           %, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order\n                           for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred\n                           from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:\n                           1) Calculating the ratio of %/em/rem/vh/vw relative to pixels\n                           2) Converting startValue into the same unit of measurement as endValue based on these ratios. */\n                        /* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,\n                           setting values with the target unit type then comparing the returned pixel value. */\n                        /* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead\n                           of batching the SETs and GETs together upfront outweights the potential overhead\n                           of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */\n                        /* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */\n                        function calculateUnitRatios () {\n\n                            /************************\n                                Same Ratio Checks\n                            ************************/\n\n                            /* The properties below are used to determine whether the element differs sufficiently from this call's\n                               previously iterated element to also differ in its unit conversion ratios. If the properties match up with those\n                               of the prior element, the prior element's conversion ratios are used. Like most optimizations in Velocity,\n                               this is done to minimize DOM querying. */\n                            var sameRatioIndicators = {\n                                    myParent: element.parentNode || document.body, /* GET */\n                                    position: CSS.getPropertyValue(element, \"position\"), /* GET */\n                                    fontSize: CSS.getPropertyValue(element, \"fontSize\") /* GET */\n                                },\n                                /* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */\n                                samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent)),\n                                /* Determine if the same em ratio can be used. em is relative to the element's fontSize. */\n                                sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);\n\n                            /* Store these ratio indicators call-wide for the next element to compare against. */\n                            callUnitConversionData.lastParent = sameRatioIndicators.myParent;\n                            callUnitConversionData.lastPosition = sameRatioIndicators.position;\n                            callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;\n\n                            /***************************\n                               Element-Specific Units\n                            ***************************/\n\n                            /* Note: IE8 rounds to the nearest pixel when returning CSS values, thus we perform conversions using a measurement\n                               of 100 (instead of 1) to give our ratios a precision of at least 2 decimal values. */\n                            var measurement = 100,\n                                unitRatios = {};\n\n                            if (!sameEmRatio || !samePercentRatio) {\n                                var dummy = Data(element).isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\") : document.createElement(\"div\");\n\n                                Velocity.init(dummy);\n                                sameRatioIndicators.myParent.appendChild(dummy);\n\n                                /* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.\n                                   Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */\n                                /* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */\n                                $.each([ \"overflow\", \"overflowX\", \"overflowY\" ], function(i, property) {\n                                    Velocity.CSS.setPropertyValue(dummy, property, \"hidden\");\n                                });\n                                Velocity.CSS.setPropertyValue(dummy, \"position\", sameRatioIndicators.position);\n                                Velocity.CSS.setPropertyValue(dummy, \"fontSize\", sameRatioIndicators.fontSize);\n                                Velocity.CSS.setPropertyValue(dummy, \"boxSizing\", \"content-box\");\n\n                                /* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */\n                                $.each([ \"minWidth\", \"maxWidth\", \"width\", \"minHeight\", \"maxHeight\", \"height\" ], function(i, property) {\n                                    Velocity.CSS.setPropertyValue(dummy, property, measurement + \"%\");\n                                });\n                                /* paddingLeft arbitrarily acts as our proxy property for the em ratio. */\n                                Velocity.CSS.setPropertyValue(dummy, \"paddingLeft\", measurement + \"em\");\n\n                                /* Divide the returned value by the measurement to get the ratio between 1% and 1px. Default to 1 since working with 0 can produce Infinite. */\n                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, \"width\", null, true)) || 1) / measurement; /* GET */\n                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, \"height\", null, true)) || 1) / measurement; /* GET */\n                                unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, \"paddingLeft\")) || 1) / measurement; /* GET */\n\n                                sameRatioIndicators.myParent.removeChild(dummy);\n                            } else {\n                                unitRatios.emToPx = callUnitConversionData.lastEmToPx;\n                                unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;\n                                unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;\n                            }\n\n                            /***************************\n                               Element-Agnostic Units\n                            ***************************/\n\n                            /* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked\n                               once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time\n                               that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,\n                               so we calculate it now. */\n                            if (callUnitConversionData.remToPx === null) {\n                                /* Default to browsers' default fontSize of 16px in the case of 0. */\n                                callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, \"fontSize\")) || 16; /* GET */\n                            }\n\n                            /* Similarly, viewport units are %-relative to the window's inner dimensions. */\n                            if (callUnitConversionData.vwToPx === null) {\n                                callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */\n                                callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */\n                            }\n\n                            unitRatios.remToPx = callUnitConversionData.remToPx;\n                            unitRatios.vwToPx = callUnitConversionData.vwToPx;\n                            unitRatios.vhToPx = callUnitConversionData.vhToPx;\n\n                            if (Velocity.debug >= 1) console.log(\"Unit ratios: \" + JSON.stringify(unitRatios), element);\n\n                            return unitRatios;\n                        }\n\n                        /********************\n                           Unit Conversion\n                        ********************/\n\n                        /* The * and / operators, which are not passed in with an associated unit, inherently use startValue's unit. Skip value and unit conversion. */\n                        if (/[\\/*]/.test(operator)) {\n                            endValueUnitType = startValueUnitType;\n                        /* If startValue and endValue differ in unit type, convert startValue into the same unit type as endValue so that if endValueUnitType\n                           is a relative unit (%, em, rem), the values set during tweening will continue to be accurately relative even if the metrics they depend\n                           on are dynamically changing during the course of the animation. Conversely, if we always normalized into px and used px for setting values, the px ratio\n                           would become stale if the original unit being animated toward was relative and the underlying metrics change during the animation. */\n                        /* Since 0 is 0 in any unit type, no conversion is necessary when startValue is 0 -- we just start at 0 with endValueUnitType. */\n                        } else if ((startValueUnitType !== endValueUnitType) && startValue !== 0) {\n                            /* Unit conversion is also skipped when endValue is 0, but *startValueUnitType* must be used for tween values to remain accurate. */\n                            /* Note: Skipping unit conversion here means that if endValueUnitType was originally a relative unit, the animation won't relatively\n                               match the underlying metrics if they change, but this is acceptable since we're animating toward invisibility instead of toward visibility,\n                               which remains past the point of the animation's completion. */\n                            if (endValue === 0) {\n                                endValueUnitType = startValueUnitType;\n                            } else {\n                                /* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).\n                                   If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */\n                                elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();\n\n                                /* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */\n                                /* Note: W3C spec mandates that all of margin and padding's properties (even top and bottom) are %-relative to the *width* of the parent element. */\n                                var axis = (/margin|padding|left|right|width|text|word|letter/i.test(property) || /X$/.test(property) || property === \"x\") ? \"x\" : \"y\";\n\n                                /* In order to avoid generating n^2 bespoke conversion functions, unit conversion is a two-step process:\n                                   1) Convert startValue into pixels. 2) Convert this new pixel value into endValue's unit type. */\n                                switch (startValueUnitType) {\n                                    case \"%\":\n                                        /* Note: translateX and translateY are the only properties that are %-relative to an element's own dimensions -- not its parent's dimensions.\n                                           Velocity does not include a special conversion process to account for this behavior. Therefore, animating translateX/Y from a % value\n                                           to a non-% value will produce an incorrect start value. Fortunately, this sort of cross-unit conversion is rarely done by users in practice. */\n                                        startValue *= (axis === \"x\" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);\n                                        break;\n\n                                    case \"px\":\n                                        /* px acts as our midpoint in the unit conversion process; do nothing. */\n                                        break;\n\n                                    default:\n                                        startValue *= elementUnitConversionData[startValueUnitType + \"ToPx\"];\n                                }\n\n                                /* Invert the px ratios to convert into to the target unit. */\n                                switch (endValueUnitType) {\n                                    case \"%\":\n                                        startValue *= 1 / (axis === \"x\" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);\n                                        break;\n\n                                    case \"px\":\n                                        /* startValue is already in px, do nothing; we're done. */\n                                        break;\n\n                                    default:\n                                        startValue *= 1 / elementUnitConversionData[endValueUnitType + \"ToPx\"];\n                                }\n                            }\n                        }\n\n                        /*********************\n                           Relative Values\n                        *********************/\n\n                        /* Operator logic must be performed last since it requires unit-normalized start and end values. */\n                        /* Note: Relative *percent values* do not behave how most people think; while one would expect \"+=50%\"\n                           to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms:\n                           50 points is added on top of the current % value. */\n                        switch (operator) {\n                            case \"+\":\n                                endValue = startValue + endValue;\n                                break;\n\n                            case \"-\":\n                                endValue = startValue - endValue;\n                                break;\n\n                            case \"*\":\n                                endValue = startValue * endValue;\n                                break;\n\n                            case \"/\":\n                                endValue = startValue / endValue;\n                                break;\n                        }\n\n                        /**************************\n                           tweensContainer Push\n                        **************************/\n\n                        /* Construct the per-property tween object, and push it to the element's tweensContainer. */\n                        tweensContainer[property] = {\n                            rootPropertyValue: rootPropertyValue,\n                            startValue: startValue,\n                            currentValue: startValue,\n                            endValue: endValue,\n                            unitType: endValueUnitType,\n                            easing: easing\n                        };\n\n                        if (Velocity.debug) console.log(\"tweensContainer (\" + property + \"): \" + JSON.stringify(tweensContainer[property]), element);\n                    }\n\n                    /* Along with its property data, store a reference to the element itself onto tweensContainer. */\n                    tweensContainer.element = element;\n                }\n\n                /*****************\n                    Call Push\n                *****************/\n\n                /* Note: tweensContainer can be empty if all of the properties in this call's property map were skipped due to not\n                   being supported by the browser. The element property is used for checking that the tweensContainer has been appended to. */\n                if (tweensContainer.element) {\n                    /* Apply the \"velocity-animating\" indicator class. */\n                    CSS.Values.addClass(element, \"velocity-animating\");\n\n                    /* The call array houses the tweensContainers for each element being animated in the current call. */\n                    call.push(tweensContainer);\n\n                    /* Store the tweensContainer and options if we're working on the default effects queue, so that they can be used by the reverse command. */\n                    if (opts.queue === \"\") {\n                        Data(element).tweensContainer = tweensContainer;\n                        Data(element).opts = opts;\n                    }\n\n                    /* Switch on the element's animating flag. */\n                    Data(element).isAnimating = true;\n\n                    /* Once the final element in this call's element set has been processed, push the call array onto\n                       Velocity.State.calls for the animation tick to immediately begin processing. */\n                    if (elementsIndex === elementsLength - 1) {\n                        /* Add the current call plus its associated metadata (the element set and the call's options) onto the global call container.\n                           Anything on this call container is subjected to tick() processing. */\n                        Velocity.State.calls.push([ call, elements, opts, null, promiseData.resolver ]);\n\n                        /* If the animation tick isn't running, start it. (Velocity shuts it off when there are no active calls to process.) */\n                        if (Velocity.State.isTicking === false) {\n                            Velocity.State.isTicking = true;\n\n                            /* Start the tick loop. */\n                            tick();\n                        }\n                    } else {\n                        elementsIndex++;\n                    }\n                }\n            }\n\n            /* When the queue option is set to false, the call skips the element's queue and fires immediately. */\n            if (opts.queue === false) {\n                /* Since this buildQueue call doesn't respect the element's existing queue (which is where a delay option would have been appended),\n                   we manually inject the delay property here with an explicit setTimeout. */\n                if (opts.delay) {\n                    setTimeout(buildQueue, opts.delay);\n                } else {\n                    buildQueue();\n                }\n            /* Otherwise, the call undergoes element queueing as normal. */\n            /* Note: To interoperate with jQuery, Velocity uses jQuery's own $.queue() stack for queuing logic. */\n            } else {\n                $.queue(element, opts.queue, function(next, clearQueue) {\n                    /* If the clearQueue flag was passed in by the stop command, resolve this call's promise. (Promises can only be resolved once,\n                       so it's fine if this is repeatedly triggered for each element in the associated call.) */\n                    if (clearQueue === true) {\n                        if (promiseData.promise) {\n                            promiseData.resolver(elements);\n                        }\n\n                        /* Do not continue with animation queueing. */\n                        return true;\n                    }\n\n                    /* This flag indicates to the upcoming completeCall() function that this queue entry was initiated by Velocity.\n                       See completeCall() for further details. */\n                    Velocity.velocityQueueEntryFlag = true;\n\n                    buildQueue(next);\n                });\n            }\n\n            /*********************\n                Auto-Dequeuing\n            *********************/\n\n            /* As per jQuery's $.queue() behavior, to fire the first non-custom-queue entry on an element, the element\n               must be dequeued if its queue stack consists *solely* of the current call. (This can be determined by checking\n               for the \"inprogress\" item that jQuery prepends to active queue stack arrays.) Regardless, whenever the element's\n               queue is further appended with additional items -- including $.delay()'s or even $.animate() calls, the queue's\n               first entry is automatically fired. This behavior contrasts that of custom queues, which never auto-fire. */\n            /* Note: When an element set is being subjected to a non-parallel Velocity call, the animation will not begin until\n               each one of the elements in the set has reached the end of its individually pre-existing queue chain. */\n            /* Note: Unfortunately, most people don't fully grasp jQuery's powerful, yet quirky, $.queue() function.\n               Lean more here: http://stackoverflow.com/questions/1058158/can-somebody-explain-jquery-queue-to-me */\n            if ((opts.queue === \"\" || opts.queue === \"fx\") && $.queue(element)[0] !== \"inprogress\") {\n                $.dequeue(element);\n            }\n        }\n\n        /**************************\n           Element Set Iteration\n        **************************/\n\n        /* If the \"nodeType\" property exists on the elements variable, we're animating a single element.\n           Place it in an array so that $.each() can iterate over it. */\n        $.each(elements, function(i, element) {\n            /* Ensure each element in a set has a nodeType (is a real element) to avoid throwing errors. */\n            if (Type.isNode(element)) {\n                processElement.call(element);\n            }\n        });\n\n        /******************\n           Option: Loop\n        ******************/\n\n        /* The loop option accepts an integer indicating how many times the element should loop between the values in the\n           current call's properties map and the element's property values prior to this call. */\n        /* Note: The loop option's logic is performed here -- after element processing -- because the current call needs\n           to undergo its queue insertion prior to the loop option generating its series of constituent \"reverse\" calls,\n           which chain after the current call. Two reverse calls (two \"alternations\") constitute one loop. */\n        var opts = $.extend({}, Velocity.defaults, options),\n            reverseCallsCount;\n\n        opts.loop = parseInt(opts.loop);\n        reverseCallsCount = (opts.loop * 2) - 1;\n\n        if (opts.loop) {\n            /* Double the loop count to convert it into its appropriate number of \"reverse\" calls.\n               Subtract 1 from the resulting value since the current call is included in the total alternation count. */\n            for (var x = 0; x < reverseCallsCount; x++) {\n                /* Since the logic for the reverse action occurs inside Queueing and therefore this call's options object\n                   isn't parsed until then as well, the current call's delay option must be explicitly passed into the reverse\n                   call so that the delay logic that occurs inside *Pre-Queueing* can process it. */\n                var reverseOptions = {\n                    delay: opts.delay,\n                    progress: opts.progress\n                };\n\n                /* If a complete callback was passed into this call, transfer it to the loop redirect's final \"reverse\" call\n                   so that it's triggered when the entire redirect is complete (and not when the very first animation is complete). */\n                if (x === reverseCallsCount - 1) {\n                    reverseOptions.display = opts.display;\n                    reverseOptions.visibility = opts.visibility;\n                    reverseOptions.complete = opts.complete;\n                }\n\n                animate(elements, \"reverse\", reverseOptions);\n            }\n        }\n\n        /***************\n            Chaining\n        ***************/\n\n        /* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */\n        return getChain();\n    };\n\n    /* Turn Velocity into the animation function, extended with the pre-existing Velocity object. */\n    Velocity = $.extend(animate, Velocity);\n    /* For legacy support, also expose the literal animate method. */\n    Velocity.animate = animate;\n\n    /**************\n        Timing\n    **************/\n\n    /* Ticker function. */\n    var ticker = window.requestAnimationFrame || rAFShim;\n\n    /* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses.\n       To get around this, we dynamically switch rAF to setTimeout (which the browser *doesn't* pause) when the tab loses focus. We skip this for mobile\n       devices to avoid wasting battery power on inactive tabs. */\n    /* Note: Tab focus detection doesn't work on older versions of IE, but that's okay since they don't support rAF to begin with. */\n    if (!Velocity.State.isMobile && document.hidden !== undefined) {\n        document.addEventListener(\"visibilitychange\", function() {\n            /* Reassign the rAF function (which the global tick() function uses) based on the tab's focus state. */\n            if (document.hidden) {\n                ticker = function(callback) {\n                    /* The tick function needs a truthy first argument in order to pass its internal timestamp check. */\n                    return setTimeout(function() { callback(true) }, 16);\n                };\n\n                /* The rAF loop has been paused by the browser, so we manually restart the tick. */\n                tick();\n            } else {\n                ticker = window.requestAnimationFrame || rAFShim;\n            }\n        });\n    }\n\n    /************\n        Tick\n    ************/\n\n    /* Note: All calls to Velocity are pushed to the Velocity.State.calls array, which is fully iterated through upon each tick. */\n    function tick (timestamp) {\n        /* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on.\n           We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever\n           the browser's next tick sync time occurs, which results in the first elements subjected to Velocity\n           calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore\n           the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated\n           by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */\n        if (timestamp) {\n            /* We ignore RAF's high resolution timestamp since it can be significantly offset when the browser is\n               under high stress; we opt for choppiness over allowing the browser to drop huge chunks of frames. */\n            var timeCurrent = (new Date).getTime();\n\n            /********************\n               Call Iteration\n            ********************/\n\n            var callsLength = Velocity.State.calls.length;\n\n            /* To speed up iterating over this array, it is compacted (falsey items -- calls that have completed -- are removed)\n               when its length has ballooned to a point that can impact tick performance. This only becomes necessary when animation\n               has been continuous with many elements over a long period of time; whenever all active calls are completed, completeCall() clears Velocity.State.calls. */\n            if (callsLength > 10000) {\n                Velocity.State.calls = compactSparseArray(Velocity.State.calls);\n            }\n\n            /* Iterate through each active call. */\n            for (var i = 0; i < callsLength; i++) {\n                /* When a Velocity call is completed, its Velocity.State.calls entry is set to false. Continue on to the next call. */\n                if (!Velocity.State.calls[i]) {\n                    continue;\n                }\n\n                /************************\n                   Call-Wide Variables\n                ************************/\n\n                var callContainer = Velocity.State.calls[i],\n                    call = callContainer[0],\n                    opts = callContainer[2],\n                    timeStart = callContainer[3],\n                    firstTick = !!timeStart,\n                    tweenDummyValue = null;\n\n                /* If timeStart is undefined, then this is the first time that this call has been processed by tick().\n                   We assign timeStart now so that its value is as close to the real animation start time as possible.\n                   (Conversely, had timeStart been defined when this call was added to Velocity.State.calls, the delay\n                   between that time and now would cause the first few frames of the tween to be skipped since\n                   percentComplete is calculated relative to timeStart.) */\n                /* Further, subtract 16ms (the approximate resolution of RAF) from the current time value so that the\n                   first tick iteration isn't wasted by animating at 0% tween completion, which would produce the\n                   same style value as the element's current value. */\n                if (!timeStart) {\n                    timeStart = Velocity.State.calls[i][3] = timeCurrent - 16;\n                }\n\n                /* The tween's completion percentage is relative to the tween's start time, not the tween's start value\n                   (which would result in unpredictable tween durations since JavaScript's timers are not particularly accurate).\n                   Accordingly, we ensure that percentComplete does not exceed 1. */\n                var percentComplete = Math.min((timeCurrent - timeStart) / opts.duration, 1);\n\n                /**********************\n                   Element Iteration\n                **********************/\n\n                /* For every call, iterate through each of the elements in its set. */\n                for (var j = 0, callLength = call.length; j < callLength; j++) {\n                    var tweensContainer = call[j],\n                        element = tweensContainer.element;\n\n                    /* Check to see if this element has been deleted midway through the animation by checking for the\n                       continued existence of its data cache. If it's gone, skip animating this element. */\n                    if (!Data(element)) {\n                        continue;\n                    }\n\n                    var transformPropertyExists = false;\n\n                    /**********************************\n                       Display & Visibility Toggling\n                    **********************************/\n\n                    /* If the display option is set to non-\"none\", set it upfront so that the element can become visible before tweening begins.\n                       (Otherwise, display's \"none\" value is set in completeCall() once the animation has completed.) */\n                    if (opts.display !== undefined && opts.display !== null && opts.display !== \"none\") {\n                        if (opts.display === \"flex\") {\n                            var flexValues = [ \"-webkit-box\", \"-moz-box\", \"-ms-flexbox\", \"-webkit-flex\" ];\n\n                            $.each(flexValues, function(i, flexValue) {\n                                CSS.setPropertyValue(element, \"display\", flexValue);\n                            });\n                        }\n\n                        CSS.setPropertyValue(element, \"display\", opts.display);\n                    }\n\n                    /* Same goes with the visibility option, but its \"none\" equivalent is \"hidden\". */\n                    if (opts.visibility !== undefined && opts.visibility !== \"hidden\") {\n                        CSS.setPropertyValue(element, \"visibility\", opts.visibility);\n                    }\n\n                    /************************\n                       Property Iteration\n                    ************************/\n\n                    /* For every element, iterate through each property. */\n                    for (var property in tweensContainer) {\n                        /* Note: In addition to property tween data, tweensContainer contains a reference to its associated element. */\n                        if (property !== \"element\") {\n                            var tween = tweensContainer[property],\n                                currentValue,\n                                /* Easing can either be a pre-genereated function or a string that references a pre-registered easing\n                                   on the Velocity.Easings object. In either case, return the appropriate easing *function*. */\n                                easing = Type.isString(tween.easing) ? Velocity.Easings[tween.easing] : tween.easing;\n\n                            /******************************\n                               Current Value Calculation\n                            ******************************/\n\n                            /* If this is the last tick pass (if we've reached 100% completion for this tween),\n                               ensure that currentValue is explicitly set to its target endValue so that it's not subjected to any rounding. */\n                            if (percentComplete === 1) {\n                                currentValue = tween.endValue;\n                            /* Otherwise, calculate currentValue based on the current delta from startValue. */\n                            } else {\n                                var tweenDelta = tween.endValue - tween.startValue;\n                                currentValue = tween.startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));\n\n                                /* If no value change is occurring, don't proceed with DOM updating. */\n                                if (!firstTick && (currentValue === tween.currentValue)) {\n                                    continue;\n                                }\n                            }\n\n                            tween.currentValue = currentValue;\n\n                            /* If we're tweening a fake 'tween' property in order to log transition values, update the one-per-call variable so that\n                               it can be passed into the progress callback. */ \n                            if (property === \"tween\") {\n                                tweenDummyValue = currentValue;\n                            } else {\n                                /******************\n                                   Hooks: Part I\n                                ******************/\n\n                                /* For hooked properties, the newly-updated rootPropertyValueCache is cached onto the element so that it can be used\n                                   for subsequent hooks in this call that are associated with the same root property. If we didn't cache the updated\n                                   rootPropertyValue, each subsequent update to the root property in this tick pass would reset the previous hook's\n                                   updates to rootPropertyValue prior to injection. A nice performance byproduct of rootPropertyValue caching is that\n                                   subsequently chained animations using the same hookRoot but a different hook can use this cached rootPropertyValue. */\n                                if (CSS.Hooks.registered[property]) {\n                                    var hookRoot = CSS.Hooks.getRoot(property),\n                                        rootPropertyValueCache = Data(element).rootPropertyValueCache[hookRoot];\n\n                                    if (rootPropertyValueCache) {\n                                        tween.rootPropertyValue = rootPropertyValueCache;\n                                    }\n                                }\n\n                                /*****************\n                                    DOM Update\n                                *****************/\n\n                                /* setPropertyValue() returns an array of the property name and property value post any normalization that may have been performed. */\n                                /* Note: To solve an IE<=8 positioning bug, the unit type is dropped when setting a property value of 0. */\n                                var adjustedSetData = CSS.setPropertyValue(element, /* SET */\n                                                                           property,\n                                                                           tween.currentValue + (parseFloat(currentValue) === 0 ? \"\" : tween.unitType),\n                                                                           tween.rootPropertyValue,\n                                                                           tween.scrollData);\n\n                                /*******************\n                                   Hooks: Part II\n                                *******************/\n\n                                /* Now that we have the hook's updated rootPropertyValue (the post-processed value provided by adjustedSetData), cache it onto the element. */\n                                if (CSS.Hooks.registered[property]) {\n                                    /* Since adjustedSetData contains normalized data ready for DOM updating, the rootPropertyValue needs to be re-extracted from its normalized form. ?? */\n                                    if (CSS.Normalizations.registered[hookRoot]) {\n                                        Data(element).rootPropertyValueCache[hookRoot] = CSS.Normalizations.registered[hookRoot](\"extract\", null, adjustedSetData[1]);\n                                    } else {\n                                        Data(element).rootPropertyValueCache[hookRoot] = adjustedSetData[1];\n                                    }\n                                }\n\n                                /***************\n                                   Transforms\n                                ***************/\n\n                                /* Flag whether a transform property is being animated so that flushTransformCache() can be triggered once this tick pass is complete. */\n                                if (adjustedSetData[0] === \"transform\") {\n                                    transformPropertyExists = true;\n                                }\n\n                            }\n                        }\n                    }\n\n                    /****************\n                        mobileHA\n                    ****************/\n\n                    /* If mobileHA is enabled, set the translate3d transform to null to force hardware acceleration.\n                       It's safe to override this property since Velocity doesn't actually support its animation (hooks are used in its place). */\n                    if (opts.mobileHA) {\n                        /* Don't set the null transform hack if we've already done so. */\n                        if (Data(element).transformCache.translate3d === undefined) {\n                            /* All entries on the transformCache object are later concatenated into a single transform string via flushTransformCache(). */\n                            Data(element).transformCache.translate3d = \"(0px, 0px, 0px)\";\n\n                            transformPropertyExists = true;\n                        }\n                    }\n\n                    if (transformPropertyExists) {\n                        CSS.flushTransformCache(element);\n                    }\n                }\n\n                /* The non-\"none\" display value is only applied to an element once -- when its associated call is first ticked through.\n                   Accordingly, it's set to false so that it isn't re-processed by this call in the next tick. */\n                if (opts.display !== undefined && opts.display !== \"none\") {\n                    Velocity.State.calls[i][2].display = false;\n                }\n                if (opts.visibility !== undefined && opts.visibility !== \"hidden\") {\n                    Velocity.State.calls[i][2].visibility = false;\n                }\n\n                /* Pass the elements and the timing data (percentComplete, msRemaining, timeStart, tweenDummyValue) into the progress callback. */\n                if (opts.progress) {\n                    opts.progress.call(callContainer[1],\n                                       callContainer[1],\n                                       percentComplete,\n                                       Math.max(0, (timeStart + opts.duration) - timeCurrent),\n                                       timeStart,\n                                       tweenDummyValue);\n                }\n\n                /* If this call has finished tweening, pass its index to completeCall() to handle call cleanup. */\n                if (percentComplete === 1) {\n                    completeCall(i);\n                }\n            }\n        }\n\n        /* Note: completeCall() sets the isTicking flag to false when the last call on Velocity.State.calls has completed. */\n        if (Velocity.State.isTicking) {\n            ticker(tick);\n        }\n    }\n\n    /**********************\n        Call Completion\n    **********************/\n\n    /* Note: Unlike tick(), which processes all active calls at once, call completion is handled on a per-call basis. */\n    function completeCall (callIndex, isStopped) {\n        /* Ensure the call exists. */\n        if (!Velocity.State.calls[callIndex]) {\n            return false;\n        }\n\n        /* Pull the metadata from the call. */\n        var call = Velocity.State.calls[callIndex][0],\n            elements = Velocity.State.calls[callIndex][1],\n            opts = Velocity.State.calls[callIndex][2],\n            resolver = Velocity.State.calls[callIndex][4];\n\n        var remainingCallsExist = false;\n\n        /*************************\n           Element Finalization\n        *************************/\n\n        for (var i = 0, callLength = call.length; i < callLength; i++) {\n            var element = call[i].element;\n\n            /* If the user set display to \"none\" (intending to hide the element), set it now that the animation has completed. */\n            /* Note: display:none isn't set when calls are manually stopped (via Velocity(\"stop\"). */\n            /* Note: Display gets ignored with \"reverse\" calls and infinite loops, since this behavior would be undesirable. */\n            if (!isStopped && !opts.loop) {\n                if (opts.display === \"none\") {\n                    CSS.setPropertyValue(element, \"display\", opts.display);\n                }\n\n                if (opts.visibility === \"hidden\") {\n                    CSS.setPropertyValue(element, \"visibility\", opts.visibility);\n                }\n            }\n\n            /* If the element's queue is empty (if only the \"inprogress\" item is left at position 0) or if its queue is about to run\n               a non-Velocity-initiated entry, turn off the isAnimating flag. A non-Velocity-initiatied queue entry's logic might alter\n               an element's CSS values and thereby cause Velocity's cached value data to go stale. To detect if a queue entry was initiated by Velocity,\n               we check for the existence of our special Velocity.queueEntryFlag declaration, which minifiers won't rename since the flag\n               is assigned to jQuery's global $ object and thus exists out of Velocity's own scope. */\n            if (opts.loop !== true && ($.queue(element)[1] === undefined || !/\\.velocityQueueEntryFlag/i.test($.queue(element)[1]))) {\n                /* The element may have been deleted. Ensure that its data cache still exists before acting on it. */\n                if (Data(element)) {\n                    Data(element).isAnimating = false;\n                    /* Clear the element's rootPropertyValueCache, which will become stale. */\n                    Data(element).rootPropertyValueCache = {};\n\n                    var transformHAPropertyExists = false;\n                    /* If any 3D transform subproperty is at its default value (regardless of unit type), remove it. */\n                    $.each(CSS.Lists.transforms3D, function(i, transformName) {\n                        var defaultValue = /^scale/.test(transformName) ? 1 : 0,\n                            currentValue = Data(element).transformCache[transformName];\n\n                        if (Data(element).transformCache[transformName] !== undefined && new RegExp(\"^\\\\(\" + defaultValue + \"[^.]\").test(currentValue)) {\n                            transformHAPropertyExists = true;\n\n                            delete Data(element).transformCache[transformName];\n                        }\n                    });\n\n                    /* Mobile devices have hardware acceleration removed at the end of the animation in order to avoid hogging the GPU's memory. */\n                    if (opts.mobileHA) {\n                        transformHAPropertyExists = true;\n                        delete Data(element).transformCache.translate3d;\n                    }\n\n                    /* Flush the subproperty removals to the DOM. */\n                    if (transformHAPropertyExists) {\n                        CSS.flushTransformCache(element);\n                    }\n\n                    /* Remove the \"velocity-animating\" indicator class. */\n                    CSS.Values.removeClass(element, \"velocity-animating\");\n                }\n            }\n\n            /*********************\n               Option: Complete\n            *********************/\n\n            /* Complete is fired once per call (not once per element) and is passed the full raw DOM element set as both its context and its first argument. */\n            /* Note: Callbacks aren't fired when calls are manually stopped (via Velocity(\"stop\"). */\n            if (!isStopped && opts.complete && !opts.loop && (i === callLength - 1)) {\n                /* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */\n                try {\n                    opts.complete.call(elements, elements);\n                } catch (error) {\n                    setTimeout(function() { throw error; }, 1);\n                }\n            }\n\n            /**********************\n               Promise Resolving\n            **********************/\n\n            /* Note: Infinite loops don't return promises. */\n            if (resolver && opts.loop !== true) {\n                resolver(elements);\n            }\n\n            /****************************\n               Option: Loop (Infinite)\n            ****************************/\n\n            if (Data(element) && opts.loop === true && !isStopped) {\n                /* If a rotateX/Y/Z property is being animated to 360 deg with loop:true, swap tween start/end values to enable\n                   continuous iterative rotation looping. (Otherise, the element would just rotate back and forth.) */\n                $.each(Data(element).tweensContainer, function(propertyName, tweenContainer) {\n                    if (/^rotate/.test(propertyName) && parseFloat(tweenContainer.endValue) === 360) {\n                        tweenContainer.endValue = 0;\n                        tweenContainer.startValue = 360;\n                    }\n\n                    if (/^backgroundPosition/.test(propertyName) && parseFloat(tweenContainer.endValue) === 100 && tweenContainer.unitType === \"%\") {\n                        tweenContainer.endValue = 0;\n                        tweenContainer.startValue = 100;\n                    }\n                });\n\n                Velocity(element, \"reverse\", { loop: true, delay: opts.delay });\n            }\n\n            /***************\n               Dequeueing\n            ***************/\n\n            /* Fire the next call in the queue so long as this call's queue wasn't set to false (to trigger a parallel animation),\n               which would have already caused the next call to fire. Note: Even if the end of the animation queue has been reached,\n               $.dequeue() must still be called in order to completely clear jQuery's animation queue. */\n            if (opts.queue !== false) {\n                $.dequeue(element, opts.queue);\n            }\n        }\n\n        /************************\n           Calls Array Cleanup\n        ************************/\n\n        /* Since this call is complete, set it to false so that the rAF tick skips it. This array is later compacted via compactSparseArray().\n          (For performance reasons, the call is set to false instead of being deleted from the array: http://www.html5rocks.com/en/tutorials/speed/v8/) */\n        Velocity.State.calls[callIndex] = false;\n\n        /* Iterate through the calls array to determine if this was the final in-progress animation.\n           If so, set a flag to end ticking and clear the calls array. */\n        for (var j = 0, callsLength = Velocity.State.calls.length; j < callsLength; j++) {\n            if (Velocity.State.calls[j] !== false) {\n                remainingCallsExist = true;\n\n                break;\n            }\n        }\n\n        if (remainingCallsExist === false) {\n            /* tick() will detect this flag upon its next iteration and subsequently turn itself off. */\n            Velocity.State.isTicking = false;\n\n            /* Clear the calls array so that its length is reset. */\n            delete Velocity.State.calls;\n            Velocity.State.calls = [];\n        }\n    }\n\n    /******************\n        Frameworks\n    ******************/\n\n    /* Both jQuery and Zepto allow their $.fn object to be extended to allow wrapped elements to be subjected to plugin calls.\n       If either framework is loaded, register a \"velocity\" extension pointing to Velocity's core animate() method.  Velocity\n       also registers itself onto a global container (window.jQuery || window.Zepto || window) so that certain features are\n       accessible beyond just a per-element scope. This master object contains an .animate() method, which is later assigned to $.fn\n       (if jQuery or Zepto are present). Accordingly, Velocity can both act on wrapped DOM elements and stand alone for targeting raw DOM elements. */\n    global.Velocity = Velocity;\n\n    if (global !== window) {\n        /* Assign the element function to Velocity's core animate() method. */\n        global.fn.velocity = animate;\n        /* Assign the object function's defaults to Velocity's global defaults object. */\n        global.fn.velocity.defaults = Velocity.defaults;\n    }\n\n    /***********************\n       Packaged Redirects\n    ***********************/\n\n    /* slideUp, slideDown */\n    $.each([ \"Down\", \"Up\" ], function(i, direction) {\n        Velocity.Redirects[\"slide\" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {\n            var opts = $.extend({}, options),\n                begin = opts.begin,\n                complete = opts.complete,\n                computedValues = { height: \"\", marginTop: \"\", marginBottom: \"\", paddingTop: \"\", paddingBottom: \"\" },\n                inlineValues = {};\n\n            if (opts.display === undefined) {\n                /* Show the element before slideDown begins and hide the element after slideUp completes. */\n                /* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */\n                opts.display = (direction === \"Down\" ? (Velocity.CSS.Values.getDisplayType(element) === \"inline\" ? \"inline-block\" : \"block\") : \"none\");\n            }\n\n            opts.begin = function() {\n                var style = element.renderer === \"webgl\" ? element.styleGL : element.style;\n                /* If the user passed in a begin callback, fire it now. */\n                begin && begin.call(elements, elements);\n\n                /* Cache the elements' original vertical dimensional property values so that we can animate back to them. */\n                for (var property in computedValues) {\n                    inlineValues[property] = style[property];\n\n                    /* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp,\n                       use forcefeeding to start from computed values and animate down to 0. */\n                    var propertyValue = Velocity.CSS.getPropertyValue(element, property);\n                    computedValues[property] = (direction === \"Down\") ? [ propertyValue, 0 ] : [ 0, propertyValue ];\n                }\n\n                /* Force vertical overflow content to clip so that sliding works as expected. */\n                inlineValues.overflow = style.overflow;\n                style.overflow = \"hidden\";\n            }\n\n            opts.complete = function() {\n                /* Reset element to its pre-slide inline values once its slide animation is complete. */\n                for (var property in inlineValues) {\n                    style[property] = inlineValues[property];\n                }\n\n                /* If the user passed in a complete callback, fire it now. */\n                complete && complete.call(elements, elements);\n                promiseData && promiseData.resolver(elements);\n            };\n\n            Velocity(element, computedValues, opts);\n        };\n    });\n\n    /* fadeIn, fadeOut */\n    $.each([ \"In\", \"Out\" ], function(i, direction) {\n        Velocity.Redirects[\"fade\" + direction] = function (element, options, elementsIndex, elementsSize, elements, promiseData) {\n            var opts = $.extend({}, options),\n                propertiesMap = { opacity: (direction === \"In\") ? 1 : 0 },\n                originalComplete = opts.complete;\n\n            /* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering\n               callbacks by firing them only when the final element has been reached. */\n            if (elementsIndex !== elementsSize - 1) {\n                opts.complete = opts.begin = null;\n            } else {\n                opts.complete = function() {\n                    if (originalComplete) {\n                        originalComplete.call(elements, elements);\n                    }\n\n                    promiseData && promiseData.resolver(elements);\n                }\n            }\n\n            /* If a display was passed in, use it. Otherwise, default to \"none\" for fadeOut or the element-specific default for fadeIn. */\n            /* Note: We allow users to pass in \"null\" to skip display setting altogether. */\n            if (opts.display === undefined) {\n                opts.display = (direction === \"In\" ? \"auto\" : \"none\");\n            }\n\n            Velocity(this, propertiesMap, opts);\n        };\n    });\n\n    return Velocity;\n}((window.jQuery || window.Zepto || window), window, document);\n}));\n\n/******************\n   Known Issues\n******************/\n\n/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.\nVelocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties\nwill produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */\n/*\n * Util is a part of HTML GL library\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function(w){\n    w.HTMLGL = w.HTMLGL || {};\n    w.HTMLGL.util = {\n        getterSetter: function  (variableParent, variableName, getterFunction, setterFunction) {\n            if (Object.defineProperty) {\n                Object.defineProperty(variableParent, variableName, {\n                    get: getterFunction,\n                    set: setterFunction\n                });\n            }\n            else if (document.__defineGetter__) {\n                variableParent.__defineGetter__(variableName, getterFunction);\n                variableParent.__defineSetter__(variableName, setterFunction);\n            }\n\n            variableParent[\"get\" + variableName] = getterFunction;\n            variableParent[\"set\" + variableName] = setterFunction;\n        },\n        emitEvent: function (element, event) {\n            var newEvent = new MouseEvent(event.type, event);\n            newEvent.dispatcher = 'html-gl';\n            event.stopPropagation();\n            element.dispatchEvent(newEvent);\n        },\n        debounce: function(func, wait, immediate) {\n            var timeout;\n            return function() {\n                var context = this, args = arguments;\n                var later = function() {\n                    timeout = null;\n                    if (!immediate) func.apply(context, args);\n                };\n                var callNow = immediate && !timeout;\n                clearTimeout(timeout);\n                timeout = setTimeout(later, wait);\n                if (callNow) func.apply(context, args);\n            };\n        }\n    }\n})(window);\n/*\n * GLElementResolver is a part of HTML GL library for resolving elements by coordinates given\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var GLElementResolver = function (context) {\n    }\n\n    var p = GLElementResolver.prototype;\n\n    p.getElementByCoordinates = function (x, y) {\n        var element,\n            self = this,\n            result;\n\n        w.HTMLGL.elements.forEach(function (glelement) {\n            element = document.elementFromPoint(x - parseInt(glelement.transformObject.translateX || 0), y - parseInt(glelement.transformObject.translateY || 0))\n            if (self.isChildOf(element, glelement)) {\n                result = element;\n            }\n        });\n\n        return result;\n    }\n\n    p.isChildOf = function (child, parent) {\n        var current = child;\n        while (current) {\n            if (current === parent) return true;\n            current = current.parentNode;\n        }\n        return false;\n    }\n\n    w.HTMLGL.GLElementResolver = GLElementResolver;\n})(window);\n/*\n * GLContext is a part of HTML GL library describing rendering context\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    //Defining global namespace with respect if exists\n    HTMLGL = w.HTMLGL = w.HTMLGL || {};\n\n    //Defining it`s properties\n    HTMLGL.JQ_PLUGIN_NAME = 'htmlgl';\n    HTMLGL.CUSTOM_ELEMENT_TAG_NAME = 'html-gl';\n    HTMLGL.READY_EVENT = 'htmlglReady';\n    HTMLGL.context = undefined;\n    HTMLGL.stage = undefined;\n    HTMLGL.renderer = undefined;\n    HTMLGL.elements = [];\n    HTMLGL.pixelRatio = null;\n    HTMLGL.oldPixelRatio = null;\n    HTMLGL.enabled = true;\n\n    //Cache for window`s scroll position, filled in by updateScrollPosition\n    HTMLGL.scrollX = 0;\n    HTMLGL.scrollY = 0;\n\n    var GLContext = function () {\n        w.HTMLGL.context = this;\n\n        this.createStage();             //Creating stage before showing it\n        this.updateScrollPosition();    //Initialize scroll position for first time\n        this.initListeners();\n        this.elementResolver = new w.HTMLGL.GLElementResolver(this);\n\n        //Wait for DOMContentLoaded and initialize viewer then\n        if (!document.body) {\n            document.addEventListener(\"DOMContentLoaded\", this.initViewer.bind(this));\n        } else {\n            this.initViewer();\n        }\n    }\n\n    var p = GLContext.prototype;\n\n    p.initViewer = function () {\n        this.createViewer();\n        this.resizeViewer();\n        this.appendViewer();\n    }\n\n    p.createViewer = function () {\n        w.HTMLGL.renderer = this.renderer = PIXI.autoDetectRenderer(0, 0, {transparent: true});\n        this.renderer.view.style.position = 'fixed';\n        this.renderer.view.style.top = '0px';\n        this.renderer.view.style.left = '0px';\n        this.renderer.view.style['pointer-events'] = 'none';\n        this.renderer.view.style['pointerEvents'] = 'none';\n    }\n\n    p.appendViewer = function () {\n        document.body.appendChild(this.renderer.view);\n        requestAnimationFrame(this.redrawStage.bind(this));\n    }\n\n    p.resizeViewer = function () {\n        var self = this,\n            width = w.innerWidth,\n            height = w.innerHeight;\n\n        //Update pixelRatio since could be resized on different screen with different ratio\n        HTMLGL.pixelRatio = w.HTMLGL.getPixelRatio();\n\n        console.log(HTMLGL.pixelRatio);\n\n        width = width * HTMLGL.pixelRatio;\n        height = height * HTMLGL.pixelRatio;\n\n        if (HTMLGL.pixelRatio !== HTMLGL.oldPixelRatio) {\n            this.disable();\n            this.updateTextures().then(function(){\n                self.updateScrollPosition();\n                self.updateElementsPositions();\n\n                var rendererScale = 1 / HTMLGL.pixelRatio;\n                self.renderer.view.style.transformOrigin = '0 0';\n                self.renderer.view.style.webkitTransformOrigin = '0 0';\n                self.renderer.view.style.transform = 'scaleX(' + rendererScale + ') scaleY(' + rendererScale + ')';\n                self.renderer.view.style.webkitTransform = 'scaleX(' + rendererScale + ') scaleY(' + rendererScale + ')';\n                self.renderer.resize(width, height);\n\n                w.HTMLGL.renderer.render(w.HTMLGL.stage);\n            });\n        } else {\n            if (this.renderer.view.parentNode) { //No need to update textures when is not mounted yet\n                this.updateTextures();\n            }\n            this.updateElementsPositions();\n            this.markStageAsChanged();\n        }\n\n        HTMLGL.oldPixelRatio = HTMLGL.pixelRatio;\n    }\n\n    p.initListeners = function () {\n        //window listeners\n        w.addEventListener('scroll', this.updateScrollPosition.bind(this));\n        w.addEventListener('resize', w.HTMLGL.util.debounce(this.resizeViewer, 500).bind(this));\n        w.addEventListener('resize', this.updateElementsPositions.bind(this));\n\n        //document listeners - mouse and touch events\n        document.addEventListener('click', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mousemove', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mouseup', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mousedown', this.onMouseEvent.bind(this), true);\n        document.addEventListener('touchstart', this.onMouseEvent.bind(this));\n        document.addEventListener('touchend', this.onMouseEvent.bind(this));\n    }\n\n    p.updateScrollPosition = function () {\n        var scrollOffset = {};\n\n        if (window.pageYOffset != undefined) {\n            scrollOffset = {\n                left: pageXOffset,\n                top: pageYOffset\n            };\n        } else {\n            var sx, sy, d = document, r = d.documentElement, b = d.body;\n            sx = r.scrollLeft || b.scrollLeft || 0;\n            sy = r.scrollTop || b.scrollTop || 0;\n            scrollOffset = {\n                left: sx,\n                top: sy\n            };\n        }\n\n        this.document.x = -scrollOffset.left * HTMLGL.pixelRatio;\n        this.document.y = -scrollOffset.top * HTMLGL.pixelRatio;\n\n        w.HTMLGL.scrollX = scrollOffset.left;\n        w.HTMLGL.scrollY = scrollOffset.top;\n\n        this.markStageAsChanged();\n    }\n\n    p.createStage = function () {\n        w.HTMLGL.stage = this.stage = new PIXI.Stage(0xFFFFFF);\n        w.HTMLGL.document = this.document = new PIXI.DisplayObjectContainer();\n        this.stage.addChild(w.HTMLGL.document);\n    }\n\n    //Avoiding function.bind() for performance and memory consuming reasons\n    p.redrawStage = function () {\n        if (w.HTMLGL.stage.changed && w.HTMLGL.renderer && w.HTMLGL.enabled) {\n            w.HTMLGL.renderer.render(w.HTMLGL.stage);\n            w.HTMLGL.stage.changed = false;\n        }\n    }\n\n    p.updateTextures = function () {\n        var updatePromises = [];\n\n        w.HTMLGL.elements.forEach(function (element) {\n            updatePromises.push(element.updateTexture());\n        });\n\n        return Promise.all(updatePromises);\n    }\n\n    p.initElements = function () {\n        w.HTMLGL.elements.forEach(function (element) {\n            element.init();\n        });\n    }\n\n    p.updateElementsPositions = function () {\n        w.HTMLGL.elements.forEach(function (element) {\n            element.updateBoundingRect();\n            element.updatePivot();\n            element.updateSpriteTransform();\n        });\n    }\n\n    p.onMouseEvent = function (event) {\n        var x = event.x || event.pageX,\n            y = event.y || event.pageY,\n        //Finding element under mouse position\n            element = event.dispatcher !== 'html-gl' ? this.elementResolver.getElementByCoordinates(x, y) : null;\n\n        //Emit event if there is an element under mouse position\n        element ? w.HTMLGL.util.emitEvent(element, event) : null;\n    }\n\n    //We would like to rerender if something changed, otherwise stand by\n    p.markStageAsChanged = function () {\n        if (w.HTMLGL.stage && !w.HTMLGL.stage.changed) {\n            requestAnimationFrame(this.redrawStage);\n            w.HTMLGL.stage.changed = true;\n        }\n    }\n\n    p.disable = function () {\n        w.HTMLGL.enabled = true;\n    }\n\n    p.enable = function () {\n        w.HTMLGL.enabled = false;\n    }\n\n    w.HTMLGL.getPixelRatio = function() {\n        return window.devicePixelRatio || 1;\n    }\n\n    w.HTMLGL.pixelRatio = w.HTMLGL.getPixelRatio();\n\n    w.HTMLGL.GLContext = GLContext;\n    new GLContext();\n})(window);\n/*\n * ImagesLoaded is a part of HTML GL library which is a robust solution for determining \"are images loaded or not?\"\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var ImagesLoaded = function (element, callback) {\n        this.element = element;\n        this.images = this.element.querySelectorAll('img');\n        this.callback = callback;\n        this.imagesLoaded = this.getImagesLoaded();\n\n        if (this.images.length === this.imagesLoaded) {\n            this.onImageLoaded();\n        } else {\n            this.addListeners();\n        }\n    }\n\n    var p = ImagesLoaded.prototype;\n\n    p.getImagesLoaded = function () {\n        var result = 0;\n        for (var i = 0; i < this.images.length; i++) {\n            if (this.images[i].complete === true) {\n                result++;\n            }\n        }\n        return result;\n    }\n\n    p.addListeners = function () {\n        var result = 0;\n        for (var i = 0; i < this.images.length; i++) {\n            if (this.images[i].complete !== true) {\n                this.images[i].addEventListener('load', this.onImageLoaded.bind(this));\n                this.images[i].addEventListener('error', this.onImageLoaded.bind(this));\n            }\n        }\n        return result;\n    }\n\n    p.onImageLoaded = function () {\n        this.imagesLoaded++;\n        if (this.images.length - this.imagesLoaded <= 0) {\n            setTimeout(this.callback, 0);\n        }\n    }\n\n    w.HTMLGL.ImagesLoaded = ImagesLoaded;\n})(window);\n/*\n * GLElement is a part of HTML GL library describing single HTML-GL element\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n *\n * Please, take into account:\n * - updateTexture is expensive\n * - updateSpriteTransform is cheap\n * */\n\n(function (w) {\n    var p = Object.create(HTMLElement.prototype),\n        style = document.createElement('style');\n\n    //Default styling for html-gl elements\n    style.innerHTML = HTMLGL.CUSTOM_ELEMENT_TAG_NAME + ' { display: inline-block; transform: translateZ(0);}';\n    document.head.appendChild(style);\n\n    p.createdCallback = function () {\n        //Checking is node created inside of html2canvas virtual window or not. We do not need WebGL there\n        var currentNode = this,\n            isMounted = false;\n\n        while (currentNode = currentNode.parentNode) {\n            if (currentNode.tagName === 'BODY') {\n                isMounted = true;\n            }\n        }\n\n        var isInsideHtml2Canvas = !isMounted || (this.baseURI === undefined || this.baseURI === '' || this.baseURI === null);\n\n        if (!isInsideHtml2Canvas) {\n            HTMLGL.elements.push(this);\n            //Needed to determine is element WebGL rendered or not relying on tag name\n            this.setAttribute('renderer', 'webgl');\n            this.renderer = 'webgl';\n\n            this.transformObject = {};\n            this.boundingRect = {};\n            this.image = {};\n            this.sprite = new PIXI.Sprite();\n            this.texture = {};\n\n            this.halfWidth = 0;\n            this.halfHeight = 0;\n\n            this.observer = undefined;\n\n            this.glChilds = [];\n            this.glChildsReady = 0;\n            this.glParent = this.getGlParent();\n\n            this.initEffects();\n            this.bindCallbacks();\n            this.transformProperty = this.style.transform !== undefined ? 'transform' : 'WebkitTransform';\n            this.init();\n        }\n    }\n\n    p.init = function () {\n        this.notifyGlParent();\n        this.updateTexture();\n        this.initObservers();\n        this.patchStyleGLTransform();\n    }\n\n    p.getGlParent = function () {\n        var parent = this,\n            tagName = HTMLGL.CUSTOM_ELEMENT_TAG_NAME.toUpperCase();\n\n        while (parent) {\n            parent = parent.parentNode;\n\n            if (parent && parent.tagName === tagName) {\n                return parent;\n            } else if (parent === w.document) {\n                return null;\n            }\n        }\n    }\n\n    //Notify GL parent about one more HTML GL child in the tree\n    p.notifyGlParent = function () {\n        if (this.glParent) {\n            this.glParent.addGlChild(this);\n        }\n    }\n\n    p.addGlChild = function (child) {\n        this.glChilds.push(child);\n    }\n\n    p.glChildReady = function () {\n        this.glChildsReady++;\n        this.dispatchReady();\n    }\n\n    //If all my childs ready notify parent that I am\n    p.dispatchReady = function () {\n        if (this.isReady()) {\n            var event = new Event(HTMLGL.READY_EVENT);\n            this.dispatchEvent(event);\n\n            if (this.glParent) {\n                //Inform parent\n                this.glParent.glChildReady();\n            }\n        }\n    }\n\n    p.isReady = function () {\n        return (this.glChilds.length - this.glChildsReady === 0) && this.haveSprite();\n    }\n\n    //Updating bounds, waiting for all images to load and calling rasterization then\n    p.updateTexture = function () {\n        var self = this;\n        self.updateBoundingRect();\n\n        return new Promise(function(resolve, reject){\n            self.image = html2canvas(self, {\n                width: self.boundingRect.width * HTMLGL.pixelRatio,\n                height: self.boundingRect.height * HTMLGL.pixelRatio\n            }).then(function(textureCanvas){\n                self.applyNewTexture(textureCanvas);\n                resolve();\n            });\n        });\n    }\n\n    //Recreating texture from canvas given after calling updateTexture\n    p.applyNewTexture = function (textureCanvas) {\n        this.image = textureCanvas;\n        this.texture = PIXI.Texture.fromCanvas(this.image);\n\n        if (!this.haveSprite()) {\n            this.initSprite(this.texture);\n        } else {\n            this.sprite.texture.destroy();\n            this.sprite.texture = this.texture;\n        }\n\n        this.updatePivot();\n        this.updateSpriteTransform();\n\n        HTMLGL.context.markStageAsChanged();\n    }\n\n    //Just updates WebGL representation coordinates and transformation\n    p.updateSpriteTransform = function () {\n\n        //TODO add 3d rotation support\n        var translateX = parseFloat(this.transformObject.translateX) || 0,\n            translateY = parseFloat(this.transformObject.translateY) || 0,\n            scaleX = parseFloat(this.transformObject.scaleX) || 1,\n            scaleY = parseFloat(this.transformObject.scaleY) || 1,\n            rotate = (parseFloat(this.transformObject.rotateZ) / 180) * Math.PI || 0;\n\n        if (this.sprite && this.sprite.position) {\n            this.sprite.position.x = (this.boundingRect.left + translateX) * HTMLGL.pixelRatio + this.halfWidth;\n            this.sprite.position.y = (this.boundingRect.top + translateY) * HTMLGL.pixelRatio + this.halfHeight;\n            this.sprite.scale.x = scaleX;\n            this.sprite.scale.y = scaleY;\n            this.sprite.rotation = rotate;\n        }\n\n        HTMLGL.context.markStageAsChanged();\n    }\n\n    //Getting bounding rect with respect to current scroll position\n    p.updateBoundingRect = function () {\n        var boundingRect = this.getBoundingClientRect();\n\n        this.boundingRect = {\n            left: boundingRect.left,\n            right: boundingRect.right,\n            top: boundingRect.top,\n            bottom: boundingRect.bottom,\n            width: boundingRect.width,\n            height: boundingRect.height,\n        };\n\n        if (this.glParent && this.glParent.boundingRect) {\n            this.boundingRect.left -= this.glParent.boundingRect.left;\n            this.boundingRect.top -= this.glParent.boundingRect.top;\n        }\n\n        this.boundingRect.left = HTMLGL.scrollX + parseFloat(this.boundingRect.left);\n        this.boundingRect.top = HTMLGL.scrollY + parseFloat(this.boundingRect.top);\n    }\n\n    //Correct pivot needed to rotate element around it`s center\n    p.updatePivot = function () {\n        this.halfWidth = this.sprite.width / 2;\n        this.halfHeight = this.sprite.height / 2;\n        this.sprite.pivot.x = this.halfWidth;\n        this.sprite.pivot.y = this.halfHeight;\n    }\n\n    p.initSprite = function (texture) {\n        var self = this,\n            parentSprite = this.glParent && this.glParent.sprite || w.HTMLGL.document;\n\n        this.sprite.texture = texture;\n        parentSprite.addChild(this.sprite);\n\n        setTimeout(function () {\n            self.hideDOM();\n            //Notify parents that I am initialized\n            self.dispatchReady();\n        }, 0);\n    }\n\n    p.initObservers = function () {\n        //TODO Better heuristics for rerendering condition #2\n        var self = this,\n            config = {\n                childList: true,\n                characterData: true,\n                subtree: true,\n                attributes: true,\n                attributeFilter: ['style']\n            };\n\n        this.observer = this.observer || new MutationObserver(function (mutations) {\n            if (mutations[0].attributeName === 'style') {\n                self.transformObject = self.getTransformObjectFromString(self.style[self.transformProperty]);\n                self.updateSpriteTransform();\n            } else {\n                self.updateTexture();\n            }\n        });\n\n        this.observer.observe(this, config);\n    }\n\n    p.patchStyleGLTransform = function () {\n        var self = this;\n        self.styleGL = {};\n\n        HTMLGL.util.getterSetter(this.styleGL, this.transformProperty, function () {\n                var result = '';\n\n                for (var transformPropertyName in self.transformObject) {\n                    var transformPropertyValue = '(' + self.transformObject[transformPropertyName] + ') ';\n                    result += transformPropertyName + transformPropertyValue;\n                }\n\n                return result;\n            },\n            function (value) {\n                self.transformObject = self.getTransformObjectFromString(value);\n                self.updateSpriteTransform();\n            }\n        )\n    }\n\n    p.getTransformObjectFromString = function (transformString) {\n        return (transformString.match(/([\\w]+)\\(([^\\)]+)\\)/g) || [])\n            .map(function (it) {\n                return it.replace(/\\)$/, \"\").split(/\\(/)\n            })\n            .reduce(function (m, it) {\n                return m[it[0]] = it[1], m\n            }, {});\n    }\n\n    p.hideDOM = function () {\n        this.style.opacity = 0;\n    }\n\n    p.bindCallbacks = function () {\n        this.applyNewTexture = this.applyNewTexture.bind(this);\n    }\n\n    p.haveSprite = function () {\n        return this.sprite.stage;\n    }\n\n    p.initEffects = function () {\n        if (HTMLGL.GLEffectsManager) {\n            this.effectsManager = new HTMLGL.GLEffectsManager(this);\n        }\n    }\n\n    HTMLGL.GLElement = document.registerElement(HTMLGL.CUSTOM_ELEMENT_TAG_NAME, {\n        prototype: p\n    })\n\n    HTMLGL.GLElement.createFromNode = function (node) {\n        //Extending node with GLElement methods\n        for (var i in p) {\n            if (p.hasOwnProperty(i)) {\n                node[i] = p[i];\n            }\n        }\n\n        p.createdCallback.apply(node);\n        return node;\n    }\n\n    //Wrap to jQuery plugin\n    if (w.jQuery !== undefined) {\n        jQuery[HTMLGL.JQ_PLUGIN_NAME] = {};\n        jQuery[HTMLGL.JQ_PLUGIN_NAME].elements = [];\n\n        jQuery.fn[HTMLGL.JQ_PLUGIN_NAME] = function () {\n            return this.each(function () {\n                if (!jQuery.data(this, 'plugin_' + HTMLGL.JQ_PLUGIN_NAME)) {\n                    var htmlGLobj = HTMLGL.GLElement.createFromNode(this);\n                    jQuery.data(this, 'plugin_' + HTMLGL.JQ_PLUGIN_NAME, htmlGLobj);\n                    jQuery[HTMLGL.JQ_PLUGIN_NAME].elements.push(htmlGLobj);\n                }\n            });\n        };\n    }\n})(window);"
  },
  {
    "path": "figures/htmlgl-flow-diagram.ep",
    "content": "<?xml version=\"1.0\"?>\n<Document xmlns=\"http://www.evolus.vn/Namespace/Pencil\"><Properties/><Pages><Page><Properties><Property name=\"name\">Untitled Page</Property><Property name=\"id\">1425479107853_8445</Property><Property name=\"width\">520</Property><Property name=\"height\">350</Property><Property name=\"dimBackground\"/><Property name=\"transparentBackground\">true</Property><Property name=\"backgroundColor\">#FFFFFFFF</Property><Property name=\"background\">transparent</Property></Properties><Content><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Flowchart:process\" id=\"6bc98be7498aec43ae19d01c53d3fe85\" transform=\"matrix(1,0,0,1,140,17)\"><p:metadata><p:property name=\"box\"><![CDATA[100,80]]></p:property><p:property name=\"outputPin1Origin\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin1\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin2Origin\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin2\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin3Origin\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin3\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin4Origin\"><![CDATA[0,40]]></p:property><p:property name=\"outputPin4\"><![CDATA[0,40]]></p:property><p:property name=\"fillColor\"><![CDATA[#BDDFFFFF]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[Rasterization to a texture]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <rect style=\"stroke-linejoin: round; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2; fill: rgb(189, 223, 255); fill-opacity: 1;\" p:name=\"path\" id=\"b7bf6c694d518448841abe31de2e9c34\" transform=\"translate(0,0)\" x=\"0\" y=\"0\" width=\"100\" height=\"80\"/>\n            <text text-anchor=\"start\" xml:space=\"preserve\" p:name=\"text\" id=\"ec257f4be1472c42b9743f7df9968e5b\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;\" transform=\"translate(7,37)\"><tspan x=\"1.3666648864746094\" y=\"0\">Rasterization to</tspan><tspan x=\"19.674999237060547\" y=\"13\">a texture</tspan></text>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow1\" id=\"d09bf914c0ee8f428b4f7a9963c3e5d9\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow2\" id=\"3f205ea6495f1547982f17e9526878cc\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow3\" id=\"f4d05dd217b7444898d9b6f21f772d05\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow4\" id=\"4ef70ee0bb784f408690b44177810d4d\" d=\"\"/>\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Straight Connector\" id=\"5dad907ef3b90249818a8b36f1773e8c\" transform=\"matrix(1,0,0,1,227,317)\"><p:metadata><p:property name=\"startPin\" p:viay=\"-260\" p:viax=\"23\" p:connectedOutletId=\"middle-right\" p:connectedShapeId=\"6bc98be7498aec43ae19d01c53d3fe85\"><![CDATA[13,-260]]></p:property><p:property name=\"endPin\" p:connectedShapeId=\"4bf292a0bf4c4a48a765f6425dac3c14\" p:connectedOutletId=\"middle-left\" p:viax=\"23\" p:viay=\"-260\"><![CDATA[33,-260]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"225d2132981f804895f2d85659755756\" d=\"M 13 -260 L 23 -260 L 33 -260 M 27 -266 L 33 -260 L 27 -254\"/>\n            </defs>\n            <use xlink:href=\"#225d2132981f804895f2d85659755756\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#225d2132981f804895f2d85659755756\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"57ba1aa7b427214285363607355eb6c6\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"bc821a1e3b382a46ae253d49a748d84e\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#225d2132981f804895f2d85659755756\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"81a7c4873989dc419392a4fb867fe723\" dx=\"-16\"/>\n                </textPath>\n            </text>\n\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Flowchart:Document\" id=\"84d7162fa549874da8195fef9338a0de\" transform=\"matrix(1,0,0,1,18,17)\"><p:metadata><p:property name=\"box\"><![CDATA[100,80]]></p:property><p:property name=\"outputPin1Origin\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin1\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin2Origin\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin2\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin3Origin\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin3\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin4Origin\"><![CDATA[0,40]]></p:property><p:property name=\"outputPin4\"><![CDATA[0,40]]></p:property><p:property name=\"fillColor\"><![CDATA[#BDDFFFFF]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[<html-gl> element]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <path style=\"stroke-linejoin: round; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2; fill: rgb(189, 223, 255); fill-opacity: 1;\" p:name=\"path\" id=\"8142bc7d39328140806d4bdaeab37918\" transform=\"translate(0,0)\" d=\"M 0 0 L 100 0 L 100 64 C 75 64 75 64 50 72 S 25 80 0 72 z\"/>\n\n            <text text-anchor=\"start\" xml:space=\"preserve\" p:name=\"text\" id=\"8c735c9f4e743043876988289ac61a49\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;\" transform=\"translate(7,29)\"><tspan x=\"18.524999618530273\" y=\"0\">&lt;html-gl&gt;</tspan><tspan x=\"22.183332443237305\" y=\"12.5\">element</tspan></text>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow1\" id=\"61aeb856f2f98f4d86cdba794daff2fe\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow2\" id=\"ee48d0efc75ea34aa49ae3a969cc8beb\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow3\" id=\"b8edc4a1d680c943a4eca7bb4ae2afad\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow4\" id=\"5c5771fd0d776d49bb52a6381b79703d\" d=\"\"/>\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Straight Connector\" id=\"f9885a72ec38a2408a8319a3868803a2\" transform=\"matrix(1,0,0,1,267,103)\"><p:metadata><p:property name=\"startPin\" p:viay=\"-46\" p:viax=\"-139\" p:connectedOutletId=\"middle-right\" p:connectedShapeId=\"84d7162fa549874da8195fef9338a0de\"><![CDATA[-149,-46]]></p:property><p:property name=\"endPin\" p:connectedShapeId=\"6bc98be7498aec43ae19d01c53d3fe85\" p:connectedOutletId=\"middle-left\" p:viax=\"-137\" p:viay=\"-46\"><![CDATA[-127,-46]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"0bcd0909376d2e4788cf0d91e847867a\" d=\"M -149 -46 L -137 -46 L -127 -46 M -133 -52 L -127 -46 L -133 -40\"/>\n            </defs>\n            <use xlink:href=\"#0bcd0909376d2e4788cf0d91e847867a\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#0bcd0909376d2e4788cf0d91e847867a\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"4f50cd7daaf99d4aaf47dffb68bbcc46\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"07bbc90e511cbc43b3e55702d06318c8\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#0bcd0909376d2e4788cf0d91e847867a\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"bba30e274c7aa34dbd52ccedb9b650de\" dx=\"-16\"></tspan>\n                </textPath>\n            </text>\n\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Flowchart:process\" id=\"4bf292a0bf4c4a48a765f6425dac3c14\" transform=\"matrix(1,0,0,1,260,17)\"><p:metadata><p:property name=\"box\"><![CDATA[100,80]]></p:property><p:property name=\"outputPin1Origin\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin1\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin2Origin\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin2\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin3Origin\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin3\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin4Origin\"><![CDATA[0,40]]></p:property><p:property name=\"outputPin4\"><![CDATA[0,40]]></p:property><p:property name=\"fillColor\"><![CDATA[#BDDFFFFF]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[Displaying on WebGL surface (with Canvas fallback)]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <rect style=\"stroke-linejoin: round; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2; fill: rgb(189, 223, 255); fill-opacity: 1;\" p:name=\"path\" id=\"0a1061957e2abc489eaae2a9bcbed7ca\" transform=\"translate(0,0)\" x=\"0\" y=\"0\" width=\"100\" height=\"80\"/>\n            <text text-anchor=\"start\" xml:space=\"preserve\" p:name=\"text\" id=\"9ad27fd7358b63429c466317a193e884\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;\" transform=\"translate(7,24)\"><tspan x=\"7.033332824707031\" y=\"0\">Displaying on</tspan><tspan x=\"1.4583320617675781\" y=\"13\">WebGL surface</tspan><tspan x=\"8.36666488647461\" y=\"26\">(with Canvas</tspan><tspan x=\"20.691667556762695\" y=\"39\">fallback)</tspan></text>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow1\" id=\"60d77f9175933d479dedc9ea0792c3c1\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow2\" id=\"b61b29a96a1c474c9513f398db1be562\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow3\" id=\"35b1d52150f465439220327b5026ce20\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow4\" id=\"a77ef1995e8d904d94684d3ebad7cae7\" d=\"\"/>\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Flowchart:Decision\" id=\"ba5bb1450e401a42a5d3593e7928d1b4\" transform=\"matrix(1,0,0,1,260,256)\"><p:metadata><p:property name=\"box\"><![CDATA[100,80]]></p:property><p:property name=\"outputPin1Origin\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin1\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin2Origin\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin2\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin3Origin\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin3\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin4Origin\"><![CDATA[0,40]]></p:property><p:property name=\"outputPin4\"><![CDATA[0,40]]></p:property><p:property name=\"fillColor\"><![CDATA[#BDDFFFFF]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[Element changed]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property><p:property name=\"optionText1\"><![CDATA[Option]]></p:property><p:property name=\"optionText2\"><![CDATA[Yes]]></p:property><p:property name=\"optionText3\"><![CDATA[No]]></p:property><p:property name=\"optionText4\"><![CDATA[Option]]></p:property><p:property name=\"optionTextFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"optionTextColor\"><![CDATA[#666666FF]]></p:property></p:metadata>\n            <path style=\"stroke-linejoin: round; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2; fill: rgb(189, 223, 255); fill-opacity: 1;\" p:name=\"path\" id=\"db41c9584128ec46930aac04fb17cd1e\" transform=\"translate(0,0)\" d=\"M 50 0 L 100 40 L 50 80 L 0 40 z\"/>\n            \n            <text p:name=\"text1\" id=\"d053695deeecf040827258b2c8ab1178\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(102, 102, 102); fill-opacity: 1; visibility: hidden; display: none;\" transform=\"translate(55,-6)\">Option</text>\n            <text p:name=\"text2\" id=\"768611e10900e2409568449d3435d2c1\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(102, 102, 102); fill-opacity: 1; visibility: hidden; display: none;\" transform=\"translate(105,34)\">Yes</text>\n            <text p:name=\"text3\" id=\"a8a78bf44181ee4980b3db7c4b865868\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(102, 102, 102); fill-opacity: 1; visibility: hidden; display: none;\" transform=\"translate(55,94)\">No</text>\n            <text p:name=\"text4\" id=\"8720ca63d0ad9d4ba411acf0605ca0f4\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(102, 102, 102); fill-opacity: 1; visibility: hidden; display: none;\" transform=\"translate(-39,34)\">Option</text>\n            \n            <rect style=\"fill: #FF0000; fill-opacity: 0; stroke: none;\" p:name=\"bg1\" id=\"67b333a04280ae4fae843ee109e85e21\"/>\n            <rect style=\"fill: #FF0000; fill-opacity: 0; stroke: none;\" p:name=\"bg2\" id=\"419af89fa3f79548a39330e08c97e275\"/>\n            <rect style=\"fill: #FF0000; fill-opacity: 0; stroke: none;\" p:name=\"bg3\" id=\"1e6aa65ab093db4aa7861e34a6114447\"/>\n            <rect style=\"fill: #FF0000; fill-opacity: 0; stroke: none;\" p:name=\"bg4\" id=\"3db36ddadd331a479a92da5542698cf8\"/>\n\n            <text text-anchor=\"start\" xml:space=\"preserve\" p:name=\"text\" id=\"4d50ef2b46714f42b6747af2d19194b0\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;\" transform=\"translate(7,37)\"><tspan x=\"21.016666412353516\" y=\"0\">Element</tspan><tspan x=\"20\" y=\"13\">changed</tspan></text>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow1\" id=\"07bbe07f44144647b3f5dfdde744fa56\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow2\" id=\"c0f7d29268c1084293d75f45e5a4660c\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow3\" id=\"87fcb05f998f644cb751d3ae1d21638c\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow4\" id=\"97a3fa3662d5a242812129d0d3dd1296\" d=\"\"/>\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Straight Connector\" id=\"cf48af904380b943b9d394642cd62215\" transform=\"matrix(1,0,0,1,309,287)\"><p:metadata><p:property name=\"startPin\" p:connectedShapeId=\"4bf292a0bf4c4a48a765f6425dac3c14\" p:connectedOutletId=\"bottom-center\" p:viax=\"1\" p:viay=\"-180\"><![CDATA[1,-190]]></p:property><p:property name=\"endPin\" p:viay=\"-41\" p:viax=\"1\" p:connectedOutletId=\"top-center\" p:connectedShapeId=\"ba5bb1450e401a42a5d3593e7928d1b4\"><![CDATA[1,-31]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"6d5a3ddb73cadb40a0e3fc869a093b3d\" d=\"M 1 -190 L 1 -41 L 1 -31 M 7 -37 L 1 -31 L -5 -37\"/>\n            </defs>\n            <use xlink:href=\"#6d5a3ddb73cadb40a0e3fc869a093b3d\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#6d5a3ddb73cadb40a0e3fc869a093b3d\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"5d503dfa0d11364cbbf7edc35fd57151\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"ec6be62af9dbdb49a0088e30e3345d90\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#6d5a3ddb73cadb40a0e3fc869a093b3d\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"7c7c0a2e4deade4d9ac818550133e172\" dx=\"-16\"/>\n                </textPath>\n            </text>\n\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Multi-segment Connector\" id=\"2d5336fe28890844beebbfb2911d53df\" transform=\"matrix(1,0,0,1,412,246)\"><p:metadata><p:property name=\"startPin\" p:viay=\"50\" p:viax=\"-162\" p:connectedOutletId=\"middle-left\" p:connectedShapeId=\"ba5bb1450e401a42a5d3593e7928d1b4\"><![CDATA[-152,50]]></p:property><p:property name=\"endPin\" p:viay=\"-139\" p:viax=\"-222\" p:connectedOutletId=\"bottom-center\" p:connectedShapeId=\"6bc98be7498aec43ae19d01c53d3fe85\"><![CDATA[-222,-149]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[multi-straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[CSS style or content changed (except transform)]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"8faecbd9b0c86e419a3184e7a0149bc9\" d=\"M -152 50 L -222 50 L -222 -139 L -222 -149 M -228 -143 L -222 -149 L -216 -143\"/>\n            </defs>\n            <use xlink:href=\"#8faecbd9b0c86e419a3184e7a0149bc9\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#8faecbd9b0c86e419a3184e7a0149bc9\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"d6470a9248213b4b91908b531bd0b53d\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"43f64325dbcf2845b361e1a5f28bd0c2\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#8faecbd9b0c86e419a3184e7a0149bc9\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"76aa06fd49c85f49a4185a763ff857ab\" dx=\"-16\">CSS style or content changed (except transform)</tspan>\n                </textPath>\n            </text>\n\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Flowchart:process\" id=\"b3da2a087993854f931f1cc09dc59546\" transform=\"matrix(1,0,0,1,383,17)\"><p:metadata><p:property name=\"box\"><![CDATA[100,80]]></p:property><p:property name=\"outputPin1Origin\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin1\"><![CDATA[50,0]]></p:property><p:property name=\"outputPin2Origin\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin2\"><![CDATA[100,40]]></p:property><p:property name=\"outputPin3Origin\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin3\"><![CDATA[50,80]]></p:property><p:property name=\"outputPin4Origin\"><![CDATA[0,40]]></p:property><p:property name=\"outputPin4\"><![CDATA[0,40]]></p:property><p:property name=\"fillColor\"><![CDATA[#BDDFFFFF]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[Changing element`s WebGL representation`s coordinates or transformations]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <rect style=\"stroke-linejoin: round; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2; fill: rgb(189, 223, 255); fill-opacity: 1;\" p:name=\"path\" id=\"11e2625fc7f59b45acc2f7fc82aa83b2\" transform=\"translate(0,0)\" x=\"0\" y=\"0\" width=\"100\" height=\"80\"/>\n            <text text-anchor=\"start\" xml:space=\"preserve\" p:name=\"text\" id=\"af89b5118bc28041bb7673b64c4ddcfe\" style=\"font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;\" transform=\"translate(7,11)\"><tspan x=\"17.350000381469727\" y=\"0\">Changing</tspan><tspan x=\"16.691667556762695\" y=\"13\">element`s</tspan><tspan x=\"22.78333282470703\" y=\"26\">WebGL</tspan><tspan x=\"-0.2999992370605469\" y=\"39\">representation`s</tspan><tspan x=\"5.025001525878906\" y=\"52\">coordinates or</tspan><tspan x=\"1.7000007629394531\" y=\"65\">transformations</tspan></text>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow1\" id=\"bbd774cdef8b364a8d6978eae80a8046\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow2\" id=\"95e8bcb082f035468d764168d9a83513\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow3\" id=\"7391bb145bc9184badea94123c8bdd44\" d=\"\"/>\n            <path style=\"stroke-linejoin: round; fill: none; stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\" p:name=\"outputArrrow4\" id=\"f283a4ea28b67a469e69d8fbe308f043\" d=\"\"/>\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Straight Connector\" id=\"3f095a652002ff4f8777ca7e097c824b\" transform=\"matrix(1,0,0,1,385,402)\"><p:metadata><p:property name=\"startPin\" p:connectedShapeId=\"ba5bb1450e401a42a5d3593e7928d1b4\" p:connectedOutletId=\"middle-right\" p:viax=\"-15\" p:viay=\"-106\"><![CDATA[-25,-106]]></p:property><p:property name=\"endPin\" p:connectedShapeId=\"b3da2a087993854f931f1cc09dc59546\" p:connectedOutletId=\"bottom-center\" p:viax=\"48\" p:viay=\"-295\"><![CDATA[48,-305]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[multi-straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[CSS transform]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"8b940853d7214246b09a40a6bbe3a6af\" d=\"M -25 -106 L 48 -106 L 48 -295 L 48 -305 M 42 -299 L 48 -305 L 54 -299\"/>\n            </defs>\n            <use xlink:href=\"#8b940853d7214246b09a40a6bbe3a6af\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#8b940853d7214246b09a40a6bbe3a6af\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"7c27c6efeb1b2d47a977943b2700822e\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"8717edc27d2584408dc73ebbba00c70b\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#8b940853d7214246b09a40a6bbe3a6af\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"11287df1cd2270499250b5f8fe724dd5\" dx=\"-16\">CSS transform</tspan>\n                </textPath>\n            </text>\n\n        </g><g xmlns=\"http://www.w3.org/2000/svg\" p:type=\"Shape\" xmlns:p=\"http://www.evolus.vn/Namespace/Pencil\" p:def=\"Evolus.Common:arrow\" p:sc=\"Straight Connector\" id=\"ad4b9169efcaa74eb6f485f40dc4d0af\" transform=\"matrix(1,0,0,1,631,231)\"><p:metadata><p:property name=\"startPin\" p:viay=\"-174\" p:viax=\"-258\" p:connectedOutletId=\"middle-left\" p:connectedShapeId=\"b3da2a087993854f931f1cc09dc59546\"><![CDATA[-248,-174]]></p:property><p:property name=\"endPin\" p:connectedShapeId=\"4bf292a0bf4c4a48a765f6425dac3c14\" p:connectedOutletId=\"middle-right\" p:viax=\"-261\" p:viay=\"-174\"><![CDATA[-271,-174]]></p:property><p:property name=\"withStartArrow\"><![CDATA[false]]></p:property><p:property name=\"withEndArrow\"><![CDATA[true]]></p:property><p:property name=\"mode\"><![CDATA[straight]]></p:property><p:property name=\"detached\"><![CDATA[false]]></p:property><p:property name=\"strokeColor\"><![CDATA[#666666FF]]></p:property><p:property name=\"strokeStyle\"><![CDATA[2|]]></p:property><p:property name=\"textContent\"><![CDATA[]]></p:property><p:property name=\"textFont\"><![CDATA[Helvetica|normal|normal|12px|none]]></p:property><p:property name=\"textColor\"><![CDATA[#000000FF]]></p:property><p:property name=\"textAlign\"><![CDATA[1,1]]></p:property></p:metadata>\n            <defs>\n                <path style=\"stroke-linejoin: round; fill: none;\" p:name=\"path\" id=\"b8a30a2419bef249b623dbc5079d5955\" d=\"M -248 -174 L -261 -174 L -271 -174 M -265 -168 L -271 -174 L -265 -180\"/>\n            </defs>\n            <use xlink:href=\"#b8a30a2419bef249b623dbc5079d5955\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" stroke-width=\"10\" stroke-opacity=\"0\" stroke=\"#FF0000\"/>\n            <use xlink:href=\"#b8a30a2419bef249b623dbc5079d5955\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" p:name=\"outArrow1\" id=\"aeddab27075a9742852855504adca783\" style=\"stroke: rgb(102, 102, 102); stroke-opacity: 1; stroke-width: 2;\"/>\n            <text p:name=\"text\" id=\"36d36544f6d5064297fbdc8d4d1f4b94\" style=\"fill: rgb(0, 0, 0); fill-opacity: 1; font-family: Helvetica; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;\">\n                <textPath xlink:href=\"#b8a30a2419bef249b623dbc5079d5955\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" startOffset=\"50%\" text-anchor=\"middle\" alignment-baseline=\"middle\">\n                    <tspan dy=\"-4\" p:name=\"textSpan\" id=\"703badc50ad3ac418a70654bf858590b\" dx=\"-16\"/>\n                </textPath>\n            </text>\n\n        </g></Content></Page></Pages></Document>"
  },
  {
    "path": "gulpfile.js",
    "content": "var BUNDLE_NAME = 'htmlgl',\n    gulp = require('gulp'),\n    concat = require('gulp-concat'),\n    uglify = require('gulp-uglifyjs');\n\ngulp.task('default', function () {\n    //Main library\n    gulp.src(['bower_components/promise-polyfill/Promise.min.js', 'bower_components/webcomponents.js/CustomElements.min.js', 'bower_components/pixi/bin/pixi.js', 'demo/js/vendor/html2canvas.js', 'demo/js/vendor/velocity.js', 'src/util.js', 'src/gl-element-resolver.js', 'src/gl-context.js', 'src/images-loaded.js', 'src/gl-element.js'])\n        .pipe(concat(BUNDLE_NAME + '.js'))\n        .pipe(gulp.dest('dist'))\n        .pipe(uglify(BUNDLE_NAME + '.min.js'))\n        .pipe(gulp.dest('dist'));\n\n    //Effects add-on\n    gulp.src(['bower_components/tween.js/build/tween.min.js', 'src/effects/*.js', 'src/gl-effects-manager.js'])\n        .pipe(concat(BUNDLE_NAME + '-effects.js'))\n        .pipe(gulp.dest('dist'))\n        .pipe(uglify(BUNDLE_NAME + '-effects.min.js'))\n        .pipe(gulp.dest('dist'));\n});\n\n//Copying files to page folder\ngulp.task('builddemo', function () {\n    //Main library\n    gulp.src('./dist/' + BUNDLE_NAME + '.min.js').pipe(gulp.dest('./page/js/'));\n\n    //Effects add-on\n    gulp.src('./dist/' + BUNDLE_NAME + '-effects.min.js').pipe(gulp.dest('./page/js/'));\n});"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"html-gl\",\n  \"version\": \"0.3.2\",\n  \"description\": \"Get as many FPS as you need by rendering HTML/CSS in WebGL\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/PixelsCommander/HTML-GL.git\"\n  },\n  \"keywords\": [\n    \"WebGL\",\n    \"HTML\",\n    \"CSS\",\n    \"JS\",\n    \"performance\",\n    \"NoDOM\",\n    \"60fps\",\n    \"animations\"\n  ],\n  \"author\": \"PixelsCommander\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/PixelsCommander/HTML-GL/issues\"\n  },\n  \"homepage\": \"https://github.com/PixelsCommander/HTML-GL\",\n  \"devDependencies\": {\n    \"gulp\": \"~3.8.11\",\n    \"gulp-concat\": \"~2.5.2\",\n    \"gulp-uglifyjs\": \"~0.6.0\"\n  },\n  \"dependencies\": {\n    \"gulp-bump\": \"^0.2.2\"\n  }\n}\n"
  },
  {
    "path": "page/css/style.css",
    "content": "/* ======== MAIN STYLES ========== */\nhtml, body {\n    height: 100%;\n    width: 100%;\n    margin: 0;\n    padding: 0;\n    min-width: 930px;\n}\n\nbody {\n    font-size: 14px;\n    font-weight: normal;\n    font-family: \"Uni Sans Thin CAPS\";\n    color:  #fff;\n}\n\nhtml-gl {\n    display: block !important;\n    position: absolute;\n    top: 0px;\n    left: 0px;\n}\n\n/* ======== Fonts ========== */\n@font-face {\n    font-family: \"Uni Sans Thin CAPS\";\n    src: url(\"../fonts/uni-sans.thin-caps-webfont.eot\");\n    src: url(\"../fonts/uni-sans.thin-caps-webfont.eot?#iefix\") format(\"embedded-opentype\"),\n    url(\"../fonts/uni-sans.thin-caps-webfont.woff2\") format(\"woff2\"),\n    url(\"../fonts/uni-sans.thin-caps-webfont.woff\") format(\"woff\"),\n    url(\"../fonts/uni-sans.thin-caps-webfont.ttf\") format(\"truetype\"),\n    url(\"../fonts/uni-sans.thin-caps-webfont.svg#uni_sansthin_caps\") format(\"svg\");\n    font-weight: normal;\n    font-style: normal;\n}\n\n\n@font-face {\n    font-family: \"Uni Sans Heavy CAPS\";\n    src: url(\"../fonts/uni-sans.heavy-caps-webfont.eot\");\n    src: url(\"../fonts/uni-sans.heavy-caps-webfont.eot?#iefix\") format(\"embedded-opentype\"),\n    url(\"../fonts/uni-sans.heavy-caps-webfont.woff2\") format(\"woff2\"),\n    url(\"../fonts/uni-sans.heavy-caps-webfont.woff\") format(\"woff\"),\n    url(\"../fonts/uni-sans.heavy-caps-webfont.ttf\") format(\"truetype\"),\n    url(\"../fonts/uni-sans.heavy-caps-webfont.svg#uni_sansheavy_caps\") format(\"svg\");\n    font-weight: normal;\n    font-style: normal;\n}\n\n/* general content styles  ============================================ */\n\n.content {\n    padding: 0 25px 60px 25px;\n    margin: 0 auto;\n    text-align: center;\n    text-align: center;\n    overflow: hidden;\n}\n\n/* Headings  ============================================ */\n\nh2 {\n    font-size: 36px;\n    margin: 0;\n    padding: 46px 0 36px 0;\n    font-weight: normal;\n}\n\nh3 {\n    font-size: 24px;\n    margin: 0;\n    font-weight: normal;\n}\n\np.page-title {\n    font-family: \"Uni Sans Heavy CAPS\";\n    font-size: 36px;\n    margin: 0;\n    padding: 85px 0 60px 0;\n}\n\n/* orange text  ============================================ */\n\n.orange-text {\n    color: #ff8300;\n}\n/* yellow text  ============================================ */\n\n.yellow-text {\n    color: #d9cd94;\n}\n\n/* highlighted text  ============================================ */\n.highlighted {\n    font-size: 18px;\n    font-family: \"Uni Sans Heavy CAPS\";\n}\n\n/* Links  ============================================ */\na {\n    color: #fff;\n}\n\n/**\n  * @hover\n  */\n\na:hover {\n    color: #b7b7b9;\n}\n\n/* github(orange) link  ============================================ */\n\n.github-link {\n    color: #eeae50;\n    font-size: 24px;\n}\n\n/**\n  * @hover\n  */\n\n.github-link:hover {\n    color: #be8a3e;\n}\n\n/* button-like links  ============================================ */\n\n.box-link {\n    text-decoration: none;\n    padding: 12px 22px;\n    border: 2px solid #fff;\n    margin-right: 5px;\n    margin-bottom: 10px;\n    text-align: center;\n}\n\n.box-link.last-in-row {\n    margin-right: 0px;\n}\n\n/**\n  * @hover\n  */\n\n.box-link:hover {\n    color: #b7b7b9;\n    border: 2px solid #b7b7b9;\n}\n\n\n/* Slide-1  ============================================ */\n\n.slide-1 {\n    width: 100%;\n    min-height: 100%;\n    background-image: url(../img/background-1.png);\n    background-size: cover;\n    background-repeat: no-repeat;\n}\n\n\n.title {\n    padding-top: 145px;\n    position: relative;\n}\n\n.title img {\n    margin: 0 auto;\n    max-width: 100%;\n    display: block;\n}\n\n.slide-1 h1 {\n    margin: 0;\n    padding: 0;\n    opacity: 0;\n    position: absolute;\n}\n\n.slide-1 h3 {\n    margin: 0 0 120px 0;\n}\n\n/* Slide-2  ============================================ */\n\n.slide-2 {\n    width: 100%;\n    background-image: url(../img/background-2.png);\n    background-size: cover;\n    background-repeat: no-repeat;\n}\n\n.slide-2 .content {\n    max-width: 560px;\n    margin: 0 auto;\n    padding-bottom: 100px;\n}\n\n.slide-2 h4 {\n    font-family: Helvetica, Arial, sans-serif;\n    font-size: 36px;\n    font-weight: normal;\n}\n\n.slide-2 html-gl {\n    font-family: Helvetica, Arial, sans-serif;\n}\n\n.why-container {\n    height: 280px;\n    position: relative;\n    margin-bottom: 50px;\n}\n\n.why-container h4 {\n    margin-bottom: 20px;\n}\n\n.justified-text {\n    text-align: justify;\n}\n\n\n/* Slide-3  ============================================ */\n\n.slide-3 {\n    width: 100%;\n    background-image: url(../img/background-3.png);\n    background-size: cover;\n    background-repeat: no-repeat;\n}\n\n.slide-3 .content {\n    max-width: 870px;\n    padding-bottom: 80px;\n}\n\n.slide-3 html-gl {\n    display: inline-block !important;\n}\n\n/* Styles for movie-list ============================================ */\n\n.example {\n    position: relative;\n    text-align: left;\n    margin-top: 50px;\n    display: inline-block;\n    width: 613px;\n}\n\n.example html-gl {\n    padding: 40px;\n    margin: -40px;\n}\n\n.movie-preview {\n    display: inline-block;\n    margin-right: 17px;\n}\n\n.movie-preview p img {\n    margin-right: 5px;\n    vertical-align: text-bottom;\n}\n/* Styles for controls ============================================ */\n\n.controls {\n    width: 245px;\n    height: 328px;\n\n    display: inline-block;\n    vertical-align: top;\n    margin-top: 50px;\n}\n\n/* Footer ============================================ */\n\n.footer {\n    text-align: left;\n    margin-top: 70px;\n}\n\n.footer a,\n.footer p,\n.footer div {\n    display: inline-block;\n}\n\n.slide-3 .box-link {\n    margin-right: 20px;\n}\n\n.footer p {\n    max-width: 400px;\n    margin-top: 5px;\n    vertical-align: top;\n    margin-right: 5px;\n}\n\n/* styles for add this buttons ============================================ */\n.add-this {\n    width: 245px;\n    height: 18px;\n    float: right;\n    margin-top: 10px;\n}\n\n\n/* styles for breakpoints ============================================ */\n\n@media screen and (max-width: 880px) {\n\n    .link-wrapper {\n        width: 100%;\n        text-align: center;\n    }\n\n    .slide-3 .box-link {\n        width: 100%;\n        padding: 12px 0;\n        max-width: 564px;\n    }\n\n    .footer p {\n        margin-bottom: 10px;\n    }\n\n}\n\n@media screen and (max-width: 650px) {\n\n    .slide-2 .box-link {\n        display: block;\n        width: 100%;\n        padding: 12px 0;\n    }\n}\n\n@media screen and (max-width: 720px) {\n\n    .footer p {\n        max-width: 100%;\n    }\n\n    .add-this {\n        float: left;\n    }\n}\n"
  },
  {
    "path": "page/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\"/>\n    <title>HTML GL - Render HTML/CSS via WebGL for amazing effects and 60 FPS using GPU hardware acceleration</title>\n    <link href=\"css/style.css\" rel=\"stylesheet\" type=\"text/css\">\n    <meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">\n</head>\n<body>\n<!-- First slide BEGIN -->\n<div class=\"slide-1\">\n    <div class=\"content\">\n        <div class=\"title\">\n            <h1>HTML GL</h1>\n            <img src=\"img/title.svg\">\n        </div>\n        <h2>Render HTML/CSS via WebGL</h2>\n\n        <h3>Hardware acceleration guaranteed, amazing effects available</h3>\n        <a class=\"github-link\" href=\"https://github.com/PixelsCommander/HTML-GL\">GitHub</a>\n    </div>\n</div>\n<!-- First slide END-->\n<!-- Second slide BEGIN -->\n<div class=\"slide-2\">\n    <div class=\"content\">\n        <p class=\"page-title orange-text\">Basics</p>\n\n        <h3>The following content is rendered in WebGL\n            since it is wrapped with &#60;html-gl&#62; tag</h3>\n\n        <div class=\"why-container\">\n            <html-gl class=\"why-block\">\n                <h4>Why HTML-GL?</h4>\n\n                <p class=\"justified-text\">DOM is slow. It is a complex model which creates chain reaction over whole\n                    document on\n                    every modification. Powerful desktops are fine with handling that but mobile and low-level PCs\n                    provide\n                    bad\n                    user experience. HTML-GL solves “Slow DOM problem” by creating WebGL representations for DOM nodes\n                    and\n                    render them using GPU taking all benefits of hardware acceleration approach modern video games use\n                    including\n                    special effects.</p>\n\n                <p class=\"justified-text\">Even since content is rendered in WebGL it is still selectable with Dev Tools\n                    inspector\n                    and is accessible for text selection and copying. Links are active and DOM event system is\n                    respected.</p>\n\n                <p class=\"highlighted\">Just <span\n                        class=\"orange-text\">use HTML and CSS in the way you are common to!</span></p>\n            </html-gl>\n        </div>\n        <a class=\"box-link\" href=\"#\" onclick=\"window.animateBasic(); return false;\">Animate with velocity JS</a><a class=\"box-link\" href=\"#\" onclick=\"window.changeNodeContent(); return false;\">Change content</a><a\n            class=\"box-link last-in-row\" href=\"#\" onclick=\"window.changeNodeTransform(); return false;\">CSS TRANSFORM</a>\n    </div>\n</div>\n<!-- Second slide END-->\n<!-- Third slide BEGIN -->\n<div class=\"slide-3\">\n    <div class=\"content\">\n        <p class=\"yellow-text page-title\">INTERACTIVITY AND EFFECTS</p>\n\n        <h3>YOU MAY DRAG OR CLICK SLIDER TO ENSURE THAT DOM EVENTS ARE RESPECTED\n            DESPITE IT IS A WEB GL RENDERED CONTENT WITH FILTERS APPLIED</h3>\n\n        <div class=\"example\">\n            <html-gl>\n                <div class=\"movie-preview\" onclick=\"alert('Clicked Argo')\"><img src=\"img/example-1.png\">\n\n                    <p>Select me with devtools</p>\n\n                    <p>\n                        <img src=\"img/imbd-icon.png\">\n                        <span class=\"highlighted\"> 7.8 </span>\n                        <span>/ 10</span>\n                    </p>\n                </div>\n                <div class=\"movie-preview\" onclick=\"alert('Clicked Avatar')\">\n                    <img src=\"img/example-2.png\">\n\n                    <p>Change me in devtools</p>\n\n                    <p>\n                        <img src=\"img/imbd-icon.png\">\n                        <span class=\"highlighted\"> 9.4 </span>\n                        <span>/ 10</span>\n                    </p>\n                </div>\n                <div class=\"movie-preview\" onclick=\"alert('Breaking Bad')\">\n                    <img src=\"img/example-3.png\">\n\n                    <p>BREAKING BAD</p>\n\n                    <p>\n                        <img src=\"img/imbd-icon.png\">\n                        <span class=\"highlighted\"> 8.5 </span>\n                        <span>/ 10</span>\n                    </p>\n                </div>\n            </html-gl>\n        </div>\n\n        <div class=\"controls\"></div>\n        <div class=\"footer\">\n            <div class=\"link-wrapper\"><a class=\"box-link\" href=\"http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/\">Article\n                about</a></div>\n\n            <p>YOU MAY CREATE YOU OWN FILTERS USING SHADERS, there are\n                thousands of THEM predefined at <a href=\"https://www.shadertoy.com/\">SHADERTOY.COM</a>\n            </p>\n\n            <div class=\"add-this\">      <!-- AddThis Button BEGIN -->\n                <div class=\"addthis_toolbox addthis_default_style\">\n                    <iframe style=\"display: inline-block;\"\n                            src=\"http://ghbtns.com/github-btn.html?user=PixelsCommander&repo=HTML-GL&type=watch\"\n                            allowtransparency=\"true\" frameborder=\"0\" scrolling=\"0\" width=\"62\" height=\"20\"></iframe>\n                    <a class=\"addthis_button_tweet\"></a>\n                    <!-- <a class=\"addthis_button_google_plusone\" g:plusone:size=\"medium\"></a> -->\n                </div>\n                <script type=\"text/javascript\">var addthis_config = {\"data_track_addressbar\": true};</script>\n                <script type=\"text/javascript\" src=\"//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4ea2f9164143bcfb\"></script>\n                <!-- AddThis Button END --></div>\n        </div>\n    </div>\n</div>\n<!-- Third slide END-->\n<!-- <script src=\"../dist/htmlgl.js\"></script> -->\n\n<!-- <script src=\"../bower_components/promise-polyfill/Promise.min.js\"></script>\n<script src=\"../bower_components/webcomponents.js/CustomElements.min.js\"></script>\n<script src=\"../demo/js/vendor/velocity.js\"></script>\n<script src=\"../demo/js/vendor/html2canvas.js\"></script>\n<script src=\"../bower_components/pixi/bin/pixi.dev.js\"></script>\n<script src=\"../src/util.js\"></script>\n<script src=\"../src/gl-element-resolver.js\"></script>\n<script src=\"../src/gl-context.js\"></script>\n<script src=\"../src/images-loaded.js\"></script>\n<script src=\"../src/gl-element.js\"></script> -->\n\n<script src=\"./js/htmlgl.min.js\"></script>\n<script src=\"./js/dat.gui.js\"></script>\n<script src=\"./js/basics.js\"></script>\n<script src=\"./js/effects.js\"></script>\n<script src=\"./js/slider.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "page/js/basics.js",
    "content": "window.changeNodeContent = function () {\n    document.getElementsByTagName('html-gl')[0].innerHTML = '<h4>WOW!</h4> <p class=\"justified-text\">innerHTML changed and element was rerendered <span class=\"orange-text\">automaticaly</span>. Sorry, retina is not supported yet, so a bit blurry.</p>';\n}\n\nwindow.changeNodeTransform = function () {\n    var element = document.getElementsByTagName('html-gl')[0];\n    element.style.webkitTransform = 'translateX(400px) translateY(100px)';\n    element.style.transform = 'translateX(400px) translateY(100px)';\n}\n\nwindow.animateBasic = function () {\n    var element = document.getElementsByTagName('html-gl')[0];\n\n    var v = Velocity(element, {\n        translateX: 100,\n        translateY: 100,\n        scaleX: 4,\n        scaleY: 4,\n        rotateZ: \"360deg\"\n    }, {duration: 1000}).then(function () {\n        Velocity(element, {\n            translateX: 0,\n            translateY: 0,\n            scaleX: 1,\n            scaleY: 1,\n            rotateZ: \"0\"\n        }, {duration: 1000});\n    });\n}"
  },
  {
    "path": "page/js/dat.gui.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\nvar deploymentNode = document.getElementsByClassName('controls')[0];\n\n/** @namespace */\nvar dat = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n  return {\n    load: function (url, doc) {\n      doc = doc || document;\n      var link = doc.createElement('link');\n      link.type = 'text/css';\n      link.rel = 'stylesheet';\n      link.href = url;\n      doc.getElementsByTagName('head')[0].appendChild(link);\n    },\n    inject: function(css, doc) {\n      doc = doc || document;\n      var injected = document.createElement('style');\n      injected.type = 'text/css';\n      injected.innerHTML = css;\n      doc.getElementsByTagName('head')[0].appendChild(injected);\n    }\n  }\n})();\n\n\ndat.utils.common = (function () {\n  \n  var ARR_EACH = Array.prototype.forEach;\n  var ARR_SLICE = Array.prototype.slice;\n\n  /**\n   * Band-aid methods for things that should be a lot easier in JavaScript.\n   * Implementation and structure inspired by underscore.js\n   * http://documentcloud.github.com/underscore/\n   */\n\n  return { \n    \n    BREAK: {},\n  \n    extend: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (!this.isUndefined(obj[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n      \n    },\n    \n    defaults: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (this.isUndefined(target[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n    \n    },\n    \n    compose: function() {\n      var toCall = ARR_SLICE.call(arguments);\n            return function() {\n              var args = ARR_SLICE.call(arguments);\n              for (var i = toCall.length -1; i >= 0; i--) {\n                args = [toCall[i].apply(this, args)];\n              }\n              return args[0];\n            }\n    },\n    \n    each: function(obj, itr, scope) {\n\n      if (!obj) return;\n\n      if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) { \n        \n        obj.forEach(itr, scope);\n        \n      } else if (obj.length === obj.length + 0) { // Is number but not NaN\n        \n        for (var key = 0, l = obj.length; key < l; key++)\n          if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n            return;\n            \n      } else {\n\n        for (var key in obj) \n          if (itr.call(scope, obj[key], key) === this.BREAK)\n            return;\n            \n      }\n            \n    },\n    \n    defer: function(fnc) {\n      setTimeout(fnc, 0);\n    },\n    \n    toArray: function(obj) {\n      if (obj.toArray) return obj.toArray();\n      return ARR_SLICE.call(obj);\n    },\n\n    isUndefined: function(obj) {\n      return obj === undefined;\n    },\n    \n    isNull: function(obj) {\n      return obj === null;\n    },\n    \n    isNaN: function(obj) {\n      return obj !== obj;\n    },\n    \n    isArray: Array.isArray || function(obj) {\n      return obj.constructor === Array;\n    },\n    \n    isObject: function(obj) {\n      return obj === Object(obj);\n    },\n    \n    isNumber: function(obj) {\n      return obj === obj+0;\n    },\n    \n    isString: function(obj) {\n      return obj === obj+'';\n    },\n    \n    isBoolean: function(obj) {\n      return obj === false || obj === true;\n    },\n    \n    isFunction: function(obj) {\n      return Object.prototype.toString.call(obj) === '[object Function]';\n    }\n  \n  };\n    \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n  /**\n   * @class An \"abstract\" class that represents a given property of an object.\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var Controller = function(object, property) {\n\n    this.initialValue = object[property];\n\n    /**\n     * Those who extend this class will put their DOM elements in here.\n     * @type {DOMElement}\n     */\n    this.domElement = document.createElement('div');\n\n    /**\n     * The object to manipulate\n     * @type {Object}\n     */\n    this.object = object;\n\n    /**\n     * The name of the property to manipulate\n     * @type {String}\n     */\n    this.property = property;\n\n    /**\n     * The function to be called on change.\n     * @type {Function}\n     * @ignore\n     */\n    this.__onChange = undefined;\n\n    /**\n     * The function to be called on finishing change.\n     * @type {Function}\n     * @ignore\n     */\n    this.__onFinishChange = undefined;\n\n  };\n\n  common.extend(\n\n      Controller.prototype,\n\n      /** @lends dat.controllers.Controller.prototype */\n      {\n\n        /**\n         * Specify that a function fire every time someone changes the value with\n         * this Controller.\n         *\n         * @param {Function} fnc This function will be called whenever the value\n         * is modified via this Controller.\n         * @returns {dat.controllers.Controller} this\n         */\n        onChange: function(fnc) {\n          this.__onChange = fnc;\n          return this;\n        },\n\n        /**\n         * Specify that a function fire every time someone \"finishes\" changing\n         * the value wih this Controller. Useful for values that change\n         * incrementally like numbers or strings.\n         *\n         * @param {Function} fnc This function will be called whenever\n         * someone \"finishes\" changing the value via this Controller.\n         * @returns {dat.controllers.Controller} this\n         */\n        onFinishChange: function(fnc) {\n          this.__onFinishChange = fnc;\n          return this;\n        },\n\n        /**\n         * Change the value of <code>object[property]</code>\n         *\n         * @param {Object} newValue The new value of <code>object[property]</code>\n         */\n        setValue: function(newValue) {\n          this.object[this.property] = newValue;\n          if (this.__onChange) {\n            this.__onChange.call(this, newValue);\n          }\n          this.updateDisplay();\n          return this;\n        },\n\n        /**\n         * Gets the value of <code>object[property]</code>\n         *\n         * @returns {Object} The current value of <code>object[property]</code>\n         */\n        getValue: function() {\n          return this.object[this.property];\n        },\n\n        /**\n         * Refreshes the visual display of a Controller in order to keep sync\n         * with the object's current value.\n         * @returns {dat.controllers.Controller} this\n         */\n        updateDisplay: function() {\n          return this;\n        },\n\n        /**\n         * @returns {Boolean} true if the value has deviated from initialValue\n         */\n        isModified: function() {\n          return this.initialValue !== this.getValue()\n        }\n\n      }\n\n  );\n\n  return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n  var EVENT_MAP = {\n    'HTMLEvents': ['change'],\n    'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n    'KeyboardEvents': ['keydown']\n  };\n\n  var EVENT_MAP_INV = {};\n  common.each(EVENT_MAP, function(v, k) {\n    common.each(v, function(e) {\n      EVENT_MAP_INV[e] = k;\n    });\n  });\n\n  var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n  function cssValueToPixels(val) {\n\n    if (val === '0' || common.isUndefined(val)) return 0;\n\n    var match = val.match(CSS_VALUE_PIXELS);\n\n    if (!common.isNull(match)) {\n      return parseFloat(match[1]);\n    }\n\n    // TODO ...ems? %?\n\n    return 0;\n\n  }\n\n  /**\n   * @namespace\n   * @member dat.dom\n   */\n  var dom = {\n\n    /**\n     * \n     * @param elem\n     * @param selectable\n     */\n    makeSelectable: function(elem, selectable) {\n\n      if (elem === undefined || elem.style === undefined) return;\n\n      elem.onselectstart = selectable ? function() {\n        return false;\n      } : function() {\n      };\n\n      elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n      elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n      elem.unselectable = selectable ? 'on' : 'off';\n\n    },\n\n    /**\n     *\n     * @param elem\n     * @param horizontal\n     * @param vertical\n     */\n    makeFullscreen: function(elem, horizontal, vertical) {\n\n      if (common.isUndefined(horizontal)) horizontal = true;\n      if (common.isUndefined(vertical)) vertical = true;\n\n      elem.style.position = 'absolute';\n\n      if (horizontal) {\n        elem.style.left = 0;\n        elem.style.right = 0;\n      }\n      if (vertical) {\n        elem.style.top = 0;\n        elem.style.bottom = 0;\n      }\n\n    },\n\n    /**\n     *\n     * @param elem\n     * @param eventType\n     * @param params\n     */\n    fakeEvent: function(elem, eventType, params, aux) {\n      params = params || {};\n      var className = EVENT_MAP_INV[eventType];\n      if (!className) {\n        throw new Error('Event type ' + eventType + ' not supported.');\n      }\n      var evt = document.createEvent(className);\n      switch (className) {\n        case 'MouseEvents':\n          var clientX = params.x || params.clientX || 0;\n          var clientY = params.y || params.clientY || 0;\n          evt.initMouseEvent(eventType, params.bubbles || false,\n              params.cancelable || true, window, params.clickCount || 1,\n              0, //screen X\n              0, //screen Y\n              clientX, //client X\n              clientY, //client Y\n              false, false, false, false, 0, null);\n          break;\n        case 'KeyboardEvents':\n          var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n          common.defaults(params, {\n            cancelable: true,\n            ctrlKey: false,\n            altKey: false,\n            shiftKey: false,\n            metaKey: false,\n            keyCode: undefined,\n            charCode: undefined\n          });\n          init(eventType, params.bubbles || false,\n              params.cancelable, window,\n              params.ctrlKey, params.altKey,\n              params.shiftKey, params.metaKey,\n              params.keyCode, params.charCode);\n          break;\n        default:\n          evt.initEvent(eventType, params.bubbles || false,\n              params.cancelable || true);\n          break;\n      }\n      common.defaults(evt, aux);\n      elem.dispatchEvent(evt);\n    },\n\n    /**\n     *\n     * @param elem\n     * @param event\n     * @param func\n     * @param bool\n     */\n    bind: function(elem, event, func, bool) {\n      bool = bool || false;\n      if (elem.addEventListener)\n        elem.addEventListener(event, func, bool);\n      else if (elem.attachEvent)\n        elem.attachEvent('on' + event, func);\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param event\n     * @param func\n     * @param bool\n     */\n    unbind: function(elem, event, func, bool) {\n      bool = bool || false;\n      if (elem.removeEventListener)\n        elem.removeEventListener(event, func, bool);\n      else if (elem.detachEvent)\n        elem.detachEvent('on' + event, func);\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param className\n     */\n    addClass: function(elem, className) {\n      if (elem.className === undefined) {\n        elem.className = className;\n      } else if (elem.className !== className) {\n        var classes = elem.className.split(/ +/);\n        if (classes.indexOf(className) == -1) {\n          classes.push(className);\n          elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n        }\n      }\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param className\n     */\n    removeClass: function(elem, className) {\n      if (className) {\n        if (elem.className === undefined) {\n          // elem.className = className;\n        } else if (elem.className === className) {\n          elem.removeAttribute('class');\n        } else {\n          var classes = elem.className.split(/ +/);\n          var index = classes.indexOf(className);\n          if (index != -1) {\n            classes.splice(index, 1);\n            elem.className = classes.join(' ');\n          }\n        }\n      } else {\n        elem.className = undefined;\n      }\n      return dom;\n    },\n\n    hasClass: function(elem, className) {\n      return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getWidth: function(elem) {\n\n      var style = getComputedStyle(elem);\n\n      return cssValueToPixels(style['border-left-width']) +\n          cssValueToPixels(style['border-right-width']) +\n          cssValueToPixels(style['padding-left']) +\n          cssValueToPixels(style['padding-right']) +\n          cssValueToPixels(style['width']);\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getHeight: function(elem) {\n\n      var style = getComputedStyle(elem);\n\n      return cssValueToPixels(style['border-top-width']) +\n          cssValueToPixels(style['border-bottom-width']) +\n          cssValueToPixels(style['padding-top']) +\n          cssValueToPixels(style['padding-bottom']) +\n          cssValueToPixels(style['height']);\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getOffset: function(elem) {\n      var offset = {left: 0, top:0};\n      if (elem.offsetParent) {\n        do {\n          offset.left += elem.offsetLeft;\n          offset.top += elem.offsetTop;\n        } while (elem = elem.offsetParent);\n      }\n      return offset;\n    },\n\n    // http://stackoverflow.com/posts/2684561/revisions\n    /**\n     * \n     * @param elem\n     */\n    isActive: function(elem) {\n      return elem === document.activeElement && ( elem.type || elem.href );\n    }\n\n  };\n\n  return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a select input to alter the property of an object, using a\n   * list of accepted values.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object|string[]} options A map of labels to acceptable values, or\n   * a list of acceptable string values.\n   *\n   * @member dat.controllers\n   */\n  var OptionController = function(object, property, options) {\n\n    OptionController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    /**\n     * The drop down menu\n     * @ignore\n     */\n    this.__select = document.createElement('select');\n\n    if (common.isArray(options)) {\n      var map = {};\n      common.each(options, function(element) {\n        map[element] = element;\n      });\n      options = map;\n    }\n\n    common.each(options, function(value, key) {\n\n      var opt = document.createElement('option');\n      opt.innerHTML = key;\n      opt.setAttribute('value', value);\n      _this.__select.appendChild(opt);\n\n    });\n\n    // Acknowledge original value\n    this.updateDisplay();\n\n    dom.bind(this.__select, 'change', function() {\n      var desiredValue = this.options[this.selectedIndex].value;\n      _this.setValue(desiredValue);\n    });\n\n    this.domElement.appendChild(this.__select);\n\n  };\n\n  OptionController.superclass = Controller;\n\n  common.extend(\n\n      OptionController.prototype,\n      Controller.prototype,\n\n      {\n\n        setValue: function(v) {\n          var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n          return toReturn;\n        },\n\n        updateDisplay: function() {\n          this.__select.value = this.getValue();\n          return OptionController.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n  /**\n   * @class Represents a given property of an object that is a number.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object} [params] Optional parameters\n   * @param {Number} [params.min] Minimum allowed value\n   * @param {Number} [params.max] Maximum allowed value\n   * @param {Number} [params.step] Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberController = function(object, property, params) {\n\n    NumberController.superclass.call(this, object, property);\n\n    params = params || {};\n\n    this.__min = params.min;\n    this.__max = params.max;\n    this.__step = params.step;\n\n    if (common.isUndefined(this.__step)) {\n\n      if (this.initialValue == 0) {\n        this.__impliedStep = 1; // What are we, psychics?\n      } else {\n        // Hey Doug, check this out.\n        this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n      }\n\n    } else {\n\n    \tthis.__impliedStep = this.__step;\n\n    }\n\n    this.__precision = numDecimals(this.__impliedStep);\n\n\n  };\n\n  NumberController.superclass = Controller;\n\n  common.extend(\n\n      NumberController.prototype,\n      Controller.prototype,\n\n      /** @lends dat.controllers.NumberController.prototype */\n      {\n\n        setValue: function(v) {\n\n          if (this.__min !== undefined && v < this.__min) {\n            v = this.__min;\n          } else if (this.__max !== undefined && v > this.__max) {\n            v = this.__max;\n          }\n\n          if (this.__step !== undefined && v % this.__step != 0) {\n            v = Math.round(v / this.__step) * this.__step;\n          }\n\n          return NumberController.superclass.prototype.setValue.call(this, v);\n\n        },\n\n        /**\n         * Specify a minimum value for <code>object[property]</code>.\n         *\n         * @param {Number} minValue The minimum value for\n         * <code>object[property]</code>\n         * @returns {dat.controllers.NumberController} this\n         */\n        min: function(v) {\n          this.__min = v;\n          return this;\n        },\n\n        /**\n         * Specify a maximum value for <code>object[property]</code>.\n         *\n         * @param {Number} maxValue The maximum value for\n         * <code>object[property]</code>\n         * @returns {dat.controllers.NumberController} this\n         */\n        max: function(v) {\n          this.__max = v;\n          return this;\n        },\n\n        /**\n         * Specify a step value that dat.controllers.NumberController\n         * increments by.\n         *\n         * @param {Number} stepValue The step value for\n         * dat.controllers.NumberController\n         * @default if minimum and maximum specified increment is 1% of the\n         * difference otherwise stepValue is 1\n         * @returns {dat.controllers.NumberController} this\n         */\n        step: function(v) {\n          this.__step = v;\n          this.__impliedStep = v;\n          this.__precision = numDecimals(v);\n          return this;\n        }\n\n      }\n\n  );\n\n  function numDecimals(x) {\n    x = x.toString();\n    if (x.indexOf('.') > -1) {\n      return x.length - x.indexOf('.') - 1;\n    } else {\n      return 0;\n    }\n  }\n\n  return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n  /**\n   * @class Represents a given property of an object that is a number and\n   * provides an input element with which to manipulate it.\n   *\n   * @extends dat.controllers.Controller\n   * @extends dat.controllers.NumberController\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object} [params] Optional parameters\n   * @param {Number} [params.min] Minimum allowed value\n   * @param {Number} [params.max] Maximum allowed value\n   * @param {Number} [params.step] Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberControllerBox = function(object, property, params) {\n\n    this.__truncationSuspended = false;\n\n    NumberControllerBox.superclass.call(this, object, property, params);\n\n    var _this = this;\n\n    /**\n     * {Number} Previous mouse y position\n     * @ignore\n     */\n    var prev_y;\n\n    this.__input = document.createElement('input');\n    this.__input.setAttribute('type', 'text');\n\n    // Makes it so manually specified values are not truncated.\n\n    dom.bind(this.__input, 'change', onChange);\n    dom.bind(this.__input, 'blur', onBlur);\n    dom.bind(this.__input, 'mousedown', onMouseDown);\n    dom.bind(this.__input, 'keydown', function(e) {\n\n      // When pressing entire, you can be as precise as you want.\n      if (e.keyCode === 13) {\n        _this.__truncationSuspended = true;\n        this.blur();\n        _this.__truncationSuspended = false;\n      }\n\n    });\n\n    function onChange() {\n      var attempted = parseFloat(_this.__input.value);\n      if (!common.isNaN(attempted)) _this.setValue(attempted);\n    }\n\n    function onBlur() {\n      onChange();\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    function onMouseDown(e) {\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      prev_y = e.clientY;\n    }\n\n    function onMouseDrag(e) {\n\n      var diff = prev_y - e.clientY;\n      _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n      prev_y = e.clientY;\n\n    }\n\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n    }\n\n    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n\n  };\n\n  NumberControllerBox.superclass = NumberController;\n\n  common.extend(\n\n      NumberControllerBox.prototype,\n      NumberController.prototype,\n\n      {\n\n        updateDisplay: function() {\n\n          this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n          return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  function roundToDecimal(value, decimals) {\n    var tenTo = Math.pow(10, decimals);\n    return Math.round(value * tenTo) / tenTo;\n  }\n\n  return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n  /**\n   * @class Represents a given property of an object that is a number, contains\n   * a minimum and maximum, and provides a slider element with which to\n   * manipulate it. It should be noted that the slider element is made up of\n   * <code>&lt;div&gt;</code> tags, <strong>not</strong> the html5\n   * <code>&lt;slider&gt;</code> element.\n   *\n   * @extends dat.controllers.Controller\n   * @extends dat.controllers.NumberController\n   * \n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Number} minValue Minimum allowed value\n   * @param {Number} maxValue Maximum allowed value\n   * @param {Number} stepValue Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberControllerSlider = function(object, property, min, max, step) {\n\n    NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n    var _this = this;\n\n    this.__background = document.createElement('div');\n    this.__foreground = document.createElement('div');\n    \n\n\n    dom.bind(this.__background, 'mousedown', onMouseDown);\n    \n    dom.addClass(this.__background, 'slider');\n    dom.addClass(this.__foreground, 'slider-fg');\n\n    function onMouseDown(e) {\n\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n\n      onMouseDrag(e);\n    }\n\n    function onMouseDrag(e) {\n\n      e.preventDefault();\n\n      var offset = dom.getOffset(_this.__background);\n      var width = dom.getWidth(_this.__background);\n      \n      _this.setValue(\n      \tmap(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n      );\n\n      return false;\n\n    }\n\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    this.updateDisplay();\n\n    this.__background.appendChild(this.__foreground);\n    this.domElement.appendChild(this.__background);\n\n  };\n\n  NumberControllerSlider.superclass = NumberController;\n\n  /**\n   * Injects default stylesheet for slider elements.\n   */\n  NumberControllerSlider.useDefaultStyles = function() {\n    css.inject(styleSheet);\n  };\n\n  common.extend(\n\n      NumberControllerSlider.prototype,\n      NumberController.prototype,\n\n      {\n\n        updateDisplay: function() {\n          var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n          this.__foreground.style.width = pct*100+'%';\n          return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n\n\n  );\n\n\tfunction map(v, i1, i2, o1, o2) {\n\t\treturn o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n\t}\n\n  return NumberControllerSlider;\n  \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\"/**\\n * dat-gui JavaScript Controller Library\\n * http://code.google.com/p/dat-gui\\n *\\n * Copyright 2011 Data Arts Team, Google Creative Lab\\n *\\n * Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n * you may not use this file except in compliance with the License.\\n * You may obtain a copy of the License at\\n *\\n * http://www.apache.org/licenses/LICENSE-2.0\\n */\\n\\n.slider {\\n  box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n  height: 1em;\\n  border-radius: 1em;\\n  background-color: #eee;\\n  padding: 0 0.5em;\\n  overflow: hidden;\\n}\\n\\n.slider-fg {\\n  padding: 1px 0 2px 0;\\n  background-color: #aaa;\\n  height: 1em;\\n  margin-left: -0.5em;\\n  padding-right: 0.5em;\\n  border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n  display: inline-block;\\n  border-radius: 1em;\\n  background-color: #fff;\\n  border:  1px solid #aaa;\\n  content: '';\\n  float: right;\\n  margin-right: -1em;\\n  margin-top: -1px;\\n  height: 0.9em;\\n  width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a GUI interface to fire a specified method, a property of an object.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var FunctionController = function(object, property, text) {\n\n    FunctionController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    this.__button = document.createElement('div');\n    this.__button.innerHTML = text === undefined ? 'Fire' : text;\n    dom.bind(this.__button, 'click', function(e) {\n      e.preventDefault();\n      _this.fire();\n      return false;\n    });\n\n    dom.addClass(this.__button, 'button');\n\n    this.domElement.appendChild(this.__button);\n\n\n  };\n\n  FunctionController.superclass = Controller;\n\n  common.extend(\n\n      FunctionController.prototype,\n      Controller.prototype,\n      {\n        \n        fire: function() {\n          if (this.__onChange) {\n            this.__onChange.call(this);\n          }\n          this.getValue().call(this.object);\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n        }\n      }\n\n  );\n\n  return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a checkbox input to alter the boolean property of an object.\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var BooleanController = function(object, property) {\n\n    BooleanController.superclass.call(this, object, property);\n\n    var _this = this;\n    this.__prev = this.getValue();\n\n    this.__checkbox = document.createElement('input');\n    this.__checkbox.setAttribute('type', 'checkbox');\n\n\n    dom.bind(this.__checkbox, 'change', onChange, false);\n\n    this.domElement.appendChild(this.__checkbox);\n\n    // Match original value\n    this.updateDisplay();\n\n    function onChange() {\n      _this.setValue(!_this.__prev);\n    }\n\n  };\n\n  BooleanController.superclass = Controller;\n\n  common.extend(\n\n      BooleanController.prototype,\n      Controller.prototype,\n\n      {\n\n        setValue: function(v) {\n          var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n          this.__prev = this.getValue();\n          return toReturn;\n        },\n\n        updateDisplay: function() {\n          \n          if (this.getValue() === true) {\n            this.__checkbox.setAttribute('checked', 'checked');\n            this.__checkbox.checked = true;    \n          } else {\n              this.__checkbox.checked = false;\n          }\n\n          return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n        }\n\n\n      }\n\n  );\n\n  return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n  return function(color) {\n\n    if (color.a == 1 || common.isUndefined(color.a)) {\n\n      var s = color.hex.toString(16);\n      while (s.length < 6) {\n        s = '0' + s;\n      }\n\n      return '#' + s;\n\n    } else {\n\n      return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n    }\n\n  }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n  var result, toReturn;\n\n  var interpret = function() {\n\n    toReturn = false;\n\n    var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n    common.each(INTERPRETATIONS, function(family) {\n\n      if (family.litmus(original)) {\n\n        common.each(family.conversions, function(conversion, conversionName) {\n\n          result = conversion.read(original);\n\n          if (toReturn === false && result !== false) {\n            toReturn = result;\n            result.conversionName = conversionName;\n            result.conversion = conversion;\n            return common.BREAK;\n\n          }\n\n        });\n\n        return common.BREAK;\n\n      }\n\n    });\n\n    return toReturn;\n\n  };\n\n  var INTERPRETATIONS = [\n\n    // Strings\n    {\n\n      litmus: common.isString,\n\n      conversions: {\n\n        THREE_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt(\n                  '0x' +\n                      test[1].toString() + test[1].toString() +\n                      test[2].toString() + test[2].toString() +\n                      test[3].toString() + test[3].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        SIX_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9]{6})$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt('0x' + test[1].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGB: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3])\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGBA: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3]),\n              a: parseFloat(test[4])\n            };\n\n          },\n\n          write: toString\n\n        }\n\n      }\n\n    },\n\n    // Numbers\n    {\n\n      litmus: common.isNumber,\n\n      conversions: {\n\n        HEX: {\n          read: function(original) {\n            return {\n              space: 'HEX',\n              hex: original,\n              conversionName: 'HEX'\n            }\n          },\n\n          write: function(color) {\n            return color.hex;\n          }\n        }\n\n      }\n\n    },\n\n    // Arrays\n    {\n\n      litmus: common.isArray,\n\n      conversions: {\n\n        RGB_ARRAY: {\n          read: function(original) {\n            if (original.length != 3) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b];\n          }\n\n        },\n\n        RGBA_ARRAY: {\n          read: function(original) {\n            if (original.length != 4) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2],\n              a: original[3]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b, color.a];\n          }\n\n        }\n\n      }\n\n    },\n\n    // Objects\n    {\n\n      litmus: common.isObject,\n\n      conversions: {\n\n        RGBA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b,\n              a: color.a\n            }\n          }\n        },\n\n        RGB_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b\n            }\n          }\n        },\n\n        HSVA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v,\n              a: color.a\n            }\n          }\n        },\n\n        HSV_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v\n            }\n          }\n\n        }\n\n      }\n\n    }\n\n\n  ];\n\n  return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n  css.inject(styleSheet);\n\n  /** Outer-most className for GUI's */\n  var CSS_NAMESPACE = 'dg';\n\n  var HIDE_KEY_CODE = 72;\n\n  /** The only value shared between the JS and SCSS. Use caution. */\n  var CLOSE_BUTTON_HEIGHT = 20;\n\n  var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n  var SUPPORTS_LOCAL_STORAGE = (function() {\n    try {\n      return 'localStorage' in window && window['localStorage'] !== null;\n    } catch (e) {\n      return false;\n    }\n  })();\n\n  var SAVE_DIALOGUE;\n\n  /** Have we yet to create an autoPlace GUI? */\n  var auto_place_virgin = true;\n\n  /** Fixed position div that auto place GUI's go inside */\n  var auto_place_container;\n\n  /** Are we hiding the GUI's ? */\n  var hide = false;\n\n  /** GUI's which should be hidden */\n  var hideable_guis = [];\n\n  /**\n   * A lightweight controller library for JavaScript. It allows you to easily\n   * manipulate variables and fire functions on the fly.\n   * @class\n   *\n   * @member dat.gui\n   *\n   * @param {Object} [params]\n   * @param {String} [params.name] The name of this GUI.\n   * @param {Object} [params.load] JSON object representing the saved state of\n   * this GUI.\n   * @param {Boolean} [params.auto=true]\n   * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n   * @param {Boolean} [params.closed] If true, starts closed\n   */\n  var GUI = function(params) {\n\n    var _this = this;\n\n    /**\n     * Outermost DOM Element\n     * @type DOMElement\n     */\n    this.domElement = document.createElement('div');\n    this.__ul = document.createElement('ul');\n    this.domElement.appendChild(this.__ul);\n\n    dom.addClass(this.domElement, CSS_NAMESPACE);\n\n    /**\n     * Nested GUI's by name\n     * @ignore\n     */\n    this.__folders = {};\n\n    this.__controllers = [];\n\n    /**\n     * List of objects I'm remembering for save, only used in top level GUI\n     * @ignore\n     */\n    this.__rememberedObjects = [];\n\n    /**\n     * Maps the index of remembered objects to a map of controllers, only used\n     * in top level GUI.\n     *\n     * @private\n     * @ignore\n     *\n     * @example\n     * [\n     *  {\n     *    propertyName: Controller,\n     *    anotherPropertyName: Controller\n     *  },\n     *  {\n     *    propertyName: Controller\n     *  }\n     * ]\n     */\n    this.__rememberedObjectIndecesToControllers = [];\n\n    this.__listening = [];\n\n    params = params || {};\n\n    // Default parameters\n    params = common.defaults(params, {\n      autoPlace: true,\n      width: GUI.DEFAULT_WIDTH\n    });\n\n    params = common.defaults(params, {\n      resizable: params.autoPlace,\n      hideable: params.autoPlace\n    });\n\n\n    if (!common.isUndefined(params.load)) {\n\n      // Explicit preset\n      if (params.preset) params.load.preset = params.preset;\n\n    } else {\n\n      params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n    }\n\n    if (common.isUndefined(params.parent) && params.hideable) {\n      hideable_guis.push(this);\n    }\n\n    // Only root level GUI's are resizable.\n    params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n    if (params.autoPlace && common.isUndefined(params.scrollable)) {\n      params.scrollable = true;\n    }\n//    params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n    // Not part of params because I don't want people passing this in via\n    // constructor. Should be a 'remembered' value.\n    var use_local_storage =\n        SUPPORTS_LOCAL_STORAGE &&\n            localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n    var saveToLocalStorage;\n\n    Object.defineProperties(this,\n\n        /** @lends dat.gui.GUI.prototype */\n        {\n\n          /**\n           * The parent <code>GUI</code>\n           * @type dat.gui.GUI\n           */\n          parent: {\n            get: function() {\n              return params.parent;\n            }\n          },\n\n          scrollable: {\n            get: function() {\n              return params.scrollable;\n            }\n          },\n\n          /**\n           * Handles <code>GUI</code>'s element placement for you\n           * @type Boolean\n           */\n          autoPlace: {\n            get: function() {\n              return params.autoPlace;\n            }\n          },\n\n          /**\n           * The identifier for a set of saved values\n           * @type String\n           */\n          preset: {\n\n            get: function() {\n              if (_this.parent) {\n                return _this.getRoot().preset;\n              } else {\n                return params.load.preset;\n              }\n            },\n\n            set: function(v) {\n              if (_this.parent) {\n                _this.getRoot().preset = v;\n              } else {\n                params.load.preset = v;\n              }\n              setPresetSelectIndex(this);\n              _this.revert();\n            }\n\n          },\n\n          /**\n           * The width of <code>GUI</code> element\n           * @type Number\n           */\n          width: {\n            get: function() {\n              return params.width;\n            },\n            set: function(v) {\n              params.width = v;\n              setWidth(_this, v);\n            }\n          },\n\n          /**\n           * The name of <code>GUI</code>. Used for folders. i.e\n           * a folder's name\n           * @type String\n           */\n          name: {\n            get: function() {\n              return params.name;\n            },\n            set: function(v) {\n              // TODO Check for collisions among sibling folders\n              params.name = v;\n              if (title_row_name) {\n                title_row_name.innerHTML = params.name;\n              }\n            }\n          },\n\n          /**\n           * Whether the <code>GUI</code> is collapsed or not\n           * @type Boolean\n           */\n          closed: {\n            get: function() {\n              return params.closed;\n            },\n            set: function(v) {\n              params.closed = v;\n              if (params.closed) {\n                dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n              } else {\n                dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n              }\n              // For browsers that aren't going to respect the CSS transition,\n              // Lets just check our height against the window height right off\n              // the bat.\n              this.onResize();\n\n              if (_this.__closeButton) {\n                _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n              }\n            }\n          },\n\n          /**\n           * Contains all presets\n           * @type Object\n           */\n          load: {\n            get: function() {\n              return params.load;\n            }\n          },\n\n          /**\n           * Determines whether or not to use <a href=\"https://developer.mozilla.org/en/DOM/Storage#localStorage\">localStorage</a> as the means for\n           * <code>remember</code>ing\n           * @type Boolean\n           */\n          useLocalStorage: {\n\n            get: function() {\n              return use_local_storage;\n            },\n            set: function(bool) {\n              if (SUPPORTS_LOCAL_STORAGE) {\n                use_local_storage = bool;\n                if (bool) {\n                  dom.bind(window, 'unload', saveToLocalStorage);\n                } else {\n                  dom.unbind(window, 'unload', saveToLocalStorage);\n                }\n                localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n              }\n            }\n\n          }\n\n        });\n\n    // Are we a root level GUI?\n    if (common.isUndefined(params.parent)) {\n\n      params.closed = false;\n\n      dom.addClass(this.domElement, GUI.CLASS_MAIN);\n      dom.makeSelectable(this.domElement, false);\n\n      // Are we supposed to be loading locally?\n      if (SUPPORTS_LOCAL_STORAGE) {\n\n        if (use_local_storage) {\n\n          _this.useLocalStorage = true;\n\n          var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n          if (saved_gui) {\n            params.load = JSON.parse(saved_gui);\n          }\n\n        }\n\n      }\n\n      /*this.__closeButton = document.createElement('div');\n      this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n      this.domElement.appendChild(this.__closeButton);\n\n      dom.bind(this.__closeButton, 'click', function() {\n\n        _this.closed = !_this.closed;\n\n\n      });*/\n\n\n      // Oh, you're a nested GUI!\n    } else {\n\n      if (params.closed === undefined) {\n        params.closed = true;\n      }\n\n      var title_row_name = document.createTextNode(params.name);\n      dom.addClass(title_row_name, 'controller-name');\n\n      var title_row = addRow(_this, title_row_name);\n\n      var on_click_title = function(e) {\n        e.preventDefault();\n        _this.closed = !_this.closed;\n        return false;\n      };\n\n      dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n      dom.addClass(title_row, 'title');\n      dom.bind(title_row, 'click', on_click_title);\n\n      if (!params.closed) {\n        this.closed = false;\n      }\n\n    }\n\n    if (params.autoPlace) {\n\n      if (common.isUndefined(params.parent)) {\n\n        if (auto_place_virgin) {\n          auto_place_container = document.createElement('div');\n          dom.addClass(auto_place_container, CSS_NAMESPACE);\n          dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n          deploymentNode.appendChild(auto_place_container);\n          auto_place_virgin = false;\n        }\n\n        // Put it in the dom for you.\n        auto_place_container.appendChild(this.domElement);\n\n        // Apply the auto styles\n        dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n      }\n\n\n      // Make it not elastic.\n      if (!this.parent) setWidth(_this, params.width);\n\n    }\n\n    dom.bind(window, 'resize', function() { _this.onResize() });\n    dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n    dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n    dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n    this.onResize();\n\n\n    if (params.resizable) {\n      addResizeHandle(this);\n    }\n\n    saveToLocalStorage = function () {\n      if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {\n        localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n      }\n    }\n\n    // expose this method publicly\n    this.saveToLocalStorageIfPossible = saveToLocalStorage;\n\n    var root = _this.getRoot();\n    function resetWidth() {\n\t      var root = _this.getRoot();\n\t      root.width += 1;\n\t      common.defer(function() {\n\t        root.width -= 1;\n\t      });\n\t    }\n\n\t    if (!params.parent) {\n\t      resetWidth();\n\t    }\n\n  };\n\n  GUI.toggleHide = function() {\n\n    hide = !hide;\n    common.each(hideable_guis, function(gui) {\n      gui.domElement.style.zIndex = hide ? -999 : 999;\n      gui.domElement.style.opacity = hide ? 0 : 1;\n    });\n  };\n\n  GUI.CLASS_AUTO_PLACE = 'a';\n  GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n  GUI.CLASS_MAIN = 'main';\n  GUI.CLASS_CONTROLLER_ROW = 'cr';\n  GUI.CLASS_TOO_TALL = 'taller-than-window';\n  GUI.CLASS_CLOSED = 'closed';\n  GUI.CLASS_CLOSE_BUTTON = 'close-button';\n  GUI.CLASS_DRAG = 'drag';\n\n  GUI.DEFAULT_WIDTH = 245;\n  GUI.TEXT_CLOSED = 'Close Controls';\n  GUI.TEXT_OPEN = 'Open Controls';\n\n  dom.bind(window, 'keydown', function(e) {\n\n    if (document.activeElement.type !== 'text' &&\n        (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n      GUI.toggleHide();\n    }\n\n  }, false);\n\n  common.extend(\n\n      GUI.prototype,\n\n      /** @lends dat.gui.GUI */\n      {\n\n        /**\n         * @param object\n         * @param property\n         * @returns {dat.controllers.Controller} The new controller that was added.\n         * @instance\n         */\n        add: function(object, property) {\n\n          return add(\n              this,\n              object,\n              property,\n              {\n                factoryArgs: Array.prototype.slice.call(arguments, 2)\n              }\n          );\n\n        },\n\n        /**\n         * @param object\n         * @param property\n         * @returns {dat.controllers.ColorController} The new controller that was added.\n         * @instance\n         */\n        addColor: function(object, property) {\n\n          return add(\n              this,\n              object,\n              property,\n              {\n                color: true\n              }\n          );\n\n        },\n\n        /**\n         * @param controller\n         * @instance\n         */\n        remove: function(controller) {\n\n          // TODO listening?\n          this.__ul.removeChild(controller.__li);\n          this.__controllers.splice(this.__controllers.indexOf(controller), 1);\n          var _this = this;\n          common.defer(function() {\n            _this.onResize();\n          });\n\n        },\n\n        destroy: function() {\n\n          if (this.autoPlace) {\n            auto_place_container.removeChild(this.domElement);\n          }\n\n        },\n\n        /**\n         * @param name\n         * @returns {dat.gui.GUI} The new folder.\n         * @throws {Error} if this GUI already has a folder by the specified\n         * name\n         * @instance\n         */\n        addFolder: function(name) {\n\n          // We have to prevent collisions on names in order to have a key\n          // by which to remember saved values\n          if (this.__folders[name] !== undefined) {\n            throw new Error('You already have a folder in this GUI by the' +\n                ' name \"' + name + '\"');\n          }\n\n          var new_gui_params = { name: name, parent: this };\n\n          // We need to pass down the autoPlace trait so that we can\n          // attach event listeners to open/close folder actions to\n          // ensure that a scrollbar appears if the window is too short.\n          new_gui_params.autoPlace = this.autoPlace;\n\n          // Do we have saved appearance data for this folder?\n\n          if (this.load && // Anything loaded?\n              this.load.folders && // Was my parent a dead-end?\n              this.load.folders[name]) { // Did daddy remember me?\n\n            // Start me closed if I was closed\n            new_gui_params.closed = this.load.folders[name].closed;\n\n            // Pass down the loaded data\n            new_gui_params.load = this.load.folders[name];\n\n          }\n\n          var gui = new GUI(new_gui_params);\n          this.__folders[name] = gui;\n\n          var li = addRow(this, gui.domElement);\n          dom.addClass(li, 'folder');\n          return gui;\n\n        },\n\n        open: function() {\n          this.closed = false;\n        },\n\n        close: function() {\n          this.closed = true;\n        },\n\n        onResize: function() {\n\n          var root = this.getRoot();\n\n          if (root.scrollable) {\n\n            var top = dom.getOffset(root.__ul).top;\n            var h = 0;\n\n            common.each(root.__ul.childNodes, function(node) {\n              if (! (root.autoPlace && node === root.__save_row))\n                h += dom.getHeight(node);\n            });\n\n            if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n              dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n              root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n            } else {\n              dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n              root.__ul.style.height = 'auto';\n            }\n\n          }\n\n          if (root.__resize_handle) {\n            common.defer(function() {\n              root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n            });\n          }\n\n          /*if (root.__closeButton) {\n            root.__closeButton.style.width = root.width + 'px';\n          }*/\n\n        },\n\n        /**\n         * Mark objects for saving. The order of these objects cannot change as\n         * the GUI grows. When remembering new objects, append them to the end\n         * of the list.\n         *\n         * @param {Object...} objects\n         * @throws {Error} if not called on a top level GUI.\n         * @instance\n         */\n        remember: function() {\n\n          if (common.isUndefined(SAVE_DIALOGUE)) {\n            SAVE_DIALOGUE = new CenteredDiv();\n            SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n          }\n\n          if (this.parent) {\n            throw new Error(\"You can only call remember on a top level GUI.\");\n          }\n\n          var _this = this;\n\n          common.each(Array.prototype.slice.call(arguments), function(object) {\n            if (_this.__rememberedObjects.length == 0) {\n              addSaveMenu(_this);\n            }\n            if (_this.__rememberedObjects.indexOf(object) == -1) {\n              _this.__rememberedObjects.push(object);\n            }\n          });\n\n          if (this.autoPlace) {\n            // Set save row width\n            setWidth(this, this.width);\n          }\n\n        },\n\n        /**\n         * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n         * @instance\n         */\n        getRoot: function() {\n          var gui = this;\n          while (gui.parent) {\n            gui = gui.parent;\n          }\n          return gui;\n        },\n\n        /**\n         * @returns {Object} a JSON object representing the current state of\n         * this GUI as well as its remembered properties.\n         * @instance\n         */\n        getSaveObject: function() {\n\n          var toReturn = this.load;\n\n          toReturn.closed = this.closed;\n\n          // Am I remembering any values?\n          if (this.__rememberedObjects.length > 0) {\n\n            toReturn.preset = this.preset;\n\n            if (!toReturn.remembered) {\n              toReturn.remembered = {};\n            }\n\n            toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n          }\n\n          toReturn.folders = {};\n          common.each(this.__folders, function(element, key) {\n            toReturn.folders[key] = element.getSaveObject();\n          });\n\n          return toReturn;\n\n        },\n\n        save: function() {\n\n          if (!this.load.remembered) {\n            this.load.remembered = {};\n          }\n\n          this.load.remembered[this.preset] = getCurrentPreset(this);\n          markPresetModified(this, false);\n          this.saveToLocalStorageIfPossible();\n\n        },\n\n        saveAs: function(presetName) {\n\n          if (!this.load.remembered) {\n\n            // Retain default values upon first save\n            this.load.remembered = {};\n            this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n          }\n\n          this.load.remembered[presetName] = getCurrentPreset(this);\n          this.preset = presetName;\n          addPresetOption(this, presetName, true);\n          this.saveToLocalStorageIfPossible();\n\n        },\n\n        revert: function(gui) {\n\n          common.each(this.__controllers, function(controller) {\n            // Make revert work on Default.\n            if (!this.getRoot().load.remembered) {\n              controller.setValue(controller.initialValue);\n            } else {\n              recallSavedValue(gui || this.getRoot(), controller);\n            }\n          }, this);\n\n          common.each(this.__folders, function(folder) {\n            folder.revert(folder);\n          });\n\n          if (!gui) {\n            markPresetModified(this.getRoot(), false);\n          }\n\n\n        },\n\n        listen: function(controller) {\n\n          var init = this.__listening.length == 0;\n          this.__listening.push(controller);\n          if (init) updateDisplays(this.__listening);\n\n        }\n\n      }\n\n  );\n\n  function add(gui, object, property, params) {\n\n    if (object[property] === undefined) {\n      throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n    }\n\n    var controller;\n\n    if (params.color) {\n\n      controller = new ColorController(object, property);\n\n    } else {\n\n      var factoryArgs = [object,property].concat(params.factoryArgs);\n      controller = controllerFactory.apply(gui, factoryArgs);\n\n    }\n\n    if (params.before instanceof Controller) {\n      params.before = params.before.__li;\n    }\n\n    recallSavedValue(gui, controller);\n\n    dom.addClass(controller.domElement, 'c');\n\n    var name = document.createElement('span');\n    dom.addClass(name, 'property-name');\n    name.innerHTML = controller.property;\n\n    var container = document.createElement('div');\n    container.appendChild(name);\n    container.appendChild(controller.domElement);\n\n    var li = addRow(gui, container, params.before);\n\n    dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n    dom.addClass(li, typeof controller.getValue());\n\n    augmentController(gui, li, controller);\n\n    gui.__controllers.push(controller);\n\n    return controller;\n\n  }\n\n  /**\n   * Add a row to the end of the GUI or before another row.\n   *\n   * @param gui\n   * @param [dom] If specified, inserts the dom content in the new row\n   * @param [liBefore] If specified, places the new row before another row\n   */\n  function addRow(gui, dom, liBefore) {\n    var li = document.createElement('li');\n    if (dom) li.appendChild(dom);\n    if (liBefore) {\n      gui.__ul.insertBefore(li, params.before);\n    } else {\n      gui.__ul.appendChild(li);\n    }\n    gui.onResize();\n    return li;\n  }\n\n  function augmentController(gui, li, controller) {\n\n    controller.__li = li;\n    controller.__gui = gui;\n\n    common.extend(controller, {\n\n      options: function(options) {\n\n        if (arguments.length > 1) {\n          controller.remove();\n\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [common.toArray(arguments)]\n              }\n          );\n\n        }\n\n        if (common.isArray(options) || common.isObject(options)) {\n          controller.remove();\n\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [options]\n              }\n          );\n\n        }\n\n      },\n\n      name: function(v) {\n        controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n        return controller;\n      },\n\n      listen: function() {\n        controller.__gui.listen(controller);\n        return controller;\n      },\n\n      remove: function() {\n        controller.__gui.remove(controller);\n        return controller;\n      }\n\n    });\n\n    // All sliders should be accompanied by a box.\n    if (controller instanceof NumberControllerSlider) {\n\n      var box = new NumberControllerBox(controller.object, controller.property,\n          { min: controller.__min, max: controller.__max, step: controller.__step });\n\n      common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n        var pc = controller[method];\n        var pb = box[method];\n        controller[method] = box[method] = function() {\n          var args = Array.prototype.slice.call(arguments);\n          pc.apply(controller, args);\n          return pb.apply(box, args);\n        }\n      });\n\n      dom.addClass(li, 'has-slider');\n      controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n    }\n    else if (controller instanceof NumberControllerBox) {\n\n      var r = function(returned) {\n\n        // Have we defined both boundaries?\n        if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n          // Well, then lets just replace this with a slider.\n          controller.remove();\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [controller.__min, controller.__max, controller.__step]\n              });\n\n        }\n\n        return returned;\n\n      };\n\n      controller.min = common.compose(r, controller.min);\n      controller.max = common.compose(r, controller.max);\n\n    }\n    else if (controller instanceof BooleanController) {\n\n      dom.bind(li, 'click', function() {\n        dom.fakeEvent(controller.__checkbox, 'click');\n      });\n\n      dom.bind(controller.__checkbox, 'click', function(e) {\n        e.stopPropagation(); // Prevents double-toggle\n      })\n\n    }\n    else if (controller instanceof FunctionController) {\n\n      dom.bind(li, 'click', function() {\n        dom.fakeEvent(controller.__button, 'click');\n      });\n\n      dom.bind(li, 'mouseover', function() {\n        dom.addClass(controller.__button, 'hover');\n      });\n\n      dom.bind(li, 'mouseout', function() {\n        dom.removeClass(controller.__button, 'hover');\n      });\n\n    }\n    else if (controller instanceof ColorController) {\n\n      dom.addClass(li, 'color');\n      controller.updateDisplay = common.compose(function(r) {\n        li.style.borderLeftColor = controller.__color.toString();\n        return r;\n      }, controller.updateDisplay);\n\n      controller.updateDisplay();\n\n    }\n\n    controller.setValue = common.compose(function(r) {\n      if (gui.getRoot().__preset_select && controller.isModified()) {\n        markPresetModified(gui.getRoot(), true);\n      }\n      return r;\n    }, controller.setValue);\n\n  }\n\n  function recallSavedValue(gui, controller) {\n\n    // Find the topmost GUI, that's where remembered objects live.\n    var root = gui.getRoot();\n\n    // Does the object we're controlling match anything we've been told to\n    // remember?\n    var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n    // Why yes, it does!\n    if (matched_index != -1) {\n\n      // Let me fetch a map of controllers for thcommon.isObject.\n      var controller_map =\n          root.__rememberedObjectIndecesToControllers[matched_index];\n\n      // Ohp, I believe this is the first controller we've created for this\n      // object. Lets make the map fresh.\n      if (controller_map === undefined) {\n        controller_map = {};\n        root.__rememberedObjectIndecesToControllers[matched_index] =\n            controller_map;\n      }\n\n      // Keep track of this controller\n      controller_map[controller.property] = controller;\n\n      // Okay, now have we saved any values for this controller?\n      if (root.load && root.load.remembered) {\n\n        var preset_map = root.load.remembered;\n\n        // Which preset are we trying to load?\n        var preset;\n\n        if (preset_map[gui.preset]) {\n\n          preset = preset_map[gui.preset];\n\n        } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n          // Uhh, you can have the default instead?\n          preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n        } else {\n\n          // Nada.\n\n          return;\n\n        }\n\n\n        // Did the loaded object remember thcommon.isObject?\n        if (preset[matched_index] &&\n\n          // Did we remember this particular property?\n            preset[matched_index][controller.property] !== undefined) {\n\n          // We did remember something for this guy ...\n          var value = preset[matched_index][controller.property];\n\n          // And that's what it is.\n          controller.initialValue = value;\n          controller.setValue(value);\n\n        }\n\n      }\n\n    }\n\n  }\n\n  function getLocalStorageHash(gui, key) {\n    // TODO how does this deal with multiple GUI's?\n    return document.location.href + '.' + key;\n\n  }\n\n  function addSaveMenu(gui) {\n\n    var div = gui.__save_row = document.createElement('li');\n\n    dom.addClass(gui.domElement, 'has-save');\n\n    gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n    dom.addClass(div, 'save-row');\n\n    var gears = document.createElement('span');\n    gears.innerHTML = '&nbsp;';\n    dom.addClass(gears, 'button gears');\n\n    // TODO replace with FunctionController\n    var button = document.createElement('span');\n    button.innerHTML = 'Save';\n    dom.addClass(button, 'button');\n    dom.addClass(button, 'save');\n\n    var button2 = document.createElement('span');\n    button2.innerHTML = 'New';\n    dom.addClass(button2, 'button');\n    dom.addClass(button2, 'save-as');\n\n    var button3 = document.createElement('span');\n    button3.innerHTML = 'Revert';\n    dom.addClass(button3, 'button');\n    dom.addClass(button3, 'revert');\n\n    var select = gui.__preset_select = document.createElement('select');\n\n    if (gui.load && gui.load.remembered) {\n\n      common.each(gui.load.remembered, function(value, key) {\n        addPresetOption(gui, key, key == gui.preset);\n      });\n\n    } else {\n      addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n    }\n\n    dom.bind(select, 'change', function() {\n\n\n      for (var index = 0; index < gui.__preset_select.length; index++) {\n        gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n      }\n\n      gui.preset = this.value;\n\n    });\n\n    div.appendChild(select);\n    div.appendChild(gears);\n    div.appendChild(button);\n    div.appendChild(button2);\n    div.appendChild(button3);\n\n    if (SUPPORTS_LOCAL_STORAGE) {\n\n      var saveLocally = document.getElementById('dg-save-locally');\n      var explain = document.getElementById('dg-local-explain');\n\n      saveLocally.style.display = 'block';\n\n      var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n      if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n        localStorageCheckBox.setAttribute('checked', 'checked');\n      }\n\n      function showHideExplain() {\n        explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n      }\n\n      showHideExplain();\n\n      // TODO: Use a boolean controller, fool!\n      dom.bind(localStorageCheckBox, 'change', function() {\n        gui.useLocalStorage = !gui.useLocalStorage;\n        showHideExplain();\n      });\n\n    }\n\n    var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n    dom.bind(newConstructorTextArea, 'keydown', function(e) {\n      if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n        SAVE_DIALOGUE.hide();\n      }\n    });\n\n    dom.bind(gears, 'click', function() {\n      newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n      SAVE_DIALOGUE.show();\n      newConstructorTextArea.focus();\n      newConstructorTextArea.select();\n    });\n\n    dom.bind(button, 'click', function() {\n      gui.save();\n    });\n\n    dom.bind(button2, 'click', function() {\n      var presetName = prompt('Enter a new preset name.');\n      if (presetName) gui.saveAs(presetName);\n    });\n\n    dom.bind(button3, 'click', function() {\n      gui.revert();\n    });\n\n//    div.appendChild(button2);\n\n  }\n\n  function addResizeHandle(gui) {\n\n    gui.__resize_handle = document.createElement('div');\n\n    common.extend(gui.__resize_handle.style, {\n\n      width: '6px',\n      marginLeft: '-3px',\n      height: '200px',\n      cursor: 'ew-resize',\n      position: 'absolute'\n//      border: '1px solid blue'\n\n    });\n\n    var pmouseX;\n\n    dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n    //dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n    gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n    function dragStart(e) {\n\n      e.preventDefault();\n\n      pmouseX = e.clientX;\n\n      //dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n      dom.bind(window, 'mousemove', drag);\n      dom.bind(window, 'mouseup', dragStop);\n\n      return false;\n\n    }\n\n    function drag(e) {\n\n      e.preventDefault();\n\n      gui.width += pmouseX - e.clientX;\n      gui.onResize();\n      pmouseX = e.clientX;\n\n      return false;\n\n    }\n\n    function dragStop() {\n\n      //dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n      dom.unbind(window, 'mousemove', drag);\n      dom.unbind(window, 'mouseup', dragStop);\n\n    }\n\n  }\n\n  function setWidth(gui, w) {\n    gui.domElement.style.width = w + 'px';\n    // Auto placed save-rows are position fixed, so we have to\n    // set the width manually if we want it to bleed to the edge\n    if (gui.__save_row && gui.autoPlace) {\n      gui.__save_row.style.width = w + 'px';\n    }if (gui.__closeButton) {\n      gui.__closeButton.style.width = w + 'px';\n    }\n  }\n\n  function getCurrentPreset(gui, useInitialValues) {\n\n    var toReturn = {};\n\n    // For each object I'm remembering\n    common.each(gui.__rememberedObjects, function(val, index) {\n\n      var saved_values = {};\n\n      // The controllers I've made for thcommon.isObject by property\n      var controller_map =\n          gui.__rememberedObjectIndecesToControllers[index];\n\n      // Remember each value for each property\n      common.each(controller_map, function(controller, property) {\n        saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n      });\n\n      // Save the values for thcommon.isObject\n      toReturn[index] = saved_values;\n\n    });\n\n    return toReturn;\n\n  }\n\n  function addPresetOption(gui, name, setSelected) {\n    var opt = document.createElement('option');\n    opt.innerHTML = name;\n    opt.value = name;\n    gui.__preset_select.appendChild(opt);\n    if (setSelected) {\n      gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n    }\n  }\n\n  function setPresetSelectIndex(gui) {\n    for (var index = 0; index < gui.__preset_select.length; index++) {\n      if (gui.__preset_select[index].value == gui.preset) {\n        gui.__preset_select.selectedIndex = index;\n      }\n    }\n  }\n\n  function markPresetModified(gui, modified) {\n    var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n//    console.log('mark', modified, opt);\n    if (modified) {\n      opt.innerHTML = opt.value + \"*\";\n    } else {\n      opt.innerHTML = opt.value;\n    }\n  }\n\n  function updateDisplays(controllerArray) {\n\n\n    if (controllerArray.length != 0) {\n\n      requestAnimationFrame(function() {\n        updateDisplays(controllerArray);\n      });\n\n    }\n\n    common.each(controllerArray, function(c) {\n      c.updateDisplay();\n    });\n\n  }\n\n  return GUI;\n\n})(dat.utils.css,\n\"<div id=\\\"dg-save\\\" class=\\\"dg dialogue\\\">\\n\\n  Here's the new load parameter for your <code>GUI</code>'s constructor:\\n\\n  <textarea id=\\\"dg-new-constructor\\\"></textarea>\\n\\n  <div id=\\\"dg-save-locally\\\">\\n\\n    <input id=\\\"dg-local-storage\\\" type=\\\"checkbox\\\"/> Automatically save\\n    values to <code>localStorage</code> on exit.\\n\\n    <div id=\\\"dg-local-explain\\\">The values saved to <code>localStorage</code> will\\n      override those passed to <code>dat.GUI</code>'s constructor. This makes it\\n      easier to work incrementally, but <code>localStorage</code> is fragile,\\n      and your friends may not see the same values you do.\\n      \\n    </div>\\n    \\n  </div>\\n\\n</div>\",\n\".dg {\\n  /** Clear list styles */\\n  /* Auto-place container */\\n  /* Auto-placed GUI's */\\n  /* Line items that don't contain folders. */\\n  /** Folder names */\\n  /** Hides closed items */\\n  /** Controller row */\\n  /** Name-half (left) */\\n  /** Controller-half (right) */\\n  /** Controller placement */\\n  /** Shorter number boxes when slider is present. */\\n  /** Ensure the entire boolean and function row shows a hand */ }\\n  .dg ul {\\n    list-style: none;\\n    margin: 0;\\n    padding: 0;\\n    width: 100%;\\n    clear: both; }\\n  .dg.ac {\\n        top: 0;\\n    left: 0;\\n    right: 0;\\n    height: 0;\\n    z-index: 0; }\\n  .dg:not(.ac) .main {\\n    /** Exclude mains in ac so that we don't hide close button */\\n    overflow: hidden; }\\n  .dg.main {\\n    -webkit-transition: opacity 0.1s linear;\\n    -o-transition: opacity 0.1s linear;\\n    -moz-transition: opacity 0.1s linear;\\n    transition: opacity 0.1s linear; }\\n    .dg.main.taller-than-window {\\n      overflow-y: auto; }\\n      .dg.main.taller-than-window .close-button {\\n        opacity: 1;\\n        /* TODO, these are style notes */\\n        margin-top: -1px;\\n        border-top: 1px solid #2c2c2c; }\\n    .dg.main ul.closed .close-button {\\n      opacity: 1 !important; }\\n    .dg.main:hover .close-button,\\n    .dg.main .close-button.drag {\\n      opacity: 1; }\\n    .dg.main .close-button {\\n      /*opacity: 0;*/\\n      -webkit-transition: opacity 0.1s linear;\\n      -o-transition: opacity 0.1s linear;\\n      -moz-transition: opacity 0.1s linear;\\n      transition: opacity 0.1s linear;\\n      border: 0;\\n      position: absolute;\\n      line-height: 19px;\\n      height: 20px;\\n      /* TODO, these are style notes */\\n      cursor: pointer;\\n      text-align: center;\\n      background-color: #000; }\\n      .dg.main .close-button:hover {\\n        background-color: #111; }\\n  .dg.a {\\n    float: right;\\n    margin-right: 15px;\\n    overflow-x: hidden; }\\n    .dg.a.has-save > ul {\\n      margin-top: 27px; }\\n      .dg.a.has-save > ul.closed {\\n        margin-top: 0; }\\n    .dg.a .save-row {\\n      position: fixed;\\n      top: 0;\\n      z-index: 1002; }\\n  .dg li {\\n    -webkit-transition: height 0.1s ease-out;\\n    -o-transition: height 0.1s ease-out;\\n    -moz-transition: height 0.1s ease-out;\\n    transition: height 0.1s ease-out; }\\n  .dg li:not(.folder) {\\n    cursor: auto;\\n    height: 27px;\\n    line-height: 27px;\\n    overflow: hidden;\\n    padding: 0 4px 0 5px; }\\n  .dg li.folder {\\n    padding: 0;\\n    border-left: 4px solid rgba(0, 0, 0, 0); }\\n  .dg li.title {\\n    cursor: pointer;\\n    margin-left: -4px; }\\n  .dg .closed li:not(.title),\\n  .dg .closed ul li,\\n  .dg .closed ul li > * {\\n    height: 0;\\n    overflow: hidden;\\n    border: 0; }\\n  .dg .cr {\\n    clear: both;\\n    padding-left: 3px;\\n    height: 27px; }\\n  .dg .property-name {\\n    cursor: default;\\n    float: left;\\n    clear: left;\\n    width: 40%;\\n    overflow: hidden;\\n    text-overflow: ellipsis; }\\n  .dg .c {\\n    float: left;\\n    width: 60%; }\\n  .dg .c input[type=text] {\\n    border: 0;\\n    margin-top: 4px;\\n    padding: 3px;\\n    width: 100%;\\n    float: right; }\\n  .dg .has-slider input[type=text] {\\n    width: 30%;\\n    /*display: none;*/\\n    margin-left: 0; }\\n  .dg .slider {\\n    float: left;\\n    width: 66%;\\n    margin-left: -5px;\\n    margin-right: 0;\\n    height: 19px;\\n    margin-top: 4px; }\\n  .dg .slider-fg {\\n    height: 100%; }\\n  .dg .c input[type=checkbox] {\\n    margin-top: 9px; }\\n  .dg .c select {\\n    margin-top: 5px; }\\n  .dg .cr.function,\\n  .dg .cr.function .property-name,\\n  .dg .cr.function *,\\n  .dg .cr.boolean,\\n  .dg .cr.boolean * {\\n    cursor: pointer; }\\n  .dg .selector {\\n    display: none;\\n    position: absolute;\\n    margin-left: -9px;\\n    margin-top: 23px;\\n    z-index: 10; }\\n  .dg .c:hover .selector,\\n  .dg .selector.drag {\\n    display: block; }\\n  .dg li.save-row {\\n    padding: 0; }\\n    .dg li.save-row .button {\\n      display: inline-block;\\n      padding: 0px 6px; }\\n  .dg.dialogue {\\n    background-color: #222;\\n    width: 460px;\\n    padding: 15px;\\n    font-size: 13px;\\n    line-height: 15px; }\\n\\n/* TODO Separate style and structure */\\n#dg-new-constructor {\\n  padding: 10px;\\n  color: #222;\\n  font-family: Monaco, monospace;\\n  font-size: 10px;\\n  border: 0;\\n  resize: none;\\n  box-shadow: inset 1px 1px 1px #888;\\n  word-wrap: break-word;\\n  margin: 12px 0;\\n  display: block;\\n  width: 440px;\\n  overflow-y: scroll;\\n  height: 100px;\\n  position: relative; }\\n\\n#dg-local-explain {\\n  display: none;\\n  font-size: 11px;\\n  line-height: 17px;\\n  border-radius: 3px;\\n  background-color: #333;\\n  padding: 8px;\\n  margin-top: 10px; }\\n  #dg-local-explain code {\\n    font-size: 10px; }\\n\\n#dat-gui-save-locally {\\n  display: none; }\\n\\n/** Main type */\\n.dg {\\n  color: #eee;\\n  font: 11px 'Lucida Grande', sans-serif;\\n  text-shadow: 0 -1px 0 #111;\\n  /** Auto place */\\n  /* Controller row, <li> */\\n  /** Controllers */ }\\n  .dg.main {\\n    /** Scrollbar */ }\\n    .dg.main::-webkit-scrollbar {\\n      width: 5px;\\n      background: #1a1a1a; }\\n    .dg.main::-webkit-scrollbar-corner {\\n      height: 0;\\n      display: none; }\\n    .dg.main::-webkit-scrollbar-thumb {\\n      border-radius: 5px;\\n      background: #676767; }\\n  .dg li:not(.folder) {\\n    background: #1a1a1a;\\n    border-bottom: 1px solid #2c2c2c; }\\n  .dg li.save-row {\\n    line-height: 25px;\\n    background: #dad5cb;\\n    border: 0; }\\n    .dg li.save-row select {\\n      margin-left: 5px;\\n      width: 108px; }\\n    .dg li.save-row .button {\\n      margin-left: 5px;\\n      margin-top: 1px;\\n      border-radius: 2px;\\n      font-size: 9px;\\n      line-height: 7px;\\n      padding: 4px 4px 5px 4px;\\n      background: #c5bdad;\\n      color: #fff;\\n      text-shadow: 0 1px 0 #b0a58f;\\n      box-shadow: 0 -1px 0 #b0a58f;\\n      cursor: pointer; }\\n      .dg li.save-row .button.gears {\\n        background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\\n        height: 7px;\\n        width: 8px; }\\n      .dg li.save-row .button:hover {\\n        background-color: #bab19e;\\n        box-shadow: 0 -1px 0 #b0a58f; }\\n  .dg li.folder {\\n    border-bottom: 0; }\\n  .dg li.title {\\n    padding-left: 16px;\\n    background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\\n    cursor: pointer;\\n    border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\\n  .dg .closed li.title {\\n    background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\\n  .dg .cr.boolean {\\n    border-left: 3px solid #806787; }\\n  .dg .cr.function {\\n    border-left: 3px solid #e61d5f; }\\n  .dg .cr.number {\\n    border-left: 3px solid #2fa1d6; }\\n    .dg .cr.number input[type=text] {\\n      color: #2fa1d6; }\\n  .dg .cr.string {\\n    border-left: 3px solid #1ed36f; }\\n    .dg .cr.string input[type=text] {\\n      color: #1ed36f; }\\n  .dg .cr.function:hover, .dg .cr.boolean:hover {\\n    background: #111; }\\n  .dg .c input[type=text] {\\n    background: #303030;\\n    outline: none; }\\n    .dg .c input[type=text]:hover {\\n      background: #3c3c3c; }\\n    .dg .c input[type=text]:focus {\\n      background: #494949;\\n      color: #fff; }\\n  .dg .c .slider {\\n    background: #303030;\\n    cursor: ew-resize; }\\n  .dg .c .slider-fg {\\n    background: #2fa1d6; }\\n  .dg .c .slider:hover {\\n    background: #3c3c3c; }\\n    .dg .c .slider:hover .slider-fg {\\n      background: #44abda; }\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n      return function(object, property) {\n\n        var initialValue = object[property];\n\n        // Providing options?\n        if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n          return new OptionController(object, property, arguments[2]);\n        }\n\n        // Providing a map?\n\n        if (common.isNumber(initialValue)) {\n\n          if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n            // Has min and max.\n            return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n          } else {\n\n            return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n          }\n\n        }\n\n        if (common.isString(initialValue)) {\n          return new StringController(object, property);\n        }\n\n        if (common.isFunction(initialValue)) {\n          return new FunctionController(object, property, '');\n        }\n\n        if (common.isBoolean(initialValue)) {\n          return new BooleanController(object, property);\n        }\n\n      }\n\n    })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a text input to alter the string property of an object.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var StringController = function(object, property) {\n\n    StringController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    this.__input = document.createElement('input');\n    this.__input.setAttribute('type', 'text');\n\n    dom.bind(this.__input, 'keyup', onChange);\n    dom.bind(this.__input, 'change', onChange);\n    dom.bind(this.__input, 'blur', onBlur);\n    dom.bind(this.__input, 'keydown', function(e) {\n      if (e.keyCode === 13) {\n        this.blur();\n      }\n    });\n\n\n    function onChange() {\n      _this.setValue(_this.__input.value);\n    }\n\n    function onBlur() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n\n  };\n\n  StringController.superclass = Controller;\n\n  common.extend(\n\n      StringController.prototype,\n      Controller.prototype,\n\n      {\n\n        updateDisplay: function() {\n          // Stops the caret from moving on account of:\n          // keyup -> setValue -> updateDisplay\n          if (!dom.isActive(this.__input)) {\n            this.__input.value = this.getValue();\n          }\n          return StringController.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n  var ColorController = function(object, property) {\n\n    ColorController.superclass.call(this, object, property);\n\n    this.__color = new Color(this.getValue());\n    this.__temp = new Color(0);\n\n    var _this = this;\n\n    this.domElement = document.createElement('div');\n\n    dom.makeSelectable(this.domElement, false);\n\n    this.__selector = document.createElement('div');\n    this.__selector.className = 'selector';\n\n    this.__saturation_field = document.createElement('div');\n    this.__saturation_field.className = 'saturation-field';\n\n    this.__field_knob = document.createElement('div');\n    this.__field_knob.className = 'field-knob';\n    this.__field_knob_border = '2px solid ';\n\n    this.__hue_knob = document.createElement('div');\n    this.__hue_knob.className = 'hue-knob';\n\n    this.__hue_field = document.createElement('div');\n    this.__hue_field.className = 'hue-field';\n\n    this.__input = document.createElement('input');\n    this.__input.type = 'text';\n    this.__input_textShadow = '0 1px 1px ';\n\n    dom.bind(this.__input, 'keydown', function(e) {\n      if (e.keyCode === 13) { // on enter\n        onBlur.call(this);\n      }\n    });\n\n    dom.bind(this.__input, 'blur', onBlur);\n\n    dom.bind(this.__selector, 'mousedown', function(e) {\n\n      dom\n        .addClass(this, 'drag')\n        .bind(window, 'mouseup', function(e) {\n          dom.removeClass(_this.__selector, 'drag');\n        });\n\n    });\n\n    var value_field = document.createElement('div');\n\n    common.extend(this.__selector.style, {\n      width: '122px',\n      height: '102px',\n      padding: '3px',\n      backgroundColor: '#222',\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n    });\n\n    common.extend(this.__field_knob.style, {\n      position: 'absolute',\n      width: '12px',\n      height: '12px',\n      border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n      borderRadius: '12px',\n      zIndex: 1\n    });\n\n    common.extend(this.__hue_knob.style, {\n      position: 'absolute',\n      width: '15px',\n      height: '2px',\n      borderRight: '4px solid #fff',\n      zIndex: 1\n    });\n\n    common.extend(this.__saturation_field.style, {\n      width: '100px',\n      height: '100px',\n      border: '1px solid #555',\n      marginRight: '3px',\n      display: 'inline-block',\n      cursor: 'pointer'\n    });\n\n    common.extend(value_field.style, {\n      width: '100%',\n      height: '100%',\n      background: 'none'\n    });\n\n    linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n    common.extend(this.__hue_field.style, {\n      width: '15px',\n      height: '100px',\n      display: 'inline-block',\n      border: '1px solid #555',\n      cursor: 'ns-resize'\n    });\n\n    hueGradient(this.__hue_field);\n\n    common.extend(this.__input.style, {\n      outline: 'none',\n//      width: '120px',\n      textAlign: 'center',\n//      padding: '4px',\n//      marginBottom: '6px',\n      color: '#fff',\n      border: 0,\n      fontWeight: 'bold',\n      textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n    });\n\n    dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n    dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n    dom.bind(this.__hue_field, 'mousedown', function(e) {\n      setH(e);\n      dom.bind(window, 'mousemove', setH);\n      dom.bind(window, 'mouseup', unbindH);\n    });\n\n    function fieldDown(e) {\n      setSV(e);\n      // deploymentNode.style.cursor = 'none';\n      dom.bind(window, 'mousemove', setSV);\n      dom.bind(window, 'mouseup', unbindSV);\n    }\n\n    function unbindSV() {\n      dom.unbind(window, 'mousemove', setSV);\n      dom.unbind(window, 'mouseup', unbindSV);\n      // deploymentNode.style.cursor = 'default';\n    }\n\n    function onBlur() {\n      var i = interpret(this.value);\n      if (i !== false) {\n        _this.__color.__state = i;\n        _this.setValue(_this.__color.toOriginal());\n      } else {\n        this.value = _this.__color.toString();\n      }\n    }\n\n    function unbindH() {\n      dom.unbind(window, 'mousemove', setH);\n      dom.unbind(window, 'mouseup', unbindH);\n    }\n\n    this.__saturation_field.appendChild(value_field);\n    this.__selector.appendChild(this.__field_knob);\n    this.__selector.appendChild(this.__saturation_field);\n    this.__selector.appendChild(this.__hue_field);\n    this.__hue_field.appendChild(this.__hue_knob);\n\n    this.domElement.appendChild(this.__input);\n    this.domElement.appendChild(this.__selector);\n\n    this.updateDisplay();\n\n    function setSV(e) {\n\n      e.preventDefault();\n\n      var w = dom.getWidth(_this.__saturation_field);\n      var o = dom.getOffset(_this.__saturation_field);\n      var s = (e.clientX - o.left + deploymentNode.scrollLeft) / w;\n      var v = 1 - (e.clientY - o.top + deploymentNode.scrollTop) / w;\n\n      if (v > 1) v = 1;\n      else if (v < 0) v = 0;\n\n      if (s > 1) s = 1;\n      else if (s < 0) s = 0;\n\n      _this.__color.v = v;\n      _this.__color.s = s;\n\n      _this.setValue(_this.__color.toOriginal());\n\n\n      return false;\n\n    }\n\n    function setH(e) {\n\n      e.preventDefault();\n\n      var s = dom.getHeight(_this.__hue_field);\n      var o = dom.getOffset(_this.__hue_field);\n      var h = 1 - (e.clientY - o.top + deploymentNode.scrollTop) / s;\n\n      if (h > 1) h = 1;\n      else if (h < 0) h = 0;\n\n      _this.__color.h = h * 360;\n\n      _this.setValue(_this.__color.toOriginal());\n\n      return false;\n\n    }\n\n  };\n\n  ColorController.superclass = Controller;\n\n  common.extend(\n\n      ColorController.prototype,\n      Controller.prototype,\n\n      {\n\n        updateDisplay: function() {\n\n          var i = interpret(this.getValue());\n\n          if (i !== false) {\n\n            var mismatch = false;\n\n            // Check for mismatch on the interpreted value.\n\n            common.each(Color.COMPONENTS, function(component) {\n              if (!common.isUndefined(i[component]) &&\n                  !common.isUndefined(this.__color.__state[component]) &&\n                  i[component] !== this.__color.__state[component]) {\n                mismatch = true;\n                return {}; // break\n              }\n            }, this);\n\n            // If nothing diverges, we keep our previous values\n            // for statefulness, otherwise we recalculate fresh\n            if (mismatch) {\n              common.extend(this.__color.__state, i);\n            }\n\n          }\n\n          common.extend(this.__temp.__state, this.__color.__state);\n\n          this.__temp.a = 1;\n\n          var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n          var _flip = 255 - flip;\n\n          common.extend(this.__field_knob.style, {\n            marginLeft: 100 * this.__color.s - 7 + 'px',\n            marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n            backgroundColor: this.__temp.toString(),\n            border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n          });\n\n          this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n          this.__temp.s = 1;\n          this.__temp.v = 1;\n\n          linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n          common.extend(this.__input.style, {\n            backgroundColor: this.__input.value = this.__color.toString(),\n            color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n            textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n          });\n\n        }\n\n      }\n\n  );\n\n  var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n\n  function linearGradient(elem, x, a, b) {\n    elem.style.background = '';\n    common.each(vendors, function(vendor) {\n      elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n    });\n  }\n\n  function hueGradient(elem) {\n    elem.style.background = '';\n    elem.style.cssText += 'background: -moz-linear-gradient(top,  #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n    elem.style.cssText += 'background: -webkit-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: -o-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: -ms-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n  }\n\n\n  return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n  var Color = function() {\n\n    this.__state = interpret.apply(this, arguments);\n\n    if (this.__state === false) {\n      throw 'Failed to interpret color arguments';\n    }\n\n    this.__state.a = this.__state.a || 1;\n\n\n  };\n\n  Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n  common.extend(Color.prototype, {\n\n    toString: function() {\n      return toString(this);\n    },\n\n    toOriginal: function() {\n      return this.__state.conversion.write(this);\n    }\n\n  });\n\n  defineRGBComponent(Color.prototype, 'r', 2);\n  defineRGBComponent(Color.prototype, 'g', 1);\n  defineRGBComponent(Color.prototype, 'b', 0);\n\n  defineHSVComponent(Color.prototype, 'h');\n  defineHSVComponent(Color.prototype, 's');\n  defineHSVComponent(Color.prototype, 'v');\n\n  Object.defineProperty(Color.prototype, 'a', {\n\n    get: function() {\n      return this.__state.a;\n    },\n\n    set: function(v) {\n      this.__state.a = v;\n    }\n\n  });\n\n  Object.defineProperty(Color.prototype, 'hex', {\n\n    get: function() {\n\n      if (!this.__state.space !== 'HEX') {\n        this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n      }\n\n      return this.__state.hex;\n\n    },\n\n    set: function(v) {\n\n      this.__state.space = 'HEX';\n      this.__state.hex = v;\n\n    }\n\n  });\n\n  function defineRGBComponent(target, component, componentHexIndex) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'RGB') {\n          return this.__state[component];\n        }\n\n        recalculateRGB(this, component, componentHexIndex);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'RGB') {\n          recalculateRGB(this, component, componentHexIndex);\n          this.__state.space = 'RGB';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function defineHSVComponent(target, component) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'HSV')\n          return this.__state[component];\n\n        recalculateHSV(this);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'HSV') {\n          recalculateHSV(this);\n          this.__state.space = 'HSV';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function recalculateRGB(color, component, componentHexIndex) {\n\n    if (color.__state.space === 'HEX') {\n\n      color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n    } else if (color.__state.space === 'HSV') {\n\n      common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n    } else {\n\n      throw 'Corrupted color state';\n\n    }\n\n  }\n\n  function recalculateHSV(color) {\n\n    var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n    common.extend(color.__state,\n        {\n          s: result.s,\n          v: result.v\n        }\n    );\n\n    if (!common.isNaN(result.h)) {\n      color.__state.h = result.h;\n    } else if (common.isUndefined(color.__state.h)) {\n      color.__state.h = 0;\n    }\n\n  }\n\n  return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n  var tmpComponent;\n\n  return {\n\n    hsv_to_rgb: function(h, s, v) {\n\n      var hi = Math.floor(h / 60) % 6;\n\n      var f = h / 60 - Math.floor(h / 60);\n      var p = v * (1.0 - s);\n      var q = v * (1.0 - (f * s));\n      var t = v * (1.0 - ((1.0 - f) * s));\n      var c = [\n        [v, t, p],\n        [q, v, p],\n        [p, v, t],\n        [p, q, v],\n        [t, p, v],\n        [v, p, q]\n      ][hi];\n\n      return {\n        r: c[0] * 255,\n        g: c[1] * 255,\n        b: c[2] * 255\n      };\n\n    },\n\n    rgb_to_hsv: function(r, g, b) {\n\n      var min = Math.min(r, g, b),\n          max = Math.max(r, g, b),\n          delta = max - min,\n          h, s;\n\n      if (max != 0) {\n        s = delta / max;\n      } else {\n        return {\n          h: NaN,\n          s: 0,\n          v: 0\n        };\n      }\n\n      if (r == max) {\n        h = (g - b) / delta;\n      } else if (g == max) {\n        h = 2 + (b - r) / delta;\n      } else {\n        h = 4 + (r - g) / delta;\n      }\n      h /= 6;\n      if (h < 0) {\n        h += 1;\n      }\n\n      return {\n        h: h * 360,\n        s: s,\n        v: max / 255\n      };\n    },\n\n    rgb_to_hex: function(r, g, b) {\n      var hex = this.hex_with_component(0, 2, r);\n      hex = this.hex_with_component(hex, 1, g);\n      hex = this.hex_with_component(hex, 0, b);\n      return hex;\n    },\n\n    component_from_hex: function(hex, componentIndex) {\n      return (hex >> (componentIndex * 8)) & 0xFF;\n    },\n\n    hex_with_component: function(hex, componentIndex, value) {\n      return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n    }\n\n  }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n  /**\n   * requirejs version of Paul Irish's RequestAnimationFrame\n   * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n   */\n\n  return window.webkitRequestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.oRequestAnimationFrame ||\n      window.msRequestAnimationFrame ||\n      function(callback, element) {\n\n        window.setTimeout(callback, 1000 / 60);\n\n      };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n  var CenteredDiv = function() {\n\n    this.backgroundElement = document.createElement('div');\n    common.extend(this.backgroundElement.style, {\n      backgroundColor: 'rgba(0,0,0,0.8)',\n      top: 0,\n      left: 0,\n      display: 'none',\n      zIndex: '1000',\n      opacity: 0,\n      WebkitTransition: 'opacity 0.2s linear',\n      transition: 'opacity 0.2s linear'\n    });\n\n    dom.makeFullscreen(this.backgroundElement);\n    this.backgroundElement.style.position = 'fixed';\n\n    this.domElement = document.createElement('div');\n    common.extend(this.domElement.style, {\n      position: 'fixed',\n      display: 'none',\n      zIndex: '1001',\n      opacity: 0,\n      WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear',\n      transition: 'transform 0.2s ease-out, opacity 0.2s linear'\n    });\n\n\n    deploymentNode.appendChild(this.backgroundElement);\n    deploymentNode.appendChild(this.domElement);\n\n    var _this = this;\n    dom.bind(this.backgroundElement, 'click', function() {\n      _this.hide();\n    });\n\n\n  };\n\n  CenteredDiv.prototype.show = function() {\n\n    var _this = this;\n\n    this.backgroundElement.style.display = 'block';\n\n    this.domElement.style.display = 'block';\n    this.domElement.style.opacity = 0;\n//    this.domElement.style.top = '52%';\n    this.domElement.style.webkitTransform = 'scale(1.1)';\n\n    this.layout();\n\n    common.defer(function() {\n      _this.backgroundElement.style.opacity = 1;\n      _this.domElement.style.opacity = 1;\n      _this.domElement.style.webkitTransform = 'scale(1)';\n    });\n\n  };\n\n  CenteredDiv.prototype.hide = function() {\n\n    var _this = this;\n\n    var hide = function() {\n\n      _this.domElement.style.display = 'none';\n      _this.backgroundElement.style.display = 'none';\n\n      dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n      dom.unbind(_this.domElement, 'transitionend', hide);\n      dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n    };\n\n    dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n    dom.bind(this.domElement, 'transitionend', hide);\n    dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n    this.backgroundElement.style.opacity = 0;\n//    this.domElement.style.top = '48%';\n    this.domElement.style.opacity = 0;\n    this.domElement.style.webkitTransform = 'scale(1.1)';\n\n  };\n\n  CenteredDiv.prototype.layout = function() {\n    this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n    this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n  };\n  \n  function lockScroll(e) {\n    console.log(e);\n  }\n\n  return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);"
  },
  {
    "path": "page/js/effects.js",
    "content": "window.addEventListener('DOMContentLoaded', function(){\n\n    var slider = document.getElementsByTagName('html-gl')[1];\n\n    var renderer = window.HTMLGL.renderer;\n\n    var filtersSwitchs = [true, false, false, false, false, false, false, false, false, false, false];\n\n    var gui = new dat.GUI({});\n\n    var displacementSprite = new PIXI.TilingSprite.fromImage(\"assets/img/displacement_map.jpg\");\n    window.HTMLGL.stage.addChild(displacementSprite);\n    var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);\n\n    var displacementFolder = gui.addFolder('Displacement');\n    displacementFolder.add(filtersSwitchs, '0').name(\"apply\");\n    displacementFolder.add(displacementFilter.scale, 'x', 1, 200).name(\"scaleX\");\n    displacementFolder.add(displacementFilter.scale, 'y', 1, 200).name(\"scaleY\");\n    displacementFolder.open();\n\n    var blurFilter = new PIXI.filters.BlurFilter();\n\n    var blurFolder = gui.addFolder('Blur');\n    blurFolder.add(filtersSwitchs, '1').name(\"apply\");\n    blurFolder.add(blurFilter, 'blurX', 0, 32).name(\"blurX\");\n    blurFolder.add(blurFilter, 'blurY', 0, 32).name(\"blurY\");\n\n    ////\n\n    var invertFilter = new PIXI.filters.InvertFilter();\n\n    var invertFolder = gui.addFolder('Invert');\n    invertFolder.add(filtersSwitchs, '2').name(\"apply\");\n    invertFolder.add(invertFilter, 'invert', 0, 1).name(\"Invert\");\n\n    ////\n\n    var pixelateFilter = new PIXI.filters.PixelateFilter();\n\n    var pixelateFolder = gui.addFolder('Pixelate');\n    pixelateFolder.add(filtersSwitchs, '3').name(\"apply\");\n    pixelateFolder.add(pixelateFilter.size, 'x', 1, 32).name(\"PixelSizeX\");\n    pixelateFolder.add(pixelateFilter.size, 'y', 1, 32).name(\"PixelSizeY\");\n\n    ////\n\n    var grayFilter = new PIXI.filters.GrayFilter();\n\n    var grayFolder = gui.addFolder('Gray');\n    grayFolder.add(filtersSwitchs, '4').name(\"apply\");\n    grayFolder.add(grayFilter, 'gray', 0, 1).name(\"Gray\");\n\n    ////\n\n    var sepiaFilter = new PIXI.filters.SepiaFilter();\n\n    var sepiaFolder = gui.addFolder('Sepia');\n    sepiaFolder.add(filtersSwitchs, '5').name(\"apply\");\n    sepiaFolder.add(sepiaFilter, 'sepia', 0, 1).name(\"Sepia\");\n\n    ////\n\n    var twistFilter = new PIXI.filters.TwistFilter();\n\n    var twistFolder = gui.addFolder('Twist');\n    twistFolder.add(filtersSwitchs, '6').name(\"apply\");\n    twistFolder.add(twistFilter, 'angle', 0, 10).name(\"Angle\");\n    twistFolder.add(twistFilter, 'radius', 0, 1).name(\"Radius\");\n\n    twistFolder.add(twistFilter.offset, 'x', 0, 1).name(\"offset.x\");;\n    twistFolder.add(twistFilter.offset, 'y', 0, 1).name(\"offset.y\");;\n\n    ////\n\n    var dotScreenFilter = new PIXI.filters.DotScreenFilter();\n\n    var dotScreenFolder = gui.addFolder('DotScreen');\n    dotScreenFolder.add(filtersSwitchs, '7').name(\"apply\");\n    dotScreenFolder.add(dotScreenFilter, 'angle', 0, 10);\n    dotScreenFolder.add(dotScreenFilter, 'scale', 0, 1);\n\n    ////\n\n    var colorStepFilter = new PIXI.filters.ColorStepFilter();\n\n    var colorStepFolder = gui.addFolder('ColorStep');\n    colorStepFolder.add(filtersSwitchs, '8').name(\"apply\");\n\n    colorStepFolder.add(colorStepFilter, 'step', 1, 100);\n    colorStepFolder.add(colorStepFilter, 'step', 1, 100);\n\n    ////\n\n    var crossHatchFilter = new PIXI.filters.CrossHatchFilter();\n\n    var crossHatchFolder = gui.addFolder('CrossHatch');\n    crossHatchFolder.add(filtersSwitchs, '9').name(\"apply\");\n\n    var rgbSplitterFilter = new PIXI.filters.RGBSplitFilter();\n\n    rgbSplitterFilter.blue = new PIXI.Point(10, 10);\n    rgbSplitterFilter.green = new PIXI.Point(-10, 10);\n    rgbSplitterFilter.red = new PIXI.Point(10, -10);\n\n    var rgbSplitFolder = gui.addFolder('RGB Splitter');\n    rgbSplitFolder.add(filtersSwitchs, '10').name(\"apply\");\n\n\n    var filterCollection = [displacementFilter, blurFilter, invertFilter, pixelateFilter, grayFilter, sepiaFilter, twistFilter, dotScreenFilter, colorStepFilter, crossHatchFilter, rgbSplitterFilter];\n\n    // create an new instance of a pixi stage\n    var stage = window.HTMLGL.stage;\n\n    var pondContainer = slider.sprite;\n\n    stage.interactive = true;\n\n    var padding = 100;\n    var bounds = new PIXI.Rectangle(-padding, -padding, window.HTMLGL.renderer.width + padding * 2, window.HTMLGL.renderer.height + padding * 2)\n\n    //var overlay = new PIXI.TilingSprite(PIXI.Texture.fromImage(\"assets/img/zeldaWaves.png\"), window.HTMLGL.renderer.width, window.HTMLGL.renderer.height);\n    //overlay.alpha = 0.1//0.2\n    //pondContainer.addChild(overlay);\n\n    displacementFilter.scale.x = 25;\n    displacementFilter.scale.y = 25;\n\n    var count = 0;\n    var switchy = false;\n\n    function animate() {\n\n        if (window.HTMLGL.scrollY > 1000) {\n            count += 0.1;\n\n            var blurAmount = Math.cos(count);\n            var blurAmount2 = Math.sin(count * 0.8);\n\n            var filtersToApply = [];\n\n            for (var i = 0; i < filterCollection.length; i++) {\n                if (filtersSwitchs[i])filtersToApply.push(filterCollection[i]);\n            }\n\n            var rgbFilterIndex = filtersToApply.indexOf(rgbSplitterFilter);\n\n            if (rgbFilterIndex !== -1) {\n                slider.sprite.filters = [rgbSplitterFilter];\n                filtersToApply.splice(rgbFilterIndex, 1);\n            } else {\n                if (slider.sprite.filters) {\n                    var rgbFilterIndexOnSlider = slider.sprite.filters.indexOf(rgbSplitterFilter);\n                    if (rgbFilterIndexOnSlider !== -1) {\n                        slider.sprite.filters = null;\n                    }\n                }\n            }\n\n            pondContainer.filters = filtersToApply.length > 0 ? filtersToApply : null;\n\n            displacementSprite.x = count * 10;\n            displacementSprite.y = count * 10;\n\n            renderer.render(stage);\n        }\n\n        requestAnimationFrame(animate);\n    }\n\n    renderer.render(stage);\n    requestAnimationFrame( animate );\n});"
  },
  {
    "path": "page/js/slider.js",
    "content": "//Slider logic, written in HTML / JS.\n//The only difference between HTML GL and basic HTML is that you should use element.styleGL.transform instead of element.style.transform\n\nvar images = document.getElementsByTagName('img'),\n    dragStart = false,\n    slider = document.getElementsByTagName('html-gl')[1],\n    startX = 0,\n    startLeft = 0,\n    transformPropertyName = document.body.style.transform !== undefined ? 'transform' : 'WebkitTransform';\n\nfor (var i = 0; i < images.length; i++) {\n    images[i].ondragstart = function () {\n        return false;\n    };\n}\n\nfunction setSliderX(x) {\n    (slider.styleGL || slider.style)[transformPropertyName] = 'translateZ(0) translateX(' + (startLeft - (startX - (x || 0))) + 'px)';\n}\n\nfunction getSliderX() {\n    return parseInt(parseCSSTransform((slider.styleGL || slider.style)[transformPropertyName]).translateX) || 0\n}\n\nfunction onDragStart(event) {\n    dragStart = true;\n    startX = (event.pageX || event.x) || event.touches[0].pageX;\n    startLeft = getSliderX();\n}\n\nfunction onDragEnd() {\n    dragStart = false;\n}\n\nfunction onMove(event) {\n    if (dragStart) {\n        var pageX = (event.pageX || event.x) || event.touches[0].pageX,\n            moveTime = new Date();\n\n        setSliderX(pageX);\n    }\n}\n\nslider.addEventListener('mousedown', onDragStart);\nslider.addEventListener('mouseup', onDragEnd);\nslider.addEventListener('mousemove', onMove);\nslider.addEventListener('touchstart', onDragStart);\nslider.addEventListener('touchend', onDragEnd);\nslider.addEventListener('touchmove', onMove);\n\nparseCSSTransform = function (transformString) {\n    return (transformString.match(/([\\w]+)\\(([^\\)]+)\\)/g) || [])\n        //make pairs of prop and value\n        .map(function (it) {\n            return it.replace(/\\)$/, \"\").split(/\\(/)\n        })\n        //convert to key-value map/object\n        .reduce(function (m, it) {\n            return m[it[0]] = it[1], m\n        }, {});\n}"
  },
  {
    "path": "src/effects/ascii.js",
    "content": "(function (w) {\n\n    var Ascii = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.AsciiFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Ascii.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.ascii = Ascii;\n})(window);"
  },
  {
    "path": "src/effects/bloom.js",
    "content": "(function (w) {\n\n    var Bloom = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.BloomFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Bloom.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.bloom = Bloom;\n})(window);"
  },
  {
    "path": "src/effects/diagonal-blur.js",
    "content": "(function (w) {\n\n    var DiagonalBlur = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.BlurDirFilter(2, 2);\n        this.filter.passes = 2;\n        this.filter.blur = 3;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = DiagonalBlur.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.diagonalblur = DiagonalBlur;\n})(window);"
  },
  {
    "path": "src/effects/dotscreen.js",
    "content": "(function (w) {\n\n    var DotScreen = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.DotScreenFilter();\n        this.filter.scale = parseInt(this.element.getAttribute('dotScreenScale')) || 1;\n        this.filter.angle = parseInt(this.element.getAttribute('dotScreenAngle')) || 1;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = DotScreen.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.dotscreen = DotScreen;\n})(window);"
  },
  {
    "path": "src/effects/invert.js",
    "content": "(function (w) {\n\n    var Invert = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.InvertFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Invert.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.invert = Invert;\n})(window);"
  },
  {
    "path": "src/effects/noise.js",
    "content": "(function (w) {\n\n    var Noise = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.NoiseFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Noise.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.noise = Noise;\n})(window);"
  },
  {
    "path": "src/effects/pixelate.js",
    "content": "(function (w) {\n\n    var Pixelate = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.PixelateFilter();\n        this.filter.size.x = parseInt(this.element.getAttribute('pixelSizeX')) || 2;\n        this.filter.size.y = parseInt(this.element.getAttribute('pixelSizeY')) || 2;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Pixelate.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.pixelate = Pixelate;\n})(window);"
  },
  {
    "path": "src/effects/rgbsplit.js",
    "content": "(function (w) {\n\n    var RGBSplit = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.RGBSplitFilter();\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = RGBSplit.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.rgbsplit = RGBSplit;\n})(window);"
  },
  {
    "path": "src/effects/ripples.js",
    "content": "(function (w) {\n\n    var Ripples = function (element) {\n        this.element = element;\n        this.ripple = this.ripple.bind(this);\n        this.element.addEventListener('mousedown', this.ripple);\n\n        var displacementMapImage = new Image();\n        displacementMapImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgEAAAIBCAIAAABfhPs2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2tpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo1MjZkMzQyYS1kMzZjLTRkOTYtOGU4My1kNjYyNTkxZTIxMGQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTEwRUI3MDRGNEMxMTFFNDg1RDBBMEJCQ0UzMDExRkIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTEwRUI3MDNGNEMxMTFFNDg1RDBBMEJCQ0UzMDExRkIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OEI3NEM0QTE2MUM1MTFFMzgzM0FGOEVFNDc1RkUxMEYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OEI3NEM0QTI2MUM1MTFFMzgzM0FGOEVFNDc1RkUxMEYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7Uf9pCAAMjnUlEQVR42uy9CWMjx5E0WlcDnBkdPnZ/7/7gt9+uTw3RXVX5KiKyuhskJdt7eG2pIQoDNkAQxJFHRGRk/Ld/+7dwna7TdbpO1+kXeUrXU3CdrtN1uk5XDrhO1+k6XafrdOWA63SdrtN1uk6/mFO5noLr9M97ijyFGOY/uKDj+o43Oi6GYKfL707G/3S1ze/2i2Z+K9sPzH/mVdfpOl054Dpdp//5KL+fPNzrYppx/RzFfyy6n+M8U4HCuZIEzuzIEzNzzMfgF8+pI4bnQ0oEOOu8/27n0/U6XqcrB1yn6/TXhfukM/2Dgx+H+Bj6+O/jOwp/Oeza28vIDTH8ZDZ5ujo+32rPUCFHHj2SBBNDYHboShJXYrhOVw64TlfEV6Sf0Z7/23MARmF9XNaPva3o34Rtex+un3/qL7YMp+I//sRNo8W3Nz/9bZ4kbKaDjHSWQtYji2wUPBd0/+/KCtfpygHX6Wcd9GfET2kE/DDO7aNw/zYNHHnBBNUf3z9DN09ZIZ5CffyRcL/fV/yphPBxJniiFeITemT7XZ74CO9MPDfgYsLx5PdRxj+9jzzA8/nf9Z65TlcOuE7/3JU+wj2Cvtf8p2rdhOS8SQMe3M91vc0qPp1D/IyoM+KeuwT78drfM4eF97TwkRFsv9+n2v7pH4unFHMK/ZNUOLoEXti/9dzwnBhi9Pw2LpWU2UaIUWBe6PrnSgnX6coB1+kf/jSDflLc38O0ynwL75EcsycYR2W7nQK9napt289PjcJzW8Db99PlNxHf4pu4bx+BR+dwf3QZ/jfuhb89HZ/JQCE8zocZ/YHYDP3maJHnyZlH4s5j6B6QElJJM9cxEXiX0Pv1TrtOVw64Tv9AcV8nYt7pCPqAM+zHI/4Z7bED9pk1vh+Pz7eMB7yjeh3ncZf6HLgQDtop4scz8GNvIaC4x3oLb8B9e0odAG1mmDalAcV0f+wzypuOxBnC40wYk+Oe/YHf3iWt+z17FtC96puUU86JT1BHGzVP1zvwOl054Dr93XEeL/ZZ75/jPiKk2YHYHOHeToGetfx+Yd4yzgQQvAPY43uf0f8U8Z/ygf+sH4n2TvfDHzz1BNHeIkL2Lu6HowM48QsxnkP5TC+eDCweYNE8mHY4yDPE0SLE/Wf3b2cGIkI080KIjh1NrjrlOBLC+Pw6XMTTRSFcpysHXKf/zbgfT3E/fxz3GVmf4/45Exxh+nTVDvIgrFvfbxDtHO6fzsMpJeyJIc7Ye9YOPV0OT+X/CWUKB0tg55L/PRBEInceP6p+pKm454N+JIBx3vdbdhb+HvS9UYh9Jwz89vN+4mwL5tSbHfnA9n4l4T/vD7rjRRd/cJ2uHHCd/odL/jz+SyPixBni38b9d8X+Kfoj9E+c53TQI76u3bPCuJxm7E52ZI55M9Cl+jaFgwZIx+TXmTDgj8Rd+2/xY6r4iSSwk+BHd8MfO9D/GfoV1mfsxs2SnYCgp3B/yg19B4UQ1vGsesLw6B8t7k1D9L5pTsfZzAdMG2/6g/FK5fEVMtkDa71dzcF1unLAdfovnrziz5GynnONv8M1T/X+Efd3PMejNpXvM4j3eAr0Nm+fmAOS5xIT6J1sr/39yM4Q+L31M3Ng8awXCk88gb2p+t8PELyTh6rofpMPJrsbT2jPbFfSDP0zoPfzDfTtOPeAjtvwBr17T6AjaeYGP6iGQOfm3YDniQM4OuNFZ7Co4Nk8NQfXu/o6XTngOv0VoT8r+p/RnjOm72nAy//o9f6pVLf9qvOXB+jE2J2OVsCyzZ5goj1JP6I+oKPGT6AEPLuwSzAC7QfaE8kZhJOmKErE3/cyv8eDEFY/o4p8903cb/rkpMh2I55AIS/SI0v+HtKpZp/1PtsnxnT8YEtxYkSeCcLp8rxZtDR+sCu489rkoT+emol5bdxpCUFDZ5jIwaKZDMZLiU86uoKRC9qVDK7TlQOu04+EfsA9R+jvJ5znKPy9VI97ye+XD5wnWT8lA9b4jPuK6ftV42bJL3hAZ27wb0egS/vPekOAI4Htgu7tJBzq0RuCgwBgwujxyV7Co7pMJuL7KYA0o/xTQ5BCOM0geLifN0OWyTvTO+L4wQOz6u9RTYBielQr0ND17LHey39exsHmUNJ4OogvjTvBjWOf+SAd+cAv7L3C22Rw8MnoDMYjLcUTwZUMrtOVA67TBHzOVX8/l/8z9NtO4e7R/00O6Eesn1E7mQp5VfrG3BCOsO4RPybHiI6In3WkTyBIswVBv+LgD2Lv57h/YEHWT2nAZon/Bv/pbzqAPVMc+E+aR+Lp2ngkBqdw44Y/K+3o/8T6Q94DdGMQ3mv/PskAxf3GtqWnaEegn7fEszZ7hb3VQMegfBPPvcJzMnATIzsnA/wFMXESrRSlgQsmunLAdfrFnaDwyfovnkvjs6rnKfTH48L8tivKd2I7DDi977U8whSTQZqlPavZnvvBCiTE+jC7gc7b71X/uGoyBxgy6JnRXD+bZq46yYTsSVQqXrbPOv7ZcSjsCtRzse8F/jkT+FPl36b9lnHmk9zjWR2E+twJAFXooXqUF1UQ294TeLwOqY1ozlCOziBmtRFNN0veInS/7MG9HXeIH+nJ0wMZlT1P2Ik2OAFEALCeOgMITHNvJJDbpSa6csB1+rmfcs6C++ncsPuUHSX/m6r/CMqxn3NAT90pXMXuzKwwjuRRmzMx4Ab8kdxVyI8fCWkyvfzxhiPIFvxxFP59kgE97b8U5X8/OOfQGdwJ8tg+D6yg38PZLsLEBrwxIAofmwOhK9g7g13lmZwkCCkegtHZCqQUppTTNDw84SDOEp/QG6aQkQ8arfG8G0gjuAP9RxpAj5PZCimg55ZmuEdq5Y8kEgxk6T0HpHGD2qM3BEoVe+jnDWziRbuI6APOIIhAXpB3iRO11q5PypUDrtPPq/AHzp8d85EfgfVDX38O/Wesf8b9ifb0qeHpHvqTzXofFxDlc1esRyZg9Fe4x12l3pQt5o1tTwm483au9NkE9IMHjtYUjT0feN5SPkgEfxA/z54TUu2HvRuY/U589pV7Tgg+zzWviYr/nhvi3h/keOIDBAQdSBEr93Ebipl2zWjCM8XM4Y1CyA2Yl1PHyAeJ+cDjfupEh8aFJiwITx+mDdg6JIb+MNODOgayyrjKlBJcqjTho5kP3icD/a14k2DUII8HRr6gXbrSKwdcp59J4Y8ZIsEA+ljHU9w3wSlPUIwKfJ33M6yvWp4lvwp8hPLcHPbJuJNeeIOlTbBI1T2DvhMDShJd7UJ3Brgx0OuxdScPwJ5SGkRso+0MsOP7Nqd/DZUxU0CPvvaLdxV050/WdG8gIEFGMYWTK+nOE4B/Za2c+54ZoMjZPMQHPau7NGgEeqn3c4jNJ8KSHmMSvMPEkJkYquWMx8lWAF2CkJw0/uasGzckgK7mALRBBrHMiK9MgG/HQTYTez7ojjgxiyD06267qJUnMnm2PWcOGc8FdaVlvK79aguuHHCd/mkRf4d9fqTwP8p/lKd77a8QL9EOKve9xg9KBg7o915GaGqeCSKCu5LB+PERtXpWSmjiilXyH3cYrUkeiguG+1G4p3yyTRWpo0Os4Dsr/a6+pM9aHlmhme1js7iBsRfoaUJcdlT1PUz1aj8phBLzkQLjNP/pqPRlVOrTWJvA/gn7THtQOuONLDqiJiNoZuE/uoTx1Iy0gmo9qg9AHsm4Q6QERn8SBiMfjDheMpF9kb0s9lH+nxJDzyQMUqp44tAZ4AjRJKQKRnwkA79s3c/JM6c9c7BlElugC6oH0qkh8K0HWteGd9DeFrR2sQVXDrhO/wQnyHwc9Kclsffzs7r3wv+M9fenCwnMLW6WBeMI7u/C91m5NwA+GVX/KIaJ6TeP8lmVfnOsn/1BU9XvhPCILq0lJ5lb9OZDxb4CeWfz0QTrW9Ojb+OXQlFEP2Xyz8wSTGvjfrpCq0UWrFC5NM4TKAGMSNiZJlLfe4E+0SCXEDX/tvtPgOtIUzmq2dzuH5jxgLP4g/EMbXjCR3leE39Bo5PEJn54JBJOViP0IhZviXeWR46wDdGfWE1z7ChVU/k/QnOG3lRNQwfrywSQs4J7RdYlmexUQaoZEb+hb2Ce8M6A7YXyAVLxhIlwgVk1EWxTSkw7RjQzwf4l6riMN5UywSUiunLAdfrHhX0Y/b3I7aaZpx3oJxzNoaYJ8fen0C/sPjrO4wlAFf2I8uNm5XSktInt9FaAUzTvCVrnwQ5hT5vFfhO2I8SpxXlwAjtdyQoZrBHz6X2ubPd409g3jBhkDvpHVOu4foTH8QOo05nqOv+PgJhwC/0nT2bSvrDX6RMCYpRHMY0cMv6c8TuSZPlpS7xBEL/b8+TN8ZeMUJ/YFI0/eHyA2gp4JyIlBEb25KZCxIcafjhZLoyoxVINtYDXDfw9uD3cONgoNOqI0pykQHw3kOwJmSA31vVpwUETc9DyuPFILuwA0AqMbGmLeGZ2EmwXgkJ/m50B6GUejBo7SEis5nwyaeTE7JlmPphsAcqLBBcKnq5P3JUDrtM/CuwjxD8jCh3TvIei33Zp/4njBQQkoU7vk7OVlBMXGO5HUFIVbyr8Bf1nIfvEgvLE9LO3AjMHNId0kDzID48wk9uO7zei5YzWIHuRGDqBoOAMRSOw37pDODheR1eAiMrOgCF+5gP+aFh5MSFME9TRUi7W9uOWI1Xk8Wjwe/vU/5ADGKU8yIAtK9dEfCR2gRCGJgpSQJqtQ056SgDw1PGrOgt+Ur8Vt09r6gu7BcZN/NgCLmBrpIVHQAaRYL5WLTjnrFkBIPEY0yNjPJ5TbKA0jY9l7xJaLqBcMkngBFZ5BPoCqCe03Fn7Z8R6hH52Bg2Rvo7fmL0z6A7PsS0QDEYsyGEobXDu5C3smTf2gQOJiMZvEVtwAURXDrhO/8egfyboz8jZD4+2w9SBZXuYWvs0y3+P+IeCM3hkZ40/blPMyV6g/KPYdwio7zSAQ0D4qeYDX42/rlUXbjZAFET5gdgQ/GGM79XkNhoqYBpU9/yvdy3aJZ6DyN56ZbnezEEfn2Lorgo1wj6BqlAiQ2GjPAj3IX8IPilRKFHcdiyoQZU6iuYZgy1UJAmIi15FC099EBuEXrLGEoibKHfQRFWVP6t73g+NtDvuOOUyveYA+iTiLCNLj8eeKm6FZmH8CEEh0AYZ94uJgqisErBRrAFxiugyRmodt8yxjviO4n0kI0d4FM3JGIMwMFzFgzUHYkS2pFgZ8Y/OgHMZbZcVEXeK3hB4CnVFqXcDZ8IAD51NAV76dlEFVw64Tv8n0b8w+qfki8mDnXB/wuVnqMeRdx5RoI+noJ/3Yr8ilJemlNBY9fsNCnoC4UItiyTQEVX6zS0iEF2BqaBGjnpUqPTZCvQRyxF8jDHas1ZT+IYyXXg/i3wTqm/+PXngDtlQZ1hnqtCsAJIIMequwA1Fo0tC2xwRBmUB6IZJowcJ+/edk92d4XzZZSMhjGtTuI8shcJ8NAu9aDR4/NKMUQLLtvDBx2V8V8XECGhaAOiksiWCPWl6CeFyxoTAuH+CQfwWDDNzSWfcZ6PAaJuk7pegi60eOYLMBIDqPoM5wDBBBXUDXGhkhQUXDAkg2W1kjCR9UVTHwAuxgU4Yf4a1eW1nbhCTbK4x9REEvFKJCeAAiCzMxTcYOR5vRPQErV6Z4MoB1+l//4TpLi/+44z+Hvqnn/NpdEv1/oH4T2UOBTwCc0jtNpf2Z6BA4Hgd7gf4M5mAhiYgNglAm45zUKAB02mMHogChGvIEyDMt8YCHfiPeNzahOcQ6GE+IMqvmr732oj04KboIMLmI2F1ZBlA0MwfCMokBPTnfuWNR+BmLmCV7jyCO1Y0aiMfc1cN8kHcwf2ugzl5eBu/ZPQEN7QIcWX5qzi+jTYCok+SzCj206Zl8AinPlVG4Wd6pLCMBBkFBo2UgFaAhM34kXRD6mpkh1GRiz8IGBRjXzFyC4WqVB8lERfUFCEKjwQy+gY4RBveAJH6IkvkAzL4ADIHeKlGMggt54VEcWcyaGQIWhFMNFI5GYKZG/DaavoMN0M7wqkCTmSwn5kA0eSKXXoV90yQMluCa6rgygHX6e8S/btEMZL2PxEAs+R32KdPw4Z2LvwF9/dZ8ptrPUHwEvTHZQhAIyCgxqs6L3NqF7U/SV3gNU1w/zgwQjUBGzw83CYgKHTaREPFOS6BSqxEbhDiWeAby/4HVUCjfdC23HEBl8Y91ERUXxmCHIB6BLHJ7HmEFK3mIlWGJop8utf15BCMmkur0XF/YUmN2n8NE9ymMXPA4x0lus8rVGJN+sEbYiSqdxIewFfYVTANo6ofQXhEWQJUZUT/ke/ia6FstIzQ2kak7gj+CJxLxn2KoE0kem94kVtEYhn3gF3CaAbYP5C0kF0oKWfQB4nTCxHCJOPPZ5psNE0JZJAEqO5Z+xdywugVGpqAhi4vNE8MAV0CvkVya+hiOMbskFHktyeAKJ1mjAUWeU+wXJngygHX6e8V/cNT1S/Zz0nk8xb0d7i/zcsj+gPe8XxQKoSbwvpV+6szSI72aDgA+D7kiCzgEeJZ6aP4BtqDmGhaeM7af+QDEoZdh60DKiCgD9yADzBUYj7jSPOfAVgE3AjNxfhTKhQo0UmAcf2Gfyv/cqQEcseq3BH0OSzQmBKWiG831qyNqaJp+Ux49oczL2UlfnngucYgswGmN6QE1e+8VqRxzYyHFHjiUYyS33QEOWMLrQB7B21QEvsCthfA8VFmB2A1qNFR+/ekhZx1HG+AfNKaUwmA8UuJ9JkDK0wMKNJaAiMHpAsAvWGZG6bN4AaameoBFAFZIjEwHiKHLzA3MK4pTAk1g5ofob9mj/4VHV+sIzFkZwvGo89IG51ORKmTVOhyniBtQHQoSLwU5KDtjLFdPcGVA67T/w7u/1T7O9+7z/oKdtd4V+wnhY+K/XmOBNCA9e+If24u8UQTUMHv6TaggiHdEU+g0A+FfjL5iuGqQHgfxfwokxs32iIEd0E7jfpOgv3caFUpDh2hnhmjI+ijkN+IATWEabqWofwHCoR0ITrXKn4fJ4XbFLeKEuC3mfxDk4XDuGPNB+xmobzQ3Gx0LpNxEsDdI3w6dg6NNdIAHu4LKYToTcNcWAZ0ZNT+NUXVwA0RHEesqMMwXOBKnC63CMg/R42PG4yvRJp2BPuiwF60TCABVM+pFqhFcQ+EiDqlQuP2iOEEpVIUawwnaNAOALFqR9im2AtHMCKC+ToskRmRX+wDe4KszmCkh9GDoOkbWR5/QMVrL84glcRrM3gPvPA9dO8JApEiWngbB81sDhu/GSl47gkunuDKAdfpvxj9x6kkascd93fXhHPtnw7WV+h8SJrG8nof8d0vNM5wtZArOV5E/OBazyqfHwf9E0vnNDMBKV8E+7YBAiKo04ngEH/nZVMU7x6xR9HfhPMYhoqQEDYc37T+XHGf0s7G2p81OyTzlfRvl/M+w/24qovnnlhQ80yAwp91fe4O+5jvdERieKr0T3sv9yO6Ja0ZDouIJHWQJsuUCuJuIb33ZaAFRiRctAhA7QLTQBJqkigMGq0AwH4T9P/geFjCEw4opxVOJrBGN5KwbUT/Ub1nMAIjOCuWQ6uaQQCwOteOBy73RFcR6SBXuekt7YTB6Aag10nEmDCzPJoFPlxOmTViRCCQR6yvW++gBxDxJzTUa0kV75NIjIjjEwCOOGyMJBGiZ4LZEJhz189pwI5MkC7t0JUDrtPfdhq1f6HoRxvbDyu3A/w54H43e9hpXq/9VekD5yHZCyg/FAZ9AP1V4k6ofaLLgUKqLUr62YX4o46HoB6ITEfFyGqf6p5xaGOlb10jXazYu8J9XxtagViJ1lSrYo0bwJ1YJfMJW/MEANCdN+Ad4avyKuS7jgRA+WhQK9AEHpmQIvxNEM73vUWYa8Sa5EDgbLsdySA+54YwpY77sXSq9yMQIdwDOIP95xTiUNpjehdsQabQSIA5aVRcvuGhJu2LLIj+BP2RLRID/biHlcdRq/P4yPWt4N+4hFhGkB63awtYW+aCEZlTKyjWCxoDpAMIPgsaCB/8GnU+TCbQpcEfiskRGk7anmaaH2XOHoMeQJ4ZP4w+AF3GuF8MFow2ZNQKdfYE4xzAVokVii70BIk61E7tks3O4MczwdETjDTW0BNcn+4rB1ynn4z+rP017WVh1/ycof/dtc1B/x3oD1PJwxxQDRHf+jhnExAI8uDbHfnBj1QFfZoxcNQLVTghnLCRoEXVPUr5ChSI2cA4DFwJ3Y9/K2X+HOCqo2GoUPZYRTqwCqEmSn7cFJEdAv3xI7x35xAA9ziwE3kByn52BoriFJHuAs/go8NGdaYLUc1vs191qv3bLPyf3ETj+7brlBrmgslO54RGkvjJHgE4SnCz0Ohl8TkHJDYKxqs4KTBuDymSCGSoSwvoBcR60LQM2IXjAMwNmAIo3Dw58sRoFErHpviljabBMAY+XsSUqSlC+B+PkK4+BSPDaA5ggITIT2qD6FBhC6FgzVE5BHFMGiAjVciVRldC5iduSAnoX5gGUP7jN40bOqU8J9G6pgooYcoU8/5YJkj7mPEtLW32BNcn/coB1+l99E+Z1f9T9J9wv0f/OAd6ZwfgyE/a5T0e8ZEVgAJVx/0zan8mCXYAuQL5CUSHMMlF5Y8X2VwoggKdhT0K9VBpJFwd9RkXqhHhIVgPWgD0LwhcBPFR6xHZx+NtTABA+XGchXwFej2Og/KsnOuqQcO7cfYBuFAJ2TOsE+tCl1B72NVBVRA/rxU6ZNPwrE3pf5xZwZ2AnlfHn62j4+mQjjT5PQgIinPHDOF9047hTL853lIB1iMei2O6BYWVV3VGdiMHID+7cQF3rnPF/RK2DAUopoMLpEEYRgN/MNqcET1HLh+3AcrDBADxJ4fDaQKIFxpW1GCYOaXWQOZHeormTO+6rMXNhKUyyeQ6fr4TlhpvglRj4WgxJqkBVFkZ9zLKf7QIfbQbtRgIgyaqAHXG5JD5eqQ3PUGYPAEvpflMa6A9t5Zrw3vq+tRfOeA6seQEglty0XbCU/SXytPeIf7SfRK7D6k564u4XyXkV5RHJoDYf1xAgY9RVnYAjUA/Rr2A/FRI/uMIuU2zWcB/ENgl6UA8l9YHM0Dj0jYagMBw3/EpJpiDKn9lMb4xdSDQd0d4GPT7xgKfAn9U/d0vZ+aD/ZZkAjRrgCORx53gtZkhLOxVPyeHHSOaO4KfdqFpgcC58D8j0sd2sX1V8Jv+IGlV/f6dZrB5JLnbdJ9BX0MDgon81tmbBlT3uhm5YmWFpBvwWgTPRU5DyASjKE+LqS0QWLSOkh4AEWQ7C9I5ansMAoDljRhSQ1ZIZJAYxQsFReMu8GbQzgckA0brRFuKTNMKZhI40JVE9ni8JPCfGA3aiP7jDVLYwuTSGfRBWI9agD2IVXYueHswEzQKVT0HUFHqjn30nPDmQCQMptvYE4Av7pdw6MoBv+QTZOOM/tHXVB22/kE6ILd4k+KTQsg0BZ2M/oHRPwj5IesbyPQS+hf3W13qgwmvykkxUr4s6jhPu22O6jPWW6sU6muqF1U84j40/fhnYzYgVgNCYISADUkDOaRR58MSHuNHG8fDGPQDz5vyQfXKPRIdUk+Av6x6jW8C8nkDMQTC8fcMcQT34CG+tyOuy3o0hIP+DefNAe9LT3sie8/fOS40x6G8bE2uI/L1AafynzttmAN0gzJtiaKH+0S5DSaD88SLeKGxJ8C4QCHQlAHGZBT+BFoYbMf5OBJGPkDTYJFpgH1ADDerywjRLY/ymkhigQQUdT4dHThyjMQP3aaxU+AQCQaijSkBPQRp5BHNG35uvE9KAv7HRgI9ZYqjFRhVRWX3MSJ+UiuAvISOkTxBoF8FBiVg4j17gqDfaI6X+VLjCL3DyAStj54gXIngygG/cOj/7ep28/0tk/UVBNSm3FPRX4Ge57xs81vywzxHeVgh7xklN+19Oi0coOYESENylxCLEelHTmjbCP8I61w4XlXpr4T0GdYZyln4j4BQI66Vm9uI2o+IOxlfG2L6xiKdzQHmfK1N3zceDG4iobkyQCoaN+jMa8KINDwcwkERh2d8X2Ry39f/7jnAZsRPH8X9N71A/IkeLRyrVk45IE5JpHChNNWlGCzInhWy8CJVwhoUKPQnJS3cGfcFKOF+FpT/gIlG/CQuNEJuXIIkpxhHWNAQjNAfC4eGFysFwAxGmMflkU6WiNK8YCllyx2SglJy7mCQyTCjEcCgMPhZ+ntjqICSpYwXBnRxZl8xbjRuWtF0kEoIbAJ0TjQqR+FWUBPxKuQossfjlUNPADlpOFEFnLggMRDTZNVlrgS6GCz2RRJcOeAXBv4k6X7mlG9wuH+6/Rxk70T/JfVx5AfFfvVMUKpw/3PtT52PJEDkfmMV+EMOFRU8NZ1VAp8q0L936Xp63TbJe0bVX2kMiQukbbcO/Ghr49u2kvJlZN+QBlDpx80E/owcIKbXdvCncpSrKR8gcNdJ86au1sEU+n0OoM1w3zzWT4/QUwCfcH+cEd9NIuxtVI/9L0f78OGisTRlQuf+IJ008efbzIO0miOlTDiozduzM7AgjRABojYvoFEohImSjXCP2yCgEyZiqsAnFXjRSAOhAxcincBpA13uC0ChXGpewPv2xWAkCOM/SP476vUC6Q/kRpQaYeZsG5mhY9Bs/Cq0AtyEhluQsx6/rGYwElVNB4jiXPigC7nsHDVGkMEVG+lqo3Yokj0mBkSriW5zmcORBjB05tBQ0ulaTnDlgF/GM17egj+H8sfEARy4v2T+XMglvpdNQKkT8HHcnxO/1algdABVItHx6eUS4Aa9Dmw7N4g5u7T7Gz6wBGQ7MR98/kbUr7ZVyoAqZJ0M7uB4K2EcdgCjVYhhjbh2M5rDBeUAlPwViLG+FQS0F/vEdiIzh9V+gnqmTEhqJNeJTjyHdg3OGbwN2ed6f4/ifWaLcOyEdFb5jPB8xAnH88rJ+HQPbxJDj2/Wz88bp5kDdtQoT4YguuxnF4mGPO8qC/OJyg2IyYtnBdwXL3eW3bnEvBjFo2KPXVPUllBu43jvN6BGTezxwp8qlksrIweU1kpeMlcSQEYEVni88sYVBiPKQ6SV8IbLFJ1iTnj0Gp3MN8BCtDC9caIY0wPMB2KMx88C5ILhBJqRzpkC5PbEeQJ2Kwc0xMQQtNnU9zRPaAgNQa31ihJXDviZlv8AanF6B/7QLvPk8BN81rf5eZkoP518XOaPDqBFzXyBCWis/Sv31IryrcL9jeVZDYT4O2d6KetRA75VoT4I9SP09836Bp0PkJ+KiV3odsDrAvMBirSGvgLtMVICgnrQx1fgP8a04fBO9apf5TwmBrap49SPTKX/oQS1sI8LxGn+7N1A+wjT7+9QHTthQTM8m31Q5NtPdwCK6QpH+fQblGDSU544Us5JWSSXCNX46gwszTQQXUdkBI4Sq/6RH4vgk2VmCPlScIygUzuEup79QWI30FmUj+MjVtsLwCKMIxdoTzvBJZAKowe4RfLMsUAdgKmtWEYCCDfkAyh/AgCZxu2ZmQsx4XpEjKjRlW40CxUsBNChOvIHLJGmOgiZAKUJsg1ExUnoUEFD0DiX0EwDCm5uS6fDKOWsTZLgNEkwMkGtV0Nw5YCf10mWDwU47u7zE1z2IyWohJ674jM65hPhMubIfiwz+kP/M6P/4oAPhN6patZ3hO1GOx6T0FM8LjAbYwuAYN7qCP+w9KnU8rcquL+3FTmANT7Cd1WlX0fhj3mBLkB/w+6sWOO2Td3nxhzAdmG0GxgX2BjT6xzpYlvQaQUhKadkP7uoX9FcDYG+7URdYj+woCNg2wEHvanow5twH38ixv+lU3t3YaeQp5To7DPxHmkS1h/LLpXkjxetqj+xxyz5x9+3ElbBBprkUA9LhxAB76DOVmlPchi5oROKxx3eQv6KbiCJOh5twRLTYo13Mn4q3ZAh+kgDhIlGQC5lRH+YVWTcGIZA2Fgz3mZAlMb/ia8Ax+O4/tKNTQEqQV3WEzqL0UvwLUo6m80Bfn0j0ic4qOL9TO9SSUgzJUPiQ2yuW/N9CayEAA3dUqq1XaPFVw74mZzI/WaOaz4N+jr3O0WfxP1b8FEvQP8xO/ITJ9OLod+lYWN50QgYS34U/kL8K6t+JIBmgmYbZ7Aa/dsqNP5sAFjyW90qdJwr3Nwg30QJD3hHOaCvCP2NmE/XF0M/3IJY/gcpPgkBAdzfolf9RH6k/OlChLRkS2TAOejv8187oN9nwJ11vZ1JYPs4oNtPgPr2PBTwXzvZu+/iR9fE58vRdwIgq6XjuNyEOnOAuGU6Rmv2mOQBsRNAQPQIbaz6US4XjBCjMxghmyyxVKfjYLtBnxkXy8SCAloEG4V/1s/ex+XQb2gjAkJ/R01fRlvQRk0/EoMttY8eAQ5RFJR2DKMtoJEKwKFYSQ8giNO7urjQlPIhNpkzE2DQuUWBVuKNCRCFDZgSsgIyAdOArPlMS+7UFmlM26cwlqWIIbi44isH/HOX/0D/IeF2/bobP3D8SbrP4AmgeQdASCc61j+i/BaLzN2qKF9qPXsU/jOCfvLoD88fUb4GewXJc6DTHzU6RT4c3eobeF6rYHT7OtLACPRbI9CvNNAR9DfU9aMDQFZYKesc8X1zuSc4AFK+gHpqBNnLIS+Qy4SDguiBfmA4yHu6vZ3aAoEnQv8Fp9Tp4fM+ZMcfTQAfhOD3QT/+d+P+X3XtW2HprHHfPJLKoJcxNa2U4MsOqBGK7BvQIjzm7HHhJgVqhAjpuBJHfQDA/CXUm03tEK4qCzqDMFIC+4B2w23KnXdV+ugJEhJAhVvE+BG0C7bcWs2pQRnUR/hFYoiFGwkwhCCXUoYLbCmDCghKs0IAsxJKYoivcrEbCaBB/4TGRAPiZm49lDm6nWn8RBUpB8rMewJzjIztFTfsIBPUWq+G4MoB/5Tl/4j/c2fsvtV9Sj+n6DOo9o+o+r38d61nTfT1RNCfF4T/cDqs8rPHGi3VrklbTPU0zPcK8aF578bhLjg0jLJ/68Bqat9U1D8Q0+s6GgJI+3Fki+N8Y5SXvKduTAkjbK1kejdNAkdbWemzgVA533kkmXMA3XyRr7MC5p4/4XnIy9Wc8XT5J8Kr/UhMfyJ238XcN3BQ/Evpwd6d/01p4KePsDmwObcMVLxOlCt7Qcw1Mc4YayAZj3Gjt93CRmGRIkgEMu3iQANglrgvKL5HrB8NQVxoWVrM7kgPow+oS7gV4EJpAayU+SPL0keGCLeRZjBUON61cUFpP+J84WwBdcbZp9MxUpC1zx5i3sy2AAtoQCMHpgfwUInWQ427EhLcS0kaEyaS0kEjyvgo0O3IXSaSY3vEzpgIfIxA0NAVVa4c8M9Y/j+t9tWCW5d7nqB/av8d7keNL/Q/b/hYQgA6ugHQANE1Pw4BUfTZTHJP2xqd/BubgE6Z3TY+OaOIgoKzjxQwSvh1dAaI9SPuo8YH/es5ILR1cgBr8BxQeZAcb+BtVOnD5Gdz7wduV5H5D+lAkz2cK/p3zCdOiP8I9HaC+P8i/3cWX54DazpliOne8+ZHLJ9uuYP4ZzrhoyliH1J7Lz0665HeWA/1v6KHsOP+34iXgjn4o24AN6CLtUlQJH1UxTKDRL7XskhmDOfGlfwByWRRwcgBUASRQF4R/cuLqALDMjOU/xE7gsaRG5SfowXE8MEyuoBt9HzwiihAhJgqwCUbxgYyVyGgN+DgMTKBgflFJsDih5EJeoncgoz39ngzjkRU2ROgW+k8XogSgnVmpYAs58uwfTpyim3Nt9iDK16uhuDKAf9E6D+sf360/D9Cv9SfO+VLspehvwL/Kaz0BQElB4JQ8sPcv7H2hwRIoD/hfdd6AvEh77sB/4Hfc98a6NwNfC8knqttiPLIAaPMr8gHgU0AavlR4NdGd4dV6D+vEpovGoBxv071Z59uDcgKwWt8p3ZP87q2l/nhGdz/CUjnHLLTfLdmt24ObqUQwyRFk8ZuedxAonLLVtnlN+CXU/Di+kgib+RB04JUSSvUQ6cEij1I++R0tyk1gsMwPRthmwjYpLg/TgBny4r29Cd3DbXN9gXLD7JTyjF4PjOhOtnTg+YVIgEfU4zVogISyJEAUbyH/kqM6I4jiU0AbrDEdgMtvDzGPYwc0LENeeQYiIhGkhh/Y4HXyFIQgzOBIFpgCx2CsTnuhaI1LMgsWP4GPRvFQhUDw5g0HneCwYiCNIChYo3AYSMRFK/EhQJXWh8NgSRDHMgWQ0BF9XIxBFcO+Icu/yX+eVf+z3p4in8A+Ggvo3O//AgtKPPjUiX7ofKnYmctcX+kBGd9Kz862LPbKeWnc09nH0A7zwY/ripXtwfSQGX0hxH/w6N/XaOtcdv6ujnT24n8gOx9yPUhtAcr/cnxBiaDKCxI9X7zxOCWnNuc0uJVHxT7PzGm9U5dE3dZ/UJ/TQxAhXyP8QW2OSOigfDELBW3mGQ36rHd2sEv9+PO+Yzr2xwPc6Gn/G3PYfqcDOYfwubAd9W7qfV4MfE0mnopaJ8eeJKNIlouyfRmKPRTt/EjqJH1p6fI9xzM0bPICVx75Z+8uMqI+8aAyhg7gJZdThopE4rMBON9hBbhhkwQmR7ynUmC0wYL+YN4M9gW3QATFV5V0CvUfEt5jf3WC1zHE/dUtoKB5k7ji/FMw756NAoYi45ci4P5AEyWRZeKSh3UXNZaNQEzoSFCRpwhMHY3exoI0Wc2ovZoiiHAirVLMnTlgH+0U9Jkfs52eP54+R/sGflJMnpronap+q+u+wTmo4nf6stewPoiGbjVT1QdpW2MqP6l8wf929q2IfrL1QfDXqr6EfEd+TF0AGB3H2gOiPmgFWAHsO05IGqpC3IAFZ+7qYPxW5n7dxr0CzARNuKaznAa0bKfQkViOiH4yetcRPxbCJ9CekGgH1+ZQT8UF8AkGnCyGzAZ8qhGbjP62xzWNV9kclyea+bnQvl3gXjfWRk4pxXsqSfIvHHzmQauoUdYj33uNojs6MYvqEDJ4MM3zsdzju7qNfSRGB42LsTXqZXaGZE4a/8zRxJOCFV0XWlqh0Fp4gYwBHfGYA/9xL7a7AakHEXEf3UWAZARwj2OQNQzAv0dThXhJvY4jhyw3EK7g1qoJdwWazeOH29kCAq3zpU0AUwgQvAtkgldJL/PQgcb0PS2hySaKmfMEndUPISGoqCh6A0BSGMsrjdtODDbcaGZxs0ZAuJC1wzBlQP+oZ5Ehn9Yu4Tzpl8nQO0J/JHwv8Wd+122MNF/On1WWrpXEQCAg1D4cwSMomvMcpmEnhzIbaz+N1lvje/7hjleRP+N+D4SwErFp8L9uFY0wPh6ALvYVqd/46pMQAM4Ah29njSdE97pvvzrmeA9QeT2vsR+58cZ5yYWhJ7PIY2a9AUX8ifGKfCZJrkk3XIszQEr+XS6X39x0+aW/G5lxNbCefBoXoCoNRyM4x7x35y6GgLzHcVaRckE0PuBFx1edRT0zoZAx8HfKzuKI8n6dg3MDWR3v4b+FYkBHcMPOH96iuxHOeqdTA6qnpNvKdCKYzzoPBEUx8QY2TcfKEuyGLrjwWQqgiAkXfGEP8gbj1c/ctg7jwBbMGSA3cdbu90AS6FkWQrm1BbsoaPxNdVIGHRHPghdmy4xHwySGn5ErP25mBhDkiz/4XmEbxc5hMS6WMWueu59puOQBEKdK90AoiZvCMyNhhKkq1COXkPFVw74R6B/wZnZm/XuYbf9cfDHy//k0D/xny0Q94fgh4U/PmNlowxjCyJ+hfsHx/0NFj7jEqB+yfzH/9vGgS9oPRH9Wc4D81nXhnD/ANzP6E8l6INAfz06gFgl/sGHH/mAaI+q/t588kurXXywbbo9H0XrR/X+MTy1bxNhPQswh19JEf8FcQqF6s3nnrRcxSgux2f/lAMC161IQa8U0skBxH1zS3KoB2va4bTqjyFzFYyr72c3sPtDCF3OfPHyvmts/nUOEPXoCib6tHqLwEAfm3/pNc9zpQEzAZuq6gNxtzpzg4Yq1hC3GFcbOWAb+WAmBgTls2vFOQecWWjqi+LuUKTnoRxgmrcChIOcKNbBFVV4YALoVI6WG57/XGK622gR+t3GEVvQJdSllVvud8iHKkRELS8931OHY5At0BG1XBbsDsb0gdysYQ6CRTN4wQAgBXqYExoCIkTrQ1wmYYD5mBHU6X2KSTXTAmjPBBwjwN+d5ttKGFHQUDF2vV37iq8c8H9L/45m2A7By4z+4YT/CP1P7UT/Vof7x/my0f5hY49c0QdEYkGw+qH2njnAhP+Q5WXsR9Cn5sdGDthWLOkT+r8pDYwQ/0DQHxF/E+v7iqBDp4fQZgxSya8EUHejt6nzMRatbtk/c0DYBT8/LuWM8WmRFArPL6j0l08hfQNtIphJxh3I2OWwz+HYpBHZxRFtoAt5eizDox4Xiu/v9eJ3h4Okk1EELOmMAs318WcUKDxJjPZVkW1uJD6fi9EvMxZ74T9HOwLDvXJA7O6AVOiGXeXfMVOpDJSUMIw1QOQrPH5qQbZGhh4Buv0Q6p/QHPQfnGUJmqOyd52BBo/j7A8SF1gGz7id29Y6JQUhu5RI0BBnxHBhK/jV41XotzAifl6JxW2knRfQvUuJdoc/4EgJC0iCnpe0jF8z3qILvKgBDY22IIM65r4a7iRgWI+4Go1SIl3Mp8yoFqWgCBc4QBB1brAyrQW+0034GoVD7AbCkQlsWnUTssO25WuU7MoB/0f4D+T/MXxY/gMA3cv/6FY/1P5XhX5e3iKkn4z+ZXMTiLhp6LczPBD3l3vnRhiobaj8R2m5jvhSVyA/I8SjFQDuz8EuF/yE7RFHVqiPoD6gku8d344OwFnf1Q39GzGfJnPQuc4lnFe7zHp/Vzv96BAWK1ME7ntIn1jpfyamf48R30KoExffnEU7hGg308ST4njKngMc6oGlsTatT8/92QeMSGOiByKWO46mISe34qmRqQJfVqOvA7OkCa2nHcJhgndFzYG5Q3XjH5uxMoZTTd0OX4op6epzkVnYgSAKfRXuY8PLC8RG5T/PE3VEmd+OJgDeGyTeU93H7kTIx/Zq6AzGS/ZnokYrpsasfzCJtucGee25Dxv1O9g+Fn1bmZYWyAAUCh0+/3nBWuM2Yv2dvkM3JGykn4XupPew4Sq73fAyQSd6i6MPAPUNl7rYbxUmdAvQoV5SS8uCzTYdbqTwh9J6TehAI3fSY0NzLMqTGDrLTAmcIAMHXGmVWJEtImE4U9royvD0GqIJk027DWT/SRRfuNCVA/6e+A8SwJn+nQSA6sMZJPDhBglm2NXXxACD9WXEdxSIyh8jB8Bp4Ro8+leqb2ikSO0PpD4gfnsl+OO4/wbMZwO476Gfw1+o/bfXcSQiB9ACaESWFddG42gYp3+n8F9Mr+FnFfQPuH9+vQk3T9E/uilmJKObWeznz2H5Bpr0SDFiIL4v0+PEMSX53vRi3JBFWlKl/eJLFjUHizUp0z3N52OTzIkNI0az9idGhCgKGwaZLkhirtXwsxWgjQLSQD/lgBFLSjj6g/ECjpL/0yz/x/nNvMYPkyRwMYv54na91CLGszbkkCIOM9yH7qJSq3xryFZvM0V/3PjBdQvzNguNmDST0YgUjZ6g/RnkQf3q5Ly9H0ewabfHP9yaj5u5pUT2zqlPq2pJSPXkj7g/8nR72HgkaAuWUJc4Xs0yXriX0SVYu48+IKYbXq/C1qHdUWGM7uF2B2NcIDaF7fSCEffxJHJkGHEfdHFUS4KBBbS1IMCUDCLnhzEA3dkHLHJNp/zLuyrabRsc61hxcaxY3U60qRxdFk8DFy505YD/3RO9P8sJ/3HZ4NEBpDbVn1P77wkAsT6VKr8HP0fo33Qbfl7JAFutdGDAjhehPlT9jNC/0dN/9AB12jysgHcM50R+GpGf9soR34dzANL/jCMbV32pA4B9y4pf6wNiiQCFxrvO21reiPpPcV/VtEr+fEPcLwj9MX4TlhfW+zc6oDExKLIr4lDrqUUozAciAE4okM1Fu8knAEzBK03AJ+FI5LcWfJN7lOBnY8hxTzf2Afs0wK4IOpZN8ja7DNUY3/WRyFzq7nuE7dA4xX7IhJrtXn986WyyAsoBOBgZ/amXqXJO1SJl3mBjDNwiDm4AhXwErzo/T3pW8mDmBuqLtj+CUq4/ICv0Vw/6dh5kO29TIIjkTAwXSHbqOasal0pt5+Lo30ha4JBXwj6jOaP7EGS4G5AiCMwoIlpukaIEvMHKffQH0JjdR568V7x5Cw3nwKFjQJibarjlklpSY2uJBNAZ4qUKTebbJEKZEBtdKOICJIkvr79glt1KMISTW6BDfhogqHBDufRCVw74O+I/h/afA8BRxO/Efyj53xwFIuivCQCwvpnQQObnPsPjIXLmCxvaAfdw+GvDjFfdiPyPuP9AU7A9TDlgW/fziGpxHIegMzIZ4HIXqkCBkEt9Nhf8GHOAL/minF+ifpX8vX8gUJEBsgt7EsQ8iPLfsd7/LuRv+cmF5YCW39JbjNEfUWZxVaIgaXYGBIIW08iRUcRiAoWmxpHuaSY+QFqgNslhYDvFpq0AyFet6s2z/N9VJKd8wBGuqL+ACI/6BrKw501k2HMZ5kYfHixzU41EUPid7ACCncb+uvMBcgBh3Deni9UHtAMXUj7o9NNWPlDEV1sW9dIQF4r6dmq38vd+1fbnUH8P8qD9gemh+Y6dpwxnDnAFWtdpAtmbADqSQlFa3QFQDQF9RjHcADu5Oy5U2Q2tGCPo7AlG3TAyQc7dRsq9JWSI2sfbHE3DDaULvKw7vE5CpiIow9C2cRMqpf5tNlANc2jIDZ2cGfacUgPdYGdBjAgNBS6Y0wOBdLF3pkoG0XEhUtI3GktcuNCVA/4O+M80fti/duWPDJ8TFHYM/YKANio+wfrGhDmAnqgHjaR/GS2sr9zlRbt/6D0bqv5xtk7J/wMTvwB5qm0EeVbg/uNCb8T6SQKrRQj1lYj/diSAoBwgX88+V73vq3rDxH/CB3C/EoAvOv8clm/D/duQvo/lG87i3r26jwSR86nep9CTEIxyAIv9RFAGQR9CQSOV6OCPZwIdSQQJuKu8xzkQK51oMA2CSTPOaQNgxSUS8WcHEON0kYg7VX2W1czejuhQmUkvac3JTAgcQnM6U0kA4YtHhAIJRdK3vft5MDWEjGyVwvfJBscpt41z0jiKK65MA6tT8abLMw2M8/Rg2phXlS/BvufExp/D+gf0B/1PaBGO4YPZve1qok7BvUycBJqJlQGTbDMzZa8V8gJ+arx5IFK78Zfe+M5ZULeMTIAEz+1yJvfAO6+tIyXU0RxgkT0w/5GWl2V0sxwLiHi9O9iZqExQlDnB8EYOnUWsqMfxarQncsUdmwaajKYjDehjOIkBTwPj7MKFrhzwP43/nOa/nnaZOwHAcsYZYBT+XPhVU5Hr5yz/iwaAt5R4AVI5JgB4vVXM/RrX9zbpPFvdNo374t+ty9Vnpdh/e6W/P4d+HyvA4tEHoFV/uPJn1P6d8tDmRkA+2BVmB3CE/rnd5cPh1XjC+pNC//eo92/fAPQH1n+DlFBxf8T6dPPQnzV3ujgQhMDMeVStxBIMTdgHZK82p+/iHzvxw4ysLgPJ0cH9tu9xpJmawjXyBPIBzvOzW+fGCTOns/eDfOtv83JgkgoTBQrEnPfE0Mxlo/tTlEgalz4DK9GYMscI8mwFxtE8JUOZeddnBTwHQCcZN1+/40t4RMnMBKCGIBIIUt8W5eC9esJAc/A5lF+FRnVpHcngT/g6ksEBfnn9cmw94wOGNVF1w2pYCSV/4bLkpJTt5oWc8EjSd3zlFehQwWW7jRuvsd7sNh7YzdroA+AyawAuSwo3bK2hgylWJI0v0MVAh/DLuZPAwB4X7C2IvkGPRkLUVWMZxorOwGQpoUzgGKVY4t1OUMnAhUPq1685sisH/A+cZP+ZUpzQ/w4B9UMCNPEf+Xomr/qlAtqA+y8c+yL6zxtvcn0w0IJY3wtkFBu9tsqRXwA/KPxtXUf0Jw/MiI8EAJAnasJrHNlU/j9sRPlKcaGAIIP9p5eZUH82F/X3Sfkecs/+8VRXZMUNuP8TgP6X78Pt+xAxwUs/MinKl0n53ljdKx8UF32i6tdUanHEP9DVp885AAZ9CgiTx/0+vYDCFP+kGPcJAEEZSVhcOoa/FNHqXOtYnncQSPMTosf6PQDup/uJEA4nB6HGxKAp5mqnJKFzWuClfYBgMueqU4l5TLComRSl2gcR+lknSte1bW7Umat4ZM2E2n8mA4iCpqdT3mYyeGXU5vHyAKQ1OoP6NWxMBusfQSP318kevxni424DrXlQKxS5MrJzzhdvFfVkTDP5RuuLRTaCeEej5NcjWUAVlDvmopcR8cezuUDvBAnyDbshb+Oz0LkkDxw+3c1TLqMPyIL2O+aVu3Eye6QHixrCTlLWFc2f9cjdY3h7mVoEyUaV2c4yoUBnLtwz5sjiZTh65YD/XgIA/1s4APwhAdDixH9gpevGD0gAKVMDuiDi27JxJHiTIJwLv7BTkUTYyrUuHPiqjXnAof+29oeH/gbQ/yHof7QCkQetvlL7T/p3ZIKtehPg0qDV/d3GF2bBGHH8z+gn7NgOrN9O+9ARam9h+Q5ft+9iGmngC3p/BPd7jHfLJAOSQvxCX4dsMiGgeVk0UcG0roQRjVZfoQ+IpXASV/sRub0cKZb70zUCFt0rTEoh00NqNNFUB9AnPLV/uFX+11OI3696OR1/c7p/DPz5p6KcssVtWgyViUPH+JRL0j5Q5vocPnzSmYHRbKJDMwfQ/EkwONGhKIu6wKGBOOG7tEpCykywgkXSVf0xcpqlh2M1UHOuMazE8T9Dd2a/CtsPsYJDtu33of1x7mp+kwxa2M3ZoqREcVIyxUWi4yElBHT2BOCHPcQDFFqhK+0v5J/G47zF8c7s7Alw7QaT2v7SOj4NaCNKBmmcme9hLwcWBUR1ZCeFdhmYXzHfp41MAP1t5XZiHB9/xII80fhM01ti4kK7ubhYcIhLYwKEi7/ySgNXDvivPDVLmdsfn63fZvlPDajPf8WT/kflPy4XFv6FtX/Z6PmDSg/ofyL0T6M3uD1guQtIgLox6EMAOi70dQXmsz5MgX5U+o8VTEBnvY/O4NXHvqpyAMt/OEBUHzeN1Ud/ZUbmQs/+TuUZ3Z4TIvEvQHtuvx7nsXwe4d6gGaf4h/pxxPokxYjD/SbQH80Bi/3AoI+bJTd988KfQ7+h+GzX7nmZd/PLbGePB+kKe5i4PyNXigck91Nw7/N19W9aJPNX3NROq4NTcNV6PH2wPIIFVxNhcAxIEWKTpoVVbnNeis6jfSJCbAhK25kANAqBuxxG8RBW+XtzW+c6MaLxWq+0hNKUGd8Yy2cW49+H9TcYOtt+Bxq5/XDq/KazKarq6E2MLz6rcwVm4ypKjsXdiVZttJPCWMkCoxNsP+a3ucGW6oaHOpJEv98jMM4W4SR6S/CxWkYCiNxnxjKfkwSRAJGRKI9YiYkaP8V96h5LZkb5z2Q67ohr6dviT/y0mzZPA/lED5Adwp9z0ANXTLtywN/CACsBnFc/euRp++avI/pz9Ddmx/3jpAGQFej9aUVS8GZu+LyBAGD0r04BjA6gEurB2NeDmaCv9njF52p7BfgzMsGo+jeGfjHAfZ0EwObR38e+tO19X9Qu74f+kZlPPHD/Ed/Lt2H5dbh/F5dPlr+FNIPID3zEEh3ckvCfURXfLL8QNX6Rww+p3XvY/eh99Hchvq4mAEeiOb6PPgALdtzcBqh+IvFb5hpePboavb6Tp7J7PzyTumG/di//zeN+4Xk9gf71r/g8VIhReM47lNVEPt2snzuAeVWKT48nxoOW4AoW6ouC7WsJODXlYoKgmapmYgs8E5Br3anjTHo/blQUr3NqrBLtkeHrhiON7HFioQD574rXqH8X6rexfrXtj2GVmqgfvZJzyNpwqXTLCqfnyRixydoKNEJFvLSgIbIFhfXHwrUE6K3uNE+tdhulfo2tom9Y0CVAezougUAuo0RfMmomAERQ9KRGbI1ZAc/c6AnG0+HjAgmPd4mJoBDWbxT3ctqHueEqseNCYWpir+mBKwf8Nxjgt9O/ZwY40f8EApGq9V4j7ic6PycmAAMPvGnPO1oBtfeIKit1Pyj8Ofe1UceGaa91a5WFv6x+6mMcDOurw/3S/yAHPMa1NH17nTlg2j6PC3Wu+up1GnnascHxbeE/UZf8GYX/y6/C8n0sX6y8AOqBidvCQd+RAPbCX5qfGwr/JC2Q5wCTCqgvTADFtBBRyw67U75xTvmOTzIZyGgK9xKBxzlzkN4slbEj4r9h5OPU7x8ba+w4GGbEn3ZjWgFwHP/gAxD9J7dTmV9PhX+fKYGbrvgY4lNKOPiGeGSFFJzBjlykqHygYjeRQFaz46xAd3Vx4m6gxKSeyO4o/gZCQzh/Jc9PJkAwPXLAGvvDlABoVopzaMA+cWvQr8NKHdHrH5wtOJrCfYtn9MTggxF0pRY9AuPSgrdZ11oCokOtT/bi5msnbnyE/YZJ6QUtC/Wjo4MAt9xGMLd7pv9gwjR474Uz34nDwWj/QKdwcFsDw6SIsxSiwIwW9ohgCGBCR5EvvRnZCjhLnHxRMUCh8d/FEl854K9MAM8jYFP9uUNA3rqT1617B5AQ8VH+J1/5uyVQwZz8yaL84AmATb/Y3y7kn64PcHyrdPjpjwdw/5EJtkdfNyd4Hw8G/R30/xoeYAUxzyl/f2SI5mYPsvrp7ZD9WP9oPW/00A83mG9Q+9++B+W7fAb1l26xjOD+Yp4DIPiJIyt4DrjB4oU8MDoDgv4xOvFrqvrNFYcxTl/PKL43svxP7u/mQXzOc+3O/9SK+/Rdm+iKzb/CJpDtEpdJ+87yP8ZpaFHDVPcTrL+TH9GR7QT2tJMoSNQxHC+ZjfLzjvg4L7TDCw/hRfpEO1X9KfhGMJt30tXwPK8/23OVmfvlxOLokFZNByyVgIVpaj7SFVwqGqXoDy+mDqCPwoOVwbic2SDCrXpjDmDXiNvcI9RlLyF9Cffvw6c/x9c/2EgG9Y/glvuRLU8TZzY7g/kJUHkBFrqEQvK/a6htIWFwC/U+34R3jCuOgF/H+6d1qIaQCay3iFmHjnyQFxREox2IJdNPd3y4Cke4oRBNPmeBnqC73tYXENv4DIYFPn7+0hn7TYv7zH6Y7ysmgGiUxWbUJ9cQ2ZUD/hoJ0Jv1Ly7miL74t426Pp7p36IEIPRfk50s/JMM+KtCf+fwF63e6PQM6Wd7MOhD6f+wcQF7Xaj2YdU/DjIT8PO8sbLbOA4mVzghP54DdnsfuT7YaeXhOYoJfx/9+2fE/U+/CbfvUMvnF0j9APWI7519AM7vpqs4FGYu96QKKNB+MsoCOvvwka9wKb7pUDp0/0xO73tZnOUzqXvquewkZAy76/90858u/3Ls8R0NfiuGkRaepxzmKpu/DPJPACo8x3RfO3PCzdQBYGACq02Iokyf1ORe954bzpRGn/1B30FrZYtOiZTYjuQsgnqFsI8f192GCO2Mpj0Ck4Gh0OaWAmBBsXNOMKwmEzrU4wSL+quN9FBYT8CJ6MXu34T2m/D4Y3j9HQGirwdmuLcF+6Sx/GJlQ+TTxZhmhAyiE3SjYDSmatIvoS+5UZ5wp2z0Hm94kFAt252tQ62lwmsIYXz80qWjlh9RHlVCZ6Af7xdiPqWk5lMCMpjGikq2CHybd74LUfP4f11uo2zlo5iaFOYQ2TI+opdY6MoBH0qAllL2GeDD/2d2AJHaf12g0JP0L5oAJwCQAIT/0PqNYBEcAOj8jD1ecnruGAHG3NdWxfqOHACmtz5g9fwg2bs+6P7/CsCnMh8A9nkI8fcOQERc3aboszJiNld6vJnzcr434qM7av+XX4fPv47Ld4Yds0J4uK0lKw28kM6V8od2byMxpCPu01pS0Z+1P4Z7ON6VpqYTETC7dbMR6N+9mnVBDpAtHPs27bRvkqCv9X2zowQgfa7umhlOAcDraNnKcMGCTc8fjnfBdiOYL4IMDJ7xA+YXV9d4SIzKLPNnyT/bgvnnZD0s9jfgNTIv6FsUsVFRB0gRR9h8Zo03jpPittk0iPPwlZca45JGM08NWqEV/0SK6O4AdbEcn+I254qJAikf9CP68/KoxzfKyR64PFpJ4DY0c719F+sfbGSC1z9i4qzXt2sv92QsqqCzw5M0VmvjquaNKeeRK4bvn5irJoD5y0nbO1Qb7yusdIDIFI7k1kcLzqdj6XCrSEr65vywxBluIIpXvdPKo7ME6FAKLaSL2WuCdMn7nzC3RvsQmbYTX2KhKwc8PwvPJhAnDqC5so8JAOX/TADCf5AAyup2QJ4DNu7TAAfAnV8ban58wfeBqv+GRLC1FfteUOlvXzEIttLp4fHgINgrnT5fyQew9h9tdedAgKg/zXy5G+hu7dl/VPAzPlG5hNuvAPp//i2agPIJYM7IAXD3VBpg9Fc+QLj/5H1AuKEPcOXPMgeAFf3L9PmR/7NmdFjvqwQW6GE7ziMJSjhtnfTQH62fZLfTj1NK1u4qewiquNtF5WoMk9XcZrbAs0Kz+m5x//TryUmc+Wp2ft8DwzhFiVn+prAq4uPcl/i2SVPLmKhxc9kSDgErAC6tg6d73Xg2GlIIBa/MDegXsj85SgkhHjRDSMdCzbhzCcwNyceeoLI9E8gKr3lKiXyo+BOJ4tU3QvfHzAHj/CveQlk5gJUEjvMNlsZVL+H+XfjyNXz9XfjhP6El7e3UjTV/Zqz7vnvV/mJ6AvcTRCBXOG8chjHIhPjb0awYRaXWiDRyEUYcybktvW8J7MFLQitTUrlRC0QFlWkaIHWB/ujCx9NcaMXn1t6BU8emZBCZPdz+O+5l0PTOMEqGgAuF8yzxFf2uHAAN6AIRsYYObb7DXFXj4p/TBEAS9A8ICPhPkgkEtoBRuwcPMOI/Rvk/hn9HxY91v8gCK76R5/MD3p9w91yh9rHHK3zfHq/yfcMAMKzBmAxWDgm3h3u9jU/4No0/z97Ob6F/4f60C759Ez7/Jr78Nnz6YnvQh+aHl8tsBRK/8Cm9x/SCzyCJ38jC32b0146XKAk5B7tsX+Fr6TDnOQrJ2ZfEGeI3dumc/o8q6hslG17mN5qJNc8BrflB1zhxsDSwM4jyVp1Gnp330DlMGp0eMBkhNJMF0BPDbCedz75tRvC9iAqiDTOD7UtnkqeELqNTRn8rkwNIc4dXNDmYigWJnHFLnHfjhViSB1aMVjRvDnQPvg4gnhAqUsoz+plGDTp9+KWrhDOraCEQszEJI7qxHr+rD0D0zzf1lHF52GgCRq9ZxttsocsIe8HbS7x9B57gh//gGoPzrog+N19GjWpRulq8/sjmrtoQ/5BHg5MgmwPZZdOnlqX6qOHhhiWZKGF84x6CvmEmvWOkPmt7BLSh7CBkF0HCAC9KpUg0ECziI4vEghJ0yvNFFlBoeQ4OeB8gdEhpAM3fLz4N/KJzwO4C5MiP7R7Bs8hkB5DIAKekBADh/0gAaVkR6ycbzAFgCEBj3EYBRCt00AAddT9MfzZSwA+I/TEE8OCOX/QBr2B61zW8vqL8FwEAdIg7XjDjs7n4Z5RsjXyv1J++1LdPufcb5EfCmyXcfxW+/Bqs743IT1HE57hvuXvh7xd25Q9x/3T30V+M5tx894jv+WL11+nmpjC3L7QyTjtFxm75stlpMe/o/ZugAC7mnaJVxIUmCEuDbDW6oQW8s82jfz/+ZGAIyAFI0EKId782pgFT9dq4+EVYE5bXzu1c3Q5VpKiKNjU8rvcXg030JsyGZqI3UUsrYz4sjBCt0mkx8nyKYHqa3P8OL4crYgmaZZ+G086DcUsNQtOZg2NbMxn4NvmTZ1+cNmmJtsqha+kCUyOX0sDXgcocrGmrKvwR4tFEvlC68wqZqfqA/onVxlfQuctjnFv8FJYv4fYFk8Y//B7OE7jPcFodEY8L7jAo09NMW2xND9BSwqgcBTdwxxE1KGIvwsg38BpKkJOOj8uSMBk/npSSRj3fii2ZQR+uTEuajD++Et6TPfqLTLANqR6AYcMbhwkK51AK+eIHc0MJpQF89AHkXZrRX3QO+DgBePTX9E6LTgNUN4GAC5DjP+oDQmIO4MA+C02sd+lh49JHCv+h/kQe2Fanf9eRAB5kAgDOjsIfw5wP0r+YAqP6E+BPdf+frU7VP6m2wGXufTtJ/t8Rvx79vw2fRuH/63j/jqTuSxD6D/xnXs4vMc3yP90xCTy53xhfSPZq3ws9f5z1zVJxY/GLMk2fcHY4qXTciKJxQrYLzVdkN7eo6w5qq9KXZ7XJFp9my1Xgz6bVKPNnmyp9mgX4uVv0xGno3+cemEQe2I97EDgUpQcXrQI8HKNnYYZm/3aOsHnzsO+tTN5pNe23mevMlCEohzVJY0uOWUFfDthFjtWmdQjcCA/rpJ59K7LMUNPJHmPfzRknQJS6PwbkgCT2Cp5sKL0LegK0JvKhKzR0u9muE63oACLNf0gdEwYEXfxAW5AeoHNv9/EWivfv7fF79gQ/ODp03iEaozcB2qe2Zf66htDvGb0RC4IDijaYxsZPiaag6x3iUV9btPSurcULXuPllqobSVnhk0kQbtqa4+1n9JDLVIiSEjBmCH/rLRyG35u+bDP8HwZz6BQSI0D4JaeB8otNAKMEYMPZzeNol6uL3mcc4UcHELXhnQkgMgHkskYlAKL/CeY/jM3UZyBwjeBvm1z/qfyBB+go/7fNXtEHgAZgoDfK/+3xFQngoZIfuFAc6UHiH6yGpzFLn+CPKN/eJv5z1rQQlBjRYfk2fPPr8DKi/68svdjo7pcXQkAv3Bz7IhQoej7AEY7+vnC1H6SfEv8g6O+GbmiyZd//vKv9DKW7jaojNjKn2zlAhvs6VxRUR3u0tWbcptYjB6TNNSe1+04V5wN8u711R0IcC9KvyN23J4YJjqktiLP62y2fgh1pwE4Tv7vfnA8tzyfWplvR/jx3Bmh9xbncRk+++doDXkUTbJhgFkBno3PyG2AFI/SQfXYM7p7ka3OYWfd8wMs7q6/lkdMJdab8NGks3gn0QnI7aj5MMFrTvsQgUAjmQtZeRvQfaSB2CkaRAL5isGB0A/krZDyjV9ju6B1fvsSXb0ZDYF9/h3ZBPdku5ZIjXurEa/jg6erACTsNqEMEQYshmAuhUnpwkAVkMIolMAHgBm7QVeANA1AvjoSwwGWrRywkILiUZRtHsgk0AFoEvlNdcLWLueJErQ4rrO5KBP1zaEYDUShygdv2C00Dv8QckOgiknN6SgDR3LSFPl47DUAPOEx+SQPqF/Kq2j96AmBtA4fD7tHfVng/j+C/cdfjo1L4b3R58+nfkQDWr4R9vvoQwMat7nXVGgDEym3ueJHkX7HP3m9zTMKdgft/+nX48pv48p0tn6x85hbfF+p/UPhD6Y/an0zA+GhB+C8giCuixPo65rNMF09a+sjHbcfN3X9/zmk2PqoqPU8/dlJ2RnxlBToSR+h26lxm0OZC4znUJrSnapE91291X27Mkn8KS4QOKQfs+UBxv80tj8EOR083yQinkYI30NneAUwFbU0u9EyTVz9yQHYaYIT+wmdeWxv3PkBeeON5U0MAydDS27RE5a40jFULSStziNr3vxdftKk0kJlCbPpqjLcuGy8QDHniV/u2dSUe1+tQSpT0QmhaWs3BRuXojcjMyAR3dAaF37YbeoLKymB0qO0r3hjQEVEUAHTo2/D4z/D4A9DL3YfO4uT5kzs4ee+lfcBsR3Kbc4uLv+5FGqeNJUNTn9f5UkbOBowyfgXVDrdYKKJyXiTvjRgS7uwJTH5MYAWKNGI2HaVcLHTq7UzraOhhIlBITAP1Qth1gBUJHB2wKwf87BOAxoAT64GnNQDiACb+oyGAmQCKn8v/J0VKgCgANW79QN1D9L/J9lneD7R8WPHV19EBUAX0QMlPCdCKHIDQTx74ocW/D6UB1rz7kq9d9d/f7nTcof/yCXr/L7+F7nP5bLdPI/TH/Mmjf/HojwvY9cghgDA68ZEPbnSFXGzKfmKYlmEolgT9x3AknX2jljnc70EZWYo2y6e9xHValnq9v9nWXMUY92vnfmOxAlyrwg8019lryUHkVZFYkB2EPS+IUp7rXEI7xXrKFvukch3O371xTmzwsVQgOr0R8kk+qrmwmRVsAkF+QUeKTC94pADbSdMTqZFFbyz5RyiD+R0JdgirmEiaLJpPOQCGHKzom3JDdvo9ZuvTz5VOG1YmRuRUgdjsoP2aoB8ADY1bLnDlk3woIxaPt3MfmUB0MRLAI7YbZgi2G6bMRrnQ77a8Yp9wXQAQjVw13kufvsTX39sP/xlef8/X9PRuFC3P7c6cwmt88EvQEoDe3ba28WY3vr1v1d88DdVThCiok8Rv9JMbH6nbuFu8hBg24xwYXSZMLxN7IO/ieiGzXCz6SqQeTqs+qBpi0UA/7x3Um81B5OjAeL7LL3CQuFwJYPo6ygfUCQChQIl2/0oAXAOANBDTCoCII2Cdg5s2BaBVw7+j5N8o/8fMVxsR/4ExYCx5f4wm4IGG+kGx/+tXpIE6Pn4b0kOlIkgxcZPrw3ZM/NrzZke1/xBG3DDq9eVX4fNvUKwVRH8O/b6MViCozB9fC6O/RsCcAIAFvMn5OTHu+5dIznya6poN9SHonOrMJpBHFb1QHUTz2In81M3nSJv/OXDMdyX77ABG/ovT4EjDbjaHHpwrnpfDbny0+yA1x6P7HObLnURgcAOGPs1w5Jtv9qwF2lmBWVDrbpKLgjSaFsOcCGOQNQX6Y69ZdPynTXogTmds1e/C0xTHfUPOXKGchPNogyZW69AdObvu1lPCAjoBWFx2+w3thWfDEV2AS5Qp7EjRxItSUJNhsj2KtD0iVcDBgsVHi9uCSS72BDF/hS1VeSD+NmyO5IKK+1QQAVoMn78Nf/rP8MPv4DmhiLtnAthazGirRo1Yv0AhGktUkVvceLGFl/lOGBH/tlEO8DLeVQk6sfuoKVIcl/TmL528SuAcWXTyBx9eCmcDn8PuMFWcY/L99BJDStSfSii3m6Y5LXZVIDIQp/olpYHyC0sA8IF4kwCIF7Q5BEDtf9wTAOwfcl45CLa6DRy0//BypJF5pfMPv5r7/4y4D6x/qzD/QdDvlAONkt+8CXiF7AfIzw+cAMBeMBpB86AD35vvfD+Gp57hC3wVDP1/+XX45rfx9tkQ9z8B+kcaQA4gDUAIKDsDbLpM4hcLY6NmvrAtJCpsBWrb+6QlBa36mKj5B1vyfBX7TRwvH2obH+wOwYlxdqmTz2gVLsdNOyx5oW8e62dicLGTQ/99Yl8M+t4ZVC8kxTRIsYUuoU5Pm6kLqubK+7Z/2ucN3rLBbjZ/KPT7TA4tnYVApudB+ymlIIpTCFuzdwZJGy7T3IBWtAfNvfMcPpK4Nvtueyu+VFncO3MANrZvxZdxpiILJix3LAVbF8cNktMzxHaKZyM2bdzJknynZpg6IjcpooEO5xKiL2du3NxA14fR/GXukR/tIH47JsjwS7GYGlehOWiwiY35Fcmm8A3z8q39+f9hmAB08Wkgy3VcSdad7ra0b99Wzsb6DFYS8tyWZyqyDjoAgDR3jJtBPYzwrL13N9C8kCfg7x112OIlCiW8cNgw7higLJQ22PsiUWernMjoNl9XO6cBAYaMEr8sP4lyJQAlAM4AU/mDZR810wRipIGcuAgswQIoxhV8JdzfRuRbmQA4/0Xgp/a64WSkf+H+9ljb9tpR7D/CK2U/r5wGWIn2yP3twUlgOsIzDj4oeJ/E6Q5l7AvQVeKBgXwJX/41fPcv+Cgun4nYvmDya/mkC4z4AoI+mQ8AS/c5EoO4X+16LNrebju+0eOTS4/x8YxWnZ9es1mej96lai3luIqhvG4e+hnoo+cAbrHvE4ke6aFuvuBMRLeDXfPbNzmAXDHGg/q01dTMamsO9dgMIk8rcU569jP0/4T19tOR9F42MDcV9zliPTEWmf/s3UCdNIATuWIOWPvX5DSvIH7JaoHwMEO0ZS7dVNBfuK6LdnvtNg9mGrHBoXOkB5L2+PFY8LNIGOow0vTmizTmCwLSz9TxAX9xfluG1RzxQ1ex8DW6wbx53HO9Q7NgC8v/u5VXdANQji623kkewE3WymM0l+HT9+FPIxP8P77EZ/2oHc+V8jeQl7vT/lhJRhGQCCS+nSC07hr3kCHS3WiQZ/0FtQV+auH0bxGBF7CSLHH4C/RAwcvU6RYC3QDrFVDjJjPs3koyZfrdWuQAVhkXku+EIF/4y0kD5RedAIISQHMeWB0A9f45MQcw9AdPAP4F6aeagI4VYNZ84/sGAegm0ec2an81Aa9xlP+vjP51Gn9CA1qRALZXd4DwdrjhfqX73O0QnnSfc+J31P5ffovz5RsrL3FE+RH0byz2lQMWqoCytEDc/AW7N6x+pASoxDSHfkN2H7d9DCqerCao44ysw8wm2cu1sSa5KtEeOtc3zhltkaumrHPnQa9uaDq34LoosK2e5IQUBY25ekZxd4FYp/upxEU2M0T36B9OhkhxgkL7Z/uNXVLsrg19cg0622Se8H/VhU+eEukEu09oKO6KfiXO6LvP4mQFxBMoN6Rd+cMEEFTjs6LPPIhvi3UlA6Jz6hsSVzL0BXj9CNCFHUC9cR0b9rJFRPDiiFMU8pMivSumfndPc3xsAk8ob43sYGi/Xyi6xyMZHa8VPBikoko+YLxb8itq//EW2hZYT49kA2txUhfLgjb0h/8AXWzh2YV0+izpDTYKnTR7Ak55mc2ValCvdi2GwVtyo9WHWFuV7OwxIUvGYx8Pt4y/705oKGg+nn6B7HW0fz7YuQSIxCzT/tbggwBxfwKFfplpoPxyEwCgyh736C8UCLIfRP+8AAhyN1AQAJuEQFr3Z/sUGMB/hn5IgLYHCACAP5z7hQ3cqPq/wvJhXI7j21fmgLpFmsSFldO/W53IDytixTI7Lfo4r3S/fRu+/5fw5Tfh/oXhnq4PRH7CjUO/SACn6J+mGRw+scvc8Ztp9U7QX74O0sLbqXzutMREjVa9I3E9H+EdgLnaXO9ryzj6v3pW4Gp7HwiSwMmtC1a48gsCUvnvtX9D3QfRZ/V1V+G093gnA8K+/aad7OT0GW7PGP+e5cPJr6LN/ubEA++h/1CLxqfOYN++28/Hd1OH8rR8TaohzxNyz04urlVzQDQ/SkQUaZcWlRW4ccFGoF8wpdFvp0ZBy5np4A1gHYt6MLmN0I9UYf0eJS5KiMtdmaMVblqes2np1BbgiJzg4mz+Cp9AchLIQzduBxMHcMcwQYFaNFQJhO6B+lEbmWDT/oDFxsEv34Q//0f4A6GhM+DuUM/qTRLeVMtU7mLVnguFYfIxTQ+jXvo23iqRY8ZRs3+9E5skOrRgKiRwNK6PNJhsF+5SFJRkF2U+XJ39VXXDQdnWPnUDpzTgjPpoLX4RaaD8AhJA/ssJYJT89ALKeZLA6gPyGjkAHNMKgQUEoP4F9X8n+l8boP8HDsntB9Gf5w9ufREWtJINJitA9WdTMvANMIqwRtjTwnMHIHIPYpLwzb+Eb38bPv0q3D4T8CH3O0I//H/uMn8mJ3wXFuTcr/v/LHGHnqUwCemIj2erSEgwpebEoksH6zWsII53PH4ttu0UMvlaK4ezkAnqvs5+3qxzskGLjk1tAVsfqT/hfbZ50O90IPAmTRMASgM7dNOPfHDE/fdUr71dlWPPn2X7kctP7UAMx5LCeChx96v2D5Dts8TqDIqmf2kilKdbqgjhEZELd+PcXH+lmYDM+CsCADs7s1Y18PgiQyesYUFJrjzBOj0xBCNnLBQXoSoflTs6g8z0s4Dpid0nzixPk6IUn/IWnnOubjZmr5bximhLzFIw/NX4ONdx58WNo7fsfEbBAES44ZHE24uNNPD192QFJkwn1V0i9dKbz3CYyovilH7jdgSJygIpsUbrbLShlI2OC6VSFTveZLc0jixYWsbOhq9fTu4zhSSHzo/sPbGjZC5a1a6B2Haj2SMNxGPwOfnaInQD+WdPEZefdQKIH6qAWHYiuiQOAaDwj9MFKJEJQAJYo3IAGWANABt8erYu/Q+3f63Af+pjFPXruq2dI2ABM19r+Mqh3xH3Zw5wDkChf9vmALB838xVLufy36tLxoKXb8I3vwX+8/kbhPgFC355TggI0f+OxICI8OI5YF/3mHa7t8TJ1eIB6+DLpvsmkP05tSuqtrqQI3Jh7B7xMVi00Zyy0cGicc29MQc4H/CIBIjIBvPPDPh7o8t+qtW57SBUNxhodgT32Nw7yI2DejhvjD3GukN47vjDU3n/Ft/5W949J+TIPrxWX9sHFMJuGgFSkzMEgc2W6FxdEDMswCdxYgDcw0SE6p1oBkGYroWdN+j3lRVGOi93JBJ1eDCBgBe/dSaDQNwPTHK2nVtOc2pBbUFOB7cUKTDjsgeDCQdF/aPVgLfPSlaAGNToOUbVXx74tpEVGBfWG+wlNrIFo9wZvSZ8Rz6Fl8/hj7/jGEE73KL6HMnuGijpeGOL8bqZq4Fj91JgwZswLptxJJDioGa3G/2hb1T7Nyl9t0ivr5xcxXaIJmjfTTkpEDZMr0yRQNOuGWWoM6K4v1MmKJTBgI/qx37GcwM/2xwgK4iPE0DYO4BR+9fMZQAQ/7ADyKz6c/IZYEiAokNAXAKDBQBwgNja1htWPz7a9goyAIU/MR8E/dWbgAdZX5b/wH9wZAoikQMeMlKf2v9zAog+/zli/bfw/IlffmMLAZ/lLghoBH0wARoFGHXi7RO2OSIBQAZqk/WNO+4f53BTeC6Cwm7OQz2PckDFcGnkfhuU+V0JzA0pbV9jKUJb6227lljxRxr3mwepQueGS6Ohhtqd5nuyQtwboB3PmWgYIul26GKP+B7fkr1PXsfx3ZHwN20TfpdFPrw2Pt9293d7pppjdpWR4xQnTyF8uzifDAh8CoEsTxqgsCcgN4tGgT0BGgLG+szFjYmWrsbOILGBGFctN8BEo4QvN5DM6A6z9nq6Wqlp+iwd69vEeGdqqhLHcF3eWuKor0e5NBIMss4NsqWGbXEgBvIcHdjYf3xlrzP+ojsZqR/+ALuhUSWcF0K4YrVBL9Sh5Z2VODdWzjaUIs5OS6gu/3VwdvBhMa0xSFhl0VCzxO4D0pGuTeSE3e8vUCIcuZuh5dM+iLmFoieVQHb+6E1DpKSpbKaB8jOeIi4/1wRAK4i/kAASSWCcJySADBJ4dUogEgIKvs/b7IElMLYngLrSARRbwF5HGjBMgVHz8yDo3zgSvCr6fxX9a2JH2779sUlvM63w30g/KTT89G347l8BAd2/INaPkv+m6K8O4BOUP8snzH8V4T8S/9xM+I8qTZi+5RmAorv292ncJsq37YvC2aDUqlUk+Cu4wix2rqPaFP0fNBiYWBBFTVHOpkaYCP3BaNtfg6YEHOep7izfNxduHjsvt7dKHrNnSOcvfvric2iO4S3eLwznr8kHPxb97a/+Nh6/CKEtecXdfUUAJwkEYixTdJQPaEUAkejWVGJFIrdGljjflAmw4bmwA0gLVZt3DFhx3A+krnEXUKJHEBc3At4ZN4jkGNz0iS51mLDd561EbGTyB8n1nbIzGi0FBtmYkwruxEbcX5a4FVuYAPQ1Hvao/ccNxvm48f0zKpI//js00Oe3d+9Td3taWCYbUbwv2mmjZXeHVF8dbxEa7tHKYgslwzQ+2TClgryqwz0icu0wrzAVUvs+EEX/WGy3EKfBYXTi2kSHlac0IAcRGLD8bNNA+VkmAHYA9AJ6VgHxtUYCAAMcGzuAqg4A51IEYQyYNIAgIFTpa2cCaBz/ZfmPWWCu/x3lf3h9rRwDRsn/KiyIuP/KhcCQBmFHGGLlxiC7Eg8R1B5Ozs9n+nd039/8NvzqX+D9MD5LsG35NNH/T8wEdxf/aCAga+Oj07/4BEr06dNe6bQk1s01Iwt/1v6T78Uj9CVQ7lhXRVo8fHuBn68O+mtTFWCcVxO3MVqHLm5A3QBnfdPqlX7QuANRJg+UdYp8dlqi/6Ua/A0a8z4HxHetQPxI/RnmMrPwEaPwPsTbR02AffRoz7dss73bjWx2wyXOPxvd3+IynUQjXkErbiwB2mbxtiCTENa4QBQ/jGFvesHeSAncUKePnqBztgs54A5PaSiDC4Q3gZBO0szaOJ75aYCo1NwVI/iYNLKCVjVEV7smeQHR/64uQKVqwT2M86K9kmwORkoYOWDl6EPmwdvdfvfv4fH751qnTSun7qMn6GYap9VKuEV9WPFGiicDKMFJtAgFRn9Dekh0R2LXuMw3At7wWzos9gxTBgVoEt53lQnDBathJwRcKHQ6RrA0aYJkxBO4ofwcreV+hjlguoG+TwBNVhAp+hRYVOHPBJBh/4k0kOPBAfSwcg8wEoCWv9ABdKUFEPfAPBqln+wA1vD6FcSvxD/cCkBDiFdU0+P4Pv3bukshrb+NGtIXvnwbvv/X+N2v7NM3I+7H2xeo/u+f2GJ/QT4YlyUJle9bfsEgj7t+Cv8pvtFlN7zcB812NzftoPdl9C7wnzuK17m87HVefsUwc109MWhleduOCyr/g6YBtukCNIX/vltqfuYd9581oP0UP/su0J817+942uPy7gWxIzDhOcqnj9iCPo/t3/YPbnB+tGYnNe2H3cPZ3iM+JSolvybNUpx6020OE2jfwHLoRIHwJCl9qRpitwe/B81wyfaHxzu/HfVBZ2tYmAPMW4dYFpO9aDjMwKN7q2r18XzGMsNgntZ1pIsR3wsBpSVjpmwjG5GVGGgzBQaixPIV7p7jlqNj+NMn++N/4O10zBCI82cOrmxMgSwpmkc3cEEOMzeajUJNA2VC4+CNLYJxrU+v9DSlb6rWziMNRP1NNCEyzawFHxGzyQ9r8nGZ9HUUaXGWCpEiBqcgh9Ft264c8A99WqYddDhbQTgKpA4ATUASE5AQ+s8JYHQAyfcAbya7xRH9GzYAAADaNpj/Q/gvHhgEwFfQAOGVCyBfUfXTARTdQHzQ/3mdOhkNwjgwMidvj+DGoDY+3l9+G379L+HzrwyFP0p+W0j/jrh/u8HVvbxoCECbIGOE/YMJJXB3AfqR6TPcTyojoPA9Ntl5TqnPts4gvjrc3yhjrVpijBwQN/QB5tF/MgGNAlC/sJHX3Q7Jf3WHHwL65tYOdja8e7fu+P2FmA7VTTzTrd1FmU+RfZr8xHTyUdvvMJ9u2d4deZOJ99uYvckBMjE90J7mhWoMJ6nSM1ltHyUGp7j7TkLOrWGR1Gj2/cyYG3jQSihDBaRZsz5J/vGKj7obOQBur/i2vZDCvbu4qMsp9pM3DXIHAs98w2CwUT4krbD2Z3IE2uJU9GsiWrEzcsBYRj19hNeMYQKW/+hCxmduYfdZaYDBOQakh0RTvDL6A6oV/vT/hdc/z7ZvbwiUp+eWiD7FvvIO6XjH+g4J2FAbWWJ2A+Prxbh1tKd+q3h8tzQ+sLFnLBpInXs93edQuBDq/DyTndrQ7C81ZAjRk4TtUrBpOMh9A3AYNfjC1ysH/AN3ANgNZLSafZMAuncATAD4ymvJEwICCcw0IDdQ0ABAOkbzxwXwNIEYCWD8C8wHCeDx2h4SgH4F/kP3fxMBAB/QUfhvQIcklkdsrVNsM5vftwRAArDzm38N3/1r/PQt0P/7p1g+2/0z4r5U/+MI2GAaARWAP4B9gX+KLfTFXtxbm9wMOc7l8p3uDo3lvwgJbieOVUp/Li1wmvcVR7avvsS4kcp28Ec9wcNDv+ysO5U/Yd9ss/vEke+VOvBQ8tiPAOjn0v5kjPwU1k9pgOFqHj9fFU8jXbMh6G84gHTcfRQzkexc46cDpI5vav99sWI4jyk4rz530O2i1fZMYvd3PMdzWjK6HPji+Hx0BhroVcDCi7vbuxIRyq9e+0Ox84r4i/1cJIeg2uIul3GD8Y4CQ3OHpogNQbQFzAEWkMl5okUCqFq5eCJW3CzPTD51nIzrGEg2mmbDBLskq1Cjxi1DfrrR42jNkOuMTLCSgh53/nIPf/h3eA21emqPOBqckq/vGzUYtwKHV24Bwstne5YFISA7oNi1Rb4rUkfasEYkgCVqSX1BZkqBjHDwdUCR9aEvZctH+KNLBPmCHt19xHfI7S9foto0/fy2j/18ckDJeXYAewLQ5FN/nwBQ+7MPUO2vBBC1nDs8TOX/qP0bOGBYwG2YAuNgF3aBPdb2+tpHuP+BK39JAPz/7L2LlttGki2aDwBklWRZlh898/9fd2bG/bhjF0kAmXlz7x2RACX3uWfdNact94xXNZsqlapYJBGREfsV1w3V/wZnUFCAHqtVf2EAQwFbPuP+ewN4/yF881P49vtwfWnLe576X9r0DndmbYF6A6AVRPYV8KTw9xHzm736J7PB8aN3VILHruO5QOl+usfsQtoPHrD2V8wtkIs16z4Sptghdvaz5tXfZA2rnfqVbN6aGRwZyaeYlVtrX2zn/Tam0wY/HfmXB9GPp3uIY4MWXMcXK8lLMZYsjqb7msi/JNpncwCGIu0cwlODie38OvBisGwRAyqsm9SjQ+yDusoRIVXf+CvEmH/V75Vo5ndBSV96HnbvEGdDhc/S2+vRaaxs0ZOuZtMkS02WjCTK+Bcq/vaZAoIL0GPIu27c+byQrPlgY7hTPdC/4BoLjR/aBYkCYTGYAaAC88i0HcqZsSzJmzJ24k3+1c1DNLH0B1wcJSfu5/21/1BShvocgGNKphEp4QFBGr0z9W7UO8HDgeLBHE18wySGvvUhI2+mDL8Ua58MGgJVlFCB0AIc96X35628q3Kcq3lIT1BVe8PneJP8vdbkqG0zXPG5MZh8TJ920yi2gRgtdgYC53+WSPp/kh6QewNALNwA99vA42wFFMkCIhEop40NYNf2n54Qa4xbio9GHUAhFIwkSAIAu8QAOC9jDtjuZV3tyK+6udIQdHNToD4QiEpvRKDNj8b1cwMDXV79wvjmY/juT/Ed9z/LS7zY/if2NnCREAw9oGkLBOrnhZ4/sH/Q7vWU6BsOYQ481BHhhBQnKbw0lxTylNgDeJ97HqaYxcItUO8B642czvuBDZiS+eETwHoi9nDE0YVaz+TO39rvj11zdEJ9csudkMyKJy486Ccj0uTs5syzvj4qjMW2J5Bi0S2e2Y1CNScjIVo4uwweplOM+3mxv7QnsDe5k0h1MslYCiVV58acE54FSV40qlWRDTmThyR2NcSbm+v+FtJ5P3o05jmqN56fqvpEOW0Ka5SFXzaLIYhbVmR+FUeMoTF+8A7XQaCQMka4zwFAkh9Y19QrnTwWQgv0Cl0AG6AToIvPpOVwgVPoXNTaiWxlK/XGEN+oJJccLUKnDwGcEjAH5KSPfh8aZhCNskfu0NSov4H/+m/h8YtLyYLFz/Uv27hem5qWTuRQDNfu4VDaTECejkDLEN0GOmEZNPcJxF751KZURzPju64aRMTVEFOHSVjtR8EU2zgHnF8SztRcCrWRRfzP0Qb+GXqAxMDPDcD3P0cDUA/Ypt4AshoARAD8PBoAhgBSGpuSIMsmGfBaIANGENhW11u5g/pZSf4BBnBnGOSDjkCb8ICHbdg3bv93yqzqZ8f/cKj2l1eQfz5+iu++JfvzFQAA9j+gAIn7bz1g4m53pl0XtD9UmaITDLs3P7dQcWa0H7F9djI+Vw4ou+r+PcLW9OYIsOj/d/J/bn1EQCdQ5KxwgvIwr385/6DePYzkE0a8QfstKufznucYyZPhgRbAu8Tj85I1RYsvhmH89ERnxFnUUnmjxy7SGhhlhlqnpO87GkBSD2jx73BDmx0Mg0ewOJAyDuyKHTA/5JFTZQsfmqeiELHdUvWmZkCfJX4GJ9wt+r9qo2tWjz04HO7a06DQxqZITZFOSnjGVnYFt5iWrrjS4ae/N2aOBdONpOHe1CfQxna3EqlLhBmcMn4viA9jhgxGTO2XGo2JADNkBXe1FA/HKlYOMQ5itQYQCi2dd6RmGlMIqEBuD2rU6XdN9uob7sxkmv7yH+GXv1I/OHRkxd1GyaPt78ahIkZm2H7ERYwmWukWyjy5yGWRuKSFWQRpWPVlT4bzNpDicFfNNB7FKgkX7GAT1HZKyrMjgtyIqATnNPBPICGe/ikawJSUCudXWLRc+EIqNs/+0ARA/8UGQEs4u13lBNfCg0ZAW5Ud9A4aEMK/NkSA7fR/vq+91tfbDf7Ptxtq6L03gAccge73Qwa8ckOyVff/KUf277H951713Yfw7Y+0f3ht13ek/7/HpGw94BouV+x/4Ait/Y9hv3R8M6//pvPRoZutHuJYrPpr9c9CT4z6gcP+yqV/P+wX8pd2TTB3sj9vnGPYA1DoOdOYwedY/gxVsyt765csSSfnNafAR9+5iP6UZh3hVWtQNbTtSVOUehbHe5aPfp602+TDQX/hkZGSzK4ZcAp7QLZlBRtAMhfPSLaLTwPnHlDbiUZ0evxRAgqr9VSJkkeSLLUmMzuhJr2yxNjpaeBxb1TbJcCXEbFodFTlsqKxH8DQMlI7bTkHHBHaiEBsJ1zhRDpqxVMNFNSV5HtL3GXCS0O2D0wX9oWKPEX0rJwJuLtTpPB+bfMaZs12UIDHpX/+2vo/jBdOAxenck0NvuKJwaLRt+pjmMtck5NvlziBZWoLRBzCpigCY8gc73ov72Vz5ugwMwdtAWUo/OfPODlFN6mNzSyvd6+8kPUylsCWaaYQPvK0kQTWW1ClhWiAUpKNon/3Xct9XCOgLw0oyNaJDnizyQJuQbvbdZaSoVITYBTNjmjEEfMp+efwlftj9wBKAcwOyBPhPVmCPUAYQBYXKPbDECcAdALAv0kgMMMAmAX2QANgAgBu+hywygsIKWDAAB7t9kj3W72/0QV6DW+0hbg/4mNrygIDdiqivRui1fbcAFjF+psN+59/DR++0+o/9B5wuZoTHP74CusV2MBdI3OA3f9Zts9ye86eoNqMa9QrDtY+xfRoKP1bVHzxzs3P3h8q25Wya7D0vzPcmI2hjwV4/DcngFLJbJ6mqynIpGpuB2X784P/gev6cl+n+8zVDb3qYnI75Wky/Wpmle8VvzJmiwWD5/0pQusAA68AiiIqEa/dKWXvAZoAuDvS7p+YZrCt0RDHqdAb90PAcRsIcU2npfxIpWdva9GY7LutZeiu17CnruZireM/SFeBVb+/9BXR1NwBToUGyGwMyHFkxWfoQjNvVEyK2D4UsV8280ca7ngHihCOZk+Ill1Eil83pgbRZSVdp3eFG8Ui2AvFeicU/ALFVp8pCz9m8oj6Ow0Bwo84YSxgmAyWSAz24ligZCFkzFFJEMMxzzWuyQUUay+UaS60E8XZU5tngMZzaitfbgkIHpMJDvrXLJfw138Pt18OObEiaIJnTWb+rBWplr4Z87i6wcoteC2SKKB4zSpdD6k5jjDFDpNkEG1stPDwhZyp6wQPZeKCSMqxI/YAv/l5HmCuAX3l8ra1P7Ro4I/dA2ZpwdpZXVqOCcBwYJ8A0jZlHf+5BeL+R0rg2Fa1ATUAukADDl7Xfb3DBRqWn30CwJG/3d/IBWIMADJh1njXmXoHl6bIY0cBWO1zDbAmgP6+//ZT+P6n+PoR6/7rK7Y9L688/hP+xQoIi6CoILB+/J+s+sP4gQW0HcHuwaxzGcvHI3wR54crILJ6todbFZG8tKH6w9pauyBaWJP6+WbMH2EGA++tZ4v/cnq+zwwfh92s7idLueEkHsU+xJZ5pn/OpOhEnvfpht9/tZr7HSWlEJBERUvRSn+CWqrfTtz7wBWAYz6mAcx9CuAN7ATGbUz56EOD3RJOTCHfLefnjVAdsCBJPv0oL0OBgoVUP9ozNK1PALLLr41JanVmJ+CaiIJCTQYlw19cTaIX61L7cxt7l9i0MmoMUONkgPtxJcoyZwM/tWqTXVLQ2f9k6x1OlN8gSVd0uJiSbKUc49ywQWk878QJVqoH7mgGusX+Z8M6qNHgL+A2Igh+afXKlk/iUKPZ51TNYaIle2KjG/U0LuSzZDiKYubxHwhBiNrvo2ZKgOYxZ5Gpbf1V/XMOv/4n4QH3sKqcBdqQ+2V3NJGRVIma/MtwlsUUxhO/Yob5R450u8i+Ef53m/HlNKE2ox5MLcp7jvIx/QJ6kskybcHZpG4gFe3nSDv2hxYNTH/sBiAikIUCVWcBHSugRDsgMNbMCsLR4LBJCJbCWjEzgwVEL2hGAa+bYiFhB4RDdEEPQABkE/3/8TA+KGW0bacAeJPIlvXX3oH1Kf1R2S/91P/x+/Dxp/DufevVv//x6vufy9EALAYgv9DsZUh/x/bf61c0GBb4pOJ5tflBlV+bb/mjmZWy+j9Y/RFnf49c/qAr4NR/t72/XB+U3TQ4P6OljZCW88b/KAfJk1JodCrWuXBvHFf7b8dzPWO2InOME/SlxAPQKlj0ccafWNb7H2F1lxDRjlvm5yYbCDLPn5XJukSVOaFnkT8sBS2lWB2NSJZ4ng631BM6oPN1pol9G5c7s2wTsQE3NuChD89GrcIheR97RIx9Zl9TQQbgUhryEulM+jhV845ZoawFUWu9iu1IbUTD2FB20y5SfMsr3S37yWQ5wpZtMtiPmeCsPms0YDCkVJYkcpvYTLfVX9N54dL/Cofq6cY28KCM4NH6TNBL/36BKgbMoi0iYn4jZQj0IZBwSKNh/BnHstyavavtyeb7kcCvMOGJsOyMOwSKOQRsk9GEJn4kwhj4J5cw/zutp7cDBREPtDg6U13X/cj0dWvGCViTIWEIUku2LeMw6K2KLq2p8E2If1kP5qsdFPj/GUSofkBs1aAPxdN4rkEY+cN4xaPiiP/wooE/ag/A+f/Qgln151qyik3gXkCnCUCdIK0SgmEIkLA1GAUIIPCGCHi6QKMBMAsMIDA4oDQCwhZoaMGYC78R/hWsyj2M0f/rMwCghL/XD+HTD+HDp/Dyzqr/lVsgLn+IB8gHlIYQWcd/uYMpWJxBj16LWKYbFDRwbC7u3b9pkyPmEoMK7jjv07s07jQ1QjO4kRqkNsZ+Vu6m74XCazXg10rPbpZ24ax3DQdIqGO+7mT64E/5lIjLwz7McKhnZmWP2DLPjCVBkeiXKHRHnHKw/8G3mpO+kmf8RDZJpOVZ4i16BjABXuI4/uWURso4Vz3aDlXTvsZwJMj/hnEEpak1HXzwZsyyoEG/nuCW2kZXqNrjQ7YUmKscGHXS6tQHh4hzBRpAKRoOIqLXtn7qmJg9wa98qE80VPxVX8xTeaHUq5Ddr4Bl5nTW6LqE9qyydkxIu0dBBe6wRucJvrL9fJBXKLaWi/EFpivfSMh7aL09oC1dMLXMC3sPRgHMK6036R3GFYGtHT0yw05OxmpJvJ3cbEVE2+Y9KswrCrA3spDMEKPdCcGAIgagxWVuf/4Zax+n/9jL1iebPTOEMjjrbCbYRrIOrnyXYvgcQL6W4eoleo+Hdl5JO+wVxlEgdcTIaWl8n6d3R2VETRvxlHZwSEKU/tBs0T9kD8hoAFO0y1Pp5k1QMCeAPTkXKEd+JFgDYQiI+ED1j9oCcQjH3LsW/oco4H2nCEBpMPCBeLvF9VFH3V8ftgXCcZulf3ebHVkAtfYFAkwSy/tvww9/Ch++5erft/+9B7ywB2AUkCHo1RLB3CBM3H+XCwkSq6Zrt1h2ab4GvWeVVhnHf2x+cBs3RhlvrP4EflX6zc10LH/k7mCcn7HIKl+QmnwV4Gw/7Kx0/I9giA+Hg6gVFuKLp5QuWPr3ok+Na+pHRKSoL4n/KveKz+UPF0cTlP55wsE/knWYtHXWWompKCwl+FvgQryUIw9udjXHOnDgU2RM/G3joCfdlnEyW7MIcsVZ6Sloqjp8asTwUcgZ636zBlD0STWAiiEAPaABJKBBUz804k23V2Uq1A39oB8lSMBtMxw4YFVeOByIrabMzsiNTSgHK3c0g4NHxPjEaDGp5A5tfAfOeJUnJhPAOwjcZYwa053q4juyYuaX3oriBKYQ/eYY+wN4YGuLZGXUlGEeZeZMH/LAR/L9eqaUQTBLdYYo+ELEe3qdTGMI4JQgZ9z+mf6dHjx2MyMz/HxWDzRzEe/fdde77gHy7maUkGYqE66hNBZE8ZioILb5IMBXbkNnXjBZ4l9uFqnGM0EvC9W4yFxT5XBYZ/jmJzz5hvCHBE0D+Ipp+qOyRf94PUBM0JSss0d779sEQBigCgmAn1XcJnlCsPqbDoBWoCPbsF+aG5XAG2mgj0cfAjAB3CED3nsDuLOSkglKVzgaw4FBv9IQlFnwsFUohwHWWQWWCIR+/D58/0P85mO70PUBbeA1Xl8hCAAe8AIEePYJYKJjO/g/ljfbhjdONd46ZV/YLGvpTxr1cCrt1f8WVPR3dIL2uGERpH5AHQA+uPpv6hnNZwhtn5XndYQZtBO/02FtIROYUZhcGCj/0dl/Jm7R21i/0GlonKK5Xaak+xMJ3JgGUsYcoN8UbSCDCYoGgAkAq+LIRX+vId4DUPilEdAmInkH0GyfY7T83HhQWMLg/sS/Fwlw+mwcmx9xzU6blzYWfJX3mw8BRA9R64lGwp8MuoFK4TR7w46/jDj+l34sKRg+iRVjBFVXyArgBDcNdyopPdY24DtbsEspu8V2JlK/iC17smZ4gsa0KoxRPHpCCzPeJ6i5O/eKvRs9GBC2Mh2Mb+b5gVCw+hLKi7IicCLBaugCtUEjl7T1NnABihMpx9ULgcN/tMRKsLPI2Eza1UfSesGkIV8IrzDJQtkXR/IrYtvQ5vAv/xZ++eUwudI7HwOHE2prePLbKLsD5hYrTQOJYpwJ2kKA4vOg5VDkGSMZnL2by5RooCkaAs9EZvsddCv6LxZBMXpujT1Eown9Idmif7AeICLQYILG9mwI2soxAaR9wgpod0XYxmCAfvyHJZzsgOgHt+6VOPBWHrVPANYAHvCEKLT+rwMAuLMBrGwAD2ZAPobbvhNAvzSB6DP1xx/Cpz/F9+9R8V/I+wQSQD7ohYowUICgAIDv/3wRqSMO9e8AoobRUCHzR+KDna1o95CyB4/8601pNjB+kH/15kZGIH0qyJ5Dg/TDlvlVDkbKU+qW7/qj+1pnrmgSHWxmnfrhXxY5tcR8SXS6jxKyxXmalgRro4Uwb/+yXukxDWQyx60H9PNh6m0AHQXTQL8+MQdgBogwqNRmhzTQKLqPnfr0n+IRjY7qotAUDzaW2cElX2TV35IIVJvwo6QBzT5fh2ar6djRyCmFaJUveG3j5WG8iaYEWtvsvIOwRKbn8rzPlETIENUDQBPac+M0UL36V4SU9jtp32q6h3RlgPOjzsxkzphdo5F0J+NrVbouH0rj5uuUStV0s+HAQNveDIj25xVC4j4KTL3ckzmKUBqlgfb7L00hoPVKhBbHhYZOUCg02+O0eDoFVVQHawjmE3Sd4OQGS1RKxtgPYuIhW+8ojHYUl0WKAcWam/p77H+Fv/3nk7kQYBc3izriPJtRetBOSPIRSxU74ZboHKREycr3CTCDCHWlzu9kjcXgBhT+4OmoGrKlzuC3EkLAhiIYKKr2CwY52KJ/PJrQH6wHTGci0FMDqN4AIAXobWA6lf6JAECyCYAac+WCIQqMTkB7WRELX1aFwmOHXrHulyHo3UyhhQM/WHNXxr9sIy/XT15jXZ7EN1jC9z/2BhDevWsvPP6LBdRvNQFACPZKMzgBACSATtr+KxMjhqFY0vFfjm8KIwO/EzsrLnze4oPbfwstuLHoEwnQEKAcm/1Gd6DNLIDCMOdy0udn1R838ifg9QkOD/fy6gE81Ecztb+0ftJfUPQjK36aLgmK37lPA70r4OzPlhCmSZsf7BFAdkLR7w1AlxH3PomjQLJjPvb+do/XseN8LPfJltOH01B2/1Bd5vpKP8rbdNDaZzqG0QtiONIFfcEcjq5hiyGTDjebDJq9/GLzcDdEhiLvgibkdyAiqBCPqPRXTAl4QftpBOYkKL6F2yG0gYxJtX9+RW/Ye894JJRgHFDg0V04STQZUvG83b+nPKm0NGwnnMDGgmC6Nvn6pZ3LmQ25vkVeIJKCKwSUBwVIizeYiOAzF8uUrsSfGrHiRkka491jzRZXKb23olha0LqfAUJRbk9oA1jyASdoHPL4mWxUVz33/W32t7/arl9ltzQL3dOPWC1F0qACkfnTMAKpVbJxozKxAZBAsCO8ps1a5/NYYYNk1ORuYZs8CxBl2pvFEzd2tdrCCSI+2sAfkSY0/bEaAByBfE0YzRWtmiM0tkBY/UeV/rBPYARhHaRosCQQGHIdpgLUfWcgvHkB9etq2x8rtGCPG61AyQLS2Z/9wPRfDA3m/ofvRVnkt3rYcw4T0MulN4D4/U/t8g7Hf63+rzz4kwWkCYAa4EuciQBPjA0x+n8MYyERFPbSUP1N8KVbCBf4kG6xP+xNQuU7fetuXP6QxioJ2N6/YDM7IJl9krJiwG99tnGO8bBd00oqcbk/Zd/5IEYqYnZB9Y9SruH2kvqpP14yaekZi6CJpZ/7H3zxnKaJeC+WxIR2uR4mAsCibyWBi35f+TfeZa3no+PiX0RF9ARy+JolsmTV8nhYP0ZvAhZl9dsO1V73rejHcMIHxyfhWRkMJuZ9crNEILWJAPWYjYBYClZALP7oEMCNS1usH2Dtw8+UMvUeMGMvROQAuHFmBkOlhmuvwGxK1ZroURMqcu8TSF0vsIC2QOYdPVVdxMJ7Dxi/Ga1InEllNTea0zVZG1VL/exFXyW++Mey45PaO0n1go+LtxNaWYQZYcgRJdIZOZJoIOkRBTJHeXlIX8z5ADR7fpJxLdR+2AE7jdCFhFjKffcDVjVgf+dMV5slHMz5i1eSVyU5ATF6xfBQmf5d5t5OwRObh34wpgPAi8YEAqzAJpL8e9dU7C0UD4J21FoCP/MPRxP6w/SATBjgyafRP5iV7WoAYQBhtyEAMADz4gMFAZFjdnMW0L5SCrDjKL3udPps9xvUv2+eBPCmHrDaBPBQMACZoNLKqhM8iQC40+xn/B9/DN993959gzP+y/vwwkXQ5QWQAANhfAKg/cNMEFhLdk0AyrnghBFFzBf4TBwiMt6rafsP3uqtCQF+mI0duCU3dYKbkX+2YfXM76NNQjvpLY/Nz1j+0L8+uy5BeyrtfGBFsEQY2C0pXdkA5in3O/2PaAM58dSfQe/pn8zY/KBCZSyFZ1oKgFjC25wF/CruVrsdlX8tinXe50nxMJmjMYyKO1PEreIPVZiAxHhYSLfwlBz+dPp/woVP2ZAnwyD72mLgAD2DDKyM1WosuTgtF00E2hqVhNdwYmxC4zmWaSakhCK+B7cVllTIqyYvqyCHp/eOtU+pdC8EVFDp2k3MgAmmgHDuYBOVB+J2C+73Q71s0xD92IZZYT3EBCZC5oue6NiMRPsCeGBlwK/0gJgRL1GqEUHTVbFxV+YMb6YaqdQcLHQfQksocqKOcuzAbTMFQHC0IDURhptNA+ILBcMJoPogkTQ5wAvYaAp/+Zmo1SAFsfD29/BE30CEGZyxWOf2lNG+eVaPJlqXWL3wR5AQlIsWUEM0oK1RSbAZqoifcWRYH3xf1XhgDce7CW0AlYrjXv2fHvBfCQOACBTDwRUwVbDrAIKtgIADAwkgDpz2GXWfEwBBYJkNApXr/6MYeN1WHKW3HQjwWm732uvp7d56DzD/H0LB6+aKMH5mEwJcPs8B1jukX0iv78OnT/G7H9vrS3il8ktzAEYBusL1BgApgMX/op7OXv118WjAEbGtueez8z5J/RyjCcn+D84BqyaAO53sNAewae0+3W+e9zIyLEP9ovpnSzqclmihhlxPRdX9Cwjm2PPQg35i0c+o+5mlv/9xgmNl7wH9a1T9J5V+bP+x7IcgAIVfRR+nfAgAoqg/0Q77JiGKcYpW2bOxPmvSWB413/PW7YHNMju2UfGjd4Jj0WOe2qMxxNEKajg8haz6m7XlkAdFaaEabYab94DQaCLhbUCoTeW3r1PkX2l/QEEBcIKpij7UZgwEO17gVi+FphG47Z+qW5nYGPrLXZf+RTmjAZSy7tMdOMG0AE/eHxVBbzMQLtvypVb79WBcMjy0ehr1xnaoUFyW3PMD5iITdiSFke4TyUjcGoH/ulndN6GAvEPaHuOVyridvLxCdS7fKvbceCk3D3AcAlgmg62JjMXfRp6l8hu51ndHz2/5V3/9C97w7bR0TclQnEew++ELzYfSaLixSxzNok10C3jAOK/0EtHvzhIJ7ISVxC5DM3Fr6+TvCT0uUhF9teajYmyHtTVoQhuRgf/pAf+FMED0veZIBZAptLhAwoELYAAXhU1MBNMQEJlaCwAOkZDY/YAJBBCg9cPW2icAoMG2ArobuwYAwG21BrCNCWBzdubYtJ7eeTCBeB++/yl8/K69fhOuVxT9q0BgdQIy8MwO+ioX6Gju/zR/1jlD+yWGZrvpm9if9CjljALCj2Lr17eICLNfbQ7Y7kYQ2m7mBbS72edejPhf/87ZnzRNHvYziR8TMG2xevKFRb/fXlP/q/naC/2UXrjuv6a45Hkm+3OZJyAEmSRRwLxgiKIBZK74MyBfNYCghY8vBsxFSYd9TgMwTeYtigN7gMwqNeJXoX1RDpbyNrOdj3/et2nRi0IMz3aQT7OA+wSfeoD/IytpRxuA1ivJr1KHP2ekJxPt2UxgTPVitShRR8AZomanlNa6VEwCbAMVcwDYars0BP09u2ALNLH6FxA6t9zuO339sCnqI8L+6H2iNOI9E5KLQPrsX5BpEl53S3UuHl96NpgyJhsxof5yZ8jW6Crqx4WF2MP0YiQCyxDVmghrq7isVBSjE0Tg0rOtmCAPpMuQJgApilGXZ5KCSBbKDhVMkggkUxdrFEiODyfqK//8M97e400rV1cYcvDsvwkJcDhBSgKxAhiPrPwbkYoZPyYQEa8tFmEiKfGfEQEwnRnfm3ojCchup2kgyoDUNkKePGM2Eo1t4H96wH8hDFC/TAcj+VgiAMwBkxyByAediADbR0MqZDA76AMIBvNnr1SBgQ5k/B+QQduN92+ssI/NYdXdJ4DBAR0YgBewbz6EH3+M337XXt6h+vdCb0iAWwBdKABemPg6kf+TJ/d/dln8mDCoGOIP3ZjnpQO+0OmbiZaJBsO+4nGzRdA4+5s1tIc7apk7+EufJRinKAviKGp/H1A0AWDFD88ibH4m7v17D1iWKb9w9Y+iP+H4P/c5IGfCvxgCiPGC55MN/kXpF9ibeIHzHofubJc8D/sA7WKyct/yOOmjytP+DX9VsjWDZg3AtkASBw0k4LeHgP/NvDnutLELGnNAPZ0Fm/pB4qmffzRgINlwwBUC0QLJmJAVWZVUyB5gERf98yyKteL4UpuURtOOSrpPWAcRLu5DQAM20E8rJeyAiLcl562Cr9mPNPc+B6TtkfdrnRDsXPPUWwYIWr0TpAzKv6Vl8dRt7nXhJPrzdN/oS9Z0siCM9Lkr0gmvtLrbDEJArV+bDC1AvkRKd9wuTcYMkSgJqUJtmLVFt/DAiKnnRk9qPOjH+qRHOeKfDweh0QZMEMdLbyvGFj3GORFGi9G1kl4cf2+pGdEwjobcAKrhhFQFRMl0uim8h7HKyY0i2ABadOZZHeeC0Nw9IrpM7Y8CDHztPSArGebgCVMcFc0Q4lkNsLEZ2C1GATYADgH9Nd55ZCISABcIbFqxcUUmMLwTtORBDUVIJDc/PP4rKh3L9+YRYCcO6Gc00A8fwk//Er5jDvCVGMCVdkAvRIMv9ICDDJgWvkCAiaPSJ7kdvncKfCfVT2MHqvkWKU/j47wZUVXbHix/3uLtDW4WO52fFW+g1Jex+TEor34BXXhk4ESGD+r+lVkfVzv7s/S36ZqYWwCqz3TJ8yXla47sB/3IT+w3k/Xff6MJf4QQCIt+lv5MY5/s2x4QQIwiGHi/RtlAxzqxgsuVOKaqzCox+phkyIqC17x66a+8HjUTtGP1rxHBZV+j+sf4pSAghrP05xCJ2eom2KB/cEjdRs7KgnoAfYWsAehrUOJVfqp1CzUGLJk5HJDyHtUS+icJEbRWM6YAuPSARFSIHhdaDGGCRdFf23XLvR/s1wLmPqD+PN+38sjlXpAI1N9j8oN6IAUaO6INTnAzh8ia7dQvDyInNBl5VCGO/SNv8B9FyPsMDcGEaSDsCw2pMIs0XRf7i5kkMl4CGDVSHYEQcMihgzTNmY2CaZax3NPw7N+vVU4DlBBPNKCmaQg+CT+J2GbSh6ZkFKCf/z283Y5XzNB5Efr5Pt93Y+XBvyjLslSepu5awblkNW7SxnMKLnA9vCkFF5wkTBfAz/GQeLQAiaHf2SGHsHdAtSND8SGxqmkMfPgrF4591T0AR8RswQBHA0Dz1ZlQMMA+JoDJ8ABCwUGS4N3SYDBgF8IA+Ni2SgygPNZKDTAKqPIA7nfMAThT7yYGXrkO0gSwcys6Lp7gdmT9rfbth/DDnzgBvIRXxr6/XMcEQFWw7IAutEbBECA2vTmz2wkGvm/YFPQW1X+cBGjrqP50+wFK8QYdwP0mJAAPuzj2i5Z2d+boerjN1BNzKRzev+bdCOeGyfJp8fAQQcVF/5WhlS+o/jPaQO5nfND/+51rNtoP1AB5mnX215Gfd1j0R+kPVvRzr+xmDYDNflLdx06/Jp360QNKtoM/R/bEok+qOxY+/MroZL3j+D9+M3MLCEdkjB/YDqF/PPXvdmoDLZ76g/Y8ko0dvCKdVLn8TYb8Ho1B5b4PBH6H50tV+Yp1e4B6qdnuaG+2NeJMYF82VTbAkvsbtgJh7r2A90s/4c+lznA3z0uZLwWqlrnktZQl749SL1OfbbdH2ueKzt1HhP4xgTPaR+Z+GurFTMcCVOXCrMxnUoB1Bbig4iNT+9IngZlOGKj1kBA2xUiIIFT9Tj9rmVyuuBaB0wAykFMU02F0gj70wIBhPsQZaXChpYmkwI1xAtzj84XIEoX9jBldVaHQQZErNk+2KMeOS83AyWQGSrvrXaCuuU+WeBrinAr2xhIoRMYAGTdiGmhw1kCQtPnBwqeeRgSOMaZcM2kZKhisx79iYOCr7gHmC93OyXunLZBw4OAqMDSAdTY8YM8kAhEHXpuZs+zbCi2YIgF69WfwSwUR6IEMyHVr9zU+DAYA1wK5Kz4TbLuHATwHhUvs/u234YcfMQH0cv9KHcAL0WCJAC4Mh1EDWJjxBA7oAgKouVp6SElvABb1vpv1G1KLb3wMNK273bCt4tqnoRNw//Ng9detZF8PGf5wBRzqc379oP2Q9Y8HQ9InKN79/NhHgZe4LIwh7Mf8lz4H9OqfU28AWAHNCWNBbwPY/GDdry3QPBnln9U/8h5IPyT8q/Qr5IWln/WdPgNJaE7jK4lyn6zKF7YHNAPt/RODDYP2Pzz7nzc/0Zf+n533n0718f/sMmznrzuRPvJp7vfzvhkKmBjrNASgpqsrsAfw49wSCngywAawEEFLcCWrtkbaF2VtjRqDEyf0gF7ucaRZCu0lEHNaL7U8GHV338uaQBlaY76lusDucF72+gL6EN4V0O5hIFhvwAkiRY65mMx4lH65JIFRw4z1woEAQsgFp5+ssRKjNQMq3KXKaELYXEXCxY3xA1EgCFrCxBeI8T6Hb+gkpzvz9Nb7Q+RREkaD/ZEwAtkC3pFz+PnP4farwVq6jZbShkty3VxAELk44ItmKaVDm4b6zb0k/Y8y/I3wQwuO+nsOZkGiph8kUydCEMRFQJ9RfGt06QWXWMYOkpZAwEDuNed/esD/PxhgcvG7icKs+osIxDtTZJop9z8zqBDwBM0iAlU7nIBgQSsIWMLtK53g9vsOHHgFE1QE0LZukcTQoGgwFOJ7WAvFwLvZJ9STX6OOM5gAvg1/+olGQNfw7koRwCtGAVCArvF6baP6z4tPANr/JCejcJjFFb9zApADhIIqsaGC84+GldsbkABa1+FBag7YBgawWcRjo/0njv/hZF4Ujagnh5/pRR7upPogTjYuL1z+QKwQ8yuq//KCU38/8k+XqZf7+TKTD5pBA+XSf4LTA/BeuDxMWev+RIaTDGNYvun2WRU1OKnQc4eXcbGPP+rlNc3fGAjiIICq3HNrEceqWB+DzSOB7wkD+EwB9ncYoVbwY3geCJpZYx5dgQpXpwwdXcGRYe2FuE3Xaqix6DvNhfdHV8AnS0O4BYKJQUHkjqjCw6GOTgCRb8RkUDEx7RgI+kSb2Qym0rtC6bPBtpc5g0v6KHkr81y2S5vvG4hxG5JO8tL2qea17nf8Cv24g4UMrSD6fNCUD1FPtDux3TIAgJbtEkweE9342G2yHFeHlu+FU81uX8Y2EuIiKzuSvJrwfSNwRnn6s9dBRu50IPZEL/oW5tU4/zdzf8MwYH4Sxt7h9biX8Z4YrB38uFjUr40empqlVtNrCKd6tuwqICTREElTifBsohipuVygRU5SSCAfntLChz2PPhz4cH8B+iP8aoGBr7QHYIOQ8xMTtLkeOB6U0ByIAMeRD3NyhYM2H6pgUis2WkGDD7SxATzImng86s0wALDsHxTcIidyo5n+ThCYx3/DgU9sCp0zMQF8DD/9hNt+2H/nZ3+MAtdIGigjgi/QiyEJUtU2W8zJiARhFC1EAEb+gRdF3MhQ6nfYlritYg+44/hPFyA6gz64EcLjvHFUJ+u/OPz7uXWdrD1nS/dGrScODIoqMssi1v0wL0r5JU29sr+meZln+H3i4D/PaAYBpM+ptwFU+xkxLhB9JWr+dSs9UEt22Oein2WdjRuVfeK2I7PWMa6wJMN4C+s+o/2EDLPAxhPVJ1q9fqrP54N/O+93YvwC+f07bkHx6a+GkuzZQ7KG4eJvTmIySdBgYh3i1AMC60okI8j7AWcFroYwKTWNAugHkc2gH4+jmsTOHRScP+E1kXcgvOCd7/3rewPo55S54E7dU5lrWfbtUqe194Oy9VnhEvZLnwZKPxzNvMXZAlHvbe4nhgnnhpmJ8P1UhALqjodhzAQMMU7MS0YWZmEuMWyQGP+7RxrbiSBkW6B+8QHX2Mf6EZMBG7lCXaR/jOFQgFGAlSGcUF1OniuA5ynZsxsM17UuLdC48lG9ndzlJAAsZvjK2ytOIr3zwY9EQXPQHMptluYWAB5KBjGhJs+S6Y+xTpKk7+QvmBIxuIrYFCL95S4xOzc0DGzA9kLGGkRccf56FQNfYw9wU6AvYADJwYINAb76Bxo8BeqBiQFQD7w7EWgjCkA6aL9SwAcCGLAB+IXgHrKAjTjwZtx/wACbq7FIppQCs54inMZG5dsP4acfMQdciQG8AP7tpb+9vkQwgsgB7cPBmABomhilAY5u7dIPeKWZ7ei2KvArriSA3uD00G4gfcYbZ5Tbr4QEhiLMUgGIAN+pIyu/kV9v1b9Xbzd2ngn8ou6T7smPNL/2NtB7QJp7ue8TwDLla14uGX/b71+A+qYFsQ1geM7CfBNkvlb66Svf4PbJOKfMXX8Wco/5ucAAqKmD44/Rlj+2AgrBcODoJ30DdQ+896z5CidPBy/V8Qiz+aLix/+P992BAxyv8pkuet4PGUQQ3VXetEXJxEh4xEWYgSHUPPUDHFamuaYBu81MP81W54AJ4xTaYLMpflHaBRXUfvzEZ3Jlk8BX9vd1Ly99Fpj2uk/TVuo87XNvA/24k3snmO59LGjbY8tzne79gqm9Daxzib0ZzMB1+wEo4nJimnQ2R9IzPFDZHiJp+FPBw8xcMBaa1lnEEPOTI01Y2m4Z2nKya3sbPkW4I/UA1jDt8PdIZEbw6RzEq+OoHrFTyib2smN2HP5NFZeJS/vQFXYff5H6s/J5xTTClgqiFGUKPJv0N+880ayC0WFoangvZtczM6mitzUNEDYX+GNM3O7xj8n5ANEgjBidRYCmx0XWV2sl9DX2AKAARzqYksB9CPAGIF9oLIKSbrfhCBRpBxThwALxJRwhmA7ZT0IwgKObJlMh443JMDcmwgsTViJ8L6Y3Yaryg3t2A7UwgBw+fhN+/CF+/La9XNEAXt8BBH6FFahNAFAAXOIVJhBxIf9nUgZAPBSPuDqAszHvhbHv6EzDoFQfb6z7b9Ss/dpuN3N/k4jBfENF3Pb0giFbk3ORGgAI/j4E9IP/csHqf+qH+muEX8XL3BvAcmnLywWd4IrdTu5/tSzIs7TlDxsAXiHtfED/JMVzEpkbbtFtlH7teahWIqFT5T6pB7DuK3bE2P3c+fBlP5Y/rv5tvtOPfkSPJ8ZPfDq9/10BcPg/6QbxmSnkfmJnLUX0ntOcxBhH5kwbFNToSmUrC80cjRkEzJkA90lZRwNA2ZtQ2aGdTmiGFXlBrKB9MsCUUAiqamtU2BJyv19zP+b0GgnzwzyXXv3znEt/vdZ9fuy9Dez30k8h21zX3r/nnY0hPvoEsbT91vKE5fcKcWJcNyW3WKrlaAOBEHFvTBu16yz43i18ERS0F+IlcymWq8yUiyjmptlrL1G4K3Ai95gzCn8vpFPkXETvKVfgqdbmMeFVBjmOHJ0Kr+nb4zQNcJrZo62MwCFa4Xitnyu8IbqEGKd9tGZWdM9L7pND1MDaVjTcJBtU6wXG4qDZNAV4CtWUD8XQFhK+0LiC3ylwFPgaqaJfXQ/ICoc5bA8lB2tnSTAMIbBNABFoojWQPpLHwoikJigYpkDoAW3bq9wgTASwNlb/JjO4+zqyIRXDaw2glGc76OhpwB/Cn34IHz9BCdyP/6+AguO1TwCvkVygBgAAXkC4MzNGESeddCwWCiVgO6lsa6EXxU4CKJk/91uwyJrekN5ICnqjXkE4sAe/bLspAMw5soYxbg6Xf9Z9uTtgJZUZ27v04n5pDCwjCHydlpc8X3sPmNES+pFftJ8Ldj4AgacJzB/awEPxFdkAIul8uKZY9LHVmfASYQKAYg8uHuTu4jPFz/vH2idaZoeT/Y3oKYK/m7ZbMFh8Sq+UOcvni57oZs9f4L/Pm6L2eSNov7EzOn7UZx3kZCXx5ZjgOQXwsuGO6DRTWOFhRRliWRxxWdUiWEJsBjxpgy9QYHyJorjDpSaRq58ttZK7FX6eNlkYDnrlRx9IvdyXufTXq/QX7bJjLLj0mWCfL3Ve4nZN+1vJ11RuZetfwr1QfyX3/hIuDXZS/bFuhHzruAqdaJ/cGoMpLqrsC4/8gLKqH5s8hVRzQBiUU9NQ4/0iN56kgOJovM+ENaGkxTE4vj5FB1t5fMJnfPyLzvP6D28DrdkQkOQpxO/80IKon1MeKHmZTE41GEwDTduhGG2DWTCgTDWSJkSV244tEgKcMK3ysVPjjDAjoVRbc64Ym3wxBlmUw6h1rK+TKvp19YDfIIOaoq8IDebMuvOE6XIwQgLYAvXWbVLFPgHslN+DTY1ggJVyMKz7SQPlwR+8GjWAO8TAN9JA1Qmkydqa5ymeCfXkGn/4JvzQJ4BPmAC8AfQhgP3gShroBSfrywWZGItyM1LIh3mX7WpKaVo6Ye8ERwpueG4gcXv1J/Xzzcg/YoVKBTaQAy2RzPznObk+0aJdNtRZmER/YCCnpj6gXGBVHS/9yP+al8s0v4Duyc0Plv791D/b/gf34fUzcQeEqoTvaNlQqv6jB/QKhFo/8dSf2bhZ6PcsyDc63ktoV5T/Y7/fBrcOKSgMjB3Vu/nixygXBhMOByBLfRn/ycGtOm/Hvrx9ORR8tvaxfKkjmEZIcLJ7/tk2YOSnRjJe4LEwisNHpAVXEBWWtESjscQnxDiH6AfcC2Xez74g6k+88IMdFkOGHPSSi4wWlCZAx1vDUghdeio4XdSc92lnmZ+wC+r/zSVPfSYofQjIt7KCyBvnW69N/WvrmngcCYoBQ9WMQ1lyinNRh7WWUA+fCaPM7SZyTHKolscnt3zqbsahmXh/RmmWH63TrBuxVzsK8J8QtdUqtkb35gjm5e8dv/+Un/9ytIEWDkhDb5jqSIO50jXDeakUo5MFIV3Pauov227YgCyx25aNwYSvmnB4gw1uo5uQjQh67GHYSGgaEP02aSL8CqmiX1cPANKYTmTQ1iwYYNCBmumBJQSzNiBjOOx/LBpMSECpKyTBEAW3basrPpAOLwAAM4GKLz8eu6VC6uxfTk5wBw2UB5Ze6H/4HjTQV3L/36kBwAsIKyBpg4kBtIWhSBODk8wHIrjbaI0bJWCrZ9EQ4DXW/9stnHvATaKwt2AsIP4TBYftw7quPoHViT4/Mx9AFvGf+QTL3It+7Od95hVnrP5f8qUf/69TfmHd780AIgDcn2YBv6B+wtYn+dm/N4A2gdLDtQ+5PcRlYI2Dut/Gwb/QTRibYl6AxRn90nY1s38dh/TYzrotn/UHzhq9vlpoYlVkh1UkXVrxDP0aq+RkDP3FHijGz7pCHT+r+gnu8yFARhYpWVqlLO7SGFxOlKSxsIqtHf/Y4OSqVteG/Bjfd6cTPxZBWAehT6AN5H7851KivxwFucOpVDRjIckw9OmTGXHjfq7uf9Xng1ynvV9OwIrnfYJ4e58eZV5KfZS89OGgnwPCtsSylBUuT60Pi/sD36C/wRJiDOKaGTITzbYz+CkbCC23Ro9CdunMAZSLIL7EYmMw16VaADIDKSHXCTIXWoQSCx5gxFhydXYkZzpAWQgrdZKIDA2qB/XSlkLY5HCW5Nn6f/1MVqi/giYgqEGpYzl5OMFOydiECWNFrHHjQjMwtg6TwZTq6k4V/dmk10AEj4reJuFAgHE9UMdC9ygXjoUhf452R2ccbIS+Pg+Jr6gHEAVIBzetHTCALRGau8JFLYKK4cBNemBpVMAEhRHjznDIfUdWIuaARnPQdiPdHiugFaf+G27NgWcVFExyTlFay6kBZJ4a+jH/h0/xu2/byyX0j1d+cBqIKv1XckCXGQ0AJTgTVbKDjWEctXIFJAR4882+KEDnBsDq/3g7QoxlBK0JAI3qcTj/HA0gWXTlcomzmT0AlphgUMrqf43Xd3F6xcF/uRL+vfbSP2fcpqnfmSdMAHOC7mvKBvkmRT9BtqmDP83QVPqz7oMuDe121sYftA7uf7BLLVyKl6TzndXqpus5HtVZJ/ioEu8bG04DolVQSRvoxNzawdjRpuC8eNFnh2TgeVMT4/9mFG2D7OPLv2EBcCYHBZANTuYT9BqDKJqHdjaHdNh/xxPWXONYPVlYruvYLByNw0iqON3Twg0TQEIb4MEb4rve4XtL6CdRUEVJLirYaoA+lLkvyuAZ9K9IU78ECmUbGOjSvudSpjWRRDEt8QF2aYi08u4v2zYVFL41MGuJ4ldYsmGzVTyWYKQWm9+FK+dLNe+JaImbHBS8lSuDE3IQUWerFcvk89JUQxwyv0Sb0YmnaYV3MhU5XN2k2X42o9s28EX7RfHhAy7e//gr96J+5RYfYoZoIJvQDGso6ZMNISCoNRHr5fapktGccJbBpFKYUL0phyZzzyR1ysxJDhREqgukiUYbx8UQh85Quyj0idRf2/z1bIS+lh4gLlCM4XNbiKB18i41QI4OAwASMBgg0hEIK0zY7K5YBFE0g/oPJqhggMJsSLrCbdYA3BGa0ep01NmoBdvbaRd14gn24v7TD+GHj+097R/ecwJ4pQrshSygPgqgB1zahSqwibkrIVoDsBwYNQDNH95+iABDn/z2RgIokYDbzXdB3A6J/r+5+7+AivpZaIGWPxfSPSdMJGlGMwDd84IGsPQ7L2l5zZfXNF3nBcR/mP9M14ka4AlqrzmTBArqD6p/mHQbA47/JPDMKPo7h4CSm5j+6AGA6s3dYaccaNi6FZ33kwq6rpLmiKvvx4zoYZ2AZ/tiqSvKcbfRID4tYE45a+3wXBrW7r+x/Y/p78HBI2umPYsG2m99oVNH/TPwecOdzYqODJES70hhdEw4pzkn+P47MnZGaAJ/LLbj1cGDXv05Ou0FzSCb3+rUeyKCYAoZpf0a2YgTbIkIQSq9Iaf+vwqUrYhLV+Dll/YJM8EMiDgt8/5Yyjan9RanGe4p09THAuaPboAktjuHmv0IJBguQwHBaH5fl8weFnAymhQqQghMQABlGemuuweBU34ciTQkFGBDibUrg3mJwmH6L22Tkrn2KHsg8c0Sk2EVag0//9lK/wh4EaDdv2AnNpB5VabdqJ4jhXiS77VMCmlMmOGLYSgxXjX4XfX3vXZaDgwwHKGZ1kDmcdIH6lRiHkhD6Kpa9/VshL6WHjAhVeRJEhyf+KCVWFHh8UWjgJTAfXKGT5W0YLSGlikcTIEeO+2AGAkJVfAaoQYgJvxwBFjRYKtkwAMK9r3n2RF6RgOI339s7+j9KS6Q8IDrJb5cMBlc5nDhCmgCBYhhW2oAzUMPAAKDkKfw3ocsoGFWCuqniv5dcwA7gTvBNXuQd/drfG4AlpvLveqi4UOmbyT8LJd0hdknjv/LZVlAAM3LO6x9lstE859e/Wcs/cH75AfkvhMzvbz0N7k7zEnlvreBHdWfp/7M+zy6FnP44Qo2DSmvGXbyEFf97O6uX+OZ1gIfVF4W/jI+70BsO+t4jyLcXN8bD0ao5X/FZx5QPEj+xtj5zUYQniIGPm8CzX3B2smE2rc+0R8ydvJuVmGtADdZNtmWbKlHwHW5wGeUs2Z8SBq5yYO/0s+eyx+U/kpXHRr/Zzjgoz1gU1FwiAV5NJFzgPpPDcKEg0f/wDzQRwFMBXveJyyL8trvAJud+kuLgCDQvsq9/8QJS5DwCFt/qIsi0/jcnXJp9A7MPAPDWYcwrL22ZyJ1OFh+hvdIHsOjAEBxyrKUBi0pLu07+QxnZcT4NCDylU8DICmJYL3bY2vf4DD3l795ooBjA9KOIYw+4fLHo7rj8UxBDqasQmZcWjnJId3sIRsJgIB1zhI+2FkryNc2YEE0N8nHNmnB85McrdZmmXcDKSJV9GvZCH0VPeCLLVCN7Qs1ABUABw5MKUDm8T/RuKRJDla2imiYuiIZpjcAkEHvfQgA3ZP8erqByhziRl3YuloDMDeIIQY+BGsg9vz0ffjx+/bNNyj9714MA3jVBHAFOLxcAiTBi8zXQs5GIRtEhT4BrLuHv2/m7IZH8hbvD66AbhC8PN7C2w1kUPYD3HmQrvrg2d/Uv2xU4ZmrKurRDJuHwIcBzdeF+x9alqZe93vFv7yA+7+8zDMFwPM8T70T9Oqf4fWWuAPKNDKNZug7c9szQ9JFXXYbqC8NWw2soflPEN2z8PZwbWu+0nfFp5gmviMv1HCw+u9teBY044IcZ/n2GUnT9/4j0GnwhjwBzR3ffosU+rTdic/0/yeUILZnwYEM7qN5bR7FznpQPC9+1C2qmZvq9UrkVxFewYk0GOdcayjfL0WLsMU/ZFFEoAn23whDbHD/ATwg0BjvWsqfSsJxGifeijVcpolOhrwg9V7Ri/rW6/o2odhPc9z7wDft8xTXCcf/Dduhfvwv+9LfBfvcDx+5LVO7Z6xPI92kt7XJfbbsB1CMastVf4DPVbhsMJbQ5+sIJxBDtNgChzYSsRUZ/eCBkiVtGUrBafZBmtzeMJagOWnQw6KuK66hYnAXr+KvXA1//tuh6te8Ag/2DN/TTQWZlcYdPfDj7jKrYII0GaAKuukv/z21K+bhuVTGDMQBDETfCJlribsJ2bdMljnWzu9C9I+vZyP0+/cA4wL5NH/KhzmpAcQFokEQWaGbVkPcAnECYLhR3QvZoPhAA9iYDPwgH3Sztc9j8zwAAMJg5UsMrAawH4sJJ9ezvH76hB7w3io+zeDoBwchGIGBKzCAcJniQjCWcsTTXsJXQKMBiICkjN8HJ4D7m6+A7vH+q9FDkRBAypB8GfdiMuCjPPn+Z5H0N0dhv5c+lKD6Q/N1wf5nwv4HzJ/p+oJOMF+n+bpAHADnZyz+sSBA7C+0vzD2BeSr5c8stRcnsf6sz/ay1DzIurL6CWbmPAj+ejF1wY6ohUHa0YEfrphIUDlROY5bxw2M8TmK9Hi7xHBC4E5rH+8Bny+C4me38TOwN8Ynq9F48HyeseNmp3sA0sc3sg6nnuEzwqFcM3Ex0Oud/Etq7CKabybzKJybge08xCaNlgoP2S63Q32o2KkqQAYWlV2s/n16q2mPGdMZeQhACyAjwEywE5qBkVNJAAl2aGvgzIRmNO2M6uuvf1nnLflAsCKclSflB4DVTOStMKDLIN/gw0HDxNBbElMpuZkZeAC2MeYl50xvxSt4spjbPwgfonNnM+t/LoXoxQz0mBk8bAa8pjg2sspvZnqKyn6J7RMkDn/95fSWIj00OT6M/2Z85zkB+ZhEoc50S00CCfqbPuGv+gXQ5ymUoP6TK5lD/VnabBqAdz2IRb2t9bMphuF+i8ZVRnMhelydOGTv86+HI/T794BJQ8BhaU/XDpsAjjlgChgCZt6SaYjjPzjNNDCsMFmvtNHiHoiWcCCDrgwG2JQE0O4PyALuwoFXw4E34cC7xVU/LVi4Ovz+Y/jXn8K3lIC9vxID4AroHRFgNADvAfMsFlBTlsUAzeAEVw0DAPC7GQsIE8C9/cKl/xtx4LdfMRP8+ua+0Hc+NkZ2bMU9EUd/Csargxk19/6S/iKp+BKvSCvrx/98ec3AAK7zBfsfVP/pMoMM2o//8wTbByp+Wfr7ux3ZvliNghyBvT+RXlgxkZOV7fiPTyrEMw6KZzM7h2BOYAeFp43Mdc7vIGvRBrO0I/a8HS4Lw4XtWCvY+XjYNR+C3SMe0PJ+j4O/i/bPC6JzS/h8F0Rc93Su9w4gAk97PrnQzSckPzG4bXU8/EqbQ73DsW7I3Iy91d+2+NudJhuZKziuihSeactRFyMbnoI5wB33aa0BEhFtOdES+nkbeYy2/waS2VDbAVKAOAQGTH8VC/cd/eft4I/2n7zNEP9tO8hgG95LU5yn3gwShssswmnrY8H+oK/DZjD2IKRVz6x3FRfuzJITa2lZwji2B6/jyjT2RE6j1kexNqE6t708Q6Yb4qzrKb6B1hFg2zkvKDZLlaHNXvjhO6yJfnlz0UC111O8puCmcncpgD2+SYE2mS8S2Q4IweNYQGyAnkEtb3yn7JEkOSrGtyoGaTX/07OLLPleJQwJmm+ENAr87qqx37kH8AAyePPkAg1fIBcEJFsE6fiPBoCNUJMgwIaAUCwgDLZAO9LiMQ2YRzTgX+P+0xHosceVvMziskZ8OGZ7lgL0Uv7NN+Ffvo8fXigG1v6Hu6ALMYBe+i/9Y7IGAB7ORJZbPDIu0ABK2w0DiMIAVtB+YPr/djfyz00g8K1/Bmui22oJwFIPVF9ShZNUDWw2hv2m2cyI5gt83y7XdHmNLzz+T6+5H/z7EDD3HvAC+v/Mzc+0LKR+5oQJQJm/vfrPOPQErvtrNgim+up/5/4HzSA2er2hAVQ7vdne/3Rob0bLr+biUuxlKbXGI4BnTAbaDbd6WhYlLgxaGKkizroes7UOicEb0FH3nZKTTtX/jBb81v+PrOFhRGozSVK4ShyIbqhqH4nkTicUVTeYrG4+JOoLyS0DtTlZ3VUDm+jA1t+2CL5DK9C5KAfTIiTXGej4GE18ZP+QR/xKyhDeItwFcSwAYICZgM4TgKUxc0A7lQgsxAlnW7J96aCP1dSedyb6phV+XaVXf/r8AU+eMDBATcaBAM8TZvCHXtlwNO1qiFpzueIIq5Hnj2uPTeUhxzbZ6MUmZzeZx5FvK2zAly79cc8UpuEIr/6BcRLfp+5e6IMJGvrnf/gO04BJiC21xwLrEylPWxKk0sAWzWHeiBgTFejP8NLbHuaDymdp28AAqvKX5kNTshgtn2KWI2Aghj1FZUTsWTE5JnGrnpejNxyWXNNX4CP0e/eAybdA7YkMemyB6Aw6H9KwXocAA2QlROLVXgUC117wt7oCDOiFHsd/8X8e/LhRDgauPfig2LBLE2BzQLN37dkOqL/z3r+Gf/0+fPsNtWCo/vH1Cg84ckDby8wJADgwbPelA8jhyckEUs6d0hs8jAgIehXxnyAw9z/Cgd9+5e3K9AKzsSNb6YHjzOFYd3J/WybFvDCYbI4vS5jegaJ66aPAe7L+ewN4nSkAhgqsjwLYAi3zRAyAtp+MMYvsAc3gX4SGcN3fq391WZ44WXVAvhrVzMjBjsy2+cEF4O6dyEEhR5fpbcd5f4wF9mtZF6B0zNRIoJJqjohHzrvndlCrf1ofHDRDCxVup3VQOFG6fwMYGNNAbM4z9T2+gxjxJDWOg+VX2y6P+xN2HO14KccLI7WnoRBLA2CInoKpNuC2ZA0OJ7swAzQDMUFJFtWKXA012GTiKBqhYC4cK/HLjAmgF3meTFmXuDEUDgGNcQJvV3jCpZf7fUu9vCOOtf+HySCv+lIcazAtSONS0oPL9NEsa9NC2yiYzWXq1RzLU7D0Snx6j/b1cpOu9AEl0puIDEeB3zo501sF6HayFwBarSzjDMnpfICo5JiNfhBa888DCv5I0QA7RBxs793H6ABxqaykUdJ9PaVl1MwXbFphBAGpBjeemaMAXDOAy4Ct3qKc//RyxNm8g+gLD+MybYRKbXF07tPwCI7Quv537QFMCc7PybwHESjbQbRSCWxkUH1Aa0QpQOgjGDKW4JSykRO67W3d9u2BhEh+MBlGDYCrGFHyV8IA/Zlfqc83jvNJNtQPAr3E//QpfPzAhc/VdACvV1v+jBXQlXnriF7BXrWdcQ0sLZ0GurG4my8Fzv7AAN7eYFt9+xWd4E1pMNpQaQKgGJirpKfgX7ry8yfO8fIaSAGK1yuWP8sLJoClzwHvZk4DmACu12VeCABw9Q/57zJz7YAtQIgLWdGTVf82NfSAGTLJiie+2dk/0VHMF3Us0iZ8sQbQfAhQiHdg3UdsMxk+UgU0jumtDbiu2dGt2hzvvcGj21s4xTcaTNrcq9lkm/LoDfGLaSCdmJjnHhC/9Bc6MUGDL3Z89Q8fgWatojnTOzY73fsMZGWltRgP9qgD44Y0xHrsdGBOyYKeLAvBcFDG3lL8hmawpxlcXTC9xKo9gnGiRpOmdGNGwiWuYyp1AvDsIzBFewl4++2UH3MvwbU1dyC7HbhDL2ZcRaWp94OM6r/1P69oHPBEYCgQNkJ3SBOO5de0WfM82kAxwLzff/Qje7WeqGxNEw3UgfFzGojhcIvTkoueEJQIhCHyyB7pgu++BK/1VAlguYQAg+bqARHnPn6DPeq//Y0yNwfnGkmiGCP6d1vZCRhE82jU8ydc0f2HLti1Rirg8VLlBBusDWhFYRKC2KIa1KCgCcaQgjF8i5sMQOQEa7zWVp0qft4I9ZPY7+kj9Lv1gMS8qRMZ1LhAvC2mMRUMgLpPRhDvUMPNeABugSrd1DfNAjvoQPcHpQAPNABKwJrWQUAF9riRtiyJ1k4MwC7kE8u+v5hLxj7x+w/hdXEtGFZAbTQADAEAgYUBRLOD9oUCyA79SuwThszgVosmNuUXz/5vrPsSgt3ZAPrQSr8gg6z3zwiguhgy3d9mWOAinp78n6vV/fjSJ4DXCXjAu9xP/fNrnwby5bIsVyz9wf+ZZkp/+wW94FAIywec/VudueJH9Q9g/rgrR6UEuwkAiObypmTA5mqqw4fBbBp2W/tsag228+GlWbnx07mQDaAqYN1gANaJI4+FsJ+BqWkseZof/EM7b35iO7WEwIQWKyeHJWg6ndbDyHt6SpNMJ883tYF9VHlTeagBRIsgl7s1fqFYfC1uPmh0P0v15Hga3UiUJVERyskWVcKFGXqiyBJ8Zyhe4F6DzR2DtUfqkNPPHSBPtiuCNZ18mVhuxSKd4HgDqR66wg4dW2Tdi+T/93fTnBG7jY3QLj9AjgTblMRqLdOEbJU0Ff0+LVj4+wZYNWomK2c5sa6r3Sps/2+lDkCvjkHpxFIN469HG8h8JXNzFRYc3Q6SHt6C3LbERaxTFP0yt3YVOIFpANMFA+57Z+rHuP6j//z/HIRvUYoA0e0o2yv3P49qeVD92ZpXC5VM9zChW+Olmte2YhiqEGL3gatxy4d+sAuiIfUUS9Vg/uAbAiJQtaRkKO2QjB3AVP9T77VwD/+dNkK/Ww8AFeJwaK9Ri6Dm2QAeE5atE/SDqGLi6Q1nwbhIswYaA0BYBqHbttIXmrbPK2aCcGeoFv+IYAClBG/FlMClHIvLMALncvju2/DjJ/pAXOL7S0MPWEQBohSAi5eXpWECIHM0RVtaqOAVYAAWP4nlz4PxZMIApAPgxxuNgO76I8/+6+ri4e2IrT/WU3T9FAYAFBoWQECAr68Qf11gVjEt76D8ennFLX1A5/kyLzYB9DKyYLfJ6Pcg0S/MHnCLJ7hfSXD2nzgEEHapBvyS9OmaqxqP6t/CWO+A7yKTPk4uVddaG3ssYQMs+ogaGVBi/35mB1N0Z0S0izevCcD0N1wWJI9wkdNoVLy7jwXx6eA/uENfYsIHV+/Jf9TUALLzUX7Z8I0ISSbxxPkqzeyqxVNFfYbYI7cKOI6jMRg5XHY4B9tFn1ap1hwA4SqLOKtrbSNxK6ZtX/sT24/magaM5/ShoPqWWSuyKpu5SEw4RaNnOk5A4jv8kHmo5u+XqV7Am6LSgAJTB/zSaAhu0XDbPMHok7BBf6BbL5ePzAenOSAh7kIo8XCa02WlBC15/ZtDv8aAOIx6PusBrohojXlr1EWoDXgO5dLLwWwMAAQvC3Pm0Z4WRuCb1msz9XLD5dwvqP98s+mkcoNXgvenjLYIM7gNgMfkv9oKWQKIQ/35zrGt/cLAk9DPBJXWiTihwGE0pWgNEeVe+TRTIHUXZCHk19TjPR3bcTCpHB3A+BVH6L9RD1DUuI/+9TwHjC2QuEAGAACU3JPzQRlkt4lauJMMRBy4gAW0iQ6Ej/tG681efDeewTdbB2lBrzfrZ1Jbnco+fRP+5VP85n3rx+pXir/QAK5Y+/S6f13QAC4LuBMTceBxZY81B1dATarjhxrAjUnFt2YV/+2YACAGZlTkuluK/QCB24mSjjl+xgqoX42XK9zfAEdf40tvAH0CeMkXrP7T9XXG2f91WogBTMsyL9O84PifqftF9Y9Lr/70e+DtPjcAAL0BgPzjKyC6G+/Mz6tujD78wqz62/a+iJHbXwZ6+Fhxb6a1oPhVrZYm+Dwq67imbW4lule0LLAeUKsthoOHc1kdr7E64cLs3H1ECOf5wHw6U/AieZBKw8CKWzqGAh7rShgmFmaQaaaWLPdDgZxqiAeIHL1+ucmc9ixVX8labJpzW/3HKt4AREbNst208yrUmCbnTAqWEi+FK2rIpssWQeYiWjAZPShIRuCqs2rMKnASyRsS0NmE5ZANypEBIwLTKxMRgp0rJQ0OG8VsFLVxPAGLNZoXIdnxXMmiiFG4dbN6umueKyc2TgsDFabmzPFh91fTeCacNpkoly+4RU+iSqXJZ6VwJL+jDasBwK2IWAlHjUKPUqkTQPhu4V0NP3zEUujXdbAVDhpA2uiURySFrG4UAcnHMl1LsQIK0CL1OQBx2Nj8wCM3YkmaIH2OhTnzgioyD4H7JAdwDnz0/eA0ICPkOI4k1XMKfje5wO/QA6LeT2NxLkkw54AhCc6SBBOaVEKk+YPCGgiucLVyEURRMDEAWsKtcIWjCAAN4OEYwIM9QBHtcGne3Rf6swZA+vM3r+Gn78KH9zz7X9q7F3BAwQi6sB8s2AL1TjCDPAc3iCm7Eth4aYDlFAZAXwqEAbw92o0YwNsN+x/AAOwB0gTc6AP60D95mAz4yKyPppqB9Cyh6NOVOl5eew/A7Qu2QGD9C/4FC6hX/+ukCWAG+Yf7H0wAM9/hbAAgfS699I/qjxUQmD94+jGO79FY/zJn9LJYn/f+O+Vd2w5gpjrvn38nRxnWfZz99Uz7Ogjfr9Qo1JwBWxyfBANUK/rcF+FsGp72P3DxOgCAkIzSWdPRA4IO59FgAzeotpPy56YRMZx4OyeZWONPae4XGg61RxIdVr5yrgCNJu71HRNI/alEXxwFu8OSnznjJMVUJRYLbYeI7bL083fj62VOCjRHoECgwRGxd9wJKQGg7cjERoymNmJZWjPQQdak/V01RWXowlmr38nE1eJuuabM1mUORxRugL0jZwKQxvKKO6CSJnihZ1I2++QC21EcKPphq5fFe/9ZD/T8Ug5zoX048Y3V68j5ak7qH7JeUQz4FnDaKE7LFGe1NlLGAAwoowvKMrx3GCGWiJ+F3UA+XZiRF9T2KdSfEQ3iqnRmIQRoGkQpIB2IXnIP/NwpmbVcnxLSIyL8GpnZXPyDFQrmaMFybNNMpySZCSsgaN0AujT6PQVyhNjROOTIRrR6GxhygUS29H+DHiAe9ICCo0njhTaW7B+zgcBwhZtA4to4CijVF22ASgDkwyAcbC0IB96oAsPyB/T/uwHCmAC4CDpVfxlCnOTsOn5c5/Djx/Dp28BVz8kS7hKvfQKY4QaxzI2HcTJB/YqzdxXPIJAjKpiMqjTMIgKEfQKwVEh5Qd8tzFIcUDlznRuAKEDzDFbcjIM/7gMAuED9CwrQy/SCvf98fYdbSAGWhT1gmoAF0/w5L/S2WsB+bgudHvoJChNAbwZ19NyiMYwHxiY/AyzerPqJ29ZU5QMhmP7c71jsND/28VRW/X47me9ZD+CEr3CRwIxc+h4ryLWo3HMkrKLVnXZBdqVWcSt87dMsdVDH/2qnTQ/5aM9ocEtP8u8TC1gn+hTPRKA6EOU4HN4EJGKzCzMfpQ7GMDgqyXJ3Ma1YCBrrq2TCvNIDmlrG18hyFGUimlcmWYZsAEUnY74SHBdiUhi7Ba1TPstO0F/egtCNaTaEuTnnqLoFN4elJpplH+8mxp5MYK2QGcSMRbDxAf3C2ynTMUHNgTR91DPcXYkNbBgJcEaIHM3xy7DsB1owtEf/DlsTZ7SZptcujTTCM+YTxDXA3miLEvPwcVfnRGFWIEQ8RVvDqw2QH82l5Mz+MaMN7MWnfA7TW9HykfBEv8pO+HDlS9zf/r2bbEBJsDDLq2nWZmoFZu57ZSLdn4gH8aJJwlWFnU2cqDD7CZffFYTDdyrnACejNhsFLH1sKKIGOFx/D3D4H90DQC0wKNjPVAfXxLSnWUHB/WiaTB481MLI3Gqb5EVFGQF73eACDX+IO4//cF8gGfQ25gDZw22uBWPzL+2JbANHoBkD4/ffhncLEWAqwt5JEXZpr+wK1gZ4DkpWiOy3wZlihxi4zyX6iZgDgAPHG83g8MEhoLeBXz0j7CYhGIeVuj/vpqIlwMD0LYOQOjkA8PICIhCw39f5+jrhFrug6SIO6LLMCACYuTBAgD2qPwyfZ757cfwn82duNTfl8SCQ0I0/q8/iRrGUtsu5P6B7Vq6nd1n6ONunakiwg39QoUc112TAUFyIJdQGROMOIFxX5bArcrAoZ1G7IOqoQnIgMfP7EPus8n0fAeSs+AMTrrZpHsZB+lurQNm3O4cOLJ7eoT6dclUbTH4QDuVwGul25If7oknwQBDRx/wkgjoEpoHk0ATOkRUSCa59MjPXaa1KXjHe5zW5h40QFGUYaveho7DOxEcnSLAD7UPBnLLxqGJrB/u0kZcoHV8i1JzJu+k/Ku/M+GXNb8KhI/SuyRMosAzagBZMie6iG2ffZN7LiqVLNkiAP/pgQkzq/8/f3xM4lPkeLELGhuZnfV4wAn8z5leyFz8Qsmh6LRJtOZNH0vP0HokKiEMQxUllUZEtHVTNZmhRiQ/v4c//aUF70UJ8QBHEU7d5T2JJmEjvnFZOPIy9mbY2I3q4rQlzwI6NEI1F+yOFUUch4YgPkwauFXhAoaeR+kH6rY3QkJ0QHMb10P6Ze0Dm3Or0SQ39ogPJcIDmoHSloS3Enl0N4A0AE0CrLP+9EFUbBSwf+NHWXn8r0GCAsVz7rDwUnJc/ezjO2u0kB/v4Gn5gAzDmz4XTgHNAL7N/ZPSAqCk9Hnka2GdTC/bYlPSrcEpOAG926rfbh00AgwK0lQOdPscVgKbG+N9lYQMgAfR6TcwqgPr35X3CBIA5YLq+oPpPVzCAwP6chADPTv4h77OK+TNXkH+4AuLxvzIBRohMc9ajqns4BECt4knH821Gnob31gMAkItXs0meKyCw1r2mY1Um5k8RiSapAZQiVc0Rws4FESuV4IFAcDq4jlz19QT80twrHzW9pc+dIapPAyV8oRYeuQLVFEnh8KOA4c5p1jM7BzEaLVTLREyRSSkoCU7c5LTBVJiqQg97CcpLURKw1UnVcAyGsiWtwSPYmHKHmBgnVqmTpQ8ruIkyTzDjCO8EkEb2NgDtt7aHJl0Tcs4npIh1Sn/OXmyykzDRYght0pA/EA1uCs4h3y2RSLRz7GED2fjXIQ6DHVCJdn/q4HHSp9Xkfh/jyFcc4koMGrjHY8UfhvAjNc1HtG6OWopxI9Ymsu5zjiPcLUtrNbGi9nd3wUCgLHtcjxX8/F1S0JlRl3P87j2OaL/cfB3kGfQKoi/NSIOR81IuUBHNia65CXyhFerl3gnCyrgxEEVr//kcIuBiae7tjUZOmQgBS3+mNIL4gTnBntkLJ3B4muo/1ktu+sc2APJBHQoW3yL6HDC2QCz9BITZRdFmMXjufKFGQvze6z6pQNwCkQxKKx5mMbo0TGjwrQ8Hxcx2jBF09gQi6PbhXfjXT/Hb1yYpQP94Rz7oVcd/fbAHzNKCpZMh6E673mLYw0qKJycSF4JxBfTmXKC3u/WAu8yrv/ABjR4CPC2A5xaaUlxh/hNfGVbD7X9+eU2X1+ul3wEGgP3PvMwQAQj+VQPoH2FpAgDaQt7nUkmzaiYEI/xbSSdnVW5HFKNxPoX0Iph560OOlFtc9TTb+AcDAErTqSsK/i3G0k7F9v64LVyTEAfm0p9zACq+wpVbFkWs6mRMuNjKFJnWPOOfVGB6D6niV6dk6q9qrOdaP4CBJzBgsILis5Xc0AGQ2BPkaeOf51Edk6knQvIju5eDUUVRsTNP8DggNuqjtVZCUgu9QCsBVzxfGcdy4rRByYZNYACN4riK2JviDGvTWiISHuDfMkwFL9tjw35oEXcoq6iPAJboEchM64KXNRN+gA3g3dbICY06esA0cyNBdYd/IElPnEQSuxDBYoAGcM4RYgzHz1Cin6jwSybrnIqgGXbTe3tyGXJPkMONKTF/y87+2giBDCSevg1+NdnrPEWNfTEOaEEKtb1ZvJLvj4Px0qwUGDCgkJloZbgX/bVqyYXMGIUNCBxewGYMM7+MXbTfLztf3gS6hqAf4MOkL2ZeSrLt6z9hEyoQbA5IJI7UGE5tgJgRR4F+wdR/1h4whRMU7Ar/lk4WoUZRDNuEacASAjJDIkPZWl1r2SkLAwmdXE94w9378R8du2kd9NgORdi6mUqr0Ohce8lh66gt0OscfvoYPrzC+0HE/1feqvRfpnCd4svU+vGfskka3IbBa8VBoB83ykrlwSNKmwZVsDcAhQNLCCahgMg/hgHslsJxbgCgdGfDABbyfy4vAeX+Nb5cElb/r/3gv7xgCzTBEm4B/X/u5/8Zvm8GAMDzd4aynvAvJXeLVkBatvHsn1v1o/WYAAbbn3dR+tFt9/C07ZGnP6s/oqxasbpPizC0Ad3uLphj9U8KwsUeIiRrBkVKGk4ATEw0prDRMDkh4jtzvVPYDOohC7AsenNkOG3/azztGeLxxy+ixDC3m8VbGhBRGv6gEgO3ESWvtQYeXUriKRVAgUJQRFEF2kpMWj5tVZYSqGuJsoCdgDDrP/1WE/1kKlPWkRlGYKBClo01jHqLZdgyhywTnIn8qfxFyZuXlz2CwgpgApwHZokTLAfY113i0aMOcZFi/rBN1Z92bYlYgPVKviUjY+MwAejHYIceLfcADnJiRgWBQ5gIcUVIxYZXbfODl7/PE+teomVbjM/vfAAmrPjcwOCWv95kAx7DTIPbSATbbEWyXnGGwC3TzSQRIMYms0XIbi7hQ4Fh8PZXFgQ1J5qswg5ohUNqpg82VEgN/J41YQi49zcg/CJ6N64z+LL4ggnrPFmmAuKBG5NyCejTR55UMtWYt4GsjRAeca1h0BjsmoscBfqp9p+wB+SzN5xRwLV6KOkgg/Lg71EBSglOlZQzLsvx1sIUULa1aBkEd+ityhD0zgO46ED33T5uagbVWGK1Pa2AcLyYsAL6/gMP/otggIhw4Ishwy/oAWgAF3Ihpjg8JHXKjQrRJvAQlUxwewADUAN4E/mH7kCPW1zvpgS+bx4Kf24AwS6DywVwHTIpL7GPIwuS63vd73NAennXO8F0uaIBXK7T5WUSBpAEAAAFXnCV4MgC+LfVJUj6ixVQroR/tf2vhcd/k2B5f66H2Q9nrt4B1tZ86d9qHWwfqvEVjuksIMadRxE9d2WmCRWoJHs3q/ilRPMLrgyNLcbz4deQDsSiUrnyGAf/VuySMVGS7XbiAQL72qeOgneKArKjfT2xQ21DHY+Df2pP84AW0+PL8wlAAuypSUPIMAFSRePQfriqfBYYFJO6FFntm0kGaJYPpzdRipgJEHkwJ82zZVV8nvqTWCqsexmr7khDW0mHg4Szxh2iNURj+M4ukADcc2M3JWHX3PM0sTFQ8OXSwlIaaCzEEUEgdH8bbpanPB/TQLJQhGj0IfBe3DOPVhX93z/IwV+S9ZutHDAAoNr91JWDTVTJEn3Pf8S/maI9EUb9rZhvazIlRdNT0J8OLoWC1qoYAppVf26EdIvzyNI+vcN1+udfDnm6wpDB8N8tkwCDeCAviDsfgB8PXFTsTIq2h6soeUk12ZIzK1ImYX2dPW/SpMLV4qGLUIFqTiFkCtmJg1yuRLemfxRP9B/XAw4oWL6QMp1xDRKhYNlCoEQxN5iAMNa8sIVgPswma9BKV7jeCcAH3RNlAaz71AQ8VpFB48rEYEVbm2fhZ2HiWJOHT6/hhw/xvRH/2ytvTQ/c54CJAwFxYDgzR9OlNueWgQVUIAbmDwVD7o2qYGX/6uB/u0saFt/cC+i+mVVR/a0GwBDK0A/+ywIx8OUlXXvphxQAFKCX/sfrcn3xBgAFAAaAyaz/Cf+GC70/58btf28D2P+wB4wGQOs336GYysu3PzB2aVr993lrEPxZ99kDWnWXDTFBCxVRcATmol+bn51LHu76yQTF+T0V4wJxBcQLAZwfihAMDQ7iJQkxprGA7cyVM3/WGQUdQU8H/3j8lfRoZzf/01wAVuZ4G1TnE3HcEH4bnrNkSjy6hp9bh/+nMhd96+0xWDZMJGY8xiofeVnKYvOFDRFYP3uwzcdOS2gQxVEzIUCKWSYFLBPOEK3KjEwYF2CXkGgJxI0FOZUq7YQMtu3RL5mZCBHAYA/XNGekZPg/Q2cs9gdVrYkcarZo5lRExJgH8Ch1WWAfEh/+YPrj9ysJccNS9NatkosgKV85KQbIsEo8m6sQDs9vln48I4qw6H+8cYWGFRhVuwhtkWlnO6YBRbZE5pya4LBwHTSf5gA6TAAhuITvPuDU+IsfuB3yolaAqNFeaCu90ksLTwy+9yKeHsYUqGxWOm1tShRgntkMPf3WHys4pfgnE3fa+9AMF7pvVDKvxNs9DCTcLD0jAu6fqwdMzDN1OVizlJhDFGa2EOYR1PYpURLckBKcmuJ75AxRquIB9l6hyAhay4hlX08B8QiHYT8fghFjKdYTDBARAvPTd+Hbdw1EoEt7ByiYDnG2FIp9AujHf4mBFaZ1JgL1YfOAAegJSkcgBL/8ygZADmh8u4EXNCLMbE+1nRLv/PGoAYD9yQaAmOILbq/X+EoRwDv0gAspQGIBoQFkmICiB/TTUQJZGg2gtQWoL6ifS+WTirdiy2wGyZS1NcVTGrERePoThhjOdZfLmx//1fLYIlD9SyttwLwch3z5g+xXgsC2/OGtqJ/cBQkMSM0O+7goAvuH7X+awb+cD1id6on0aX1qjGLBWeeR7y83HbQ4lla+JKDUMy3x1B6aScp81XP4jur/yrmVpOYgAVdD+mY1GZWoBNF+8KshlDzZV0TjP9EspZIjGGHwT8wFFHGsjiiozRh1EKHIjALKxJwEA15MY1fBCWnCUw0MuRFTnPiiAjWg5iDAUhcSPogF+4zonY2qimI8J/b8wB0/RGp4l1c6JKPIOkzN/5L2WUG0UVVqwcTR9znFINywRYs+YNvewpA8GndYL040ldTdewD5Ftbo9bSRN6nyroAX1M7MHX2F46m9Tgh3xBHceoAIEEICsJ3caKS0NWWK9U7/vmAB8PgLjmIjeLKQDlZkHQGjC+iEHzmMQCWeBcMKE+669YsNdq9hS2qnJU0YIQCEQDi200tun5uRgvhPcfiq2HYkixlwqcvYY4IghEmg/mPawD+iB3DDlY8hwEUgPgeUkza4F6pdFmVGBoU3XBEXqMGCmW9osoJWCHE5Chj9v60lPPixUREGmmaxzTvg/pP1ptQAvaz/8E389B4wgKwgIAdbAAYID1gm+kJDChDn3CQhCR53tpeI8GFrPFFDABmfTfufN08JvhH+vckMjo9n39zhdoQBjBWQ7EidA9pP/ewBmgDyOzYAYADIAOgnvEuGAuzC7JcLGwDO/q1desXvbaDA72GutH6jIsydn50oU6sTP6XarX14Wsn8KWP1jwJNoI00a67kdLS3FZAq/l5ErGDdD4SC7T7W97xv+/2iSkiKBPlCgwxqI0KrbqMJlrk51Fm9sPCAZtnsvNPkIT8MGdupwvt8kI7qryf8CwZec8rQaUVR0slO6tC7qo635uTRkQrsvSJ6WGW19buEr4WIMUICWqGXAHoATouAApBCjmxOnCcTDSQAFNNTJ3MWSjSHK1Q19deSbB7ZA8EZTvahTYFjLjDOsomAp+KjLlOdwddJxtiRWwXFwXx7sEpnNhcSg2CMyorfzOqIXYA/M8oVgdsurIPiI8YLGT0ermKvTznD8Btf1X33lXBUMCTEw/Xg7ppTB5lWpsDHpdeY9+tzII4zlG7kYFSuNPhciTKYuSm3oPHs3w/+/a1aLmiYG9fC/f36bQGP/D/+03Z6rdkWKMugOmEm6A0gr7gzMWt+JVyxkil07zVho+MK3saw/IE8GM9P4eqCzFru+jJsZXQQ3YUKkDhUCH9JbZjaQTLDi/MPyxz+R/QAWlSmI1E02BBwagDGBcpaAbURFl/BCIIpEMyfKAora0Fs/KNsUNWWpqJ/3xt8gWQKxI99szawDzLoc/hif59+eh++f4/0RxH/X5bPaaCAAXoPyFH62hSPaDo5AhEG6LNIlN+nUf61/xEL6I6EAKgEbhZc/JssIGWB9csTbWBhA8BHgls10mCmXv0B/0oNcF36ELBg/wMNMINgFoykcVEDCJUqMB3/aQTE0j8J/g2EVkXLOnze6KuL4/+G/Y+Y/lAC+ASA0l93N8LwRRBp/qJ+Fm1+WOuL9YAdKw3vBKwHOv5zIAiSBFdzhuCXQVqZarVoXXnGPVflaNDi2Pl45FgZR3T+8+zmRk+wcDxhA19eW80XO+frrpxx4vFJzfDtieZOFVA7Z5RVC5uhWpe/S9TQU7TiymgJdGTov/xU6ckRQdoMWrSj2yYCzf28McFNiKAzTA0otmCVnyQ9jSqMgYbM/cIBZskwBqGlEHL1Nyo4vTMig2YPU7auxZkhCcbBYMIpLAkwyJZoM2ij1IjBSZTtZ0sWyb5641YZu+DKlTDatds4ovBNV9rJ07+ap1DyVwHRCXfgHolQLY3v8LvN5GLk6B+cXTEcTY7l2NVEgQRSUD3CvjY5MMIysoL5U7QduoSP75Ha9Le7g2F8i/fHPRWAiP0N/tgUYmNg9bIzXhVH+jZtyA3cSUMHkoNgnshU1AJ/o4RDayY4jF0QQuzzZOLhZKMA+UecA6r7CA2eKGaBf4BkbPoHDAFPSICg4Oa6MLgveVg8gEt6QtAQIuoDKyDFjDN9au9n/7ptgoLNHPSxOg68mSR4O00Am4gp4YCCNaB+WMJPH+M3V9oBzfCGe13MDI53wgtB4Iu4QKmNLeruwZCYAEpjNj09SuX+RiPoX3/Fqf9XjgL9Qyugu4YAxIW40e6JBrpQCYxkgoX7n179X7EFenmZXpEDM4sC9HJFDAB2P8sCE4i85DTDBDTg1F/B/+lDwAwCKI//WK01eMChsrjX2sHabu7uBX9TuJJR9FvrCf4NVv3LYfiDol90hxk57A3c+fT7CbR9+kCwB2BcSBKIlTCJEcSBA5/cWTCq8f3xr2gyZ1IvqW8Po0fPjrckxy8FiP63ntkSCeg2bWhqOKV+DWT4uQmQJqqASNSaQf5iJ2hPtKLCxc8pwhgPPtlJ+qmvsJ5yRJFPkLj9dPPhJk5UnKlIPhZh7VmxEkoSe1Vin+jQOBv18z6h4Cq2Eas/+tHENJTKs7K+oBKZnAYBj0f2fvnAcWjOdV58IPAJixLjZiNYQqTQMGkSPqDzdqRmWEqJxGfG7Vw5FmgJFlZPVw4cXEp2a369SlSInKQDp50HIJKHiYeH7TeRgChZvq2Jmq2MUDWCq5n1Q2k62ngw6cc4SFEW5Dj1p2rHr08cjsGu/Vp+X7ERApvcE28UPpxog9rf3yAFFdhFQBxHiBs9YKNZUR8FpsbYVQwee67I5sRgVbhDQ+hzg7FSdv4oT0DwAQcOIuzLr6kah1wgtiEZA3fi//Io8H+9BzAq9TwEaBHkDUBn//40gQ9BWYD5loHBDgpdYEx8sRXQJmOIjaKwDQPBykZNYqiZgyocWHPA5q9oPcvBQnjN4U8fw6fXdu1FPze4gQIHjqYGGDCA+aI0DQEWkSFDCP7oTQalSoh8NGXUKCRAQjD9UbH16kyf6wDIx5vpPn1hht+Fi6CXFwwBvQG8XPLLdX55WSQCuLgJBFyg00IbOIDAoAAVsoCKGsBUAbFPBWf/RGg1h+G9UD20nef9Iub/tumYL4HNaQtknB8CAMR+0QB0fy9YTBM2wFm2gPCTNA3o+P//svcmCnIc2ZGgXxGZBZDNVksz//97u7Nz6CIqI/xYN7P3PKJAdotnSyM1O1UqFIBCVmaEv8Mu0vwNEnArdSHGecj9rQctciiWoo3jCEZOEkhmAoHw4QiOH/WlMV7xwemKcZxHQQ8at6O52KfF+/xLYvZu9mVhBfsKxr0MJ1w/bIkD8eY1PWRoGS465nDfUR0vgfGbtrzwRK1h6yIqILjzGBDMR5JERR7NeBnBn50HfMHCgRKByEBhocR8+zKCArBHGqw6UICLYsTjC2/dAW+nXuB4tSX3UZpvb+L+n8uh1CUJO7H4Ax7KJxTtVWEtE2W0SNdliDrNnA+aQyCA13o/NgB6Rdp7HI8gKWxzSx/WOCqzJNCWRe5B+n/yvjtQNRZ9NR/G2tGj0BWr7rrQjT+EW5fTL/jm+AEPFoO6Ay4+t0hr9/HNA7TA//GP6M/M00qVp5oM7eBua8txVrb3SoF0xct95DgPnz31rc2K2bZKtigKtaifDYAQwJtaksywcXIUOGsBHNY00la6gDZCMtb4K44Cv28NYJ5d9nJvquAkFvgtK4bNqqYBQcHyBbIHwzSaGCoEABqGgIPn/hnfaQetZODjiIqPPykPxqx3aVgvIsejwBDiH76lDoAmEPbYwudZCfaoYICdpkDM1rJNsHqELkMIFYDDrUk5BPzLC/Dvv1IJ/P2L6fAECQ4HgWszXDq4R+m8Nh4UgoEGugOjfj7TJ3BA56N8estvb9unb/bnIz8f+zz9HyCAUgRQHokIMChA6P3Z+HfgwDj3aQfUsOTN5F1SbjnW/sdDbga3/+dB1wfx/e3opwSsefvfxtePSjygElpuXPHr0Gdyoaj92Wwhlu6XAwT7fWsIkrRjQWVasES6jvrLz2MYNmiap1vnLkxxpT+k4Elb8pwjkdG/aUzj67nh49C6fLp1jIzg3MQR7ZklhaQNLa9j/AFoHKLRDdNlTHnlB/LHqfKWzmYq2oNObq6BGjVfsq22pUaX9cP8lzsNSeeZPs+ZxjjPwtAsuEKTqFIkkYoS7rF1wQuMHrO4xEAhnVDUYyBoY9/3YUI5/lNsXjFFaJ8PdVbVZBDzqU/mu5yCGY9qCDBfT9AlU3DP6+yOfOQOkZuhQnxY+s2sazXcjKbHh2E9y4iNhg36VinbiS9vUXZmJtZJinZzYpjiNzf+abM5qQiFmffgwAoXfCF8HMYc/cNnjAL/+8v1BDR6doq70KtUmEaUTlwwYhp4R2VCvd1gJDfEH81YhEKeTFhnvkenua26SgCLIOeJAh7A9puwGCv/iP2ylUZbMwQN/67uEb9vDciSHfa+csLNEXIJgwkAJLeszHSukTNoYixQp1eu0oElU2WnP7iEwSJeOlskgjV9Hafzi+CLzqp+u6qCuEDP8KdvuPnZTQHw3OQHNx46/TO04OACkfglIrup2jp6h0ou0PEyGOD1jiHge8G/L5sDKAMe5ztjhMkFau6ddj+FGOceHsIh5iDyCKB+YhdU3p75EyeAWQDm+U8RwDz8H0YBQv77LhfoEbAF6mABzTIwX8sNrHv2PyLeR3fm9JRj3N+orOdxQI3i/E6Hf+cd05nSRBCY/T4/Btv4V2ktgjb7/DpYQLMMZA5K6PHb0PYfV3MbNhxY7Hs0QLrazoenhtnt9EWWDktLtHpq/Vbi7snR2ixrtqDIRlv5p3u3n9y+ON3O/R6/RoRB6DaOab9HCgzR3p3V4mREbjVTXyEY3Km7TC0uo2nRYXq82dPaSBEXmJzG6JdnAgpEtcRmytfoNpEVZYL3gWbQPOsb5d+Z45SYotQK4K0sPMVnkZhHeh7BdkHEjbNwZAxxGgjKDkXisBebSyZqCRr+SVKOFAjBEWZoq2WNK3ON4vXGkhmmEm/CXcuIInxiUhGU966NWLocRoejsrM2FLgyME+G/9Bmnfji58CSaI4wxQodvjj/6ZxvjnJWnezSQCDtAOtv8KxQvMfssJFOtWNQeX0O33OZvFAlLQDRrp/mWvOapz82mgQJAp0sE0bXc9ZUwBV1C2A0Uh5RcbbhvW1kGyGOg7WyKNSA/JdZBiqXWOiMOYV1e9LRmjVwhWcZ+D1HgfLXGAJcefohK3hYOEyRO5DFVlWugAASBBGBYA83msEA2GZWxsTjUXHyHkbMpyKMBeDggFldnzrGh5j4PYf//m344+ex+D9vd0yYcjCWASODqqMRcVjkoiUHkyRNlnCAf18MiF/pYMsQlKTVVq2jXrxEwb8yg9s3OkA85xyQgQNTB/D58/bpM8zgMAHsmABQAGADsNv+ZxAEHg9MAHSCa3CCKywAPP2N/p+6ixBF9Zk/EIeqQ/BvEAAwnOcDSsOaoKomVgzGPP35cs72XyWBfu2puTdiDWYCYdRPzgSiskhvSm/fuEJDPsC24TrrdYB2yyAcHhxMCFDCAbIoiq9fyB8Zd4cL/2NLGcbULzMkiPHHpgArKXRmyH5Gu+v/7SLKhjqgSR7JYWn8rUrXTwtEi+FmI8GTIC8MIrrNrAHRZvIPU05r00FT1AvLAOCsIp2Y+YXtTNQUR6kXbhacikF9FgmjIS6+e7ZoGZw14E+SKZQ70+Xnv35gChwIwigF/5rOzq4nNQTKD7r0dOHsFp5Lq2zixJlChhisEgSXd0kJLGZvkoEDUxiFdFt6w+vKoewu55uXy9mt989ZrzneXRg1BlMMCBMWDzUTBgEVn/ZxeRUn/eTzRiOPCg0ODVOAB2yh7qQOVjNz+MMnjAL/zz9da4PBSTSSwTN70hd6G5wzKcpSNKpZPOJ4Ucy9Z+oJklL3YP9HRkCL7iWXozZeSJhhu9Sam0vrjeRroEDQ6PTk330UKH+VIaCby6/tgoYLg4UBWErwUoTRHq7R/wkBYZAD4D+qgmt/zQkAnzAUTGJg1oP5dS3cWzMkYNzUAGv38vffhj99xln/Jj4oV/+wgtjH00Hgh08AK4/WZkNgSuwdIEcgDvyKavy/HCZRhhHQFwOBD7cnMgvNe2A9M0sBMUENEJABuc/efx73LABvWVug51t5PqkBoA5ABSDTBm5egX3sEAGg93/g3G8yg+MEMEpYVss9umJKSb+DmApcN5bsyyS+VH71zsBv8tjo+lA1CogAai0/Tnkiw5R9sV+iGi93mxVMCmAt/1Bh4LKl+VHYx9Vo92WhO8xmFytew+HTsDtDZpnScK1US80K0QestBJg0gpaHCsk1LbPX7tGjBE8BoDncrfw+JgXRmfntrmFm690atkMq/HMmBSiEhOrvq0hu/Y9k+g23YQE4XIcCQpNU/HppI1alcRfS3Sp7hJ5ca7jedxJI8ldpCO8e1kx7IJR8MaDUAPLOWauyIN0XtrdZinmFYTBrQjtRMreDf/gMEBkoPPE5tOwuo17wzZwhmNSlcBd1CXe4wCjhIB+DLMUT1B6NkbNN9albZ6gPCCGXxLDmg44p7FVml9dNs7FVi5QXhUugja+7pjXC6tCCRbQY8D+PK9jSG5NXIAHPEGao1Ksgr0vlPjM8bvP419e4V/ebzQEDiXsgLCJmqPJjjh5EEbntbifcpYGmDdHEFjLpbFXrIPgyg2yKN4InGmZ4PCAx1IhKxS0EuY0J3zFowXUpI1kcap/lVGg/P5DgAeM2hBAPihRgWKeEF06OobFV9LXaQ00u1EyQrEHOjr2PLVj0c+ImOOMgPJvOZEHGKJWA1Y8wBKIan7/9hH+/pv4zZsZQSsYkjmRAwOBFkEJj5JcDeDdVGvxXCAwyaBf3i0g7PsXev9/nQ/BAC8mxdMNQn+ljq/tgCgEAxcIRCAlwn9CJfj8KX16ogB8/vwAC+hRHhsLAPc/8xZNNAIK8UEbuF0wQEPXb4ugLhCYlmkmxjAIgEcHdBXHnACszScM0Gi1xQVCs94fgUycBrwAkOCPL9LHn0shSGi4+hca7L0/P2k00wndckBSt4OhSwjpQK4GI+NtDjOHC1xUmH2ovPK5zCHr3ChBydz5g3lJm8wVzzVdngXmOn2d9fGq6T/KYdPbPRyWENYsMztj+zRbcyQrNZF1wstATKvDj4ZdiEWgz53GvmTIHvllCy52sYaLksiTLHpZ4eTKnRRnBXTOTLRC8AdpD2l2i+TQ4/Tlx+GTMPg+nSlYdKJIWTUoj2yBJq2+3tFUzCuNYTJ2mFPNQObWoAaLz9rgYhFfPV3HaDnz67u5W0hARwBn5KXR58XGvZRV7C/zuZ+mHdNr1xk3Nr8oT42w2bmf31c2hOaMwbozlPYl8wbwhQqa8CUXKNyoGZhHYxC2l5gDWjO9GL1CcfX//Tec8pv/+NzuVSkSKBs+ZCFHA9UXFrKQHzB1MoLEksaBgiQhvlRj0r1V/sQYDwqyiIEKcBfEpAMaDSbqb9jWeCHW4Rl/31Gg/H5DAOfavjCAGyDsQwBP/BItu4QLoppk+QoqXBtgcrUmSTDcIbALogIgymtBTNCjzSEgaEVdPUH0Cqv3M2C+bf/t2/DHT7PrNwT4rdATggOB9j98wC4l37MBhIpCoEb20RlflkkwvhzG/PmyxAEvcyjCuCCNwjA52J0JCrwhR5jBlQg1wBMsoM/z4wNWEG/Px/NRnnuBDowS4Pl/uZAFFLcRH2Gg98e6f0AEgAIwYAfdhQDHqwC4/zPZGa0dx2sOAdIDY/mjdT/bf9sIocc/u0IWomO/dujPs/7koV8pFG02AUT1/lwK4fTnmR+15k3DHeMXJz8uWMLYiHJXQzgXFwJav+GTbL5h0ZPKs/sa0d1ejCKu6pIFzBsuiF0RLdaGcUVNIzY+OAF9cA2x0z86ftu6jwsCHDwmXikBFjjZL2mnOE7KtqQDg1ZemXpcCyyQHMvW7UIueoo3e4tlGx6u2qjgmOhE1A6eCzSzGgXAf1TUCohDxVxvZn+AFpQqDap+WS2QHcMlzmAlAFrQ5QvhI9K8PHrv+7wu50k1JCGI3BoRm2jGWMkmz6ZnZjylNZN/ZnCeqMxvejcqBVepChKdzUply2Fik4d+y50cV9ocZwFsXaDPKnbj0LMTX3wlC3HK4EXAzku/ZW4EnPaSaQjw57FgM5tEzPp1o3QUKUrxaONRw2zq58nwzVv4wxn+5z99TB4GFo/TZr4cL+fhFnw+dhnU01Ru3vWwaWQlqBQJZ9ga4SbCQm+e5FHONfOUKp1cGAbepAaQUdCD3y+0c3IHod93FPhdagBz0fIYN7PdSxNgjKAsPTCHACEBSCjFRFvRAKA6MimeMeXAAhpmSJJBmQ3g8O8BN9DRVvuvwupBpuO2BfrTZwQFfyYG8KnACQ7roEJJcAnPjI+Sg2kLJLMxMwXqdqZbAaA9NY5+VwDIC+h7ByeUWbZWjXcm6LyO5z/02CK1adABvL3Fz4/4DRDg2f4X0EA/FdSAx/aAD5CsQCH0pwqMBcBZQPPcBwYwRwFSgJr81eDA5J45fYhtRp9tKAAs5lcUIKpnOAH48mdo+aOUHVI84YNYecQbAND1SbohAVgOVy7km8LQnR9Zl53z2vw067SjOy/ltcCJbPlxRTBXS0nBY6XBmy2knWPza5vxxYMMbRTqInWZzO1T8G88XD4Qrcu+qUUu3JhkT4GfLkiOvrXyhEkrCLFfcCeLT+dWXk6i/sdaFJ2FX0k00qAlm14xMVDFW03UATinvjs47Xb7pI3Ccyxi+5Zp9g3KC7n62Sk1dvRxA1Fkp+Yrhc66UtpQPhy94ihfU81jBgEOqhNuCnMa6LPv0PuTuBmkE0aKPlknv7uiSwxW9Y4Uq7ESmMM3L7cYF3FWY2c3z/754Q1SYfzh2i5VtnbnJ/188hGE0tCgArczOnE2+7MAfO9k1SzJGNHplM3bUfjNJowFpXCcJbb5cZNsF84nXApBuDOPhT89geeZj5B0DMoAI7bbuAia5XROKg+qw2YDundoCObnu51ODdKMVHl00PajIRkFUzWWfDlzL0TvoCxru8YgGiaJJtqBdDMmHBcq0JSG839FDaAmwJEAuYRemgCn/3P7v9Ep2r+C8kk+aCcU3E0ZzOR41AEl7tb4Ojq0wTxn3/1tMOzS6UD3ApAYEvkPn8M3D2K/yxeayx/uf+I+Zzp8hBuUtQ990ZbjCRCCS0MFEgAQHmr8TQ1AeOAQDtzs0cLXgfUqABsLwM4C8Hykb6EGyJgAPpW35/7pSTO4BwhA+FCkAkMSJLb/gz4QdAPt3ScAmkA0Qi08N68CQO3JAPn/PPA6Dl1eIv+wzR/Nrf81R7EkSAVmD9YA8X8g97XtP4QwgU5w/MNxmX5FM2RL6Pd+RJKbLAFSVKXr9Kfzr5lIyMH4WjgPHlXKdzIWEGnpri5z6wdx1deagf9WvP7dJeHtYWUkGFPLsYLLkshZhtxWXyZDZnu7kuaHRXW1aMe6Eo7bMDR5GFrKQYEA6jCcXCnA5AVav/+DgcDDrrpbX8ynWSVf4GtesGVBGc65yf8Hnw9ZlXZFzXBZ1wt5h9qGABaGIZueEl/lZNwhGtxU1oERYCwhKZqVqkBOkocmR2gIovl8CnLnv6aFEQlNZkdoOBSdCLsZ+uPSAeDHKtrWpvAy0VLQI7ZE1RxD33n6g7D3ItBBH7ctY/+FnUzETl+6gUxL1a6gp2GhcJ1r3vnxSUI6akBjUO0GLzn0bS08K6CCP76FL9USb4YCBijnnef7xiFgHjjITGujgBuKGWI2jo8UD9pIZMIGLdbGVKws2Rzer1m85y02n13aQDSF20Ad8ioF2RccX8vd6yIE31GB30krUH6fISDdozIvZwixQn0XVIbtf4rhwJ1R16iLnAF49NcKBPgcZx3vbbwDDY7GC+I5q7ww67iFBvePfFD2CP/wDZwhqAdmDSgqAPFtw2roQU8IXFvRNCYxXM6gnVsgLz9IqXw/LAv++xMAAPTAB5EAZoed9KozOdgyqJAYuITZzSMUfgMf9AFfaOyC3h4JptCP/e25PSECyM9te+wProA2gsA7jaAJAMyeo++tl3ZfAXHE4gu8wo0pwqL/zykFANPO1PKLALoWQXxgSuXypxojGm6IBgNEhwG08KG7w/zKybMs2EdRzJ3uGe5JyyNeRH/t2luiY1ZREnrnxpj7kpwUKGt9vUX7cV9Kexhrx6MrbJmBaL5hUZDtJSNzXF+DSLpHhv3ItevDdzTvBW2nxQQdC+gM3t+OvvIs2b4tOmsjX3OelljR+F5IxCXuV/AC5qjCiedW7ZSIvu8xv53L5C5dDCURx/2XCjSkHI5/NJnJQw/yqebBWjRwSYjmYxpt1ej7rzgtLaL1RtEsFr+xbbv98DA7kqMEUGIW7Nntba2JFkszz2iiigSe5vCYX60BIDcP/QEImIRU8cMrOhBQ/uzNf0cb36qBcF014DSqL5J+GeRSaCzHzY8MnLlZhY8bXoaNHgNFLIJkTtTBCau7VvUlHHImgNxnzCHgtfH0IFnou88QHv1/XzwkitUzct00f9yj45mc23ifz+Ekgsjn8JrdZJtHVjxiOmhxWlLfMgkUDZGTiJfpiaFjc5CosxLMmkWOkCInWzaXabYFQ+nzflH+brLh374G5EsYHOKKjFfWk/X7EoWJDiQuEFZDwNLhmQVJWFf3jzUQ9MAvkX/woAqMe/nTfYEOOvCc3bz4+0cy6Lxqv9vDf/8mft4I/BbUgLdNWyBwgeAJQShYvOPsih4aXdoQgH8LWyDTo1nvfzIfhtgvdMIVv1v5lCQ8af2yMaEYOMzD3KzocO6Hz/SEmOc+C8Dz8ywA4ICWJ+zgNuEALACPEakBVg3oWgQVrYBmAWiKllUDCuRX6BGuXPT/50GSFR3fDAMgAIC7kn09BJLG/+Hah4Cw2n9CYoOkT4ABdH1gRwOvM/LeFJEdmgms+jr62yqlXX23GnwDCHEV4OCShVFIa/VPj+nECDFZG3EHoXV/jL6cZyyLpA/W+wcLN9SWKfreP5mBXLBccisDP2YWxIppIrSVo0mmzQg3NOMynE++vaYSzSms8AgIktUySYxPii8UJ0O+EGmBreKS8pWqbq6QTBjGSPilNWOF6AuaoGa3CR8mBl1MeQaqJLdGnUoylB5sgUa0pZI8rJ3r4PGZLAmc6rIGVsijmGQyy4BJA6JKOP01B6iPoLen4mGaJm/S+xS4riEZ1faOo9kL0O9pX+yxng1b/4Yt5/xk0GzVrIQMwJkX3Wm7+PeXiSu1tt0pFNgp6JGYgPOBkzGDCUlkOLGxO4XZfx7zKOigA0EicJYxD4Q5E7wKoYKO1fG/vLBmWAYS2uu+WJdODSURW+x3YADs/YlebHynXpI3zx7n5OE233MCuzRbmu1PZcxkIewJZBooMbFitY6JXlHxGgXC7ycbLr/XEGAXmCEB3v7z41BKjDRi5hBHa0W6eMAPAsqAysTIg/6geAAZxln87oqw11q5dPOIrv1rUdi8IB4JXKBvnyCAPsj9N0FA4V6+oH2A36Z5grt5qx4EGCQIEM0fJ/5xfVQ9YHTwMDJoJeesm+4xrFQAzKdxlpzZVz129P6fEAucno/90zM/921+fDyTFQAc/yACIXlNE4B0AGNOAPPcL43GuGIB8WCVAb+OKJ1d1AAfr/N4DQPkbswfqK/b2v8MI7+pAMzj/hyKXWDvz1QrbXss/TECBmxh7XpNlNXbjWk56O7blPskyr+xY+CNQxKj2Oze6WPLkH0LxLB15qUoaC56RkwyoRT3LpHYgCORwaeHaGdVdC1Ausxir/if8EGb4BIwaaij/3l1gW6yaWxP23Or0to0QO9rOvGzMGDMVxSPVkACvKMWCoG8LRjocaVGG2gmc9kLZpQmgxyMibNieK+ENLeh4IKJNZccFAc9htxA8FfnadNYqkm3JeC6JTeLGtSREWUPVA9wBlHg+XzTXu/zd4ESSxU2CGgsL6ZWNI60blWXifWGxw7N1J1zyLze6N8ZmfIYlDrNPgkhm5SCAAzYxvLT7feUDvo5z9r6HpxXnTzWkQVgdvGgjZI8iqWQZdGM5DpthdKAS8qRck+eW7vNwwa8lHPjRuEkVFBH3cN3n8Lrn29rOSLDmbzz0hkSxlOoCBPOsI+cVQoeM+fsZ+eMnM7c90TlNSo2DnzQfMHKqh21E1ugDad/ZtRwlm9CVwEIxtgyIzmTDf/2o8BvXANgEBr1vEdceWG2pGjJ/Iur20TTIBrlodoWCEMApMGYAGYpQGBkX+nwrzlkndwFVVvO4KEzjJvsuxxsYbB/esMD7X+BE5xGAUMFpAgjT0BWUGmdBnIZbBAEkHuK2fDdLaC/vCIUYV/iF1GDpFVmkcA4ORz2DJct6MZpgyBEpBFQ+oRRoHx6gyzgm7f8ZCWYcwDFwPgwC8Bs/yOAzy2MRxvSAcwDlIlgUIRRd+4rIAsAYAHomK/nAIAIEVtpqgb008IAhtY+jSaJtcv3DRv/iu4yVlE/4YGu+JfMqsAhgG19M8hKRrBO7Q8Xn41BJpQI62QAvaQXZQQnjQKkvXHXTztrO/p5+vdo+by+8ScRCDBfZJGgevW++RFD1MuAHeHRT/7gEMHNK+5WDi7AWruTa5Gl2214+28NgqiuANeTe69Gtvl0QhrSVydzSeRRDniLpEFIuhI+z1T5znawZa2Puuua8BJQQR3lXLR8h7pTaEO8QhM8O6UbGEI/iBxNxUapB45Y5hC7UIQXeKMvb+kmeygeDWNmD4FBBvP1np0EpwER8QkO95gsxodlgOqtm2O2pBWCCWB3hD+3NW8Lu7ImAZh23vTQgCJbt1FeEh4YCJKnDVsNIM3+qIYPE++GJgDddw7fczuUotm6baJvCj3mmqoEC+vK+rnAxIztUieNusVzR4t5bPzIMJM/fsKC95+PC5oZ3PGCaMR3dRfzO9JKmrqig5VgS3EeWVsz7ikTxSptLbD+pC0IJAQF71apBERLhIo0g6HKZGkhWcNMx22VJ61A+o3jZX7rGpCTqwFUAG6R8eM+BFAnzGKQhtGBIN5oIIN2AsLzGjkbFoUYCE6aQ5g7NDmahzX+KAb09GiuCFvecPP9nqf8H78N3z4G8yCx/3luPgHk8Mym9JPfeHaXYEmCscajMdxhBtEmAUMZOAeVyQProHplwpx8MkKnh8MAOZn10OylIAh4xH1PSCt7bHCDeIAORAxgFwuIdqAAgQPEwHCDCGOfjT9XQJmVgCugYQWgd4ND7wUAE8B5LPtP0QRnAaB3l/qqkzPBabY/8eQRU6UHJhJQGdkHTDjR9mfYskihwz1rXSbuyrjt/kOIyxOEbT5VomTbMieeCbpck/Al57ZD4q+cg7Y9/pF4QDQ+CN0rNSWEaHm8OgONnBjXwtxA5sunZ1mAXg301xuhuNQky3hUG9ngC3ObA4bbUwyvGMN219mM+OiAMJoKQHNQoQwj0SZuZgAJYNXTszwjba1OCIFoQafR9FqxdPfFM86QudTRtcEFCT4HgRk0iEDK2c3g6ygl7nwmQ0sm7XgGNFhCaRhXYwuYLlM4DIMHp0nklSYDyz6Uga6jlY7dXcmYQU50kfEvWI0P2hJtwXh7TRuho9EXGAAAZKBB89RjQ9LAHR+eBeDkEiYSD5h3IqybK+w8twqIWDYSO4cD7oiY/+6ZMMNjh7uRVnBWPLrKABKDT54MQIbZWUJptIXPI377Nv71tImku2y4EYCMIDKaM82D2wKanVFHJn6LDrisuHEGfAK6abJ3ynO2huFFne1/ibPdzSgD8JdotFfEnpaRndIWxcVI/s0jxspviwTwEulyhg/h5g405A3XFwZgZkHD/UFRAHj4MwUVOQGVpz9poNQG8yBWGTiuXZDU3sqGbrd+TsfDHzUEkAL0aV+kIATE22rIfIHMdWQJ2qCI5bc9ZEQhSbBSYqQCc2XA693WQVIFax+1yKDYCdJ+7gklMGwhIAQjFPzpLX/zzJ8f2yfQQMssCY85BBRiAEgEMzfQPgsAlcAAgcOuCQB7Q4vZvRcA1q97AdDyxz6puvPYiZD9aRxQIcBQMwoGiJgGoAZI0axAyXKh+Gu1//Eyw4lOtUzD+l5j8Q+d+/KzTMFcBzJRXxiCUDubc1dmenakV77xLOJMDAwm19O2B/y54bx5WdorAzgtkxi3a4txHfoOEIxb9x/Dx3iBcCsTC8C+jQLB1dZXU8iu1lZDo4++lmOcm8TLbIYxxyZqDHGAeRyU4U4bmQMBlznYiEVBumj0s6mvbctOTYTzbC9j61Ue4q1C0LRpUO0VlS+pM74VgtOD4qoF2Ae3AyoCpPmhmH8rKX0nSZpeBlzNnCT0gzugveLcF0W3yOZGax5blgdBMu+u9WEnMQjUMS5yefq3a04JlAnxwF0+QooeS7L0eZmH6MYIBQhuxBGCWf3QRugYgkdipmamGA2ZTyWbFL6LTb4PKXdf3OW+uJaet9A8QP71S/inY6UVheY5cbMmvXeQRAvbRETMZ/aLmcz1HDeBDXxN6YoGKIAQNdIk5yyYWRtyVNgkLUWpGMA1wUxn6fl4m4uonn+PiLHfuAZcQ4AKQDAkQJYFPPFZDIbvglAsOQSSI9sMDu5KCoMD6CwGPPoVEP/iOStfoCspjLuX0D94w82r8Zs9/LfPCAqGDmvjxzLeMpZCcwIAFwhgTiSMM3Jci2xmTzNsiGRQDwg7qAnQ0f9ueQCcCYyl2pqpyZZ5vSU5AS+ClRfcIOBOkbD/2conTAMZfnA4/ekEwVCYQisIjJvwgSALCGUAKyDuf7ACWjTQsQ4mGS73/nq94APqul8ZgtICSMaN8DK0jyAqcPUf6abo7b/0X9r+R5N98Zeu9bWzz3tjV6JFcz/Gv0dqXiBzcVj6F7vFzNxEQe/Y8+ShTNpkVRgdZHEWVQ6GFthraVJhM+3RpGfhJuusv+aAuJLE0gKr7ud+vEMDdzGhApVva5Nhh6gtTTx2IWSX4GrbNsyp1FbZOEixJs/ySQsmxh4krZjud8gLOrJDxXaLAbiJYG9siF9tEl+1OO4/W3CWkwsI3IQuyrSCmm0j1MbgkPUZlArWl5C6mFLDAQ/SgrbUjIcke4lk8QsoA/Nnezz2ZELiIQiIaWBpRa4J/TeTJdz4RdVbel18x10Rj9wIka7cyQ5qDMupOxCw+cUqibZD9N2ke7gr5wGJJW0K7wmj/DzucT+mQecGrGLmv/DiXLYBAPAZzUNmkhynOTdgN13jmcb8bg8+Ti4M5nn85DTwd28kfSw/Ud4G0jHUZOkC79kIo6KKws+ObmN7FtkEQWNY4/OcUqACJixqYxlCk/2jpSAzbzIxkTmZtZ5QShsF8n/EGoDUNHd4dCSg38rA1fsX2wXJPA5coIjdIGafQJtoosHDAyO7CKAAhDt5+tKFdbficbGOD+ceOpEQFv/dG0FgIgH6iPbffYF2pxYk9xzutjsna9e84ZRWH7+8bPX/hRxQWkGYc7Wg6dP1jUvemYkBzKMfz+EZLaDmwQIwJ4AngwEeFANvDATYlAu/IW0iQAoALRg+zkchGkyrKS8A3QxzxloBoQDUoxsB1KJgglRgnQUAgJba/1OcH+5/mrZAUWqA3HiZyvHtNKsDcw+j2mct3MyDOkmTZRJA+ccguDiYZZcO/UHzy6GTnUt/6/1pC0/YjBBC1gqIA/2ygFSGIaeEFWpFDYEH2bK9S06yN7e4GNeHEK/I7h9lhf5AMxztxPc0AycYKmM5OEvH8Eue9e6T3vpVHrotkORhiJcgiSmpiAX3xBtMoUnMAmhRbpw0W8a7gK3cvKKb+0bc2/+7mGGJGHh655CMhbOxwCzBgVikInwyq34YJBKtGmzkxjZWkGJUWW5159U1/+gsA/STiAwLjhpKwJhvguNxq1vmkuntUeRR8grFAvMpz8YGFp48ynD+07G8sYthTzi/w74FWVz5q+ngcMCNaeFiKXyhdoxBT8QDosoAKTqRhv5II8AacRGEinEWoyxFgQegZ8dG6EXRAFa71I1WKoe/fUH6s2TMw0lv5A3SbcJZKkCGXSl2JmtVN3ijAmyTYCohIAgRoTHPDriAHA8HJyRLqRJUrINAENIiXX4lY7jSQSlzCBrq/7FqAIeA8CEqILg5hMXFyBeoE/EwRhBZ5tgFMjSYp35DdvDZqjQBL8+GxENZwW4LYS6e7g/axoch4Nt9FnDtfEwLBiRgtv9zICAMgAIQo1ZAl9W72+WgxixV8OGKhMMUAHig/R8yoR3dGMQfkmoYfFHKfA6QgyGX5pEgCtvT8wkwABMA0uB3roCwA5oTQKIpdMBVREdoUGgwBNR50yCcxTtrjzDpP8AAbPWPG6tyEVGdjncaEWicsvyMZAENcvxlBUpbRyqEo0A4Zi8p6svAyb6ole5EJNamno/yvHXWwyiBVvS5a/V/nf5ZpYJKV2v80TxRIOZM2pjV+0fxqhwbiHKpISTg0YaXVXD8KA64df7xKxD4L5Hbwj1NUt1FXnE18VI7aAJoItqIA2/HfR7GJxROQAzUHMEaZaJDshPifanLipVm+HinmCwaSeUxrCNIgBalISV9SxyjntJtl+W1wXdhPPZQs0/QUeXzIGoUyU+MDO6UnjgdTpVPxGLSUro19fM7FePG1GN+By2FhpOBaV9NMmxHgsC8fFourChb9OS3BGuigZTcjFhjxlLjju+toOE7R93huw9WIN0uhPD5hHuRhSrxWKxiKvRw28mIR/o0vIgBzFv7QWMfpf4WMxalgsLLwPz/O2erxlXwziX+g0hhZSWYB868Z2fT+ZbjbCX/mYIkI4l2m3kyP5/31QtmopSMNYRNQjVWSU9iFsqZ2tkzQp3wkvFayI29b8I6KMIFYv5OGanCSB6NMpeDmAnc0jEZ6sSeT0YM/7FqAJ7TuhhNr3lRQgUFyxlUeAD8ouFvCaZQ1A+JUYDSAKQEKDLMJwCA74yBJjf07LYC6ssfood7rmskMeBPz/CdIiF3FwQgHhLvqEICHj4ElJU8JTS4Ox+UYjSc9dSFWSwMjEJtKYSy9DJroA9PQylICYYQuBoIAzwIA7zt+fNDGMD2tpfnvj+3Qj9oMkETlplwQMB2yrZAlSRjvFqkVHbhjIZ9rwlgqAAortlez9FsAhgu/uIKaBgN9FTvz2TagzkWYgTR93/2T8l4ioqT1BwwrndYEVjZ1UvZ3GB1jnfBAInoKTb+g7VhIQSqvB7SrHgoDeiR1gqWQRJlCh149JMQj3RW7sujHGqiH/0WhhUcJFCSTPyw9pHD/7/13zBbiXAx8MZY7nPj+vl13AudcOdjMUdHs5hmvhBeDFqw8tC5chHHkvG9xIwbUwJof6dKUGZ7NPTlyHD6qK4aQDEnHp4BPTnS6REFNw9VTzJojKvpd/xbZQv5E/EQPXSs0Mv1g9I02iLYsJsoikJwbODBtRWnAaLaCI/GrinbU0kgXBjdViQw1MFGHQJ36rjMiU+dYzw5A3BOqGibsRoPxbYubdz2tLxhX8HcI95ZGfcyqwbxAApxCrN/C/u8k5NmpenQCEaCLWRDY10TaVmzWTt/8l4WMnzO26qHZx3fPsIfH+H//XJlIKvjlI/Q2RQfNoRN1mjWN2eAKcXBBZEwH5pow2CcSArg6gTjWcpbO6I4yJ4XR6gikVjWEWi8ui3XzUQIc4B2AP9RagB0YdTLB2//48UKBSOIhtoKNecEwALAP4amX5Hx1IWhL4BH9AHfErlDvxwM+FIB8siIjYHyTgf6uAia18d8z/7u8+y4QQd6gxFQfEIEYFqwJ8t+YRea1xDQVeEjQ4BMgCZHCmv8TaeG5c979WgwLqaazfl+1/FsWwVgIxeI8WTzY3ru5W3bnvucAJAKCSCARKCMXHhcxvPo1woINiSQAWe6QZAIFNzD3c4Y0wGcpyYAYQCM//UCgHbTNj+mADDyD65bqcCAAURJwAKJQLC4siLD9r8b7WR1nMOCTmiBQwvPzmbLdv1hKNikZ4v8Y3lg885pIFLKo2IQxehbe1q2Ez4BGN2chGMd7knFQNsga+6VcqvVd7wBwfGrpb//mb9YANQ+39Yrw+yKxrhyItflZkjhWMtIY46a92/rMmVSMcju0c3AEOY+Usid6M/akGNM7gmjF7nAl2mphjYsjhLPaHOlA2hvO43g806Ptx8wupbYiJqRdnJRvB3t61XVi3MhfIU2XB4rrxpBklSNIUievf+83uYTgW7ARceNe7hZayAAJwaAstOUTN+8DKBzL51y78JIhMqg5Nox7LIPPFt+41b4bGSObuGd9+m4lYGT7848KaHVYnLmnNFRUKj2l17smbDvhaMnvJ2BGbROYpkPhJmvVyEoOG+yB3k5R/Yt0EYrGqrGji188wRJ9Pt66cUCvd+QGKMISfoWF7kJnRgCZvmZZ8hjFsLYD9jbzao+Xz4yvvhGJ54cs61phIXlndPIpS08ijKtvYgM26UVxuUi91vpxX6jGiDYaO2Cgjy9uhUAgcCMNqc+gPm2Fhgp8LLhIqiwCGVycD99468h4IAyYMggGnSgwWmg3pLCbnSgeQX8t0/hDywAT1oDAQmQK5yM4Sgc26IxiFUAtCwfMp+4zEE9o+Y0PfC/ngSBDxcEcC4Z97xinmTAprYgW1DFFH/emQ5PJigiglEMtmeRGAxiYLgfxn1ADsajH9FguYJxUbAFAnM6WYW93LihP5oTAKh7/SsWUPMyUNe5z+NeK/5q8G+S2UOLZhQ6WBvIgovWWsr+wQMtgtiZPaSbkSffZMm7ePrj6tXmJ9h2qICvEfm5hJxJv4tmJ6rfzwyZiTzuCQVjz5NsEeQ1wLc90SaAcLX/H3HgxQqKK8QxfpVE/OeKwI2QvwRjd/ORhQnLi4iGO4s7xMlAuhigqd0zO+XJSozUXYYGxTEE9rtSwBgLUEmIqjKPpraarTb1BNAWcIXP3ju6gjaSTpqWlG6hYsGdTZXXSXKtNA1cIqGEr0QE/YRlDTmemyO02wwrhqcdzitSuoE5DTDcgKk2ZoKXyCwqkX4IXCVt3AsN4kwbvPRnX1NoH7GzagITDk2gANPe+9bqCQ5RFQzLAaWNW+Z7pEQr4MBVfsv8fub4kg0n2KT9ZEk4NHIu0qCwDpVKWV/xKn7PIPY86RsBGO/EmT6/8u0evjzARun+HOR+iLUBdm3YpBayRStFZMYOmqdERi94VtwAYMFnHHckeGXka86/BGIYqKadxq4YBTBIFOnFmlIjiCN8KAPY86X/KLugTE7oWEOAUUL7DQyQNMzkYLkDCWCL2SKTwrgN4hAAcRgSLWo1bbCRQa0kRFsKKdcqWWLw+GgB/90c3J5MijcMgB1BWjgwkQAiboY5+iTBSXCID/rOAvBiWuT7eU0DtIy2HPmzXVygcZMEg2/gTtRko8bPW3rb89uWsQJCMGRGJFgGBjA/LblEusJdQ0CgHVAnGjwngEA7IPkP+KHCdNnBLMhjFQAqwowFpBCeoGZ/GPY7lHwXuQsSwBYrCXdNxWB47Jdn0t5y0jWF9pXlMp/Cxo10Js0ve4a3COOZXbyF/XHo0t9CAUh0GlO/T/ffxFNe2VMR6UM2E6QLARbd1/4Xr5Z/RF8AxSstIN7KwPp6DOHPeUev9Ue8ObWR1yJjhXhXFN+EAqs83M36jVEq4x4b2KCJkFNTIzmfnxPOkayKKq/EhHG+X0kWPqzoQkGavR6k/RA/U5KCycNkK8DTErDyXd5qZXMQXsYfOaNsl6K119qdxegWErZnvF4m0kAb7xT+O9qMoQwAG5jXcldEMp1RlQvaxF2d430udiYki2mLXAoB2Mp9w46zIL+mYX/Z9n7WyBMgnxUL+JO0hrqhPq5IKMHuDWwk9IW5Mdl7xO20XdB8PCoer0r8L4L5s8GQ0iabaInQZiDRqSQ4OT3Mjy995On/yvGVQSX/9m38nxdGgXAzjK28kQpB/RNOElCwzpcVO1w4CGEXtFd64mecdnN+wtOps+9rDGtuTAdQ1z+PftgHFUYNE/e0mMluvsucpf09AhP/tyAIld9kCBjGhVmAsBUAnQduCwEMwIeALmnYUF4Yzv9eYcvTj9ZJ/O9LnMWAeDlF82NnLmMzTvHdBHi+qfMt/NMbRGHyg3vLkUMAP+b4cFuIwp883WwhZGV+WlAwCgCBXxYAxQMcbg0kvwpm1tewrPHNnK4QBtgpXHzu8fMjwQ9ui7AF3fJzVoK9EAlgNiTIoBkDYmIuGCTo+Ii5uBfqwgrW852mPApOkQEA/28WgPkYlxCsB08CIBOROi9kaVdtGCImAC2FAAMAgoqV1i8tKhosmuKXUp8r2NfSYWmf08ViwTu82S+l+yVeDVtjHffShaFBpPTXhq7kAZ1a7ygVPBmNNhEhiKvrT6vrT3LYtBWPzwM2EPhaaPzg6P8B5yf+RVjYEmbGZYC6RocxxofV0KLQjHsB4FHnNoHdJOd6t7TwAZuLYWCNG28HAIaOe0UedIVDYm9OFwYyxCPlQrTAx6bOn1xiZgCRm3kE0YZoId99xdSYU6pSFqLlGbiLgkUID9OZ6Ube2Cvc4zcsDhzxMXOoozt2ZBbleSBoHsH0MbrSQOlxrPW4mOXRIdpAZ1QmcpgzOmeEeOE1QwPTCBEPMW06mczzXn8QW4CR6cns5Hqdv403Xq74kR8cLbcDJ68of+/zE6z7gf0WCsdOmvnMjoMJDGZDrQu8uenQzlXBiw5CL/rKIWewo6mfPeUfH9hID399G1ei+LaNdnJx1gxACEW08hhkb3NANhzLAWXEHIjmuZEKZLGzrCZoo5GYAveIWACUJiyCiCBkapkh1SG0xlHA4mVsWPtNNMO/tgYkGQRdaLBnxcgfwuTBBv+SI4ItGFIWMOUwM5KiMIYHdxsCkCI/IBLu0ZiglYgNJ4Duub6yiQ7jgzPE5xK+e1NUJBlBs4A77feWEUahUbKWrhsUTG84Mv2NBXSSA3qYIYTUAMuydHlCfMiHwRYIo98bYsJABoUmAGFh5blBDfC2b28wBN1pCj2HAE0AO6WbpUfCAENDAHUAwQqAcsSXoQ16OebBa+MffPkjL2gOAZU6gOowwBGCbYGkAJBSTFTlSIiYMbEiZHfTP8k1fjjFnqo0Ktht3W/0uo7sKqjve9FxT9FokX9XtOUPXd+lBrDTPxvJjYsOLfpFAFUNkHdasE/SsoFbFWCFvsf7Emj8oAYsmCj8hDlg/e7H0WFcS6Lx4Ys852N0QdmwUc1tmM0bQfkFPhxAu5WUl8PIbLb84pgwIJIwIN8gpDswF0x1PUoGHJScAwcaWDnRk1QHbrMUB6JS8RbdE034xXRG5NsyqUmIw7hWX55tZhw5O23Eqe0efOMvphSsRGuBDWxlwzNihIMsJ1rne4un1+maNq/iPfk+MSUaXBfGWW/46eft/3yQGoLWpZ41w3oR+eI4AcIj1Bc9hz1joPJHO9ktv7gSe5CT8ziM+y/eh2TDggB3kXl8CNVeqBDqmK/drBYPwrnPRDh3HugUFX1q8SjjvQFo1Cigl0VcVQ5utA/iIuigVlkm0rbNJvEUs5v4LCCHMmIe7qYAPZQ23CDIz8q5gViMHhKNCdWi2IS1EXLzW2iGa/yV+WK/ugbkbKkbixJ6RYY1WwR1/lTAgZUaz99qsoxqQwrhSmFAn+d+F9B6zAJQrfGvHhdTOXBpd988hHbd4/Pt//tP8fOOev70ZGAXhRGcEREoWiy1MSoWzbRZVrA6fUWVHRwFlFn/pZs4udWbO8XdGE5uVhwCoAreIx5zFCjYApELlLYt71QDzAKQfAUEMqjBANs8+uugGRx7KBrEOwYgDTYS4SuVwM16/94/FgAkcYYLCdDOhyAw5GA9miagmR9jUCvRlPc53ADBpWAKaeFiT6seKB+l+2WUufAA/G7RLyOjz+nmwhoQi879ZAsf2kqF6/Rn4HskvT+txt8XPilcKHD0bj5enJ/1v3AXhH190H+Uh/2ZOWDcDeXGjwoIHEcNN23VuGYF40H6ZCC3aAcAZOAQTDUntiiPeyH5QW2++LidM1bz/jzBo1MMnx4tiQK1nCoxDHOiJ0VKc/sSDMf4Ad1YfKFszEZgP+OGfHgfHz4IqscNY05XQcT0Ih3wEEQ8e/BdXBU5zkFiwGhkMU1Jc5k/WuH2qSX6HJbMXVmDB+6TDjF9B0+07eWAcUxm0gvKA43uol6ppRrTRgiHKPvud25gvnCb/pz3LFngZ7YTeecokBU9n8S4tIu74JlgQ7BDLoAmEiYQMpQs8cGF0iOPzw+YEL97PLiegAEDCUNDoWPEbLggDshx3qIHnhIrCksCBGvgg1JOGKkJg3cQDsN5nucMydqGXVA+xaePPC176qIWL2sSeZz/Fvli5bdZBPmZEb92CW1F7b9pxDAW0PEcy4qoSBPqwk4NAagBQ7owe3TLdrgqKiGXPn5kjP92D3/6DA/YN4d/5Qv0kDs05eObOtJoFG67mPBcggyiBUIcmgNOSwWgLxC8ow8lRJ7mC7SehmAAbB7nxffAOugzHOK4BQIMgC0QuUCMBwAKnJUMQxyYCDCIQNQBAAYo2AsN4sCk7Ny4T3i9FAijsB0fAqQG4AjNnkNuoNHafzJBrQwwDcmCAY6wethQdUbcYFFt+fiWYtszD6mNybXK84r4Jdt85jPJoUt8K7A/uO4sPN+ZCQyWIXNYoVY1JqghAfg1a4DYjDYKhHCBAdEb+/jhf3fY9/7p+DfWPuHfUop9VULGR3XZmhho7BXdvjMOt/kdHpow/HAdCldQnYiWTGN7PEoHoBvCXIycR4X8REt4wR/IeotBGmGY77yJgi3JyLxpdINoFnVAYW6+nf7BvF2DLy+TTVmDZKF71IMlNJiYzJ+5qgxZv76QMIeKJN7rbEpAWOQBS0EZV09DIlesjwb8D0ZR9DN/OoYEoTPD9b4LF6SwHQrNefqfnfl9+PKLd2hj/rs5Sw+zh5njeGZzNssltAKRpnJRNz4s/t/JEH0hZGZe7gwfZg4MN2cmQM+yMsqw7wFXmjYGL2ySgzZCwIcPDMvfPcM/HoYKOBZEdlCHdBl3WsMLCqWCH2Ib8eFtzhYsQjXD+4Ukb+JB8BVH6LylKxoaLHf9DAchfO8LFTDCzcqW+dXI8K+qAQSDPSrgRgmVj2XUephlQA9iAIABkkPBMAhSXAxEYf0FSCAdAoSPIcdmnv5UCHOjUcMtMt57cIAwKfz9W/is03/DcTwbf53+Gyr8YIQvjiUCl9dbKAdz1YBDbNTzw0MYwCF1gk8A4yp8tgUqmxnDIc5ii9uWEBgJDfBs/As+lvzYEjGAAkcgiGgycblCw8TCLRCUwHjlhjxYrADY6pnXwetgJCS41KsAnEFJAPp8kPppFm9nhC0EeMyDyx/0lNQKiJflDW81wsW45HLW1wYVAMrTusK5xfdXprnAXkdYZjsVLMpJe6GUrs0PopqTwwBGLdd2yOHfq9+/H/3Xov9Hzv0Y/0Kn/0sqwQ/lAj/YLEW3l/3wiepBdA1BNMjAlAQ8S812ggNBNISAbBhSdTgBJNJkkvlQR0m+ycQhXMyxu0oSx817YgRNVIwm5QWML0ZFMSTA5MS318aS0iFGaVFFZ4xloB0v+7wLGxh+VYCtSV1gWjY2Sdqxecmlx4MMYI5CjSFkNEa21ylJ1ggrlD604ph1K5fZ70AIjyyV8dhG3WdFKcceIBLa8qP1PYNxhvO0YNr1DDczwj6Z7hvIGWUDDlB3nt3zzp1/8UVbMKb+4hSGUUWKlwXrMLkA21KS8xJ6/xO9vzWRCPyYA8GGY/3ThlHgi8MS7hPC0OPBTTI2TvjrEKnR0GKjYE1TCNC5k5npeZ6FPWe9DhyMaB2RU2XWfN5wJoFK09xNOslydbiLXPxtkOHyK4eAizDiWyDFBXNrwJAAnBziRBk2gKzbwR+qWV5MRXg8hgB6M2AUOIe5gc5PDj6qW/H0lRJzjwuO4dsNujCe/hoC5BUa9cuHPAXx9owt3JAADgGnev9qhJ/D/SHej/HlJDVI4oAlVB4fjOG0BUIUJRNpwAXaI4Fo+IMCDX4CCqYe+IFgMIDAGD1hCMEt0KAaAEPAABQMz34Go7oFmw0A8988X0c1KYC0YCZTZk8BsQ2OCcicCfzypuCuoMqohBgj7YBIujN7NEDH5gARF55ocb6SAc/Lu0S9gYO3TKcT+5CPOrq/oMYfbaAhwDzWjQUUTddUrOvXuX/b/vt/6Ub9SQYJf1zxL9Knnc4/2Oz8G8DvX/zdH4puvvrz6w98vWvSgW9UoriGzBjXkqjbqsUV5cMtYKweJLb8YgQlBgFFCxnH6R8VcZ1wUqEqkyaEcluJllenLPFkF3M0azZJMitNzhlNazIYBHhplyDIv7s9ZQ+qN0YLCJ7lolVX7JuEYfJTkjkQNkJ1jpWz78FKL+ugTgxEEw+4QxitnlHugIhQjtKOdeDDNIxBRHbb6Nk+T4hyQj6Ujh2bl3mfQszl8TIGDoudyScIjtBpArEvJ7l5abxn7gAYPf8gH2TPI8sjwCm0Edc3gXiwdww4fHKP9GUOBA0I32wE35gx8Idn+N8rXkZGRqb7sBPpGCJ34z48QPXjIYbPkUEPN/b5M50QPyQRoHEqzpuLpqH4qCXK4ObcqEGUbKvPTmEthX4LZPiX14BIrdoaeaMvQ/VE830FNJSkA1YoFoKkhNIgSDZxnTyfzmh4QsEuDDZToAajjcNLwtIE9I/uQN/RH3SnDkBM0KfkYIB6cBGw6x73YDl3hjAz2JP9viRgfIwvyCser+EepdXiKmv/2hbiwctu3+b1h3vgWdITDnHz6M/PLT8zOKA7HUHhCMQCoGAAkkELzMat98ep2uUIrXDCbnag83lXxgKLjkratvCASkP7xvafR7xWQMEsgDgEkBQUm4mB581oqcMjGrlpmUiGYc73iqbBs2L7TyWwrCDwEdsqXKvzlAe1v9D/eeNxX0zlixOfqXKJ6zce/Wv5s5g/afF/1hBwU/yGcIl7b+lgP8b/Cb9B7/+r/u4NNDAnZ23HJdMKaQV4DVN4Xp93GxGoxYhmKj1w3EctLQjLaMaOY/n0j2pxCf2aj7S35ySgLE6kjBVtbbQIissalemtg0mTwe3f3H1JM0ziKtLqAgbHaKpsPF2BE4VWFtIPxPM4Mk7bnVmR6PSiQpYxOGTGthdzkcHaEGa0KRb5ZcxKsGcoBurZHnt7qxl4wAHFAD0Z2/7AbDvvtUYXteohX43knNgtwxVtXIS861HRyL9XGESeNb6SuUdAuxu1jTK/WUXAaZgFKhCBIB4EEp6cKt6jnSobm7zZcR6+Ctb+VNzQHG03pdgA2YhiAoAtHRwh0IU19LwoA6nTEwonPsolTMQbmBUJSrEyyBPFwED7oGh8SzP89lmTAc6/SjNcfs0QkJRAGpZv5FhgQBR6aElXpIfq6/DAIHORtkBd6z8c+tSFNeIB2PzwzNW534d8gYYPAR80ATwxPu/hT2/xc2Y2JEziQBC67OGieUgpgDTe1GyNTFPLCq4DNnDVrCC+N5XApQp+NY+r7KsxYqYdM8JmAcAcQCLQpz18s5fPe4IobNuMDLrtO4EASYJppIvTnzhwqUHtP8ZA7vvi2szooDjPdogJSs2IuxQpEawGroDoBnoGa4xOYr9nNks42W1hAlAQl2eKyTzsIz9G4ZSa4iju9TJQZAoU4UqMWyazAEQtf3BXZxIQkZPHVEJcJrzbaXPlKyAHAG5DwLUCurY+P3ro/1D9+zud7D96U/2bY8Typbgw6uGrImOd6n4l20vpM0GpgbSDyVz8Rg7KWNPgCO3U6nU4fidxfPi3Wgwe1WrrG75rmPZk0ENpmH6T5Bx+KQSXfUQpwSlQCuhFmIEZg7umRsVYxcse6kOoFg27uU0f0cw7OMQcB5ZCW1S8MEmpVCCjaOBSmTd/JihbREBgoAuKweyTAk0RG+QCyEudDWR7YGt8wEeonSUyfmQ8qLBIqxUbVgZeBM63ynzHA+AwO/ph/vApfqGt9Jm5Uo6WgZd9PIJWACYeWBs0eYim8ClZxuQrm2gAqMAj/JM7CF2pZ3yBzUAiYVtwDLc37sMAzoTuFilCuPEKa3AUMhzInQEVvBsaDEA444vNtVZdfhHjGiOBJP26YJlfXgNSFqq61saXLgw/QNebBXBS0wBJjkDAZfTDCQDHF32BGlmhXToAkwTLJI4m3S97HTkWjCuoXbfYfJv/bgvfbRj0FhN0j9cQIAfBLViSnun6OUUy/pdIL9OALS2A0cHHaV51WA01QhHNppB7VqWgYCABEAaDSPCENAGm0M99mzPBY08gAkEPXDAGpC2nzBmceQCBhqCcBhQLwygqLHHHDQZoxIFJmiNwxu0lydJEBWgPZ+0/JgYSQLElOI0vyN+SNp1kbbMyXtzB9ZoMyyVO4Osx8iWY6LfoY1gWG2PlNVkBoAnEvNHssZY/iSFgxv+h6dvi//wQA/gg8f3BmfujZeA36eJ/1ne7l4f1x1YBuCrBDSfQObnWQTGuKEeez6b80daci35+RAUYXA0NZhKCDRo9MNmiw+S5bfo9tu2huYdSsvgUeiydxoMbQqSXP57g4pNGDzVpKHE93LrXuOCymMslPBjaDblTUQe6ADrneeK9Lswdk+hb9NjWo5wSZjuORRABWsXnIqtmHtBlm6f/jnui1B1Y4XOH9dVsftpWTjhLNyhZOkekhGZ85TuLQppA0od4GF38wRaejSCoQdFQWZH3kfJIy6BFeUUg2sDRUY1OahlTe3BeSUV5mMfLN/PAKeF/NNdQ8hSsPPEP1lkok8n1nifYg9MAUIHUz5RAHGIB3GIlM6+Lo4E7NLYlqt0YKQNN1TwuE+UCQoa77IP0Rom3+6vcpH9hDTCn6GGI13okVwj7ImgeJPgZyBPVIohxMSRE4NjH2dZp0CZ3aBpE15s5xOBUZQOBaUO+ooR+k4EEqOVnRPD6JIIaJGGwZOLDZOLdPEfpEKJ6Uw3+VTQYUwGIBBxWDypzjM9bXGVywzPziM7zn4ufHkm+QJ+oDX7u+8OgYNjC4X8JrnCQBEdugYQBGCacSQtJXenqjv/M/4EINJ8BRyjnAjkRiO5A8/LGFojMHzJ8tBEiCByqXWSwzyLTW1he7B9CF0ayoXaYAVwX6tsIAPD0N4+ltfqn4BrS3+jOPzz9g/f+yeaApMB3GwWihK/itTgVyJDWr9j+f6nr/xAA8JsmrP6CInE/97+eDBzh+JhSYNOAC7jG8FlhKCLM4eIoS5DBRQPFoi0YPMALICneimdtNaqjJ85wWyDX5qZgsHjpae7vvYyj6WqJ5YxrUW0I9Siz4W5C0XURMhNJjZbptrTDerGepP0+ZCnY09JYCz4r9EXiBl72ExoFUi8J21DcE8YW6QyUHa9tHhXJLOXl70a5QPKeTD5uJ0VbLyq2CAiT1kEHiC/JfrljRUPsl9wQBMu4dXDiJd5pOvlMQUFgn9D4Y4DQdujLPFJGeN+ACvzjiSZ1hMsX8CTlNnc/siq1OZHaIw4HVoS4qyUKzIS+UQwZTiDQUyyGUEnZa+osxXY4uZu0bQJSMEuP8WvcpH95DbgsFYXNr6CY4PCv48DZFkTUItHzCT9gA/Jbez2gCKuYBnpXYCSHpoHT/wxmb8bDd1Hy784QiYugbx9haQLkCyR5yMOcIUwVfBcGj+4e0csjqMH9FanF5lk9KAcbPs0FIvRWgRYOsW0Qd+9FxrMsAFt5znMfj/jYMqBg4sCZjwTJT264DTae+0oiEhM001cySn5iPvWwhIMhRDAQWLHAKgBrGjgJFfo0MOj6OXj0p5okBINl9HBpdb2IIt0wwGHEDacAzU6lk8KNz3eWgYTqJdEvPhH8yz1PLEa5SpkBIzYHqPHn1ZIEIHnqS7q2PV9tf+Jfav/DWqX8nhPALx4Rolv7/nhhcK5QNOcXfZ+RnHVvGtC4HCIVRizXUFkFtOB2HX6kummcKJ4K4NSBFiGxEj9fa3xEAuC7NpJT3ffZzKA6m4bCF7f5v29PiCKC+VfmMLwvxAOLx8Sljn4GopVRAbJIIZ5HX4J+GJdUGr5l4sVv8wf93BSnMwgMYBMCmnzattK3ve1tPHZuQbdZBOao3Z8tAmht3FEmoyT1cFm5oRmngP+g/Sd2OJrm9Qm3Q0cej2CyYRqkDGHCYymNaMexKQSwEmWsiLOXihj2D/PY2VAejh7WzraqfkiITzwArAwtaqUbYDbZoSBibI0oiINsGu4JYGpAZg+uVKSzjhlv0WPt5EHa6ER7aYb1Pum9/SvXgOxo8BJLOinIzgw6QxAKZvIE0OBmWyDmRFAV0O2/yqIA2IRZMVcwQEC6mxS5ep8XFOy+uDju/+6NbByWbnMHykbVlyBAmoDoGYPkAjFGvavk8NCnHIyjwFA0mHGB6qVOaPfYevYzdKmNlJhHhBMgniy+SQ2wzce25wxzoIL/wFCVNXTcCQITCgYFGO1/tSXvspvp2vpVuGkfcoSWIMDygXu/Tn9ThMEpXomPEGZi6KZWQHIwgYUyj5QR9NXrFYN1AsV8195//umNn5egJD4UgI0b1MLtP0pakjqCBQBEIMnBkgQBOvmpAZb1/23/8+H0D//26f/vdeL/4qqwVkNfWVhfiLGdtEbOl5eDgIEkoZWhr0lyKwWIcCcDr4kC9s3Z1iaD32NYrGOVIAyrbwAOjVOEwQNkB3A+wz76vhSqVHjQ4Tkkw4mGpTF3rC6riEP2W92yEdmLMusSh5dZWczrlkmJGxFc+R8hMYQ/G1ABiuIAIXMdtDFPDgloswDMLmevZXYj59bqXo4DZkKvE+sguADleLDhQzsUr7tyyPaRJHLkCfseBvc1Tv/4nsFbgInQPCWquNLOMvUw0uzI8EO6Xyx7kTz4LOO943h552/NT/7wCP/CJnLlCihYRgJ9bJ9yxG6jUqGmRtYigznKVNp+5aRJiPMek7qBecM9oqQM66M5CyFjoOFeWwQcMYwvm874i4UC5ZcNAZcs4AqOHyszcmnEMAG0Kk9hQN6+yqAUhJXgZGxkVbKJ+cEdJF+ezHKZv9VPGzBXftW4sS/mBPDtzvyHLF9omwO2hFJPGIBzQApusmL2s93lx2cT/Z9ZlR4KJhroq4vRRQXtPbDeg06kLQRbgEExzCoobzmhAOwgAj0QDVawB4IirCAgniAw1qADqaFNcjDSQLUFunyw6TZZz5MBS44Di9I3DFe/tf/NR8xqJhA0HAbtDLnwp5lB4qXt4+6FABBKFDebANDg06jOPsfpj6+bzVIkcsZRgJqvDN6/AIBU7tJfrv1Nk68yEG/2D9r8fHXu/x5Un3/fBdGProzu0LFVgkidmInJGMdMJEB299qmEBWgKFVQAfYw87CY12DkQsE1zGOtKg+1+jb+hsv9iQe+9CcpjiuJjChpFXAW5/HVhfhyRsSfrEaqR3NQ+T4qZQZqQdGEtGpVoYeYsVYYy0uQI+zbcYPETBm4bfKnZ3sE25553eVWSnps2IW3Ry51a7OpOvpsqvpRt+M4n8jnxX45Mx3emrNg5g2ZPm5q3TTcK9plHuXYOUdTDnMzQ7jYRXQ5Wt3rshjihb6bz5j5DuxuQDlHim/mKPAK//hxD185zsM1KJHjPixrDB4JGg4aYAmFX1EWLc8t9M3MesI8hB8uKowJ5tKZkgaz4JSbdHChgAEZg23XLxkFyi8dAn7EKVppAbKKK11SAEwxML1s1KDS6Y06JxgEISoAsoCBc952MuNckmCR8eVvyaowehgfs2IeMfxpAwVIdkCPYtbhcIem1sNUwcnpQN2CYroXGORH3+DfhQroE3lXNd/rjY8hAQ/aj+zUo70BEkiPfXtADJwfUIIlJAPk+ZgXNBKEAJIhPoLLnzgngIctgnD0kw60PMtMEzCf2HGeJyenZmEAg42L1kHB+KBWCaLIDjVYSCewATRW6CAUU15H6OEubWIg5ZD0Fwd9EReIyjGFL+nBZFZDgDfwQaluy2R/EhtySfBtBUTuDxOAF//H4EmtGMK9c/npQ8D/Rf/dl0J/AUIAeaZflM1ICa4sNhm8SIImN+9a/nAnyuwGRtBbqhnOb6G1JwvLPMr3gChzTwZmYnE0/EHuRY2jAHf2LpmijAAraQCkAF+5asfqr6ULhVa+Gc9wqdW4/wHRUSeB4RGhzis4pMdDvFjdgtr3zcYE5hE1Euqck7EuRwADcxQotBTdB8WltbRjG2/zcNhJsDkzmmuM76aNUYsWFtMvGt8PBsAM9Z3/xhspPdjuRlD75xBwJEAC9C+LFgYdbSuXda0jFngoEewqAyU853iBwEhYAv/hMf7Z3YuHb/QaY2QOxctgGvAzjdFmR51PaczpvyIoK7ea8g6vXyxuKe9niaRmGMljOD+ZvtUrWAFdbmxY8mEqWCITdnN/tRqQsssCVna8AcIeGMCcAGbGNYnCxAqlG3ZbSyCSg/huYVwacuzx6u2K3PtjfI0Gf5vnOAY98NNhAD32GFWxN+6Cksq7JrVgnqMqzqdUwZXso1tyvYKEDnenWF51658GFFxAB3rSH/RhorBZDAgFExKAKRB2QDgr3RraYQAyQetgAYigAy3nrqEYknnGt1rr6XZASw4miTWXP1YAgAAnIcDGedOFTfo/fKHJMYHa0JcO4+ICKd8RgkQZfw5y5DpHEy8AaPmx/aflNmRfNhMQ8r2d/mlNAHEtgmwdFOPl9BM+sv5j/Cmcn/9MxeA+Cugr9JATYiqBhjg43BSLxGD9+lUGdGTBpo3m0MmFWoL33fRjXis52dKfzUO0nJxgEkGGvEg5vGLrB3+J9h98gD6bF6yeom8pI1dOsbtrkv215kJlBf9oQZDivIYL5Amb2gHOOIlsNoVNzqOtkE2eGbAMTyAcfGYr3fdtDhPtmXvd8jHngDMe25xcY23zO+PVAx9URIflJzpskXD6TL9xF/R2kDOaTc0r2TC+D8XQygsV0x/3AM0eyBMdDxMPh2ezaWBpBT5zC/29YsUUbKAUAekpiAwfZBWC8k5iKAhLTXIB8rgTDsUOmJBwO5OlE4UC+RbDbidq5ByQbxZyl2MB7Dt/gXXQz64BiQ3tkgXED7IAgQEyl3FAGFZxneGZXVkacIA6GzNjUAfnG3waKzTe9jARI4IrwpTV0G8xr7QrC398hm92yweWqZMwAEDBYCirgyUgFS5hcCMSoJLzqlZ4TBu8YIBbNTJrin4B0ZnxFLgaEEsZMS0W6MLe8DE/U54D7L7teyIUDFEYVVTUBAgNph44M7Wd5vtkgo9lCsSV/5wB7NyXomKsLRAKKueAagUgWgHgwgyfCAemct5ygHmX9BBWCLnTQHsWIo23i36fcDAd19qHLyE2akz4Eg2UMqAkAEBDgAMAyc1/wqX/kgNcuATAf3bz85/v9P9zCMEP5cfLD8n9eYZGJWOHidI5TEfGnibC8RuHzu0uDCbpsqX80FLItV06KO13eNLT31NaAK5ALF/edZQ46sEmCJZkLAM/7Z14ADGIwsY5cr/RfMyruXRlXuLZtuOsj8RwaZOgD4vHHDzMhrCBLYn0lwoNJECi66nt2AXVupd5YhylzXpyQPCV4QBRMIa82ET2u4mQnxjNz5MH/dre16BP6uBhvSb8pevA4NOTaQWUq7CxQshz9AksASTDJ7dAj6yAkPHcwEv8cmMH0fwPLzLOjWCMdhhINLOuc6EAPKXnSXX0mhsPVXK9YmtosDKUUzIOymk5LBQ12doFmYWcy7OWUODnjgI/uwZcaQFL52ixkbb8yZdTdFNmZGp8UA/W2U4TCK7MjrTMFlBCGRWgAxfesd2Q4e5SjhuGiYP4Uw7fbQiJxAPMnPG8SjQXQdxfpGBLlm5huzYEnPNSoA3Rq0bmBOCjPl+WQRZfzOtp3GrPliwpDK1Bjp8KHm9bQiUAHxSOEI+MdJhsiyDIwchD24gDkwZqNkHavK80QmvRzwNkUE+UViWwhEjGLJkkOA0d9OJcEQcepIEKKNbs3hUMgDNeunaxBlkD0GvJ/8fkYPCBoP1nJhQcs6EqYP4UmwNw4pcLAWb77xNA5sGfwt3+YXn9hx9xffgv/t/X26FwqwSWAGbboKF8d7aL6+gnZYiS8s7wB+1qTNm7eibLQlNawLC/fpMEOsgbGR56Rcj5Tcc1O9MtsbaSu05iNEW4MUerDj9cehA6U8XGJ9YgGIBQxrEELaMYI4Cl0ByUSRPBZNCQvQifTKBj2ywDuT1LaaXVDTDbicecBvoT3s7UWDK5slHp2G4EIYTOD8bLzHs5IAfmS0Qu2Dy7ZzGQ+vfpZM2SzQU6i+6hUWAgo5gJ9XDHftBZ+pmsBtjnKXx+hP8FRNNFyzpVoxPQeeC0EmTjBQyAYcGNOcbVbH+1GCFBVkJayK8G1bWcA4JUY21VgmjWETwesm/m4/hr1IB0ZwR5sm1UWgCftDCAsgoArYFiV7Gmq808/rsIl2CG1nrZQiyvUKkBtAKyUPPwNSX0D4/56g8ryMnhGmr8tLmgaf0oK/rJw8KuXRCRADlUm10ojeFe9I2odPk4+RbeNQGoAdm2THCj2+KOrGDiwBsooft8AAQoZVYBcCUL9fRlloGKIQAFoK4CYEvSoERveQxX/HcOS07iZcIJgJ7vcgZlcrX4fAQDsAtiywZWKAUZEpkFioGvUdlJKUQZ1+RG/2d6ZxH+xcgSh4hApEgw7F7eD2jTcNBv1+mfDAMwGOCm/v3gAPEXFz7/perBV3yhH5JK7SsKpAwWRhZpd2w6jnSZxyhelJliRHr9TF8gsFlKuDtUuDnmcj8ECThXO2Yt5wqxzuU93WyCiPgaRjifEBPuav8pSyQynBhYqS1QpWxUXUeECVxOpWxLIOfQQmb1kHGDaccyWw2EzOQ+x4DSt22HszQmgL29n/2x99do22zh4bcFlY90B91FW1Vyai5hgN8mGlDK1p+JwUc2tj4YO2S80mjJHDnR6nVDiWU1X/ycWRtmBRJsdKf/XKAV8JJq9EWNI5Ws0HMPl+GNcgUAEqCJO2ezyE2bjERtWwaVOE7/OQPMAue2m+7CQAvfrpVA8HVQ/Bpj+11qwI0R9NEkzhZBUghDY0owAMU8dfWkAmTJiG3aCA0uy0wIZnjACMstjqC5R6HfJwBeqvOg/7sHRgEd+kYMjaYTlja4eHBovCwQsBSvchSpIAy8N4sKeD9vyfXN5QjdR5Bb7REjklAwKaGYPzAEYAtETFhDgDQBcwgArwYIahEMwAKg9j/RGI5ZO4bs4CZrUEUeQ9k0IoOKxjRMGQDeZ2DedjBroDguJCAOdwciPkUpUB/9skhq9IImAWkjiZeiBNlBR+2sTAxMQ4vC0B0iAYlWEKwHOvp1+vNjtCHAMN8r9v1H1V7/iVf/vxIk+CCAGEs2tzilOqZzMjojmistefh7GxOCRcP0acLHilV3lARth4YpwBI1ht6d25QfhlkCBxkrmDEOtI2nubTgAKgxLlpqpQc2rEIHs8ToXKsEpEYPiUyTZNUeHPvcBeFqJCqG+4JQU6fmuY6UN+DDYAf10p9bO1t5K/0sbX6zsyB1cidHaI7+L8IX4x4tQEbJi0m/876eH99IEJq3+eMgOEwnMageyO9o0Q5EmuXKUBrrpjMJFbjkR5gAos0En7bwhy38U73sNORoHTq3SQInToYKRHc2pU9lLUA15v2NHS5ORvq/YvLG0Q9n38whoEsowPYamTo4WmkfdE8UsHXQL2AHlZ8/BAyPF1+5wSO5EMycooPSIm07lORUY3iAVYBmsgCzhsY04Ef/KRMoOcR1KwDxRgmNdAkFJVRuoHzsQcZwQYcWoUw0tymuTD8vzhYXYxyko9/mj+Z+pVXk1K+ZSIlQsIwJMQTkhDKwpXnoP0rZU37wqqUczCcAbIHAB61EWYEGX1uguIYpexcDApQamMPDA+KVDyP+GPEAEoHM+UcKDGz/8eLrpmRCgHY+nCS89VOWIZfCMoOLpuXgJ51DgOygEXidNgmDZQJhhhC+/xEGEEwe/LX5c0ofch//a67+fz1IcO2I1MrQd5kK4eHun4zD62a/wCa+RFvWbsodW2TRcYUlD0WAqRoQIuJCIVrssMQoOgejW5ny2m9DTtO2mcLSh3mlqct0CFdX0yWAEXcQhzAecwTFIZ97SopQ6GJA4e8SD8A0kCkh7j1IbT4H0J5SK6nOXgq4APqqupsAc3vBFh6bgHOLxI95VrQP5g2GCtBQ+rrTKRrwlHJweMi6s6Af38ZZzFRObjbDOrHRnGaXHT3JEnMi/ryNt1f4vl2q65NN1jzCD7RaJgo7V7hYNB+hSuOKDY1bn+8c4iMSTVwahQJRYADz2OkjLc1wQ3C32wcNqS9++Tro59WAnNZV5FsgF7FA6zBkd0mCUCe0bR5vXWWus6VtFhlKf9AxDjwivVUB1ercr7fUZjPnGx828n/Ygcjb9t/nAFl5bJzsNqbEJNPd36Yz5RJ38MPoEwd/0HcXB7z7PurkEDf6B4NSuUpl1hjKkhEx8WmLmAAACGe41JWCISApJYZtNT92zgHgAkVBwQiBpUF8usXRIlmZW6Cxen9lwsgWFFaDgyzb3rX0Ty4XQDYpLUcQDmVuMF0RsdYIWn/UMZd0i3whE3Q+Bx73RINDUuSqsUJlt8rtv3+CE76s/c8lBVgI8A+NP/9WAH5aJbhTSC8lgQG4kiUmyx8gi6e7o5tkuLSUmJfHhk8waX/MWjL2CLBPbTxMd5nEAvK90XD3n7iunW77CVxRJw94xo/RJoJoc6VFaCNOrKgZ0lOw5iHrEikHwBlQBXKZx7llMSJjDuce/VY6g63nFZk7SQckieaC22cruT+4Faplq6XNmnCWdJQyB4ITebGIiMHG6ma9JHtuDfS5KtTFjADemQ2AaSBhyy9UQF673IuZkCgZPgaVPEVh8UhjHjWYACI+QUIJPek+lfBNCV+aHVn6f9j2DMrqpBx2gFM+0nAjrgOhlR1kHuRqoZtD0yadcKQvkFZkKAaxWaxYl1ZgCbPSzUVO66Cfd3P9jBoghsfSBIQlYbRz3z/h0S+viDS0COp0ORvEPvSRuyBkhxH+bWO9OhoF+rhZA7mYMnjW96cYvtsjsyHNE9yYoDkQw0F95mqD2M59COhRmgCxQpUWadlkdvoDJa5rGXVziBO/PSskNzMoxh5zCEgUBOQHtAGlJIXrzD/KIzXOaw9DgKHB3ALpMUixuMHBVIRVpz3bIqgZLwjzH+VgtAjlBNAYEiDfEabD09wn+U7yWsN03yZYbycWUKZHQBZeTYFoHlIAgAXEGqC7URgA0eC4Tn9TApsH3IKAr/iXnyD++tt/f2479BVCEMMSFWsMSML0RQcRZkYzoMKAdAp4Dd1db/3K+igyeOBEwIgq9CWCQw1xiH7R3FymA5LNqQnQAcClU6W0beUXRxIQpB0LJh1Ql8OkajQ46URvZAYHFjxpgyn+MoQy8woENh3ZgieYKm9pHpUFPnJbfmz7q/bt7Du8pufdB1cfhMygqWdbtMIm2fIcdFqqav6I/Jk3TKWBaPJVRCQRkQPvQtIZ4iFDRAxWe7CtA7FARwjYcX7ewv86KGNiPLS43t2xTBjUzxIyhvIH4URErxq4FeCcgWBvnodbjMoT0nJl4LhvstqMtFRKoocaEX/EeEuzurOD4s8IGf45NUCUv+VmvIaAJQ0Dj5VKtm4FwPCAxhpAXjs4oVgEDSoDIBBDPADto+sdBuhm0TxueWH2NAJK7jdlMCvYlAEiAokVaiuMYJmRwa9XQcGnkVCHuP8aAiQIeDerIvcoHfaOOtlC8nHyBOBQDVPy2fgbFAxtcHxs87wEp60wKziC84sJAPcYd0GVPBxe6HE4w9ok372fdf7vMFNoVwOoAKR5+vfm7kCVCsfqNFDCA4G0Yro/cifchy9wLRTePpKP1B0DYKIGPEGTfLVFAWIBiBQDcwJg179xx1NM/XuTAtgQkJKfYj/u/fC3AvBzZ4L7jmh5z3lBkOGf7KETwQDCt+wLqe+lJ7HEBc3Npb2RYgRNd/+4ao0zU2fMvXSpBHwU0F3ApJsmHnuSdVW8rmSGmSU2pi1YzDiFQYCzG1lDSB6eLdK2bfpb6l2bvOQAI2AvxF6c2/gEiHn+N8rW2tiRSN4fW3se+dgSHi0/aj9P2BbCHTpbZPxdKwA+SlKwO+7ud8XLJOQKvOfxHikw4qae6krM1+lOEuXudef98KAa4BVt5SDHCFSCDmzyc3LNsIHt1IupU+uWPnsyjbzxrdEZOM/Dii2Q7MKTfIGHEgU4AUgdtg247Wdt18kOkjvnhQqsZblSWX+yjejPqQE5h3FLjLFhZPjqv7OUUxAwxA0l20U7DZzxJwwyEA/dz9kPMAMFE0CLDgUPnVs6/U0UNm7qd15l8yD+ww7V3xYkBYAcbPN3RWs7tbhpXFsyM4egNvg0o1Awi1/NE+RFJa7wej0//ut6WUs0Vuhj0zYw7tQEPBLRYNv/FHqDJiPSgBIqd1ye+xh1kRAJPYgHBTvHCveTbYG4CDJ7OF8HoVRiZyhKKGdA8xHE4GVkUPkNg4RmUgD5BwdTBVCNjMi+QkpopmBtTQDbcKMUwwDY/aSsCWBjGXD6v5NBQ0oLAPih+fPf/vvtR4ThHm/m0qaO03Z/8uRhLShDybuLrs4O0Z1LZTa5YydBhQgolJZtgCtAMG8YaY0CcY0CdrZGxu7KrCLyhuuME2tYc1KpEEzwxvLTM59El2/cvM4zLicjP3UsL7jcpLoM9whkbwW7INxE3HmmVnKbXf+JIKY2p4G95r30R0bszFbGVlFINsiDhxyMwtoAe+68DGCQ6ELAj3uhBQxYY96ax4FxmNEooK2oMkj2ZRcRLZ3QQsdK/FzGP3uwjJyLFjTdszu6BEtFtKi/xi0PqfC838Gbod6PHl+uCs4aCFgP5hB3JqPhWLDbnR1EsP9nWUmXn34JphSvrClPEtLRb3bDoy9zCJKCwA2NUoVxEuCJ3/gDD0rDZNjpaLB/rOOKDNMQsJAALIJmDdhsBURFGEICVkqMP4bwHBsCJOB2KzpNgme75Ucyq0CYsMHU44MzROZ32+CMTG8imING2kixDOCRd4jBYA5RtDzhHnMYDFBaVPufeRBLAkoatguAAAWfddiFoNO/MmWIapEha6Bu4vZh6jDQOcx5nHSgiwpyUUno6IKtWOflNE/w1sV+5qGfuPZER2le0Fz9szDo3LcASIYGiQjkVhBBdhDxR878v23/f3Og+OKSXiGmyfyFkmkYuSIiRbPbaihZssvml8NAmbfWqrA6uHHxuNhzQ0sa8i1vpnLB9IbUDwsYkHdQNv/ZRP4CWECUNCTpCjBqUCmAXfc82+bNn+GQILjbHOiBkA1K0KEoQJvi8kNQkCEZyy1tD1jwH4+UZ+MFyVhOLwADuBk7VF3AK1K8ekf1f2CFZozhJ8MgDzpGMGFYYWHRNMOi1mntJpIoSSW0SMTO57SUMblHXKx0nUXfbuF/nlj0L3aQEmdrNzwAmuHkrBNzj4DpxcmdyXyNwJNJkeV7SCeurt/YQamLhAl2kMoAXtGPauEhvV/86cliP7UGcL0dnb4S7mjw5RHEdZD/smkdFBpzD3BpNK23a+2KBIB3UmDWCYuBiFwnX7jmgu8PtBye799t4dM2uIgflOpxT+eQvTwttdVOnvY5fLDQqy8RgASESg5Y+mRIuuuVVLNqz/xeJg3bcFfBPKSQDkR+AnIinQyauQuSPyizdjflgjU6xBENFlUurvs5ivI5hwDxMbpsIZq38yT7j24YAPPiAy8LDJRRY9k5D3kyRdrC0Q3zYzXs0m4PNPsUc0IJPChZGDgR4GKEV07cULlAZ/wysRIQBBYijl8QAxAM8AEDWIfX3wrA7wQU36qClkUXZZpsEPbcXgxmK925LuoihEL6FxY65ulPJhmwXdAIC0QwE5ogk+dwIQRKLLAwGWqX5b6Mvf+J301yrcD+hzHGoLoTgSCJjA3QOUcB/FdUAzAEDOqLMaHOaTfnTpGYJZKiBZ63Tiltq2kv+1nGo9Z5xz3nKJDgJ7HRdwXg1RY4TZtoS4fJ/BkP7phwdwfu5Wkxjej5PI4M66HDnbZotxuy354Sjs3BSiwgxFLRlWDvPIW4JpofHwGa4c/ZEgXMmIDfEx52jIuy/AAlCkSsQFAD1B9z+wuzb7xUbP87x/3EgElnBy2eaGSxUCzzx3UQ9Rfc1/7EUeBn1ABjhTod6A4JEKOgSHg+xYbsmwgDBIKwo9sgQEAYjqn4NcYuyQLYeuMiOrgpkzcDqKTDamm/DQEb0wLeBMVEPSJ94uhwLz1rMOusNQSwAERGlZGo69lkQOfd0ENluTZPXLyzQvlvbzDIX/VfNtGJRz+QYWIA2gQZgXIQBhAUXNPmZNBkTv3KCnZ0nVBws1FueMaL+D+0EqRBtOXzaFEIoK2bL1CSLxAl1UFCIlscJ3dXj1w1yr1d/Q0v7CiCEPZnTLaR/osYgEaB5QMqcUhmAbCA+K8LwN8AgN9bUPYD0NiPaTY8mgb0UfcquBFY3W/yfx6LNSnGqXTAXMsbFxkXTh7kpqh2yDfamGaKGcBkmTQoJG07FGw5aOJJ+zUqz2gKN2hhLosjbi34FZphZViKhnUvsGxUXMxzgs5I2YUQgfYN4IliflWDtWWGjOXyKP3InMJ7fivQTM7mbPaVZ5RKwfpVHYSN/p0Ig4zjdZOjvrortpy3g6CCENZNJK19cp7cxlyBnRDCc34rgJHm/fsY0Ar8H1nIRVcsN9v+nwoiTMbcqNlFSHCTxqt1gn1UEb9LZ1jLVGisBIxlyL0hTNPMeBBDb+wgc571jOqo0fC3rwFxXUDe/jspaD1sCzS0dEiKDu7CfxvBb8sNYDaQtdtSddOXLTanRC6boB4+qMO4CNLwNfYUn8JkKN+QTXRmLxO5BB/xivpc7+6awt67tfzYEg5fBNUPEQVLF5aJWMEfItEdKIMM+pwfM0cBVgJsgXBMbhpg6bm2ofcPGgJK0xBAJODG1oNYYrZFTiNopgqWuBoYgBFDkz6nzlybn6S9EK6uiw680pKDckKGWNsSKmciENIBFCsDHJyIeDEMUtO3VkDJQWAJwdLfCsC//0DwgTb6oQxYq6ZpwHRYXAcxVprB8erg3TN2eIxM15zALT735zleBaM7oaAvvb1mAtrca8FEYlqsfNdrYo4Wx4lktguJo63uJdCK8FtABTAyFwh5NArgpKN7RKCtOlag0I4xnaLBRCi1DLeIOQqUAxyhRDJee6RMVAAMvHNDLus5wkIFNBBXNuMvEruXOby0Aq+Eo7ySUKH5us4OSDHbFrBj+GIxEkUQQWjZEyyV0uf5r79zHcQyoCmkOipgyqQYXBpl3D5wVfiyc+s/iwBfvUEuKOlA5IbyXI2yVu0peTaXrYO6/KR8TxPST74Bf1INkBO8eTcvv+jgULAc4ogGx67geOaeGhzTmYbCRRCMQofiQMUFOj5Kgk8PPhdGPz4WgHlWfS6YtswYLsLNg5INpplYrjl39+OKi3FkhgMXYmrG0ePRr3WQYoRP5wKZQ5z/06r/G1cjhY89Jc4f87LDJbgDA5i9yUZVWKZVzqY1S2demOhALTof1FqepQubz6oaCLxwYC8A9KnwiJhhgoA0RARqFiNr0jDyrc3xnXvfTlOXoDdEKDTjCjApFfR3GgLmS2jUT537W8Qua+PO/6YEJgpgBUDJ8O4GsfY/X8tc//bf71kJ/oysLC1sgJE0QGppNRzAUBCwS77dig0eyhgm1WRwk56sl8zoRWK6QqeNZ9zTMu8aQYIDM82EPmz27BW6YwgYk9ygaTvNpZAMq5iXAh1wBbBLvZlmEmWpZIY8oRLAcBdPWXicrsitwEcIc8Ce214a7sFa512JDI8zHhnzyNYtKkrNeJRoK/lennIBE4slRIzJzlMN4q5ssmjs1hhWtszIVzg5dju2e3D52HyWsyX9TOHx0uV1Bwaqr6Mr7SLUkrbsvjhxVB2WwAQoVROtVCc+BMANzo5IGpMnW5cY454qEy4QZJC6/ZMYoj+tBtgiaPxogLAUYXSJoFR1OKHVPC8ZHax9EMPk9aNahAKZuZJQ9+rJkT+89JUdD6dos4LYydC3zz3tQYIO/GFNxMNSRnn6myRYUWWHjv6KBPkXT/9jYQYf2ahqZjYv9UoKe8ooFNOAJIsoA8yLp7oqUvgOd6DMMpDlDt0FzIqfIfnkvEpbbecZLgoQvOGi8IC+SKIsrmQVJ/lN0aEvWFaweGh9EYDGLeqgKwsMKlD6NlGrTC3YygaQEMzQ4MX/sU+i8oB1RTHIJN3b/x/v/f82BPyu6oH7J2NFUt7+ILFiXk0i9NDtnXEjOcp8KI21LNXWcSDDV3IzC7HjqbxBchiCJwn7uInOT377Q8Eyxr+gc1xnT0LPUCZeQA3AfQAOBxpMMDBrHvz1rKWcDCOSgxA96RI8IqJ5qiMtjSFoQKrmHDAHgjk87KmcpT4wFJT3rT1qQdRXjK8C+6BDA3J31Rsb8EzaPo6CSJVWM04gQgUqCKPABmgotANzg4vpGKLdmu4s+QQtRqI+LprQ5h+fYLQaGhw4CiSeabu3tpYyJqcXrSgQnhgrbDUz3XQoCY8M92DjjxmIwmxQRTvFw4CIecymC5ody3mYVfwnMkR/cg24koZuTkE3nzhjB4kRRGBTWxVJnKAMGK2OSlPvdvz/7L3pdiTJsR7o5p6obl5d6f1fUn9mjiSykO42afbZ5hGRCVSTd0SyMw4OGo2qQiZisfVbdBnwN23Z7tomClcC2ClHBCUEyYPxX6j9D6Vo63kHIYBsPIeFcKBCyeSs3DdYsUYa/VH+//z0KkCnQOCmffo6dUMiaW/xm2ad3zAIEr+aRw3SpffsGvu7hn+NocoKHgoJHfCHufeBosbqLiJ3CFAXj3lXfxh2jWhFCGt2oGneALRUGA4fzSwZYBGs0kDN+MCOHgzejW7HVRRIaJxa8jez0VZhOKGwOfJHxODaGEUZFL7BhgXSNj6pYL6geY+A/imGQn4tcjcQpZPZvnTYxkuINzcanf7oaPcDGA9SDUrCdxsmNsMZmjMSQFxguS2lgJiyttSFL+oSTRgqSStQF+kAJK4/7n+4WS6I/asExSMm3GeX+009dLSJnorOV3n0Ljtl/d+hIFFVyB9a4spDJ8/gGCodQWLoLSPZu8QE1eXvtvDw7sU/TzZzQHEJJIBEvBtYZvVl6CDVyCCzUmveNSsIpUOZWH0FSHfCarH9+NP/fmv/86d5jWQRrkQB9ARIAJ8r95GSGIY6GQxWteql296lMiCP03CTynGu2xBX4VDp70AKFZaAb4Yt9H1zJfDNHEDVOMx5YezOkQ4MNZ4whCLCNAbzDVUJldWA2QUD9pNI0MY/yUwCWmUIh3t7k03Af94Yw7jf9OODWiCCbmEczykUqpecpm6D79oHGCOsGEZqNiqA1HLlQiX0BkkiSQAsjARBhT66gZt8ViioDlBAm1JZiEcToCuBacwALWBY0wCaAF1WiDLE590yFUI/ez6AbSTmQtCGb8sIGWasySoO2ptVai4RYu9e2ueFp1HE4LqW/x2wH3gDqArQAAa02djHSQCK+yTzAuspAv18B/CO/v9XYKPPdwNQ7JBFHiDIMguUf6StAFhi5jUgUmM6dtAkIPfJ0u0RZIn1X8oL3IBHaCZwuFSpU4eOYl4/NLqSwkaHqgxN+ErScu8Ku7HvDCd49lZAWPU/wCCDeKnKOENPZdwEz/F4oO5gLIomSn/8k/6jj0+R57rrck5MO37e1o+7MDf/qq401Hw97jjR6To096pSHIL+n5oSbjqiISXROUfCdCOkCQAZLchJMhESsJB2D2gIfr8JWeynt+OYKZkDChp7DIJ6KhHYMLxjXiTDugVtKGmphkA/pBMSFX5bCC9V5+zIBDIRWmVKXxGi/5h9gA0Bwsix+MYQ3oGUpazUsGgC7E9JmcBgPcFGei6sBKQpWNN2Nfdm21AD5KytGMf9/Di//3FLSbgPIwc4o0lEtVV4kLa9aNWJ+9x3wsFImPFF7T9M8AzVr66lHiWAK0NI0O+iEHcbHx8EaaCOglqibR+MBMByw8qOS6dA7uZK7KxusdHRJoDZwj0D+aPjIFWGUDzoMjXQAQE+NRfV5ZvwLuUZsyLP1+Aw7Rb2zVBAatOq36ZAuqNDGgAXDFhPuIApEhRfhyK0kkMavRPAP2ND8DQNqJcj6lhEQ6AkOgSoWaP7/CADei9yvJA+MTeg09R8RsT9GULFrijnWrzLHG0lhYg/OkAI8hxPCRui+qCKchAqt7SEW12RQho/Hg/BHENbX20FBM5qi4FuWwGlVerW707Slg7VZBQJOSn8RUni0QGIptCPvv5GfJOVgAg7jjtHSYdA/HjwRysIfYWEmpAn+KqfQpCTarVFxoMzpskHGZGysUYetmVAN5TFTSWNfx+KeW/FWEZnanffD6vem6wnseJTL0zfBvKwWfQ0nxbSB1rGv4IHFXKAzIKamTMKis/punsawAT3a/24/p0cEKFrk4pjk59377BlhgGQCQrJMwgETfWOZyQAR+lwmgSgS1r3FIfgXS/6cWb/x035eEi/qt2hBDH5jBmHbYP9JKxYxC/1qJE+gGBSpl0Y/dXBYfd4G/uLknODRwdNXKp+kYW46SZABKdkHKTsqRtEz+HALrU/3SZBJlr7Yursbnx47uYdVpFmlKwGUSK01xbYALYZVjYgFgBwj4NOnFYqzWCeFJA/qfS1WbS5v6Ic9NxAmFc62y77ahU0lf8lzQfb5KeHDQClLXB3K5h3AvgnawhOn426XS+fK/pJ+sdVbmb2OdAFanFw07Rhk0wpOe5wpBkW/bgbP4D9xoP9ZJ8A1Lhx7FRI8lIkG2oaK27cEuPOWRryoxW4z3uA6k1NizqUtaSIMV59B2Glqy6vbgWElflbB02HFKQnOr7mHaLc5N5SeRtzZmjA/E2/NiPx2UwyYMqM+qdKCdwzgFk26C0eKkMHgScMX3GE/t80Vvyn+otEWx7alwgykgnu5GZZ/uHARV2cLp4eBJc99fIA8zRDMYTZFcOYXNCWZb0hRP8xfUD+UDaKQLy2a8MJJJT0bCkQnd3wRGXPZOOhk8LJMf+Bna+N6R8BWrfE0N2ebYOEgr/+34ac2R++gldPW1K/K7rZ/VuAa1qzBL5mQqND076ecWMm2w3hTsUrgVW2hZbZ37DL/KFKhqpMp4NIsRgdmgBAoQLBCttgrb4lDcggfhoYlELBHSyARw7YNgH2nCjSf07dAeQaAFuubnhQbbYMAK5Yi8CD6phVWYY3LSj0+RH4soBTIQuhHUDH3B+kMDGHd2swjxoqBRGZwKQg2jsB/It0A0Q+CiHn82ojKoX3kotuJjSsIxyRjCWdQ6pUBOQLVR7uhhHKsDvMFA4pR+wLctPagAhaUVTv1RlYZWIEWyxQkEctxChmIJRriQGybItELPcR08kx+WzfF4HTae4CN4bXfFePLXnkxl2wQPrxU1tzeSq7TAhuqL8YKr9z5mQ41ePJ7VwwBrgrTxgqcmQCw7MXeAibZgb2aaquRW6yqsMJci251v5yU1khznFQawYSxeRj+mbYQv9w/KhgJkl19ZsgRAX5P8gatan6GYAGpS5DuMpQNZh09t8/KAfgh5nl+QkRpDLEfRlBrAMVqqdZkjxk4cQdQX4tQ8uqlMknp5gqtFWXJoC1No1DHI8z+583TwAIyroPEIKYpmJlBTP6ALs/GaMnm/2ZNQ3zT18G/NyRqewSoTELGt4E9AH3YNGbVZOArrwwXQXLR9cgKuUV+zZ4uTKEkIThFUzGVzR9XjULQ40BPCgpJ0BuPZkC6YfhfzXoL4hZTaPjEXAdi+uZ4uZKqXAmgJWyrskJuxKDhCoKyIwhpbHu4IV12nzhYx9AdRdIv0JDfx//V/YEYRrPWvkHJ10GQZAVkpB94w4zwqGhHBoTjz+a2stOjXWMgl0HiY/bdHQ3HMB/et7SS8f7sxuLWMcnMoe8yyB1wUxG6QKCTRDfMRW0U1yoqPneP25TWTXWaqrOnMZ7crNJHaiGYrmkgTE+aOjzKDjR33VRJ1DReRfc4KNll1DEIR3RzE5cnvqPjq2swMT/OoV4ZEUh3L6mPmx38YCMopAcdA5azS04wzqU/r23/71cb6uLhNz/4wa0jV2/KEK/IiF/sgOE7jIyu3/oqJzH1AQ61RdQBgC6+GVAgJYQBYaPg4bvh4v0WHxuTPydAu329TKgGIcFQQyE1b4W+VpYdwCQitP3r5OtpVYoKhGBcC9rYWOEqXnbXT107nVhsg9kEHseSfU/bzL0/6HaZjdTcDVcEIrbDot0cgFxNq9OJajJsC83AeYXz/cQp/N9wLYM0LMjgp/cdBHUZR/QZSug+wBBM0j933UUpAU1VEKtCWhqlwpaANEKMRa2JoCR7lbsysIqAGcVmUAZYUIQM3k+pQXCQ6YpbMDkyo0TAJt4IS0Oxd8RdFesfOlIA1rEGAZ0UwTyDfDQnfDxeDaFeB//JK3ACUVquBjHcfXmcs6P21ZVJG4MOoDeisLfZTV3kah/W8YBkkmGovnHmE45ly4iBSS61R+TsYlqcHIRmaCm9jLasUoJKxF/Ti1EsCjuZl4ma8K7qFLGzsy48kYZk9oSINFmLaxshiUN3G40f4xHChnaoM/f+u2HWALw/xGNdVP68ofE6KLo+wWNwx4WhoZjiEirzS8c4fW3NOE7NnEM6wMCkn7DYlJ17H84g+wv2hl8cq4E4P22sBNm2wqIWM5dtK8FjDQF+6k60qqU8WjfJdb7VlOtwrtPjHU0pNEf/Ny+LEsWl/lvrgS+ygFEoW6vo8AjTxjEYJML1c7NBl3YbptvjH/5iMiffDdIqKr0NT0LbNzg0Ieo8HzJAaP99w+2PoBMF8iuQUuZ6I5+bSpoRt9pyAGGIIRNn6Z1AD+X09NW6kyBZnmDb/CNZBxEKg5B/VF0/CZFhwgEfaiOlcZRbQK6GcTfSVmOzSChBtg1cz9CZfXpRjGmr6sT0qZdFJlVAAY+lhs046pmnGAW1NbD27MAhbNNwCh5yLqjDhRQcyawwEDJq/7ubIAKAQIrcIeBtqIF9I7+/7RIoRbCEmFPD+cPnb2oUqcKS8stoQW+tq8K6oFqw1DUgioQwBxKfVU6AEJmIagUQXco1QJZRUxVOlR7csjVTqieNd0Jqo2p7oentwLdrQW4f97vt9uHPkdAmspOWMejwFVjyipsfXkJYNdE0eQutt33IV4CN7h5r98+6K93mdwOUViWpxjrhuZSbsuRID+74URNLgwYIQlQ9Llc18Frfzxx0CILGVENRAJYvyEu6TjoEZF+v7XfPi0HLOuUTCViKiNsTnIBSLMTmN14rPdHifgINaLBMRiySRrfZS5mhGHNBHOBMlb3AZtwEMQ9v3pUv+4DUGRCpMruqMXwvoIboW0noEcjwUtpAVObAOWFqTrEnKrbDHVWbD/uOqJZ00ZD7o7oMxmPPTeViDA2diqDyjJghLeX+h92ajG3iA2MNXf3vNgBC/vb3TWC5raEIDVsHVpw3D6EjPb7hwydPm63H7f+mwoEaQKQPbD5q3QIBN2E0i60AFJisMEbYKLNbuYtTcBU1KzNXWPxNJVivWwNsHwBwDFMVcdgVQqU2ZGSIBD6Hc6BrRU4yeoUL5lJ5SIEXtGhCGQSGGNY1U9hCmbmAOYMo9i/2gcc9Grewfef5zhIy3lnaENhJZB3pZFAkLJrfB9wGWiqVtyMOn7TCnWYBRgPeI3qeFd19SUPqIWAOs0rnNMcZiS+yc7ThcSB85TqREQQ5D4UlzDYmdrCUzsHpScLW/L+0X9YQ4s9qtQ0Co5v4yY8qqGKFN0pLCLSJaAgwQUJYfhD5Hs/fzxKm5tsBT4+xVtDtTjdXEznOZBn+Kl7PjeaV1xQF5rx/W56PiCayVBMk1pUQ0p20D0b9gEd6CDgUzwTqLnh/2oJSyW1lpyqFTHVAORTuat35SU8vgNqAiTipvgxIwnKMENmAPodqbPVYNJiwnJ4aGA1bSXQvs8S+KU+oPjGaKgytoItqS0ToJg1rIuOCT+nzoIEF6R+YkobmFqGq4uCXmkOnutRIuJR7/9nt9rf9DpIcUHKf5W5xoJKolXay5FFEKyesoJnYL+cEyAzKIz/fi4X9ODU3KFCD8YGQjcBOm2Uu01Mg2UhTCoQRCOoaT510Z0woQkAH9+eS436Kg5hLRs0IfTbpg8BQgCaA6BvVcpwTohQdbWNxJtcOXDskfdlCCsPkeJTAfCQkZT5AQADyiYLgTXAcDVowEW6u0DGQOFNA/7XWgYUuQ4CYBjWwvI4y5p2wWZAJd2UAKBP+E0L/aHI45sOam7uv8dauWK31LS+09iwnDkM9qOCMcADZsQKwQt11XDRsfzSysSwoQt+8vhaR7mCEv24md29xQFZCYj5AGj2Knmid6/cqzchzfou64d+6E749gjKvzf6P4/afJhU3YhiHDI+SyjBP+7O2pX4q6ZSZu8ldgKTjCggUHw2N2ZJa6DaK0YIHuYIRAgUt7sXqeJwpWeR83UlNA0zljGDSXJoDMFkWHVgZPY/jCcwvZLE7F3ZY+7UAqow6yCIqWegPuhI/3FsKBAhAQoqYtHxAX0IGJNbxQrzyGIjLKns0QXgG3dnys2wi3Fx0BmSx/tC+C/KDMD+PboBJwZDATl6VIcvea9nItXx9SP6r0CGSbu3XKEofHis+Xi0ezcVCu0mFCqrpw7NuK5FiMppdpkFaVRFAlBtuD7u7ha5MMokvw9kPf4od+6uD2puAaYJAaMY8RadxgmASgRAQTYO0tJqrlRxYXbWpZiUAa617InFe9B+iYarQ8vz402A68FRryQAN4N0Z+C3FvS/VCY4bQV2m0/yUUofLgOu044eM0Mta3QHqzqDmBYJ6sIGwHIjGTbUEk2DZVhTaaqpmkIKYViYDdwF7wLKi/qhgh9ks1ATy1LS8P1T+U6ulUOEEYPyj20cZKNfdzO9qWmHoIOIVD9Gx7ZSqAGvraMCrxHxlJtplXu5fLK5B/7NeQNQkwSKNDRcDK7ESAPKD5DoTyYaQWHAZJOi37QnqEdYyswwt2nWahiJzAOjjgakdFakFWpuxkBYAq9sg+eoMg0ek917OhYDrSes49f7gB784CJDseOC/IXXJF8Lm0QELyMIs/0yk/G1JgCHSeELngaEbcW5JY5HCP6PAV1oTbzaE5hbJCxxXSCok9tkx3lUaJLqQ7BqQrAuAwTjJohVdxRYJfHAsx4zKPmZrNAZAYmqUjTprfboTAmbALkJzTVedlYqDQTHrjC0J4ptsATwOSEP1wxKO00kjtdx0w4FVnXUUI8+eMioYyjdeQYaCLIQSgkmj/7ekWBdwh2eMDcbB3XshG9uDhyGwA4nx9suGeENBPoXzge+jAJz2FzqwRYDVwCjfuUtNr0XjRcmU0d9sGVoM6BF1mA15vdDX84cbsudKB+Rdy62bSaZps1UTINGdTKVG0GMayyxcRA9/tkcUlWzkZGRBrQPEKS1vCXlDEtoEspYsBmlA5DHE3BtUVjrKhohjk6Ph/2z6EZo/LkBINRNtAdiAbY1RHlOkq2Wj6ZbmQXZ88bIlvxBOaUQ9Qj9zuPZ+8tH+xGWMmTCBxKRyP2smpDRDIoaSslMoqAsoqnSgMApUPcBNveXanvqNN5EhDaWQAj7W9zWLP16HHR7PQhiswxrwB4dgKEElQhjK0AuVP4X6UwNA4QOovoQrGU4b3jQ8IrxSpzLQAbxuCsz4DffvwN+q3a3gAOxJgMehSdl7DDOZS/yuS0G2J1kuuXh+64QR+SBc9EPFarTxEOKQRKG+o8me4APyQEQ2VfuSNICULDgg5jCLh6LsUeh8xk+AYz5T3zoDqCtyrWZerbVVc74mfpQQPUdAEDUaya4SMtAzMOUbslqf1NuoVFxnwEDbb0XQWgtHK6sYN5NwL8iTMiaOXbGgGYCi9YI1Hp7QBeWuyI4QTZUJxV75kX5HcOApXwxc5/XItlnN3C2lOdRYkFXXwH5UJ6wSFIPucPFc0a2ndj+KuQH0sftUa7dx7jfPm4Gp1EEmw5UALGTGNMM5nDHHm7QJyDaj0fyQzn8P1T29ocg9pYBRorMUZC2PjllIgMYapoN7MDx2cLbV9+g4auMLwaJYA1EThjm6AM+liwy/98QLqPUEJ1BHPPNsyLUCZrSEkD7EDB9Wx+SgIcqF2mRrYt3VYlQf3n9i70iRJMckAZBrx/b/sUyILRIWwWGWraBNpzxhOX6OL4yLNGVJbBUxFUVkNv04cz0Pivpc/jOztT9neQ8osn6Ad4Wg6itBDF1bTceOm8SEfiY0yUiZm6hf+oiCFTA0JNg7wKwCdAAj/QuHaWw0gWGPMRXV9wiB9wU7bFRLhgDDkQAZTqgzMzXTM5tymocXjELoC4v7e8UbmdLiSILH5itsbsIwDg8x1ZO3TNkrH57pOC5gkDWGCAGqyjX8AbG3OEDDgTD0JgZPJ8tvI9/xYlQMryx9PdkHxWA64frRIihIyKVDeTlMFoEJx2qjF0JwwsYoebDWIJYeQPBBRQidcDGUGgaEE6Dwx2e5EaQbIomnzo2RoBpJia6AITgtqy6Gr7BBqbt8YDedCLUFbBP0qw/PsuU5lHG+TiItjSAXdqnize4hrFryC+bV7MNFcgBi4BVGW36ltIRgrm2+YSLS6usfUbYYAtjwRJKvwiA9+WyQjovueuQGP5SZilolFfMhRQbapAcDGD0TPq+toj8f+0l8HIfAJWIYkNNQRIuWCCXipuYWNlvqYsA/Hqss6DH+xcehI7hfioe9F46gMrR5fLmHgngLyrShJP7w0/xrQUq1JqA7iAs5KDpPOS7D3yyJ5jp8HlfF5bFkKi7KeHwN3Ws/A3NpmycSNPPELoCdTM5Uh7jbMX+QkUOtcKB4ZtKQTx+2fvduYMOgF6eCbFaF+QEI10IQtS9ObuKcsFJGBrQBsJGAsAYVn0cMAhqwWlnM4mMrS+dugHb/LhCxDMs0Pv4F00Gvt9xrScNoNTN9j0zAXZFWlN1ax+9JW4Qk4DoSF9mFoWJQIMTgdrfYozZFMy/xAPLFGXAcgeecJk6WBDQ8J9lgX8qYgKxRhbM5PMFUt0t1VxJmRNZyClPUwmbIt4lxh6qKv/RfzNrFynjupN+HKvts+jqLgUJYXZi6bRqFXBSSKZhJQCE6PCh9M11i7EcHhhaGI+19B/uL8a+hrToJDhZL44l/Wg5LcnJMgEGSbSqhbsuYn0ZQFGU1yYgOpCXbOH+ognY+gDnB5h9mJrcdDeyQcWKL7oDXdxMfqlDwjKxbJfKW0GbduOw1Y6uYU0HQb8LC8zOdaKDKFCh3gGUfbjyrV0sKBQ55rYl5mWXYZXEY8AveIdZ/0G/NTWJH0N6TNWHMIlQWQMAG63zdzJ5OPOKIWfpMSS3H11eboNdIgJzVbcOtpXA7BOCEM1zrboFsCIxlrlM8nJSGJ5D49EoRY8VGqQYwAb2L06VPjnNmZYW/ZtLQex74Isg8j7+paL/RQrPGZ/lAYiCm0OcO0XTyH0SE+5kfAyYklokUE0gxScbM8xEqWGX2qaywgwxSMtRD1OFY1gf0TWDI0lIBk0xohOPSbOWmnwroGlgde1OyDguthrWDleEhNTOT8y9saZTPWp5lPreB3gUnqbjT3dwleA7u1Rv2EcUbuwUZbxngmgIoB/nPoaCFFJpy990jl13wotTQRr01bkyGN4do6hvyReFU+WDZrQCCPrm4m5V+Jp9Ywm0g6fYi1agv2wCEBadFuAdms+eEKTYLzDIwzr7lg4A1BDQdNfdYfh33xljJbI8EJOfo0M9/t9UjhWsvB++f/9wyY7u2ggoPUyalBMU9Bk+8qoN97dlanHgCsxpLWFQqkMnDvLUQzAGMlhUjVJpBZQbTE6xtdKJ7e4UcoBCQtHGArar2wClAug2GBeWqyocee5UwTh5NlwDBCZiygnQRsH8hHPq5QngUaPBLgQlW7O1sOoBOPCjk7GC+y0yAUU9GBOD10Hkffzr9gGH5x49QDYB8IdQvAAqGEj3Sw5QUS5j4pswo86IBiYNgCabnAxHK/B4AO62yto/usOgDQNtVeOK8khXD06pB0AIMqJMAXXDOIhMBm/cyAn8pBOhLl5Pf7l1fWwhku428ZEG2Hezy8hD6AN+zvpBCFxGIF0GhDUcCjuZFOWpRv8flNzV37tMMiiY/PqiGEjA9f5O5nJoJmLmuqtPvuShZW5o2hD4IEjX9nIWUHnzaI7NcYOvZv1GS8T481bg9moZEP8+7MOCIuDrX/KZVF/Tp0AGymGYw4iHmBgFi49kaazCXC3SwGxHiYhHCv1L7oG1w+LmyDUeZUJJKzsfPUV6NpWXPmMZwEYYvreU7cYuvh1cw9Qw4CaDRYLXok4YoQ8xoLDTDVRnjjHL1eJ0HETYBrdcCCsGYt43+Oqy+V0DbA7acPaFXd1uorVYLyygsEOERD93n/6PhgfD/IF1ayXPsKqE9p7jIMT9Tt74+2SY6bwKfh//hnsCvZtUUgWXu0MoAlIDaAgej5c09HSz8gprWIgAi+Vth9ocbs+QD4rbEmkA5lvoEdwVQ4QiSItsJfQLcB+4FyknvdB8PCnMPzSMGeldaWIKhyAyxKp23mQzK3kub3Nqm/5IBop97nN8jI+fU2K0OtAM1aRuPgjCSlZE2EVCTg1+u0JXhLUPUIs4fEGtzYw7oMm9og9gc+Uml7WnpDFhdPGbPmrBewVLALJFMBO28n+puDQSw13AQuuGEcGdH/FoacLRjmrabGDaNH5Vppid9vSX56/Xwv0FMJRDZmmzDzM0kkOFIRwdiQGcAFVAlQy2ABblVczil6Nu0e6Za9Em14N4/B8FdZtTILbvDN76gFYSUOCO7pytQOhDxIyvxTaiJABD0esg6Icah8G38pEJ5PYCMtnddw2OiRbVBYIUbOES634OzUzZeqnUCEJfnErRbYUzj4rEsjUH+kNbKyMvZY3o55uWXzalXPmEKEO4eck/XCMoEUGbLQxo1u/a/988ASDjpx2ET4a8PpCQqnhL9t2AD8BxY8sYeKklgK2gzELABaWb1WR65y2sARqc76Zri7UVfXCLJ2KFdpb6ajwCYTNqfUxftMAaywxZCas4jDLV8Lurrpes69RfRHy/BdDRlSHZU0e6ucMgFpaBG8Sg+KdvAj5d3z6w5s3nDQ4PlXAB5MhH4QrYZljjCZjDMefI8b4GwOXmiRXOvoxIu3xOBsYEZkYOvwRJeK6UjcO+1qZquxHjSwHRp31AFAwlDbRoAiztLKeuxcgPYkFTdyfzbmaSyhOb+y85p5vGaBq8fAN/6SoT3SzTfoRjTPMVFWzrltnn+baVQK8TKOq067ocFyRinaqBW80lIh+O0AVUrQhrQZQSLEKh9HELfhja5G4PyRLPgH5vsQS2MkjpvMoNnnd2+jJgoG5wo25BflYfnUsPrQigKcD/xhKAVsG3mT19w+jWtmeqBW8LicejfFPzDchsqZp61QQtyqC0iwK9waD/flDR+MyBFtXQD6kIc15Xdi9BOmJosS8+kDe9O0WpzOA5UsgrMpwA+MBEKFXk5IdPJdfoDSz1pIocqHb148m/qRwmK0ZuQHNUwvuClpwoUYuxjAzYlXkMPI7GfVFM1ImVpSXTOR8QPlSwxqP6X8IaU4E5behVv5ea9yy5EmAfS6Ak/2zmKXvvihBVnyasBCb53Li5a4JFDDx+atKkCNHRLe5Dn+tDzCbbXz0gc6gSsGbIZkI1dzK5BPsj9D1Nx+qs+wCAsCYL96IrKhSKEQbM0X9T9wFlM8ztlYBof3bfeN64MJFHSDJYUjCYsQ9AOS7R7a53iiKCPAFExA9isI1iWlvHNyCff/dlgLHvtEL/ANKFWpQoAGDiqiYqNKjCWvX/9NfCLj7wuXUKpN2PzZq8m0NfaVBKSQwiXq4lhbMr1TW+Rwdgap3YypDPNB+X8T6b91KMYSQEggz4D6m4sGBrxv5orgy+L70b3Nvk0t9MWkIet2G+p40c8NNb7AMwOO27MWSsCU84wncC+PfbClSQKHHz3XABDlmTAOwABKaMWQIRkdgKwFNA6xNBh6gqVi/wUH0wp9IbRfAB1Qw3w7RAH3dmPchVVEEH71NZxM02w/JEG2dY98OGEDWXP4NpCztMMsGHumPbM9u6FUFa2LV22gw7cVdkgpquLYEZDWF5W94273gs4BCwHyEl3VCwOs1aPwuKvW9r4VxIaMQXxwJXzl9udjbj66YZczLsQBErbNSWzGH9gKhwM6Pf4idjw6AXbOH+fBkQ6wDLKcQ+e/Y5FAwDQF7QZabKTJnwgZGEH78CMDnTVZrntGXI0StmbwJu2gcouosABjU6GPCgaoQxVtkEVKceV4tLlQh25W69zGvZ53XqfT6GmoGJEDl8K42FiCpjkAHogB6St9DHsn2AKUVrlwqFllgJz4V9iaFQFyZQ3Tsqz+H6nKgIq1hrLzNmoGW2G2SZU0dAIHQGhBnLEWA2yPCgCw+zQujCEMbhH/7MQ83Us/4bAvRnAAtpZZBX3xSieiyKyIsGG7ibs1i/WYtpuOfhSiWqPCfjoA49UDgP6/hGlM8pPNDdYlZ72BC8jE3mijnNhOQwww4KKqYG0F85ayWsvqT4xqyziafTUIawzG8VxCFvXQWAByZClCidGWkAkeGeiJ1PD1awIVHqDgWRiEwxotlEzBeWIA3cmhFab6oc94O2XXR99RlMsShYEx1Eil0EHAmEW+Qe9AgL2h16Vp23a2j0In2TYfwpS6A/AwU5Q9iSs9ehZScMjJBNhBjccgQkCMW6EAjg7xyqcOeP6f4t9fgLPT5IS3KGQyOk/D9MsEl/Z3OQ9wGjv6jZ2LCF/k/Xi7ZlQKvM7EQi3ch8Y24a/eEWIJAIkQZtGDiqlY/NT7Q+IigFLRMKVTMOgDJV+gpw3Xk37lyqwmkOZ5v86XJlAi80PSV46WQLZMMklFlfNx0IG0ta4QZUaNubAAJ8joo6tFUGNiM9x/13Jvg3XAaceu1ghuw8QWOQ9LiFGmjD5F8MKyPUnkiw0QAuB7TDGAPLBsgOHtHANq0hsFo1CVC+IVuIJIIhwTDVUSkNHUCI8qJH8ZUABIScLiDPrPj9PT5arATk87EPCO0yh2x+TqsXp7OLELvYoxlzKGY301RSjKLIBxlfrKBXsBbek4BJJNQ0EF8jJKi+5rIVbwwuarGonKDp3i0roEFpIUC7r+QzaNDTPiA4qNQ2lQiKqVMSWWEak5Q/rIBlEKQybY58Kh/gjhV9iANIHwzh33zJDjAoli1yWidAMDa+31DzvnMO1FfshO8tWWkmz9Q2rVCsd4wVI5CI/vhQXljXlQB0w7MDaC4O6h2ALorIcKrQ6zCX7jWjL+PmwFB3XRYCtbrEKM8OK/dpqzNrdCAp4RsBzIL0Ei9zEPJMoHJArEYxC2fLjQGw9Gu5FSg7QTraA7yPf/9WICVwYj4UpHEjkLOC8d12VBGirjwIjhD6Tg3SlEWuzUkUO84Fzw4lRA1yWswa4bEGDXbVX8fRWWOQljJWY1n4xf8GZ/hm/Xo3QWlx/B4/boKGVhicDfFDXDsKU4QCVWsQloCOEARBDqYRFoo5WXFO3KEKu7nMjJHF/DtYZLYq6m89jf/qtiike4RHg66u0I8zr1mjCGj/MWfwhHvdFVdbscK8/bVZEFn92or+3Na12SICNwICU1y/5WqACmt19SD5+HS51CBKVIpWBQU9Xug3bayGb1ci6A9uPo9vFHKjywRwp+UmWwUHy8MoecoBCVzQ3KlheCK6az897huTKYXofle0hLJRQE5pkOgBKAjLAOrsClP2awAUe59ZwKMtSgtQm/+YFrcR/5ruh3UUqiC6TVZ7dc+d1pIu0Da8XmvNngrOpt4ooDZBDdZoS6zIOz7+CZNBksIbeESmKtpyK0DRUMIOzGtfsIPUBsXIQN3gkzXaWWWEgbUOK6c5pDo9PiSzzJCc/UlRJN30AETmccPkSly0XAtLbvtuSA1Fb0MiUSjEAvATnrBshnW0S1RageZ9wGeACRWnDzNcDVkMz6+phS5GQ3WIgUyA9YhJdOkJAjTI0CXKN6rNh/UfEx5sPgiqwwkGigptkkBcMEhh15cgr/5MUW+tC45YnQS1X88BVcTZXqztiqE+sEbpis6AXQDIJKMtI+S0C6OYxRSheZ22AojIv6tvzA/nBgc9GHOhm8KBUA8URwqHmdoOQPK5iIb6NbZtQbmI+YroA7oNF2+kCeBRUAgk1ER1bw1qO9QrKtTrEbQCcxtWElChTgk2sRSDxC6jR5JFcc4zOafy7KfpxEUmbzGhc2dT4fKQr+8MEiqqpiYHl5wAe8Bb3/Whid7SQH++cVB+Tc4Mz5sidkWhJmSag4w+APdYg2YDykI05IjTPW9XhypCRBpVoacBLSsnIBIxEzDMKDsoUnUjUFQB9iabYQ4QtsHCDfPmVDczR71x13Ah3n9akgtCjjQop460m0rG2OAeAhJsJFP/WqCG7COrbAVCnZETvfLhPFboS9+U50R1bclJUFCtBMp9wP6xDEBP1iQFNke7AbrPJAoUJbeo14vWD//CPoCcWExBELOhnoNSYwSkUdxGElhHYA9gAE0IQdkvnOG+ksKWrTTPO+HfFaHfHQIEX9DeNlpA52zr0NmB+pt2ls4Y8AWAI5QKgpZakYprJkY04FvaVBlC7p7HN0Y3wvmg7AW79TRYBrRYoDC7gquRHhsfJLgDCSyzIEOIwipy6l8z7fUmkyKdC64qhweBICziFBjaB3v5r0/syLFPv5E3BKj1WlWGe5IG3se/fzJISBhtycDUUsiEBTFzJzMbYJt2hjQhNsPD+WIpGkHe1xIcBr1xUKDzdD3EaTzhNf2paUERXpYenEtkCUDnDhTYaGr2YIYkuu7woB6KGVEzqrCZTdnvvA9n5OfznQuWhNNvPJqWnAiFNobzpx1NlWpCmDt90BEalCIyV6I1HAYDLjDXIBwEfoCCrKBlgSVwXyvoWWUWdOjInk56+9NbpIKCzEa4eXqBEoJzl6d9k00gFTkekyyoxcmStgA407k3TGOItxP0oSoRaKZCCB/dgJ1ugJRyPOKW9A5F1cTO90JIDmEi5q0JiD4A+UbJHaI46Ktg1d2HzEJX2ATIKUEP7jCRR6dszIC4j3UWdEeC6h733SbMrSF8sCZ9wGfrd0xOxTBSesVV+oDVXTe0O1ERq6nhbrB6lWLO033+SUUbusf2L52HqzLEOxP82y8D8otWFQLJhj8mKKWzRIQIintbQzdkumh4GabhzmRLoCcaaaBjp6XssAn7YOkDFCFKbiNeGaakwirsZDGHmjRvFsgygfbcS9kwrn0iN/cIjBBZPpC2vqc/Tm/ZB7Rctap4g4eLOxfJGdczBrClcfrJUCuLAQjYCICFckngmkK/7QKi04Hp3ApvmU2Y2ytXHQLpMBlwWXZsiF2GBbVmPemrlv++Q0mCl4fZb+YAbxm4FVCQ+0urekEQlKfjGjE8s/O0fIzFzfMn3EiNCzetM2A3k+F9HMQKCvqNrA/oAdhXaNCNi1J0/ZeWpdk0mFYB/7RcBc92TACWA7q1AiJD1NnQvt0cKkYzvxUviwAHMhkTTCfRCnAre21T/sOs1LmJHL3JsmvmAow0bdIT1xjFVChF6/ltphE0DSyxYCyB+01BGq4GMVp3nWAD/FluKL7L76D/524Iqk4UFdJ4sAa6dr8d8lOgmNxMrcEEGxOmbJI6Pgltzl/38YVOPXxiWxVoLKxa5bSi9NSF4gryot7tKi6hZLHmmwl9AFU/TpsVyKOreAP8UVX/sRvbtJ+QmhWWg3HQNr3gpJKlwjGXUUCLySx7GkieKRB7P7SirYfNrgOi4svLan4VWnWcfYA3CKzySRjIz6wmqTDFbJaT0KBreGh/vQwIJVK/YA4Q2l51hVCn0gJ0F2A2YgSRNIXf0nTjeEt3bZeKLsHzR4hvWHZ18gVGQyuTsFHD8sSle0xlewcEmC9eM83rtVukD5Oc1XaywSOi2zoVTtnOnVkdc1J3jLEiJSY2DKHQWAVj+t/Cc80a4WkwIRLKhRZNxsIDJSQI5uy7n+bSXTYS5bA2ogCJNtcC86FQ8IBKIniTwv6ss6ATGCzpAsVKqHDEzI4U4oMG0vfqZXh/DnWrHlh/o16ajrT+PTOCKaYC5o1RjXBNQ7SZ0mLRlpforwAhU+XCbGr4LsAXYWAGSB8gD/KPRmYLSNHaZCy2Spw9ASw3m1zpQDUdS7JS7SFXAvi4FTGbYU6TuRwe+yAI/lyGaOnMZV28Whllr+Wy0JCRM9qCoKrQCkwOwta2Fm4ZvVPu4bs5oPdMkVnRQg+2Csa5jjQEoKC+qntzuAe0gsmJPTvoD+xBOSZCvDUitgyAysdw2P7AUGOlNqZBJ93tk8v8blqXmVDcu3dh9/MrWrchwRIeobfmekBmGKnCm01rIoco6GMwrBsga5aaO2I3dw7jMhcK5SzyWZCsATKhrlj4WKtSFEZsGaWXbBldD3z9sTrqNQOntqQIANQRgsE9Sr9tM/w+/tytQHLFgyocjaOODk1GVMdEGHKQcSEBQ0DA6RhLRJ2lhX/zWZDctjI/cJUBl5/2WdB0wrAPlWydVgD5HPKVzhQzi5vS4HZTxWpulgRqWAe+VWlAF7f88tBk8HHXFEhg4bJdZs4e9FfBYsSEuqbF+pheDNOPkzHARzESiPlPTETuLbXUgigwi5wau+A1wqyyJFr3abyJx2FTz63WobXluVQN6l8DQ9OjslEmnNUdyuIiaDiXCwLOuHireDXgF2ZXzPA9RUkyfgzMYfTMfvjOfShD+OZrAEpVNo/+ATaD8PfOD8ilP5eLWNJyLAOQw9HEwZsCd8/AsrwV0ryzVCYVKIRP0mC+oKCgkgBwuqb9r5kGGyJI7iHbFmAZgELp7m2qbgL0THfT8M4dAPYBJpyF1RRhGVCQHpQaoe/A/z7OrXDcKkYdwP+uZqW17ju1W+7QMBzLhAkwCzGJ2wYJuQnCsBrLIEVAm38au5WmhQ4IxlEBT3Ox9xOxxbRFVP1OIleP6G6WZ4RNVDnhlD1EPE4oPibtqVDDWP7V6XyuZB0zco89Ypg85fLCYa9hnuM6Y70ghZzNavSx3+sqmErJ71VpyOesIC6wmW3yXUnTs1XGLrmcjNHEipmMFusl4byEhz5LC4XyYW1F24ndEpCIlhP43BILPZyk866Zc0IIewPFSGdg7+l+9eofrf0+tNLQ0TtC81jOUg/DAL3+zWRIUp00aWihUbETku/egu2VgL/Q0Hki6x6YlSHDOll3m13nkyk9GCAxI4iBKIPgj7Q02Zsn7JLKjZ4LMXwtzV2z/Ype9kxyhfrXjWLpaWCzC7YhFcVnQ4W2HQy6D4IvsYPv488CDYpAUeeEbYOKJnEMxHjXSUTNrYsBVwny4aWTJNuOE9WMscK9D+EB4gcQ0I1yc8Udr3Pl2bz+Nq0jt7XxGVEHrE8kgyAh124iHCRvcehQSIo64Qu4HEZYS+IN3lv6kC/zDKA5c1fsBH+b0efgBtQ1y0XK1gHBaPk6023FfsQzF67pLrA324acDN6yCo493sNdT4NhC20978Q8MkxtQyZovrj1NLDBQy+f8P4MOVA8hNs+Ywr/4hW7YgRUs4YrtICVGtEcyQ1yzSHcfwaGPt7TX8B2hTxcbNj9IzzUgzkVbza8iWZEf1eTRmKIwVFFBA1YxwDS21VdZNgyR1sQvfFJ5Mf17Igu/7Q+YBgvjCr9kFwmyE0CfKcSanFooTR1aGUDa4gJJT6D05msuCc8p1YP66RJ6cO4RMYLq1jv7tJ/OQjKvwD5wzck9J0J4qm3xyHUpHtLAllAaeyby4bqPV2ETcIA5uK2MvViGSsuFRCdKxAsfboF0jTeACIfO/bZpkFgSCECxvSXFRvK2o5o42sLMMxAGbkLYqIN6qEfo2G9DRDnYRBk05jpohEMIxdYnznfaPlI1te5hk/irE0Tx+iIdnznEUZ+6+3iMfNpj5kZLBMx4xbwGdPVZsPcN6CDIsp0wwguh+pEWG7FXN6NIK9mv/36tvBlchCOads26MyPAyC0zBPUWkpF4UMxaFpjl42P/j626eS8BnVbAmp1yu8VSecRismhmuASEcG7Cq7ddKEP6+aa60PwiZLWbGsvRQ9j3/C4s8aA94rqqeuUZxCbcRhoipaJenfYMq3S8kgf0BzqkKdxxvoe4J6+nOynSUw+Hif4Pu1yrjANdoUkIKMfP8MsnwKfN0zhm8oIqIWR7BU08B3935kANcF+b5iWnCkxKD1YnoAWYNAg7hppx+wtXI4BIOYVmGYRlKTqMqaVveUGK2ZDPihquoWVgBnwNeQF2wwDKc1GFCD3AIQb2lD96yERvw99cyoltHztt0+gEz/pYeReIsncCEbAHzpft/iXVNJS7gMoiU0fdQDFqVqG6dks2pcWMDEV0+i6DEUPBKn9k5QvDbnQxj4XsnRBZYz2DB7an5YG/pYChRmje3LxuF6dxVq4JmqyTK6fnVOOmdfK6VvV8fc3AO8FDsRVD1E0hyuP3AQYqaR40ik/YG3WNPLRTXBh35FkEhDXaa/94RIDZYgbmVEAGSudWl70BgNhTtkJdqqD+n7ZsqR5U2a3GJUtCzlIFIviNKnYtk8FqUstxo82BvUoz932wD1cQcIspFeBCHqBEnkff050UD5+kQd8iIg6QyljerO55qglAy81ipmTIUgoTF5jYBDKl8uoYY6QrntHTrJYPOMtalI0AV5yUQyGE/DsfEht2BdUkHycK7+F+cm0HajT1FNsQs+di/evpwF249fcWCdaMuChJiVtSCnzvfRJQ4k87kycdIHNhnG6t5UGDExZvFY2VFVT/SVXdHaecKJy28FF4FnT/ywH2BQop4VtbwU4MsEKLHAzGUxXRLLgbKCruQpIqSVm/9AENPdg68UhYCQ8LT8oxy65Ol/ZDdAMC/uWr36WprANr48IbRtsmFR4MFJkIDJZnuGuYahp4jGgAGOpdY6NNa0VqqLe9h2HTIAJPP0qTlMJbw4js3dqCoz6BSFROnnHxoQmDxfTIdOJo6NZ/Pt4H682xD5RTIwQUkIIj6sXabOiU6te21C6PXd9xpbez/fVgVjHlnhlGOGoXvMZaeGYAQ+qnGtTJBcXEbJ9GFEqX0u9PwrAD2vhHz1ZR3RcCO7r2VpBrjJdCIhOqYxBDvBxBdlEyPcBeC0sio9rmLKOvhcNu1UM6BdchfEeERPsMyrySErN1rSlKM8wzskW/joHcJbKdRtsyEdb7OiFCGEECFoue12gIfPc3Q2uA2WMC4W4HZyg7DA2XBD6qQ7nSIUGUfmb9XR61Q+FTZGFuANvhrfR4BEqqb7enxSq0cZEw461q8546C9DaK1RbCJ0QQC2erMTgQk7QLh6lawP8nphbSsv92KbuhCeNgUy7t9M0daD0qDcMt0Hspp/oRcEKUekM+QDs4jxul8b+5gIvkXi3sflInB3mIzOoK6aohUeLlPoUJSOKuSm3pEr58nV8Vunw1nL4P7HDhMGvhFleWY/AB1p36AayxfoGqLYCcf70apnWPVGkP5VtjCisZLEHABldXXljd5b4kSnF5GYwthe4mqYbL23hqkgjsU0G9/5sS+iW4tK33oC8zgJPFILqppv2ak5Y3pRhnjXc6sJ4LIVYP5GDoiifsMUuZ/wYs97aD3S4NzXD24RHD0aJz2WeWt8WqHtxUt9ABhKrhTklkXDEwC+fxjnuYukZQKjd3sXsg4cv/2X7V5r3wQaxGb+AOERSd0+QgHqU2sfR0E0tAJedLt6iSHcHAobKN3FXJEPldRnZIuM+PVr8w2W3/HWKM8Vj2IlT6n8brKmoMQk8O+4EXqTA97HxW3gwpq8UUlcRjRt6VKSFtAgQcdY2TNaSxlRi0Srlu4tYOV9QSFzxibAcROOi7QJg/FsfC0MT8tkZUI1SBcUA2vhbjtgOIh1uDx2CiZboxg+FBJVrfdXM3bYquJj2rTUuGrRv3ACXDvI0sCNrJz92CvXTDwU5izBAo6Ama/FMTUhC1lGCDBiXszqLSWc98+Xx+2iD2jlZVtRL6iWwtFrOGTd7M64YLqKFsfiXMxWpu5hQxsi/mHZnFRsSg9PNz+yd2kOD1WTz7Fn3DZ98BRAum6AHYTqUrmKM2vuGoZ356op0ZNy3t6Ni++atbrMhawBpxt2G85mvbRhJ0Cn1Fv5MwZBjd3cWaljsphQSRabEsYkVFGgnOzfxAg1StBfOwFD32ngz74NLsGs/H/ujwql3DeDkOKnWBQ2N4zpLlbWrVxdsKmTkl38hR83/B2kRv0bUzuHxT7WMNIMG9OSS+UIGw3jLvkgIorSGFX0UEQ3/Ws8v7AeboRw3LkoxpUIuaq4f5nXL/gJ0xZq0n/banCnSBw+2EbNN3Gcz9fjYmdmQmvuhCjkiqotajWuVc7MEeUtMBhFoG3OAbudZKasX9gJR360Kx+ZIK3rmysbczNFvxYlvkm35R4/q3VOvOqFl2RvrhTkA7VRpUP3Ep5aeiRoOrGXNP2N6KRWIoIw76PDDgwjHlL8ADK5zYLYBkFMLooLuQfyXthJYZj/BDVAQc1cJ5vMVSSOUP7cGaBPIwmnmITKlLvzsmpJdBvFQSmDs5TJWR0XecBgM5T/DVRovdDM/I6Gf9qDL0NDlRIpJQUXbBmTx4CqmMCu4bNsvEK+9wukA1CMToGdFr+no6gLO8wqKvjJ8EohXo9MgVZZyRm15BAycsD1qZaQMraWjk3FIG2L/gnFKXhCAwjtymN8pXVPZagQm+EKE7JQdoKH5maQU0E5G/1Mgsvn5wYO0RMA5Z0ACHH3hXWwfMsy4Ps74dKtUEgOxQa4ZIJmgjZH10oLgPsCdvG1VcDaR/PczG8hSHdV5y/44MdBlct0zn3JHgjRkKOYpQuJH6OcDnL1VzfTY8Vdyt5VKQCOvwIyttDUbKe7dsazAKTmyq4jlPyWU8Y4ZEOWB+Y4ZYtMocrVqVqvAC/dg/WQCNXnEoCmntpw1uhmm88nWdB3B/A+jndCZRFyC8qYjlxCPdQhGmM0V+xpoeAV0wEhCvT0f3EBRH9mVmW9JOOrOXauFcUbCLAvUyCiAg9FKxDUVV9TkuJG3Q6NwGzuoMvEgzpOkxluKWAzVyaANAFmSuWiTXnaTl53eGw2BCotgJPw0co+gLc+YGtHOAEskfMIw/9VehA/4yBn97IAoNzSHIdC52f+yU64CE3E2EdugLSBXsSFiExKfsYbL5JwvtQ5nq1VVKPPw6lbz+Fad1l/l8O3FcIhfIFitTZckOlDpFQ1H5NQxOwRV67b19ozqlPwpO7C0EbIIANHOyGAcr3jGWDhfo0ubBUBVXhDbxAwZ3Y0ywe8PDGAdm+6itg2RQdgHH0VdAQSVL0NetJ5im04XfT+70zwjv50UrNsrdwth5UA+U41Jh+jjiUMlTBD4dzuXp/8QlEGoCABv5nAkC6K0Qc3E5DABnbVOQZyAFrb5fCLbAK8OiVnCYiu9FLJL5GCt2AC5TjFCNFBMSKCr6NIbLNYKUfLkRkH6UnyBECUgSuk73ssOPWPataJw16rhkrPNIaupCpv4wChze99+bRm0VYeJ82Lv9wJn28I2pTjEibUMuMviyt4v7budFRoq8uNbXPLJwHn5uX/jZMZYIMgymWLB+4qG5qfJ9pN9hgbl9NfrpdUnGlRbxxBhao6nOCCWC24GHXEwNAnDDSUIBa4NJQkdYni4t3t8At7qzux8tJf825C3P6Ok2e/XcbVTQ/KutgkbUZBgCeV3Th+f5jb5f73nQDex/keCBIJJVcYd1u3UoNq16udsWIl7Akjakxn5F6uQeE86QC5mKQGdCTKUC7kgA124oWnF6cx/jFajLbypvCupnrAiUoUwbY225793eWGdtMIcoGDi8rdftGAgbo+BAfL9cauS1/UQ1srU6BTlWxL9IAMSdRfhq/i5fggjtaqlZjsSKHAbX5BEehfRQSbgEQ+oBY7B289qBXh7834ls9pjQun98mSOtYAvleh6LCiGaTDOG9P5mtfRxdLtWMf0B3Xpc2HesFQrp3BCU4GIvleINyDW+it74OqFfZ4DmfAsivZFctRFC4Rql+YdERrx+25LSMwGTQqv2+DJXHZ//ZY4jVwfCr8ob3lQt/Ha3TQAS+Qu4Guo36/23s8DrESg9XwrlRWAgGtVifXhKIeIWyyA96D4LpalTowBRoujwWZhj95QUZgy/RkNvSu5OZBJpnpJIeWCtIVJbjqhrZtYMJq81tDdtaQhjjNlXT6HsZvvWvV0YEHwFsvckwMNXhSS+B/pe6afJDtmym0Vhsf9flf5YDLr6tOp7sV94hljm+yk2KXaFH+Gobiar4VOBcd9XAAKNlJpCB0OOr9aqQVE6EoIZazalfbttDzySJaxZ6wCSiCnGz2RC28FwOfhJ9sgRhnexO85QTG2taESlWfd7yv1jUB6LRHMUK11YS/gNUnnjuWR3zrvApEtdWFQMhExAb8fbyPF8lA7xMu+LGKJ/PFnYd7ryesRFRzMOCCNo/You9i/W5leTWujrKO9fDqKQp/8GSj0w7luBDrjXFMdsWqqzZVN0I+3Nirb7H40K6sq4m8TZsrfMhnNRQj2nzxA4iRc1IWwcrTRqM2HUsSivcnfyzOuNHSBBehnzEmdrlQ4nbMVC9Dbj8kiL13S14vFWoEuUqsi1GsDedjqpfNDIGi31nbWUZjdbgSJq/BoeeMmR1nk1VELPii2kiRahfcSIegucf+usq3HQAmd+smSkHmPtqL0fYIq0gYWZRBEG2KfAZxO0ybci4UPR6ZEioETlsRe2rX/aGdm+4XxAws5aaOqWRxjW9VF6iAgs6wkPfxpz0u74FMAHpLkm99KfjnqDmsUu+FM9sgcq5lfj/ewKZvow++CuUathrKY2EceVhmVox1+OSS6UgbFKjbzd9CGUU/y2AXc6Glj/PqPRbCBxAkKtSc/NCsK0ZnB3uIe5VEuy8yI3AFU+x2Pv+nL1aUzjnSWAq3V7otZy6Es7yVyKblxJGQ90jO13H+ehYU06V2XCwYU4wrWdfwW5A20iZkLSrTGB8UrQLOmeW3PUj537YpEMeCxRMs9xpV481y/vC8Ti1BVyZbdJUGDSSA23ymUaVqhSoUmlsZ9VBMgXxXbqeg+P422wn73KzFufEEYMsV/LV7cLBhNSw/LJpqXrChNJcI38RDwrdByLdYMdgV5biUJu3yXgC8j+9Ohbav01bQsEI+mQSPrJuFS2EPuGYBKMQ98eUx7TSvJO19Z0y0GwR0fdVbUO3RW8fzRc6EdbG0ZMhbJ9NVTc6mQrrh09dyvAn1q22FI8hNx4xbUUDaOoMD2qYOJyouKHbFeEo3MBIXahQndtElrN2uhs2cU0cavXGAady9UzFXwcduWIvne6zQzVQPfTULKkWBx5XyneBj+I8zzegyD1rVGoydG9uohOMTurZO52+pPVimbLEDiFZrl7CrgJ+1R//F7UWtm+2FVtQKHFaGIY9YuVJlWlFxsAsHeXKT6h3UrMVDaHy7DNYycVXwxWQ2Sguwf18IbwkAoqHZ7IRdUuUvd1czohAN3dbAdJX/31uB93G+DcpC+PxXNiRCLKU4pANcS9GjZj9Ag8xsKmDay61FDFXouIqNVlm3Aim3xR4RKkZjVVs0kYoIYqfSfXrHUnu0rVCOX7aH5AK32ORFMnLRzg2TTrlXzkFFP2cCz5D9YoK97TVL6cxcatxWnUk4ZERDiS90HLhW8MQXfd+3Z0Fl8kRR+yfla79HDNfIuYKm8itR5reWympH5YYWUv6V7deOp7KVoVtNzq0M6VZRXzoQiQ/zGVOe4LKwAvvLmg8ykrDdHN3UgRI3XQzR4gT6WbY5ZlUZbEaEobzmsckp3qbnvXz0P/gxMe3HRNDBe8nqbBf7vXe8fx+/sBXYwgIVR1Kqm0iXW8l6OQhc7aAdN9NEJZ6+lowBdw4IlHnqpiTcjrHe9UCSosZxt+toyMROQRHw5SIkyOxJXRapM/5STiZaxg2GluPchhbMfJys0nF/eaAIpNJAuxoHrcx0Ww3NZ0pTyvn0cIFuLU+2R/9dOPp5nO/tSUdz+sdcd9ARquhQ1q+MY7VZuHubUwdBvRTvVHbCnXyLcuCskZ3otq2aHIrK2UzFncNlu7Ii8ZxPC7VWDeFwy7tCogm/9gBIkO8D/PFgrhinBc+ETKKr7qz9UpdkMOM9hj5u21Sssi9LE/m61AjfD/eOKWc08B7v8v99/EpDsPsMt81ypjsCzXFo7kTWW/VsDyO88JdfUW+tns+n2x8uexwosNWcj5ICD1e8hZXVlhdU3peAlWUTHwtTlLary9XcaKeJBVKRt2pyspfk25aYQy6edlfcLV65lBDqvNvLGHtY5VaV5fq/jWsY9z1wRIjaPMXfZv7VnfAxe1BW9vEasX1eVwXmOojOUfmiP3svoQbB+26djn1AOWWBvNxivdfbLth8xUWIdxK3rU2EVB+0u6ygayygC26+eiKOPoBCMiUFz5srNwUuiAL2UFqpVo2R3V4jtkKHnbBjfylOEgdqo5QzK0aip3P83v++j69XxFejWuIgqNMxdFBqyZeglLMMqhVOasYV9ePt4Qm9dH9O+BjFmIMfRc21gxwa6ats9uktiMKBly7D8IOCNJfItUk3t1Z+g5w9XJ6uiyFzzQ28ZR1nV/m8ugpF7MU1h2QQ70wxkHM9CVDBoT5dPX/ZB9QRUE0sVSTJk8zamBJhK29/dExx+Wu/nM7fyhukE9aqbZY4ictvB/RBtazRkNxLE3DZ+tg5BMu2R4vbDdbaqcUIjMh3UKE3lOeHC7GFS1pXmFoMF+GrF+w+JQavncLA6ZJmmd6smuIqdvxYy0lsTpeHgr8V6Pe7/H8f32wIilJQ46SbRz+g3++UlrjUY0+qT4fuilEtF0j/418IxkFprzxVZG6FRfluLp+Jp63YDOtauPqa+BrMpxN7sIibntQb3J/0Xp8lPgXKugGuSNB2ogXUXnyTkDtFrVb2w3/gCHjS1jKU9+o+LviirtOPg/3LqLtd/GOIrAmgzCBaMazJwbdFf+hsz3OqXFXn+Vlt7hKdnY4LgCfNw7mE4Y1VUV6o71e9fj/hb8GFt5VAT2u9oN9FGijpI6+Id6xbDW5MdyzxY8G1TDcUNmBCDtgUpKGNztVHLIgCaaZhcb7H6La9RYHexz8wISQd12FmvJVP4rSKnS7xRt9fmN1TkRj2WnXZDqA5F4vdvdwfmK32t1DIrT5y1CDkHMaW+t46VncEWF9r3gkUPf32BVeGzwIHp1nNuXrmCgSikgnKx7jyrjnXx9j58bYxXb5/WVtVXUwVqWJw6yji4pJ+2QecEiSlBqnNKwIQgzfHXmezuWxuubTui1qhWhyUG27BEaNGxyL9MG7jVhGRe5tWZi37iaaLfu388z0fWAHNm1psuUupAq9azCeTxVJSJrXcFdOhqwxKneNsUxe7Lbvk6lyvG4Fu/2uksB6UGK7KXyeN6HdKeB/f3QpcLQq250fBEo7J6aiKHDrqjpJQZFgbcYDc/jsU5mwVXG1LKjqxwOpaPPAOzgEUgpOl7zNrUwzSQVDzhkBtJEcBmFyEfp/M5DuhbfhzoOwessZ5JdBKCRu5of6bte1SdzaFa69xSTL4JjXOzoeqhmoB7xz5APxi+vL8bsiwx9fTry1RU7zpLZdeaTmE1twlZZdOcqwX+5Z29SrMvDsG8942reeTu3AEJdqCfY9HIPZg0RQ5WPUAN2rMdWBF+xlzVO/WUxJ/NbLfp1jbxqf38h46nfyC33HtffxyJjhVDTX8l2Fsr9PnrOdWa+UxvwiIG3fS4gJVwyW+WEk2kw6l7UGgxoda8fh/YSdg/IBVwi61iyHzOWodsDoXM/ZTmCLe+WKFkXoo5Hcw/TaPClLpYaxCp4FNWQNy9Y0l+mIT+BU29OrmwPAu+g2qQzIyikDb3QJoZ9bR6SRmr0SnqvyC1XUQat7atEND0FwSNqZPB0ZC+GGr/5CXNwnjorCeC1LiHrppBxfUyVjpfk7TuV1d5drBzQZBrcj/FegQWR1kf0g7pJtf7qzeDcH7+PJ+eFZMVNmIIlzYuO7y8tnu5xuxLoDPRSo9scDi0zure8Gt36AgjPUc0Pfkj12WwFtVzu2yoGwniPmzNHCYBa0zvnOHsZxjVxkJU5aC1YdmKwxXjY/bW/+lWdDVQnknRWx/eatOwa3g9kKp4tkEv0bkDW1/2Ku8+Dlx162j1EaiQp+ZiAXktAfixySYUex37w4iDbRiHbPxFaINKD3B1j3yoQhazRuY1XwKdPrtup/h4BIQ1SelnCImuvwF3w3B+/jmwS9qBDPyatQ2foxLmORm6sWYgdk8GUVFcRaLu0BXYGG2uO1SFrW6ai7QwjWJ+Pq68+byhQJZO/5eR/PnOH7fq/LW2lmcuLWn0JLaihzmFrd98nwZYs/A0GPYPQcxd486Rm9q1Lh9Qwymf6MZ3AYexE9ShYiatsXXk7bDEGa+7jPo+kxtKf9JlqkAr3YioNV3QudhXvz7fvAarquk+q/o6QCnLrg8d1PKRzuneiH0tyhYXtRp8e7JsKG5eyCnEFMYgFSpuPfxPv6eoZDvA9jvLheMO81m2UH/o/YEW6BEUOqJ0jFxlCRfxdqMNjN05jOEJ6rpzVsqmFP2OPRtoBVW7+e3ZzYHvInZBLl1tScZ4FkcaxeP9PhHXRVeT/5kK/+/8/j3Y+Q6Jp3jIO8QOGEsn1tOutgWhMZTJNL+pPM40sGqAGZr25CrVffENIo5JJ6N9Xf1y9dxkKXuXnb6fvcEDNS1ULxaOTeyQSI8TZzaqROs2KeU58sEB4ZLvzQwbapi7UMgOutAvMc+7+PvXwZk6UkXkw/O/thZq61Vxz4dVvZWxOMut3p9Xw88k+LhuhyOrtfMB1xPOZTFmsvJoZOHkSNbvdoKSpCfNEPrMM49lOr7YoDoqjjm0zSbXxd4+VfXhkJZLb3dfZiwUq8z5/5eX17VxsfIfDULOqfuzfXQhV7rIsK5T8ylID2NutpVdL5csBxK6+9AQtfV4GvbovCTEefVrda9q6FDqiqb3vBOa6en5epmcsmIraw5G8WsxsdNCW/JvR+fzr1F+WKe+04J7+MPbQUuq+/DnUhlosPkzw69+Cmr5XycdyDodeF/mB4ztZdxtR2NEK4iIn3x77YA0r+qq+niZ1J7zsvlU6XYXqQleEOB6FbOIR04wOHx1SrA6NVV7t+LHIdwtVpJBs/GW/z03z8dUvUr2Bbt2M2sABofvTI3ctV2UdfV/Gg9wfmmexr3Omc/jqvaV3dhmWbu1JLzduzIk2xPzxi17/aj5Y5+B/738esJ4cs7hy7CK5XgfjXX5rXf8HsRtZ4+QVePG+3P7d5Uu2hWdyKbYT1KhdpPuKBzmL5aqdIJmbidEHqyW600MX5yMvkq4b0Kzy6SZG1B6NN9++jfOePW6vzCsb5zd73KpXT0C6Mnvz49yQHfiZL8MplHUVO4JfTkX9LX5/Dbbc33D/7V8/4+3sc/4q57Vt7x9x6xbzasLyqq1z+Cv/2j13MtRXryW9OTyHOOS9TONeof5Aln8f13jfauz2H/9s85p0m6anRKwKZXmac/yZNP3vl5cUBXoLLrDMx8ITf08or3Y9Owb6B+qRB/Ur+svXxget190+uel77Oru/jffzj5kXZKr+eYHyjgaCsy+nLuE2/lkH669+kX73tZ2qb/mte+Ml/nQ1evunKiKBnQYDTUSZ/u6sf/qvxqf//dN/80fzPL0sKfnkF6A+94rc63sbP3xt/o2zhrW5/a7m9j3/ZhoB+MfpvD9ZJDu7yB7Erp9OLp4m/2ef/8TkGn9ID/cqA4csffvlvD2PtKnXxot77pd+8/x2niJ9G6ZNe6XcS++XeJoYvtBFyX2FDv39HjsMe+PSeDubFAUN6MpT7B4553sf7+NfpDP7oTf+HZ0d/z2SJXs5/XrDGqFR/vCH1Dww3H+vTF7877a+4rn4LSnWMbcXLl8uTPxSAbv/42uAbs6Avfwj/enf5x87CuYD/1ivS6RJfQ76e7WZoS8EmevXqrzL/kav7Pt7Hf11bf9im0i8+d9zOSBoK+MbhOVqvfzh/LyN97/1VHeILzs431oyXeJxn/ok1VK4XeYufVsm8/+L8i5Gif3P+8gve43xxOdZVK3E5/OKTB3KYTHD7npTF8waHnzZlO5UhzCQ2M6Mnwtx/JC3ZhuLvdHSn7V3qb/32iH8f/+UzoK1wOkz2Lxd334gZ6jz8jfDFz9LRi6dkM7r/I0GN6NXr8JW49HkuQS+j/OtcezkbuZ4d0XfOycsccIkE42+X9H6W/+CaYR7GTLwB5Okbp+zqLD3tSPjCravYUh7uEyo6Fvy8sHhJzv0DEfosRL7dH/RuDt7Hf3HMf1LKvGjT6atH7/tFKb2OTk+VFCsLgb7znp9Vk3R64l7uJb54zP94kUauvHSeTb1+Vf4iwvcvfo0rLDy0l/ioTuEnyBE/l9ONAxxotesZf8UHhGjIWfzioNDUrne3F25BL84Yqcq5eR1DwIeLGh+3L/qRJ2d8f93i8X7oq/0yX95/5xdYXxdOxeHhfbyPX633mZ8GvWusGr9oSCnu8Or68npY80z/qr54lWYsnlzwmDW9ypVb7C+5wf3ZG6Jzu+P+3VflOVdlm29MyM+vS99LpRzKZr9+9P2inxGKRQ+f0jcx/4BDuFIcG1R28/HV6ueMyt/q8ugPpU1qVNWee1jHUUrF9isDh5qKjsQCSQWNd0lZLqkiAus+heN2KYNoGj5bNVFhBmTeF0eeSQiIg0hcT0yoA/4SPuGdDt7H87D/NbWl1YjWqufgLmh5Kf+b4XOPEL2gn/0JIXoK/q4l5sUA6jhGKHL/9HUf0E+vGLr/9Aq/ftGWfPmocREz7v7mr+M+7XIU3FyBI+nZ9X0VuWF6fZWvtKMP+JhiCFD+bedQqmmQEedkUzPsnHtPIbTdrVrD8Xg2LgyLus07kZhjgB4WFOnheBCWFYGQfU7ST40CVc0QUn1p+UyR3LnchK7/KaYubuBIFxe53LvntuYgZbppE9JpKW3CiSuuFfdI+uZM2U10lA8Mg7Pa4vt4H788/Kl3DvNBO4VCGDHs+ugYqlCGhzJEarzTMVxeSnKel8O7f3YGemIf1lpVxGHu7e7vy/yYXq5eb3TUMf3ONMui00u8YPU8P5S8/USYoD3lpC1gnSTQ/k+3XNz3d08Xcf7p+O3JTcHVPGsf89ivRP0KJZX2kP0bt53Y/0JQudAhVAwuczof50aecyh9wQ630FBbgnba8vOzKSKnWGCD1K2Ds2h3FGvtydSLNn27vHbd1Kf1dlV1uh4qQOvVJPBxiy3LsdRX/ZmUtxe7i064Gb/D//v4u/MB533FdeRSJzGQsYl6ZT6tganc7WJ9OzqGGDlS8WaZuVSO1Q37aOnnHvbb47tJ2698JPRF6TgAaLvMJwr/Q5HaabOJvx6h82ZQEz7A8c2zZPJ48sj3wwscqWlPZP9/HY558ULHm4CuVzyhU1/+0F3inpO1w1gH3x6XzdHRQqEVP93tfV56NZgYp8zHKMRH25V7w+O4+9fTSxkWw1+N+6ulSCG3Vqcy2xCGDyX/SbPT3ecPIlZUpELVB5XjulJxJqAc+1tY58QC0WW2uGre2zsdvI/vHfS8eSxQNq6KYaSG716YL8x2pGPWL6rpqw4xJZaqEnXe8LyrgbpdpQuhl3KYal1dN2fFkomjJXD/RQ8sazn2hJ+X7K2KCp92AKen+WQ6xtt4eUVavBx6F72FV0JDe6yrfxamtgcbXf5eG9NfTN9PwiBhn8J8UKXjZhMS6ODnGz0mAEqklgTrg5r/dMMvvvIi3hMhtXaBlaEw2+QUYHhG/o7GcPm5g6J/4FNhdWF/i/0ZiH4zf+6WnKqmFJfrdDzB9RxdCU25CZw8Clw3KjX97BDaQxf/gg7z7hDex5f3A5+Dg992TxCWnK5iqbu2tp9BJ2mUfZhBT2br7UKBmT0wuT8HegL4z8i7pJg7cSrMc+8XrE5uT5kOl2uAZ0plvO8X09GE2yrQx3PnkSUs7Sr6myPN7hXYS/o0qE5YG+fk5lf2AU+GWeyuQYeUwLSdETrFeqJtzXlIrZf55u7O9AcL4rDZfCkbRXR4AwfIEF93W7POgrwhWLGPDZuecueRdTxXqAmiJ6fRZkGMz4dQ/QI6rO+Vr8yJVHmo/sN1dH17x/r38fetBDa/RjlWuQNXhG86a+DQ9iAfH3ZK2IyNWsynjw6JIe/vXvd31q+UvtyHQmbKp7nAOwH36tM/XBcbiNpWUyn2Y7TQv+FwxXWCzZsf2boyCHtW72cCKDYqB9GyAxErJwOxS6faL317FnTdG8GKAQgg6pzxFSfJnQ7DRcJ8O7kkAI7px3oel+ZOzuaTLXDLa8CHX+7CyRPKscXabr24HSPZxC7WzcC8qcxZos9beNv1lOivf/Xg67zdPhzzNEJZ0lLOtvc4a+TnjgKlqk8dAbHEC+YZlLuAvOjMF05y7/L/fXzZEPBpLuShq7pa25yFNNaSP+zih8qI5Gsbn+N+Ht31G/VvD/wzOjj35uK3OOLlm4knK2apFb0RoyCCOytGuzKpYu9I1tVcnvbSMIJcr7ggulB4vpyj83O3mYsIe9pW1pHJWZ3OAoO5eOVgzi5DvW7tuBbmL2dB55KWDzCjMoVDStgqX6Axubsf78VH9gFXOWeW2db12eSL03RxgvSt0y7K0fdEukp+nhFNda654gwuzeXkKQd5wbjLAoN2X52cDnWN6UeVcJtuyhdW7CB9uk/Z6trZ9eMZkejP/sv2fSm2gYm8GuI9H7yD/vv4o1sBqgYYfmu5wzmHb5TMgRmtanoN2wOnmSAqpsUGb0Pd4/W8PhHoA7rr0Ok3D+psvjhOYEgnX/3aM8ru0O2LWH2GbUBfh+aaENY5KJcmZNA5i71yOOerIfZhOjTpVT7oJ6RJ6T+6z7/7NuShfgCTJuyKLqZW9HoWxMdpxgWrgSMfR/yy7/c/rh1V6vRVBRoK3SOjP+Xkn4rZ5KGBQmnQ3eeOHLhKl2nQ/qp2b2Rev/Je1rJqO8aFfo8d+TF+KsgP22FRLtW9z11603dW7Cpb1d+p1zedN4We5phnxkiKaQcu2W1WLq+jOfyLJ8ZM7+N9tOvCP3BAiUJnTwYUzwM7eUWRyjTw1xYd+ItZANrzw0DEGZ6PNOh3+FNyLH/JQz8eMc8cxKUW3jzGc0XB06mlElbWwqONt0pM1wPXDIg9ai3KuUIvOYJOr1tDVg1idbi9XhOVKfcE5eWOIZprsrJ80W2u0KKsPGPh6etZ0CHKXqWQthnMX0UVffd9H2bsybMAs/opB8y2gTC52AJzKc/Xvr8xbCjVpE1x8QY9XePoK9rAZ3W9cxmx3wYtzC5WhD5pLVuK5z6g8LookQwrbLjJHePpmCz3SRnAEkeaGJcsYk9jW8nNObVunW19cbYceKtKvI9fXQnsMw4uO8FVy99YnEmApUVte/jzC2M1tcAE8cFGQIuhBLfo8mx5REv2WNl3UXQnBtngOgnlKchuL8Plm7NU5eskBN2bOc4jngw6zBKo7/YnZzuxQwm7ig8w8IfnENxrKPMX7QfXcYLfQb0cbipZATBnRYELmOD3d8Lv4328j/fxPv6tj5f8AMoUXwtzdjn/rWUosm5b+ifqZaVeu5t+skeYpeoPesWmyce5Pqo7nCg1gscx1Av4WVI9DqBYX3ppF2Kl91xOMJT5p7SPk7Ay8A4gixiiKilK0uQSRTPSYvQZBDGy95ewg4Qpce6h8kL4v3u8j0W9MhXYG97H7+COotGO+iSo7bTh91DofVwU/ocb43DnJCk/FwOcyAkwhxfxxqLkWuv2ElIeN7HadXPOSG1AwwVMESISFkl6z/IfPXbd+WE7vbCm1i2Aknwepffj0X20+/fW7j6leXzz/njA+ckipGi63GjTivAB+VGFodIC1nmOrd+800aQpt2nPsEsfLlJ9SAT1X9sY3w6ZIGaU+WT6Wqe/41Z0CkPZO9FlcjXYvTd28bk24l8RNtMLedu1A5yDkuxoXeNyPpByhigdUUcW+U99jLOG/ixdHz1A1f58EOcIEZAhdpmwh6D5VMv9mmMU+EyKfEZuEobvcTPlAJDA8LJ1jkHpPeCbd4NDsS5z2BbheVYtuyEsdfgXdyD335l7+MXB0F7duDCuXLFhxVIId8PGkaE6YRJrLTGROhpRWN4u+HFEG1xJpUSTIZlteZyKXVIFRmLkQ0U3yGbADaot4E+tr3jIRpmGHGBg0NgOYxu2mH+UwLLPBS17TgLih/uI/aclqcq8BZCdD3oU+4VQPDASlIam1gqvQSGvt4JF46rL+V9Ixn4r0W2t7HoVKje0AfKuTxttIBKtm5XEKuNr5tCESW7blKBGzI0VvmjwLk6bcyLTscXjVcEzko2AdIBPD6W8QOMmcvNhoqtL9Qa1hC0Cr4Cv9F3ABxsanLsc8w6u2o+2JnsBlrouP8LNhSyELpGiz7BGpN4DpGl8uqGsgV0hJ5e+3dD8D7Ot0FqjdTbJiqgANxLCLZIS4szyvEqk3tditGKnZZoDnX7WtZvTZARjGVvVWXrSRQgKjT7eL7CqguP4XLxIiD5vD/WfoBWA9JvyUPdliAAF9fId7EfJhtgEBeWQF09ZgzyEQDvS+B9kqHJQB7azxPfLaNWbJ5pSz/+XiqosnvpG/lWRxWG4Kcz46H+bq/6AI4hy+HvJdeLEoLlaFG/JnoZdXHRPQltsXifzLRtauR9AFu7FDcUO2lgMVUgfjv9hMyZmAIV852+U/LaaRY0TWPWwFuP97CG3DRzzpV8Etz/CP0r6NKdfctV30zvpQ8gg77lOEjh0105L9jndMDc7EdLGojc1oGvWPrUcDDvVAJLeQj61PEBFFTW9rQ3+O+o9z5e54R2nHC0Y0gJqRKPfgGP7sSGFkXlTasOSRtQoY/bu2tkH5pN4m7vUVwmID8K0wRXO2cmoRnNhiAEXj+HxBfbc0KLgUnVZ212XQ3vYaRRUR0GhJWybMU3Rylwjy0ObeOgyUcwy9QJx709mT7VUTYZHrCfaMM4wc37J8fu98SK2CibLuJrIGtf7YSZ96tNBVFr14Yphnq4YKl9uidVBjkL17rXQfwTpSC87ifjN+EVjC0n+K2N7EcXSkQQ1uTSc5Cz7ArW6aD6ZBPD/gj9Ms7UVmDhFl4+VFwhH7SMF2NpoO3sRGeKqY42rYPfnieDyATcgVN75MYhX3uJxJWdQn47GNrImgDUUj7zWeStulVnBd7HT/hirb2yu3kff5LjfA9QLgOgJ89xR7EBpfFNfVZ4kfEWUYM6eVhu4FVv40TBWas+5FnwBxXkefKOOST5YwzU5amiECttRbam9uU6CAUpbD7+OzU8yrvUZ/jxju/6xudh/oGIRFaSY+wzag5oRz3RXvhizgqmVaZABdaY/lO8h8rD4i9yH07McJpcLxeJTaG/rGzbBru0QH3cM9B3Z0HXSSr/gmdcQutRPFooQfsE1eg69inT+QGtTBIv40ts6Kz5M9Mpb9Stwhfvhw9/G6PrxzAJQNx4t1MHkK1AIZHLQtjvqeWcdDwJ3e42GjkO4t7iLif0AWRtLPHJRsZ5xtCNkMoIsFSTkQBuup9VOLgSWCT3B1F++eYaQiktZrcJ6H7rRryP70+HarFvGEfNCinfwNsa0kpPWqmMEF4xraCctboGJwaDVtd31Ji3TcNLD12eqQhnXatflIvGQvPhC9CgnivWIw3M5lOgMuw4qwZUcoA0Ld0+N4eY55+erMmScWbvgrIVoA2NenkMKBpUUQreyEIa2Xp3oqhLNnQ/72i4KKnTlILy/GrZczkL2v4quaplqC8Rt12/LmUSOu34HypT+LZThfsTQtkMUFCR91uFZ5EyDlX09UwR0BzQCz+ATjvh+oXknsX6WSE2uJD06A/khlqqixh9kacGDn5Abur1JHbnv/gmWLu70XMxYKq58i7Z0idCf2+x2NkxATmaBEE/IBm8LOabrFKcnRVJgsuoN453sHsfx63AaTfgEKAVfyvZwi3vQ583GkvpEP0x7bQdgDXmUp+vIYFseWCTfzwoNReLUARL7WgBrruMBAeIz/OQjd+lL5hLkHxz6tRnRoJYVuF5H71NY9qu2tY9dERDME604UMq2KJWc0sS2sTwW2kp6t50lCBWlxA92w5DhbChhCL9ZmTOb7aqRtlexPlXOSApttZ0eBroofKR/DT/CTajwopna6M4i/SnLLRooyh7gkins6CDWkEKUExZzDqGsEMZaAUoJ1G0N3TJE3Eho3vjO60ps6A1bSikjWTHb79cB9pI6hqa8SS0WqSkciglozkGQVZgmBJcbghsxz6urIwEEqqDINxFpGw1ConAtA+g4MBz21zQLoUh35ngHf3PolJbK2BzTnJ9KsMiFxGZztaoE3tnMPRGPQmf4DuPP1g+ENCdMJpgHR5bxM9qKVDWm+iWD4I89mjAQECSBLCWzoWXkYWXlndCF7svFJOJN6khSHoLDxeP0HHrGUNsfEX8bIgdZdgELg+xixTlKEMFTQantiPK5e7CMVVec/8aZXPnAIda7OrWhZFNiqN/im5gw59+qRvKIclU8KD+4SIeBGL3YfxkoKVeXeRc7Yme6BiftyuPiP+5FCFKOReabAjRS9WgdnKRvJFfv2IM1HdPuPoeMEq5G1GA7ose72H51F/up0RnPs7zBKRTbjPGnsnXU74m74UwzBD66XbqrNJHH9dHs8TQ5ZbVnkAuwa2jD9TbYvmsb9ncPyVNQUaOpMmB3QY6rh2cmJnP8993GngngFr2baG/FbW4aDfRfS7cijIxLQrN0I9TJI498CsechkBIYaEZJANCobKjGE30GNtJnSAgsN3coAbFmJnK8sFHyw5WBvvb3o1NLXqn/qAy9pvCThnHn5zSnnOGvQRRm4+VMg6/QkwtOwDuA6CELvuxUUgXMdGMas57B66jxJO6+veqMzasZdNpY0egwSu2haEIcLxeX/qKd/qcI4KByEF3XpV9sixDzBChf+EKxu176WFZPzv4zT9jCzdbdm9koIBQ63dUYfq6ZPConfulY5Anseusg7ukpULCZT/yy8k7n3bOqH56aQ7Y+YI/b3tHgWPEzA67wPOFisv3LzkZBn7ERR6QWxDoegPVxFIMvVVN/PTukxHnZzqFtzCfC1FXzhb+3f0fx+XmWBfHQWcYGOfaJ+MZwVQHJfhcQiolS9Tyv0RsyAN/RoCiFoo/1TxOC9dydBFkFrB8zQ6GGIJSWGj6SSt81CRc4x/Hg/4ozOQOdAy3JD7W5Zxedd6sVJKE1dyniV4ZN0TADNvhAA9R+Gswp98tQ8IMaTmvoK7QlEP2FIRgCnGJLTgQBW1YY6Gquzb/g+/6AMOCSDZTDn/Sa8wWZJG8G+4+GQjq77jenc5VrrW3HhE3r9yw8m6szVQq/YEZ1e1MuTplDv9x20z3Ejy5lv+QxoozhLYB7A1dAoonlI+KB2gARhkH+gA0CH0ItJHPhF6HENrfEpNO0oJbkpMtEb/8UhcSwFzKVBy82zZvZ4yHN3qFLOr4iBkS2v5osc+OGf/fLCWTFn4NzToT3wUg8ai3FPvmpAlz92S1xSrRO+ms8ogWXZOh4BHoX5D4Y9kQEs5AVO+GDbNGdooh4UAEECFWyPbUHuUNpGt8gD6o8y5Inv8z13RS0r5sef6zi653ooqXEGsWBjxfQDisk2Vr+wkE7oCcitzUsN0E3DnxIZusyBufTec7T7xSRquxRZftdousVgK+LLGxzNXA5e6wv66D8ghS1FiNnBLbCF88GYviQmGghhjK+uG8ghrH90o16O3ujeuGSB2s3c4vFPFBZEP/OLGzI1VTQCeBkg/eIy4ci7ddrXJacVcQonKyi1kLR+gQm7jotCKqPZErhuRsC9TAm3UAu6GiSZ7q4saZhkkLhrkjhZGMEd0cBEQGd4OpyCbDnHfjeSwprYxUFncpc1w3f4dloHv40+7Bz7gBaLmP3CDbdt0qD9cDyKIShg/8KJd9NCwQKh19G43vuTwR8BxdEUCngAHlcd2dMNiuC5BKDa2aMfxYJL9UgCG6mxZVSIemYB9tHuafti20mMiIhWC1ShL2u4DlRo86uokJ0KUU6DlzIDPlqj2ivXzGMVYO39EvsldNMh1/Zi5IbmRbFOE5QTu824rT9/KAXV1sNlUUv7c1srCgXzeXUxyjTDsi04kTz2n/eQp1vc0MPVMzdDw0WSgiYFjqVLXwlFk9+1Dbq2h8NNbrAf6JggeL3mY1iHrPO6YuwqM6CoJXPNq2GnMrMFcWlHO5khqh5EatzECSmbAwDJgBWmgE+9yoQVSrUWWpI+71wg6/dNFF/ZeWgAZEZJR+qyVm71wA39H//fxPBN4MNs1Q1WBR6pbzBuXz0e1niYV4wHK5tF3aziaOtEwvCIXvksB9pPLpys0TrgCwzbAPfCYppGjxWXHWtgZYTk6NcsaFOIkc1E8A1r4y5B0Ko9G1MB4kyHYSvKz3kxLINAQpImL0PTDwtTwRRB9iXg1SzAJAbTP2gfssB8qaNScZxwsEWu5HN47zgZYYSBDRYWpys88afgv+gBKK7JEtniQ8xCWaaeeRvz13l0B1eL+3kP1XlQ4Thvaxw/8qUub7YTqXYY1yySX/mhZJhNeSIbw2gTINeu4hIEQpSL5dMDAPu7nOSHqxHfpH+U+kiZARSNEdEQ7g2IlJp+xEDYbGQ6VDjtr2rzCPwC//8hkQN1T5FB22NACvtuDIQ/DxqmxJNf9frOxrCKthQLZqGLSHj9oFfHaYgISw6G3l8D7uMwEtQ2IaMuhS5iKKYqabrYVsyYYKzN13iZXZYlOYVnTOvgm00wbIcidP6yGHa4Y4YviWH81mayaOgOBpkMta3/5enq/4qoRgvGeKvmyFA7EuhnWodCU5mCtE1CODNly83B/s/BFEc0eb8r6g34UeDcMKEIWOSq0W08QWaGG44h+GruSwHQrM21MpVplm5pvcDeEaIj3OI7fRCPKuLuaq3xrFsQxAmqlGyCKVmBFSmg+gTJ4r4+zqA8Euu6sBzpLYbbDxjRywCfU4siAoXUTMIvT7w6fd4n+bhep46by1cqt881n7BfjPC3zp7cCd32Ju1Y4j1tIt8Q6KCKA7qcGbOV16exxGGc4ujvtF8eAgKi/xdwJlyTanMKuoLPhSoqGsO7bxkOHYZ1iCbSs7evJE3a89mLfZK/YajPzWzXufVxuBfbNXFJI1gr5NaObgErvpAFXCX3cirN3HaAawpk3TRiN4EtwQYgeNhdK1lhY/2W7HPMgLaf6sFBhq2B2RJAx9gtdV00CGGBQ/9DH+a6PQmDNaxBElPigTACxRPwYnIWsLwyihrctBBX8ei4GdARELlbKOguqkZcSI9N3lbPhOBpMn3zd2l2FxpDlywbI5NtgSjE3qgqs2RD8yj4gp1WFdcbN1UAsFFlVm2uDBuUgEnYuVqbbet2aLAUQj1aN2vP4bA7k8qCMfJAqJEavTY+faKOGUfuEgAWG8ONvfcTS3xi2mwkQDnnFZVOgx03zOXGsSaS95Cwe0YbRBHB0NNOCM/Iv+ziMwRTLTbG3UxTO8st6Arzp4diJOkUtK7BC1TC0MRtfP3k6Ee5XPsD+MFtPwCfluDdG6E+LBTrIw23SIiXWq94a19BPRc3rWBBiLlTYYb63NatIVIUKgvCKemNGpRcf2T60+1SCdxotD46JNVA5TmHQm146AAUFyUe763RXF7bMZ6f73mJoQSERioLypu/UKzo2+RaofnkOmP5xRxHZtqwwdRA097yLCTk6nL5JFW35wAcn3VetOoQW0FWHHtMq03/ORU2YPG4h9ls5oMj+NU8mIWNAgTqytXAV0WfP3Pr6A6o5SnDWjxYzouGzt356B+gD7mRsi8UVctvijC/KbgDnyNKmz/3HMJbHh3+u2N5Kw6qEEVb8QGGKaUogTECX6o3Ddgy7JZ8IGVbashK4vAINGsM2OH6jMzYBsQDoAPo8Mglpg6wPxk0AFu022iYasTR1rRiz6qk3XW19HlykRMN/b+kumUt0TvjQO/S/jy0o4JagFjq5uf1SrJxTT/DET1sRgihAmHkAxKyToq4Pbsjly+jfTbOHbAwWQHFOGijNcSsgaDMP6I+WGvDuaKRdr5QMocfRkSgkVEnCus+zlUBb2AzP6pBcUDMhLC8rWeIPZ4dFSQ6iQHctt8PGuxW74KkshNgKyLshV6J0ThpW0AnedJGijRxgE2AlXVke7C2w/2DboaNiymTgykvFtHyzBv7eLIhDk9rh6MFLxqt21LA9tD6WSZsp0w+0JzkeJ458Rt+woZVLz4+S3E758A/a+4C/LgljUwdqdzZHAbDGfASjPEDysVi3iXlgbEcw/YbtoocrCN1cqogcEYRWo7lEhC4DpC2Q9YDVDkIy9LpIZ0GKwxkiRrJ83cXRNxkeCNnPdRA5sQU2+tfa37cJhqHWauqmSX6InsRh3gXA1MDigKC+xUZWWCnv7qwGLd+8Fyiz3ZNd+Pv400Z//yqdhE0PDneN3jkrEfC+c9IHEUGbI4BrkTb6tgeWoK/cYI2gNtDsj/bapsqPckcks6xgHFQUZvAQCTnAFsLc2SXm2EDS+owqCFMX17IMlq+mCEXQ+iTZDd+BDZ2qBLNS0621o0hDjH0eceM2LHrkatPLTX/qrDHBYmSSIcdt9ESb+tnPlb7DWFXeXDqz+5Y04acKicIqQsWLejd0Y/RFNp+XBUhv7GHZc+pJPZToGQzkwktytYK5cU1VjF/wBpdOeWyxMwq3WpuoxxWjcQONTeN/OHDKTA9LWvKJWzvNZBCI/2Zxn6Un6HpCUf53mr574d16OdLA4w68KST0xk4VbrldsZRzWpEj9EvcN/jwEmjQWnchmmsvydZjOnJVCTJkyUD3w1ZFBbxtWAKIcWeBFAgQolvG1k0TeqzVo7NbSX0ZdrOgxXafG+zfHPjgQ6rkx7CpZ/Hu+vRMRvSdCf6M0f+4FC7KQS0mQitkmNU3xkBBQCL0PlW5R5tYLxQheWJziZF0yIWxqSplab04OPQdKTjzrhXRTCtCqTbNGWPaPDCnWhe2dG4Njpm/PBUS92UJ/KlfoCFYK/2E6y5k0BEL1H1Daw2BjWxDz8Jlirv7kMcXoRQdUMNGjwj284m196iUtIIHTaGz3mO0grpPP2PnqXDbR5Ydum5xRgXHOn33prl8wm/X90fPBBLkPRth+xQ70w6kLvWEKdLFJf0eqUtyteY0mZunslvjFPLsF2/g0Qf4JqBsBe4KEIpZEO/GbNg8dR2VjbLYkbZu5ZL9Rqn/VwdQvos2KsfnIv1iqeEc35U+pqXRaklTXNoE8AjUg/WFerqW9q6PQuJxQ/qUU07U4zYc8rwEp0Nds3tIRsjVfbQ/8vrd2GEUCLTuxjLAZuiPlPc0kQ/okaro7iS2gdwgJAepDpggBSy/Quc3N+x9HB8BdtnZ0I5ehoVTdFzAJtxnb/bwXtK5kOAUVnMB0WYGeTrzXYyBgTJgiDi+UNQzJ83UZ+1ODuhjhAZX0PLJoPSrh26dvv2lFY8+sEsBfqoRpFsBKf+jA+BNbAZR6KM7QLMshEeRDNKJTBH0RzG+bNpjBLRmBeudPZ6QTYQ+d3kbLmCZW3G+GoXnRLEPEL6rnglrgjT3SOiXZICwbPtFfHZ3ySobRw3uCu3rPkBmHi0pAq10FoY6cvj9srzkv0dd8Gg9Hid0dBt4YQN6oyNR4IDS+dsS1aDJBRpE/rkwL7hkY7L2gmIWZECu5jAvva6tbW5wkQD0EvLdugFpAj4ZA0TwxSwBcEBuWBOACcq5owBaai9PCJi2C7b0SBhwN4qHEb7R38lSG49Q38Zk/nSlGC3r0nr6Bm8tSpkXvOVYCwd7LHcDb5DouyHYfIPtC+8dwQwA9xYw0JXimKYXBLiGkZN27Lw/afKPdLBpRaTe56t7KRkcI0KlnfA5Ley6E4RNUcUB2UCvFtEU4wZPU4iT2Y8xhHU5DEifz0fjeQq0DysuSDWCbi41NmJA5APt7laT5OrB8THRCsAB13FBMC4G3r3qHON1gQQ1dHvJOg5LxdTkUcItjE8Ah9KT6cKdOKVWnYfbY0GgULHwXOt7OYA5Sdneg3Er6nw9M8GC+F/XeE/WMiEM64Rr6a+kcK+xrb9HTjj2fkWPvzVpnWoifXz+JKeP6UxkUaEI2CCIdQdANyLsgT+orIUd80snlKqLhipDjR/NI8k1Y0sDmhKmjYMyX0hqMNk4ZAJHQHRKV8lxu/nwp0dmJ+t5h3yMgbPHCpR+RP/ZkW674SjKaNXwFGDae+vp191Be2uZ0JHORckl1aPHb61UevtK4J0P/myIoDIjzjTg2IHi3GHUsBmbpwy+cq9PAlkMFraU22BnVHqxj2mnpIGBBKCCcaD0lOoXj7SWk2OYO3jwbbo5doRml7w0upblYNBH4w5OgOiPrfWTZar8t2XKYGelme6iMh+Y1Pf2QzPBh0YP5e72W3DXTPTCytBY+T76/U+mTy0lrRvQkAURzM9T5KWcUdMmTORLCP21R896uRuBDrwKHcAsbwISatjJjSANqEixev5mH7CKpWTzxYJh2L3jmKMkH5sFFVDVUIbHMGxkH8Yjjq3saJtAUt/d1Fklg+4mF2pqG8io2Lm7T52FvVjukyuTgyRctaPdIZrCJGiT/eM0Av3/2HsTxTiOK1swtixAft09PfP//2i3LRGoylgmzjn3RkaBFEXJaj/ZJrsaLoIUAVRlxl3OZuYe3Clyn9gqf6c0MVsHUayWfAcosVgew/00LmOGtEhB9i26Ka4NSk+au5CtlfJXW9SHtLihTsEVfsboPvOukIqO+Fg3y0LGKdm37Jje5SB0BfF8HwX+jatB+OAVsbmMLKMsk1DaNtTwp0TVZrSd5OUYodSsLeiOt2qW0l0767S4KxcdKF3rIAcDguPBaWWGJItVgSLHRgFNIZQEUNHZWAOg6algeM/TvxuvRMkB/YNYXjfplTqV0rU8WLygrOKV9qB7M/HvRpT37b8f/buwaXkQhD1VhWe9IdKLd7Q4qVHt7GIHAQeObP+tp3ZdBRtHHsLZW/OLFPRxHfTNu6BFD12HsuEz9ibrhOoeuLnC0B3KD7bJ47fOHRb0UppuMPuMsBCEPWZyHwXgHMfp6VwrtiUZG1JvWfLi8lgO/haWGFelKcT31xxwpM0H6jlSxlNrBs0qsEk8iQnPywjUIILDFlHnbunW/o+aIBO7DBS34GtcxSWX6O+Nyrg3/j7HZc0EGAJ64UcUeTcI2dT2zBY2h1Nee03CQIyhqgTRfEilYltkvlUMPhCE4sdm8HtJ+BefAL70Lm+OQLLXt9Vh3yABD42Ji4kwpJyhSqmRl2j00GGRVpegp9uBlV3CKn+b3OUTt22+Lx5+9CHA4YG0mtIgdhBHAVpEm0Woxb42YHjzhoW8xweCzl1QH/3ZcfIyh7ikAP4gL0iu0WAH5XXvGstl/XTG+5Q9NTHnuvigXgke7SMCEUXv5m+K4jVJoUlpSZHJAMJzRypkx7nix7EhurpzcEPlN3OFisTnEvDlQf/LNcDLxUYquhTCm0WRQhAv7+/gcgBLPrva/2fp8wd3jugyrp2b9NYdWpG8wl9WlwqP/pmbwjJlWFJve3DvRlboUCmK8QvTgKhBIpChoxidY904eQHxrVWXcSVdxmGDF2XDIZtiwJt+df/id4bF1b0GFpHh5t9gZ5SptpNxSuBHLIhCLMFHAf5zyVZ8WAeZS0Q0ajK7sC4J224iVFfM2BUyvIaVzzZC33/9m5CCtm3gFR8cDDdSLmkNY62D3EndcqSayyEbL25SGPJlDT+EZvmpiS7HKwF6IKxAI6/87JvkzWfX9z7cJIy03JVXmCvvODWfwwwqrAA0u+Lno1Ue+7Vxi9ssNmDPDrucKdxsRo6TOP19F0QcMWZzNQ0rsmoZxxMBtMyAlXl1WRtwp/3+JY1+2hKudo+KZAeUrVd0Tvga3TvItEkBkh3IQQvky+UzuAghfqW9Sz9/lRgAsIUGxVVwBOmomPPtDCsdJYoTn5PrrdMS3RVPYwBRZ6PElmdbbVXpWQMeIucE26bZTMCSYOwE38Ebc5b7Fb2XaPyzt/8Zj5uXhPwzjhHD8edZzOfpD0BizgFzGmhiCjVeWIKIdc5qI2mZRXH0dVW4J3pwYoNMMxIJOYZfD0vU28yXkiJjgkCCbsZBfUfmzTTUFCHN2XjNioGd/tUWV8MgbQPCukHDH5yDPi8A34vBvzYf9GkIMDbQag1WBAXpQFyz4LoCL6hGcs/iStbgOgi9We4aUrlCWmTQLppD57lvfylyzRGvWD3bdqYdFpZTdMqlyB/C3dpDvuTzHuE3dOyD+GNgAM993Lx9PHgL88SgaiBsxm3xSjWXkcw8K27JHlobFFMJjHLRQ6/WdeGIJ1r+eJ1UESEoj2FnV+347QcaUlnSsMvWbNgOavhcEjc2qu/bfX8gbWnm2sBP41UVPk/8xTny5Zv652tA3F6nK/fZB4Jk2Yb+hZNAfx2u5uCGSSqy/Ns0sOx6UrryORcfKzzPAfftrF8ePhivjIQrvSy738ULEl7P2a2UtCa7w8er6zPx4mDt1KA+vNJIK9DwQD1oRjE2erG7BkXY03Z/EB9eIjEzUJ3VKOeSN7bDkjWLCMSlUJZrdLJ31BD/pIyCjUKsd6ybxs4msXaN3VeQZHe4xLQz/uQ5EnbvAr//+vdbDK1nFoWuj9s1I3KBTwMknjkXJsV1+GgLxIYjXHzCK15DdGbphJMn6FlgwE4kWTkBOGQyNsk+HPCa9pbPI/74HUb/bmkPNwDg4dwnG4fcbqyDiAe0sYXRhisx+HA9qfYEB73Fls70cHh2KwCDI8llm9fDhQzXsMUgumX0/YJYn+QI4TOzoPWnKa6AyRSkEfPFjuGyFFobGBDTbhZku6C4nKqFB/+aGtA3VNhj5S/fUDMLsjNLBCEXvrr7jVZCTniKF9k2XUzNvCTXz8xZncqfiAfYLogvMRrzEauXXOHDi+YZNwdpfpUuy2h9vEU8jk0j9sFEeo+EfixIYJhMbD5mT3GaDBGqMTlT8ehvggTcRU53iBdhhemkvMQWcSHDSWZU82UsIxZu2DJHATdTDFZc++BAvZJMc3BZuN1uSUrMIYvVGnv1q7EN53WM/dH72Okgn6EC33/9y0MCHwCCLkpov9yhI3O3QlcsCkAxiDXHoul1z/gY1/JnNSsmWWJPY22Nwo8kCc5iBM3L3s2yVhN3+QWlUtxnet2t7s5iTDxD4OTsSzijVRMHYA7AQG9mQWMxJT4yguLlHXDwseihtjZYrNDNf8FgUfeE0Ilfl0nceh4uSsuirlj768d9cdPQD8ImVUZ+XZIsI6MJczIZNlZFoAa1ZKdxS1s+1eIFxV8AA35+Duh9W7RfpN8R9lJjJJaLnJRtGNGRz3VfMv+45RcUzLnh8umOXzATBTUozDIwTuNrctpayHDcdjHpiqt2iQDfPw1xDribI2AwYCCnS+vx+TpIcpKzjTNiKYR9osZgjJkgiY4ruLEl+YbODkIX6BUybFahAKvVzrDNCVelxG/ZEJl4koug3C+5mMkFOCU84yd4QeltOnY/vWaBrpfPl25j2wvp9l6ekGNsFrrfZcP/NougDwzRhf2OZb/MfsIAVNUDj+iKmy2C2DjoesFNuGx+LiIDumWlpSYjQ4NPmNVXd4fv1DGO9LQIorzSvXPGDgZwV0r4LY7Fe+YE0IQGNyj88RxmX9coMG/qOhYpaN87XO2pcOBVAK5EQrcjy27m6wspqAGYML4OKHWu1SgtUS4RH6qO2ceMxQIiipnN6IxfKKbs6x8tknPwGFojBQKTSS4QuzwoP5gFXekD40vigK/NAU/UoLgyZMLlZ5Ceik+Q52WKPt0kamTxgxQffPIz/n5VPP8+xvM66L3bTq0F8/CRjGs2JGdyocAIPT2tg6IbRxukU+zFFcrP7V5U2V9+HetL9yEwgAVAlkFhzpXt7I0zAWaAplABp71JJ5l9DjBp13C2nCRhoLjlzRUrXaw4+WzZYi2vAcvZt4W+TD3oRsorZZ62cWnl98haabhYnU53LpQxzrS1Sj7ph6ekMfVS30eBf5choHfL2xqXR9DYbMZtx9J0z4kP2jY5lDhCaw4HQ4GKsm7LmmBrTGBaIZv5rqsEzCDLudFu+BCd+yB/BNw0S+FKHFiWwyS8mW+dpMtdlBGGfzQ+MLJjF9RmMRh33chKE/tMHqzjWFqtg5BApmHjjfXgyLbWlkY3rZWNULggkqzpp09Z2gxBApHbp3F/BoTV78ueAdtyh4LLCrwy4uLQ4ZlT4UYoDbfYlNfkfCWbnfs4hNsiidoa+jk6JoafI4Z+DQ9wRdlKkYx7Fu4GRKSl+jPKimOeKzQlh7j4tjiCh+EwyWPhnvRiayagY8SjXyPV6Xuh6srhruyKbdNGs6ehVkNlRiugQqsivaPmAcLnYfMOWmHFOOYpFnv0cSe49Ah1lgHrKbAoRTHQvYFFkLX/JhRIm+VzcJ5zLvmyDl1CBvOLFv8nu9YjrXwA/LYI938miQoZxpxd07X9s7tUUk+T+DNDYFj2UxtO9XNUwFPG4hdc5L4Xg3+lIeCDQ1zYMqbHBgt3RwIM+vI5wFRgekLPN3N+5/njrNArVK8L6zL2ZxL72dbWDNEb1tFgUeCpSmFnhXKHwK6X8CTLQDfb+LHia+ADZPvN7qc/AADctoYPD4uYad61RbeKkxwsbS4yODGy8OEo1NBMJ9PlbzY262JbAQWThp1L2Sp5aYBj9fvngrT4ZJZTXKGWt3aZi3YDEB2RTUYP14qYcwByG0QtCWnpA568CaQMWKmC31gDvC+OKxwreOnvVxkQNs0qZBIPvNPm8sEqgO6XEgE8ykK2jYlVliAiu1hsk4l1owbZZu3hZfZc2zfbDoblw7xsXTW1zRnqoDjgxqoOmlCOR5LTqEHTxa89fVVJ0kYwa5GTl9SsBGcNmC5nPRiaA2ytLi91+PtgV9SLCKvDe6V4IeuzCFi+ji2C8ljvsG4PrYCCU0KTNqfJ3lpLZE0baZe1T6Sg2MxHhf0a3hBb+1S1KdHXoeHCA/aPY3eRe3KW/14G/oUKwAckYPX+O1a0HPiTdj7yYBbnjdgA2v/RLmY8g1N1NTr1PhkkwHSwltmxan/NtuVCEHWRLymp++wu33VjQYMqM0yMObQIMvqD7kX6Q5AV2usc1k89Qrv3eg5aRrhQcuUomVWDNMDR0iIPskJFI8w2B0jYFHO6JJ5q9/QPOmnFZAGn6EBre9Gsed133Xb++IShh4mZ1kqK3qBRTkFFYWaWpEmwMLXorBw7hz1+6jJ5260x41du45+tAZgDlsI47AbfBkC7RCC6CVTsfsALFeaimyI/E/z5j42ZJhJvGdq7bWaxT3u6t2HGQVYAnCmkwrsUAwsViFt6JWpMGao0R4lHCS+zEtAZ/CXho+Ew6bIRXXjACTCAG70ORtCpJ7MOkWkv6cBKKDKS6qB5Umh+gQ4Z5y24mn2N+eLGqBIv+EL7P2uaOl2WjEKX5B6RbbLePVhSMMNw3G6VYrEVZWE8BRd22l0t50RfCtnR3zdpaL/S578f/f+6kMD2jo8rW8L1VcKNEJnhrOILAGi2Bnb1Kw6i1MzDKvUPwYpSBbeQaW7M5kZLf5ngp+fw3OR5WYYGZ7JC3c/nmoF7WWGubv/jNWDem5Vk0HnPtrNpgsdS98EHSsS+ZgiLhm/UwYNs8v1J2WRGiUdzdFGq+0XHvvig48KB7/KH6Na8trHduC5Idt5ntLjKeQwUZsvaHxEPTjLRsBNV34TDrqEvD74Npg1bKNuqO/Np/xkw4Ks1YIxrk+QhxYsXJNZKW2hwItTjFUJ4toQCoPgaI3PWWB39oN8+IS3bRmjn6tRAdpB83IbFzRsy7OC78rTYfBjizpYi5iXxcG5SlokQIQEsiIZdXvlZMBwcz5ktBIihsyQ0sIMYQzrHzDYf+CXVoQ3ObZnHoRhYFuRwvZ5RHXIuV0z2U4C0ggRoHwSs3+zUjX8VgoUKBEeGN9YueaJUBfPd0EZIAczusgqa0NAiqHvvbyTRHvbV0JY4/P3E/FetA+G5AMhW1o0FrzHRLNcw3dZk+ZHVr6th2hQlxsgdKFyp8WYQFHQ8OUFI+UhYeEIdNOQnwz+KxoFP0YI0cKdIGMw/sPUSN+ljQ6TBXJKzO1mh89zn/sfmdch6TkHBygzwQPm9DOR8kcVv/uSiAxVGG+g7jRexZ7gy0xhBI55aBzkxVH6XGgXe6FGxilkatvkxJhLd97UkNywabWHKZn0WshEJU7gMNgw79NSp6yEO7nK0GFuI4Vdu6p/fBV11wz2pL1iYlwA3FU2wsADhyx1U7yl2QQWgRikhiXclxVYW13Ed0Jefz0dn/x97eO/xzqL66GYkdw4OXELhR+yXlYL9+HPCOPIlDrhl132k6wn+6DPj0qUjB0MUQg9BAvOBIQCqk0HC6FJhXae/gIHNRMjMLPSNUSgglQBh/hh9Wxovx73h2TJNowBvFW6HygodG5tmOFrI8HxCTCJ6pN3Fnq5LKEADSNPQfLYUMm3QF/HD7yXhX2ARtDIjx/KJCsamHNe534eHLfYVU6pPBstpCQJ31QTiLNauuK/wQU6/6vQlDcu8nnPjzsdUL5sa5skVIZm51nJH8ENs2A0Vd3DCdpugr44mQwiWAY0C2OKeVfFhYwW5PBE0eQq7KGy8cEPwsmYCbguO7MbOvmoW1qf1A9iyOijIXH+w63/4YYVjCsfXVnI8zrZsFHn2xIPHYzR/usjjCyeYbIKMVWlhDHghzKBBZaBdlv5Xpz72MMin8/zXzAGmFFvWEy4V9rKT1pOmPYblClyya0XesMpFM98QQutU/bT5dXweKilq0Hs3jdjFEw2xksK23KTNyjaOEFfsp6MOJazcBa2eDmcECw94ckayvGCDiCkPhnHQOafLfj7Qa0CBAoIQj1QJakjCMaVYNjPRnnzxZ1FvhEdkIxoNAUtmg0Irad4VWbdNMFfF0J371Q1SCyuGHpfj6LY3cn2xbLzkI2Tzg+fM8CLY9AG+DjJP6ctI+slS67uJ0D87Bej5jVvvrxstOyqwaUckDDbjA0e8tPGVGrGZWU70hSR2QVuYbdZpXfrQf7DEQ/JBEeEluRGu8x91X9Bq1+TByo4nGpxpE23312hLHowyBSIoNAE0+u0PGr8/QuWT8Rg2CuxDQApb6xnMHcgyA/LmMZNWYzrCZkvjMVLRyCncCJskx2YCSw++D1OHXQduupiQST2xS5SNILPCyzQdCRRJFjyuwjlcott09kaD3K+NULiy1oNHrP3qGmCQwNVzbsHCbhnUl7QV5CQPk3F402CezDTQeCX9rtdXk8FyzIjPi6DgYTJvTBN7EBjgI54OvzDghWjPstV0I1Id8TCMi9eO77a5SR/FXGH3MMvlHipUgNaD4Q6pMOTmlIkBbiLuVJu4E1qV2hAguUDLwZP2PEZb2hfUADe81ozntFqmifFt9g1blrk0GqjARyTTjmoyNSPaFep9CKkF/KfGE2WPIkhAQRpuqN7aRhBye1GHC3aeyPc54F8JA9howJclXPDMOecLmOMIxcCyBcVBl+SH38EvICnRaQjWEF7WjV27gSHSpHINF7KVrVZkI8IBEuPOJ7h/ou6JUsomChuW1hdhy5jNKVoWET3IFcId4rwMtHvnFhdjQWjVmB39IroYSb8sOViwvbFZy0Q7NBZCmxyKc8fqtQgaRlTRAhmA5XBjG+hYhQ8HF4wmjxDUD3isnDITiw2tgyzPwBXCcYsZW/gr0fVsLbgvhYb1vytF0uRdXxkCfqEG7HPAhglvj2BjoZD98cR1obrNlnq8Ngafl8sl4vLN2O179nUQbTfu/VILn+bvP+pYUW2jm50RWV9GtKGBlUECUQuoW3JuqAij8uSLZle376BYAJgfr3z53h9mP6JdkMSHaq1bv4IEJBGQgFxi8p6GqTQ0mmTRpNwaZbgbyGD65lifya6xXCs4lYRxxYq5SkW/9Rg73K7SaRAlHk5gi3zBHCseYs2NJ3jAbCOfJWPfTYT+iY/+jQDkXNCN/zkcCdi3QL27skQXTBP/EpaUgR1nZF569FWMiVcWGxp/k4dUGbawTuKxsNGhMN6veY3AIW7RuYAPczbfUPfHoiu7+cSFvowitMzk/88yUCuaMwzoYG+3xl1QUxj4RQpaJL0V27IKgHeKhavjFT1idKBi6rC4QG/pJuyIEFQ5v2J8BCOvz+/v5A7jQ4B9CpdvzTLMTp5ULPfQJPqgHYZpSakJCvK8zVl0oJA2i4jk5mO7iSY/9K/euV+dA9w5bqECYxMKrC1QtxyDyzfCrPqp7QM8TFSAWq0o0GM99BLfos1EeuyOEfNC+1ShGT7lFdGNGvTY8OHq3q2LmxzN7tWQFhYAUIOOfBV5oUBHuoyDdkigklFAapBthO5gF7AYDK6DjCQKe1rZlchUnTk/80FgQEqxRdeC9K+U47AkmbQwca1BRRIlaPaFjyKJcjskiYlToUT7GvFaBHFmb6nX2cQJHE5uq8KcpWvw7xcbZDOQ6P1zcPj7TPDPSAbdPrXZhutJ708gsHcDWmwGz8gTzAmXiNRsr85KgP1mVqzpFRfTCBC6nWGyXlUgsEQA2bgP0ZDWFNeD52vJWgRZB8vseJOd+WBttDdmx2MRVMHcQwF49AaHuIaPj15x/7agNPnWw0aq5s59qBHcTOKykcjNbjL7MeV6XZNomZBoc4hTh9oNgj672cbJLvRCIIKbDq0dVPCEK62DrDaMQsPsrCD5nKJnzWgIWG13x+3t2OEKebxWQNvR/dXbtvzSLmjfK9lRtpNS59S4QGqxg5J8pAd9r9X7491uZdldxCcRNlcb5P8m6Rw+ogKABM5QC176By9JIsORRg6WYGSixJWaAMiVO3PiTzj9x7gNK/Iv1KnlOuQQgn3RfM8qq4jjAYNJoY95DZVxH2O+l3cUgNlflEcd59FEEMJ20nJW0T3x3K8Y6SIXl0oNjnZQa2p2S/T5/c3XjooKUq+pWHNLKhoEEUdYT7gs0uoLPX4aEubM+7ADe+i2CWskajS+Bg13UNR3UcPS1gQzZF8x0R3vXAc9j8c/4Sf+4ZcMb7//+ieDBJ4kgcPhX6lbJAYlTYCTbWhY+JACBEbQym9NiiydV2xjQHoyLzlet1gxcnnPjeVwOoOdSsnZ5NmfJ5M/ySEhXq669NiFLADPLP7KGn9mNC37UlUsJsaQ/c/dQIeKs7V5n763zo4NnA41cH0Ducy/0pfSkgIcUA6N2Sne8jwuZqc2CGEOxAbg4HWG5TB/GrGMcNAvKDjaomJZHb9XUwZ8sCbT+LTyVNwiNB5krhfPDGDFFG5ibFoWVIxTTQYVV4RXNNWFH9EXod8FYr+xBuh6STYE8NTYQOex5gCWhMZ2lX/K8t7NHidJGdBTGQ2tdzDSFU7hxDyZ+dt2BWyq3PbNN+LTAL9qVtd7v6TCj10r4DD9iE9Vt7j760Em6NFx+kMlUMLLAFZcuolE8PPYUHt5iPLqIRlpNhqNmURcMt6BD5f5yZc+SpdvLRtt7qWIBLQCfbyg+2iiNF1FKeECy6XqsNWgJ4QXR/y8tQpas4T9fMwFo1iT/i0T482J3rx47ZjabW7okcmmppSelzT2vBwIMuoTLmNDhqWp8ziQZNkyofHYNwMuZc/bJcTahc95W7E///7rj7wFCssWdMuPW1s/XbcuIDePIFc7NRfVyoOEdCAxMtNwrQCbYt2otAbCDdhFVc5CsIbMoiEJLpYZgDAM0uD5McbLkVlo2RyTuQTRUQAoOOk+Wqndy5aftFApwionADRnFYwgTAaUB2Na7wZ5rZMhBisAh1MEeSwMykgHzCXzoDpsODZLpa7ry+xF6YqIsU7URMLBjilRg95IZol7bH3gmVMuB2XpkIuBAbGkcamFGaScVvTsOnKVMRUz2FYhrjngySloBZXErymEf3kXREbRWLZx47I6cMdYMcDwHkPc1GRi5xB25A+hQQ8/W8oW8yt6vhskFYthuDB6mcrZDo1n8Y8crx7BgBetKjV/+QUb2zKNoJuUFmjZnZhWioBNedkIo2VtjdL2WgwLhVD4nM134JzNRuNEu9GbOZOgiZIvyGm+EeYi15zDEIzVyW6MeaghH8V3ZVbhKUPcGaK4ZrrlLilnI1sAk+4lfbN5MbJ78BAFy2COQqrN5ZGmjwCunffdEZIGYKAarrHsgvuVGzWejpLw3V70n4IIFD7ogZ3ydbU3Mty/DKLrcCRgGBeIflPBFeYyJ1dw4xwCvLkM7g4UlKw7tLBO3ekhxnPTCLvIlWYyb7tQQwKCkafd6RJfjly+TnK0ygBCIfVdoUWipW+DdqeeeDT2Z/1eKxMAsQh6iAOxBYelsPmALm84twY6tu2xntgqnh0TWUrXEGCQZFzroPgY2yjQsMDoawMVNosEM4SIll2crVVlfmSiejmabyiNxq6lMeXW1+5dC5hny2gPfr+yJPsv3arl6388X2m49w1Xil3mcU8kUUwlQ+culkKRWyD8V8oUw48y3982R5vc8xH6DR00X/S+mbUaF9OD1hZTc4S/nXhBxbq9r8R582YiO0hWP0stvInO8F4Oa/mNHXSGl+AGEj3cGkc5/uW2QQJ4p+dEGTCjnanfc8IoUDM/tvk4aysFInVcnZa4jUfGBVBysCnNMiQjOaKspsC9cm5KwEjcCml9hWa/4kWbDRDHbdxF8GypEsw3z2udF17K2tn0sWB7Dm1GQ8BVJGwAUsSQmJ+hfz8sb1Pr/tjpG5YC2y9pYOb3gwVR0mV1WZ541uv3Y/cP9SvG+BmRd6XCdNOCXajPysBwhliXAsCiOnjd+oSvSoAJAAdgYIKY9oW6MrAQFWm0ozntIXNblNvqYJwapNAkmwAECxtvBFsgpq6yOxoWqu1zwJA1ry2CiGDT0K63VmvtZ+Wedp7+AAPC/ZzPw+Mc8nvvm1fooqLkwtu/YPnzEm1FbEIiWjW4hmlogx/CgoJNhGlggLrDQC2RulItLYYpA+JWeIz6WfBazlMF1jUZG2njzWcDAxjBm3VsLkYQ3gm6brQYdwi2Xw5jcQunumg1X18E/fIcYLDwhTD4BtkfTa51OXE2ibA60BIrSy2cI3H+DLVDx+8Kea8QDMeV23lkt88Olj7/wTRijlc/PnDu35nMOR8g3s4RDHvAqAURkSjLtw5xZbC55C9FY4hGvNk2ixSrPUcwK9Mn/zi1/+QXv4OfOt47sAFMnVgH9bNVKoahTZQxGyNlWh6qBHre02W2pFEAbhqYed1OmuZKxR1M+EooSNKYALIPwiuMNQ6qbJCfxAhbLAXmdCew2VtEO5chG9Fq/Z15iFawRRGM1rQQ6L1t+mFbG28b5e+xw/80aoCnacBdQHq/TMOdCKR33K8HXh5RkfFMCzCyhcSGLg1zhgOJNpsgYDOJy2I5DzeD86AkkH5sIJBDwAoP0CJIhmK2bPSwsEhNQDBTXmID1dFgFABxgQAFV21roeC5N84BmM0tIHYHhA8/cxUaczgnpTh1cBaiw4z6fUHt0rC1ilK//xhD5JR7M1ebu68r3htq6X7OiqqOjVC/5gybQqK7EslQx7KLjR56hUcu/xjc29kQeBmIRnOQ3nzivDP8++eACxJwn4PhUA8KUScvPSjKgPQVLTfk4GN2EfPvtWxczEiboKjInjL0QtDAp9kCekECCxY+CQlo/jJ2UBdbn1TR4LHO/K9SWJIGG75QZto1BwD/6eNocxbj19XfaUB1nuYPl6RRNxkoPoQQ8Q4eAj1JRpGhNDc/NaOTOqwM4DIoRMt4+RLn72rWTKSOKx63p4AIMqlpjUWCdTd4gArh+RYUBHpg1uJ10TNxWy76ubDzCxwAHfuBaktEU/SQl0u7Cmoq0ojmx84UHryzbPJsIOhd7IU0OJKPFUGxtf9CBb5jA38oItD2XmxzwGYPd22BVPi1G1wzAYmOvK5w1IboLa/ZkhMqMNDMoTMhAV2qAa59RqLKQNmSxWjNudAZ11f/KXnkrGno2RXZEGDE8bhWL2QyzG+po0RxjgGIDcsW4cAdLhHz47s9QTvz4OHQu210w3Jr2CIFd+UQzgSqcw+3bbAdTLzSBnS8rLD4cwMAWjA6kE4MAMLNF0HejwcioLctnUZS2VtYzmmA7wp9brJbxa38yGAkK+zea8qbX7RI5MYcXWZBggO4NOt/Vw1Yt75FE4cLEzZ7Cnc3a91KAkaB4e/0SArB0UdABllt7cibaYYhJCoJ7QJSFkI7X9MfT1Njn8OK7bmIWZQNa/OdxQ1dC7jFAyvgBWHWAzg8Xlp4TeMN6nA83rsZORX3Dd3TJTFXHvPQx77vvdVbyw91HL0+Wr7Nd40EIZ7+J5MLungUistzFTyO3ib4FmNHKscsIQ1CSLxW8xYt+BuD3YJwrN741s6ronVhwriRG313u1qwNaFF+y0RY0Dchd/P/FTrKzd71Ia/3Qj6uggfDUazIOTeNFv0oJ4siCY04toGxe/t/z/FNHBhwX1zBu3L67A7F0hbILqfQPC0IhHFCm3RE4N57rMG9GULsdL3kkhBbeRmx4I8TlgGPH7FVJCUwoRUotcD0hiKcpZCXEFkhBp7k/TSW3AjMXeaBAENxgpIiyBoAt7HuIO8xwhY/pxjY2eaMWe2Fbww4Zdk+x88idFQAQMJhsw7dYMNKyrPCLB4Qd0/utf9pxHGk+cdsehgzgUHzSFMn7yUs5GjgFDC7LFbu5tkUvsfCb5q9bKhwUsatk6Eb2P2/XINACQwv9MRPAqRkACYJisiLtWRjgRBYUmkb0UzC9J5TICAJm5gxdQSBkFwQALFS/H8cW8dl9785PkcMKmT6KcR/lbDn7IZ8rURkRHRI7TgPLgtDj5eYcWeU8aSM1hgCAzgPT74pPtcFlAb5r1wMuy+e/HzOQAbpzsqx+wyylnbvaaXWQl6v2EOqK2XzmlgGDsI9NAMD9FZzrtPA2jjY7zsuHMp9YT1LsoEuJiWCMOOqbMLlzPovHHzIqxylzrkGC4ChdPNjJ/nLK6a+E4la9oSOrtkam98QNGMFs4qsIfzPE9/YXK2BB0KkyJLYW//v48CfzQ1wKUGsz3QlRnXx+4QJYXgKgDN/ODIbLYtUOQWKJpaGH8N/X0gRa2PK3MJJuVclLM+SBEWsj5K6G5Rqals7tDuE2eskTz7oRCvUBfxvWW/KMk9vdltmSmX0EatvskCWANOjunS8z/CkFVc33ybs06bcGmDboUnMg9lbKdLPA7oNbmyvtZBS2dth4yUScPzwvzo9/1E+KliOFi1J7v4KW/h9RZcnDfbNCTXRx5ZiUt+k4C5NpjmEIHJXXzShAd4Ms9ll+aNIcisrf/iJZS+pQbsqrMlRTPr1LSLxUAP1ZPh4XAyPOL7jJ2Q/LgFgEgcIU7OwfK49MJl82/QRX1vqAH3bvitjDgewUCC00UDLTzFiiGpRw58EIhFlP3C3j87T5RLwFcf0LJDyvsYJGAANIM+7rW9j/7W+73iOacBsdMqJWOQiRgYECpUEVe81xC6ZfgdnMqhF4vJCPvSI/a1M7VsGRXaYkaMwUzYR1x2cpcyzgylme9JRhA9pQdKH1hkAYbAjL3rpH4rbVhUkDGGAQMbacRPD/v/vhbO4XvGwB+vADztf7wAuPLLlQE02XrKi3cu0LxcUQBkDb3oZGGZUOnK4bG/smKs2cQWqEsYTE1AJzfUCULmhW5RkcBD55lQ5KKoFvkopcg0QvtbOe8Oc0XLHmOQhGswLfhsgH/PChbQHT0ZZQG1U8Qz7rgP3SNoXMCs/CHMPsBx4Fc/CubJcCudFpNDTKHkjgO0wVBQsKGP9xHV9b/jLIpAgPkZoQI/nVZ7LPssXKEpyX01l0bqYNr5OhUzkVIpJqT5GRbTAuu9gdCobB588ZJf7JT9HQ/4xUXQt84BbG/D5uSwIAGBj/O9r8YFXkWJyiaRU9CKz+8dTJYuTgBe4g7iJk61JqdP7oh0XrsCO27DTKNguAXFwhGNwfClxMchcbY7i7PfDUvXwOiYwfkrY9owPhL1IJoK8cmEzIDCdmhNIcNJYI1isdqAQj+EB/SKKWT2HbUdkIzNsajeeo6K4U6U1SSlS7aCJSluO+1fPLVr3gup1sz1ilCnYSKMeavMVzQV8260g1zhbnKHTvzTxg2qccDcQ0Ixz8nIfObMXn0GScHAKnGB1Oeco83+h+8EKd7JWv/gMDbDLF00MEb4Pg38MScAXwc5rm9k0GUZazYhnjB6OlMADgtRUUg0Q8OZSxGSywV0pNlRYJkDWo/MwwirSYh8bAgI2TUB0gEUXKs0i7b235UxZg6RszaktEgb4jXYBCBJVlTAfaUkQHugWp0PypsRqp1KS8ezghXaeJP2z1YhtvJF00lIUpRQnP5cF3uoiRgt0Uwf+ZN2CaGlTTB7eeUE0DzGsiobN0L3fkHQceWarNBcZ6YqxSxb7DlfjJWkolcuhRXSjvM2m1vz5hedl4Hb2DKdvx0M+KYawDIwslS8z65BOvEb1cL45oan28xelRss14slH3BgGgE8ttNJtI0V38xD2SRjWgcl2VP4cTzfzr9WDFl/ypwApN4KLtJzyVjzhGGDhUmkR8MsGmiKsIedo0DnBNBsJnjvm0XUcHaQJy2ePu7dz/E4ooSIP9TxXset9dl0lNZLa5nXZrDcrgp4H5Si+bO3CsC/dfNetZsn4AcvrWCMiHZXzHusiHSB163ZKjB1QbhuGDJkKN7JJW28o4gtu0CCVN6Klet8MxKF9fSXZoZ9ZY5HNOidSAAXPoSCRaiSy1HmFwp0qDAm4Fg30hfLwHfO6D/y9P9KAehP9C4dBMsdhAIRtEw1ykjc5oBuax/0u3JPZxmw8EiCRJfxGj2icaHilMbSP6zWMHdf6mgUiEsEkxYdaDHi4nEUpgVoLwlQNJsxbiOuaMxUfqtNmgAc9ATk5rl/xyjQ3ucc0CkPBlkj3KHcCXKTXNwQbXXyMofI47VgCLgVk4ndyiUhAoNRKh3z3VzxTOYPMXvQu7vZ2xNXh71XpJ6M5RO3eOqiKYar618ulocTQ9Efc3MSaA3ZjUQrCxkE8tAoVBYRNgpcie7xsklwZUD/lsvpG2uAVALhi/RQSxHoUWBFV4JWlwcSy3mm+qHXA2rhcAzScgaRmR5eIlieADz6ReoPvhRK3oQMMkT/5wz/z40nspOxzFLUIeIDlxi2/8NdXuXLMF9ROkZIMIwJ4Ob2IC8aDlpQfKig+Dyur2vOUDXc05hlYF4rjzmBlnTWeNbMx5wFEgrB0Ea12PSql2S0AmA2SeQuJw33xIJWYA531yhAjhBuSdTRTrtryoabtPeyeyT7Z14w6tOx80mCBMJFgaDllBQFgRndzAjnfVcbb9ZliWvm1uj9o3QKgr+i3FHEXTJZWrRWxn0JP8wB3weCP0AB6JsdNJf+ir/uTg4OjREYzGEa1vWbB2OkltD9tyy3KYoeERTrGHRz4TOlyQEA0B4XFEP7ST0K82MNCbiM4cw7XeMphgDFBBDDQ9tl3vjohuS/u/IsUQYahwCiwXXedxgF6BCHxwk0+CQQfJoNurUsi3ctUuZLtuZvCQK4KB7wlzS9rnuIxYsewrTIIU/Qh8yMbQ6gY4QfQZ82RlCMm1Ap2JejN1rUWsJW0My4PeirJiNt7M2RhGX6UBeFJeODOhfIjaOdERRT2LwSvmUI+BU1YEECnl8etywBK0pNxICUaxcIgB0Rfhp55uCHauYOVOJBGdXsxA9quIiZQC5x4+uYo7E8+84Ooljs3u0hlYAr9MYDdt7U7Mo4KBkFR5w1vAeDWQ1445kXwTIwG4H3NRYUIMOnN8kLDxA5Ff5TNbzncdSBao+mYzYg/aXVo+U5HORac6kZ+P3JbqbARHp+R+i+G14H0jQ7nfSGkawIh9GUNAnphSarcO8yrB/quIT6fOshqeail67sCrIYTBAzLhBXOH4CqyQkoronRgxu2/Te2awQVWGr6YJFpRomiBwsyQopTYKLqWzYwfoYrzKwF4DvleB/6fT//HVeBcCh4MsaevnCdqlAuP03d5BBof0A9ovn+HhyUjQhrkKDGY3F5kPgQbL1eqfdSBc4QGhqLYIA/2ILVFwfkEX/t4xvagIMFs7Jh4BohEbuf2AdJhhA/DqZVQgJgCUo5oBZAO6yBjrb+9kfZ4VMjHvaxvTv1i+DIDOJcxzYfOKKDQSzEvzAkqCNkJCAnJwRpH2XWUREmoPaCnq1/1pFnD4KvLVLjrAMkkV+uQVzrVc1umkfxWU1gm9LFB6QyaR0EwEz4GGrne1hW/e8JYjFEDd9QPxly+hfWQPMOOj5C8Qr+bZrETQsM5pecqhdGUch3MrIErJfEAxX/Njz5D0zObljmIXe8CA3tt7LFDN4pMxPDXPWf6ACx0ccayNkZ3Q2VKCHq4zTdcGlepk80eURWFiECvqZeRHck40mRwxjqz1yKRRfmlrleeWl1zSH0PxygCN0a+1WJRqGdcnBzou4axGzrYBXgYESgwJeN8433bqqUmb54Lad7zxe7kQQat5Inc4rvXBNRB/V+TKPQqiXEn1ZdpNZayjDNhCYdgw9VqPfUzPthRWAOuJCTpQUwnufyHJMR5eige67RhW1J+l5xxq/W0z/44eAL2IA/SkpaJlr8uinnQkNlU83j5LaiedsNItQM51lhFJ0XXrYtrKDfoxcaYLzA9dIIcAsAOxjSsPVVYaZAkkam90XyMQBPAqKTwAOnA51PWj/s/xKLe6ieW5kBSOo8dCnXP/RZz2YJ29j2B9WNG1zh4jOD1zW0OYY5msA8wsogyugkbN/p9HmYF32RgdasoBh7jXiqd/9FEIN2AIDDPX1HVS2QC2YER35MjA+uDIvZiJMfwjFQnHP0zgH1JiR5KA0ETz3AMfNxWcj1cfuLI7fpwYIEkiLe/+UIpBUAIQNcFFFG6NEJ0x0xOQP0U8U1skcbGbRmwcMB0in4g4OBN1FHHJLpfvUAnbmTzQLwN+4DtIc8OAq/1WB727lqpyyRAwgOLCc6VlSKNK7sfHHYxASaHZBHJVTCFd1p3bs45oET8BemOCgCWzjXsdbnUd/ubU+awBpo3XOORkSxTkBVH7Nk1oT3GBElOmlxyklmi0iLrRMgtADixhlLQ06x7EdnzdPI9UCrxDDWfEiKTKHSyFyoOjjRe/UK0c6RD/qef9WFxEkWgGHHi5VNAcITk2D3NEeHVWYd3iFYD24cCx+LANfxAa+jwL/2yugZxbQFwrAJfxuJEzIUWXtfHia0RCCfHdyXuTGY+Zb/SQZVE4kXXzQsEtnUAkKGGsgBUVLPA1igibzhkvyiJYOIEOzoickvcyLHjbRTmaPIvRF0wNnOUUHi0QdjIvBL6j0zwekmlAGvHMW12dg7IgMcDya+8TFZcFGKs6yiT5UCfiAY0TxRVD2hXDapGHk2J1r6wC/AH7s/pGGBfPO/3RagnwchgObKCF5XEE0VZrQYIu6ml+30FSBGyBTVMgMRsUZGyEzh2B8b+qXVZw7jHmDrv9t/VtbsW+vAR3fchzBghGvHLmxaZe1FwJDlNdCt8YW+K/ismTbUAAbc33IHhwP+cc1GvtkHP3RgYG2WT7Nq/2nR3h/jT+UcV+YMMpvJGc03ijfaB5PZvYJw9nBg1xg4gHHAZ3wrV5WIfPjnOOOZpKN1l2rzOX4nIqPbm5QJxKG5xwQ38/6wxGxiDzOo5cDbubAgJN+PDO6anmcbIeICtA3qNNVu9tqFfQ4GJ+MbhyCph08fbUG6mDqmkbQAiheWpEydCOa/1mOQ07uVNvH7mNAF3GI5B7sWOftzfiBIV2YJMQyMmJng99jy9eDCw1msW5SdC4JsZeBCxtYZWBNBuu0+l4Jfq/TP3y06HjCAPhEp79AI8mpiIwiDpVGy+O0cGC2/265a9HosujhsausCtMLjmHCQ6mC2ShQENBt1RrIBWrBfE261OzYAmUK1LNINrqeJWDPJR/MCUibu1dUWFhwXRi9HpDZzgGAtiyYAGQNBExOZQCw8HicwOrOitvzQoM3Y7jsTtHHhzmghNsxoBOef3SQsuhEVqsBdRlTjio0mB/fh7MTPWjkcYYfq41MyTGASNpPyh4SmVeaPKcBbKUiSwK+dCoKELZIkxi5WmY4zLwJMQpoKaTp3zcxm1fo8ouO3wgG/Loa4OeV+dJ9ZAd5JeicVuZb2SkSV/njSZTBcAXsgYOdQgl6dgcTCpAsxC7+9Ji3D0xNXrZzDng7x3+UcBaIBgQO08ghQMqbqATWGs6kzc7JHQyxGQB1ZzHAHDD/8gFA+EbnuPlxFiGx2w6ag9NawQXDkAjM6wyky3miv6f+WsO9pnvDLuje8lHrUeZsDNkwNPdwdAC/CfZvyNPss6VvkagAQwPaejmHZDLHvMg5BAz8RzihyW7D38UwmjBEyQHyGOYObUlv8FviwouOtiwDqTszqlNYxuW+kYGi4TsjPNlLiZzt1oAYSzJlPzz0MVzRyqn3NQ1c2EC0wIHLn+S71/T/ZgFYvX8QC+hjJrCydmmsRuZPV+StK5wW/Z/TAHaoHOBdFhBx3WqRwISAixGmzNL56QwuUM6ta3acN7tW/6VfQ0AyKDiz/0nUwLpF3BwCkoTBRqJn3DfBLQBizN5wP3YfAhr4oOBkkwsEOtBZ32f7dZ53jAKoca1ZbOTYkACZ1ZsSKIOE8rINAS9Eg1kSKNHa88IcDtQSWMsfMFCaLOUDIWj+tqIvfKv4/LaGvXhBPM1oTqPny6CUbFTjyfKskjhIVVNnaWV7Xc1+I7XtvO3Pds5hBbDZUPi71gCphbIZ+shgchWASybWbB3kkEWyppUMmGCSp5JuvTx6K2AKUb01eApzU6+ZAGz9LXwnbnPoT2QH/feLFYBZjV/4lsg7aA4EcxQ4hvtPjC1fXjph5clgIzRe+N++Fph7YCnEgIE7xcONbFHqZh3lJyG1AA6K7w1MiDu5oW9nn33EbElmJThanwc5tvsllzmxdcL4lIzN6zOTITokp/Tvy7JagkVpt9OSY9DpAwaQxSMXr9jCNq7HZvmYVw7VAUER4PICVee+FIp+80abOniZyElUNFLtyRL7wURDbiIM0S1o+0H4QcBvw6uRxOEztu7KltAV/MXD6ztt9Hda/nz+F56UwNcKyCKCzRBCwACxTE9ftQg+qgGiIiHZ40bxQem8NYICI1eRD315ByasgIYpgbkOEvkHHdQQrZ31IC5RGLdAKzUsEwoOnhcSbY1pWyAfAsyujmWssQBwCKAzxP1sVGhyI4T+b8xbEiHy3fLAx4YEJA8NVBl4OSgNK0Hc0NcyXooJhvMyCo27OYT8IfzEJ/D73ty8sq1VBLwM6gZEi2HoB70NIk5DcnyiyJ0i0akU64NlE92z/LfpwMr0GIwC/miXTdDlEbT7RX87LFe+/aKc0xiM78MFQA9piXaG6Ow/B1lirF2Fn89RjW8mvJFwSiZm9ODymaclIE4aNpEz6i9C7kZ8z05SC74a+vEMn2r80zH0TsDIYdhu7kZqEBsexmhtOZGpX27Stv9pkewgrIbm1XDH5+MLLEdwGZ6iA28jyKA25F7npTMeWASNUsYPtzkcnPdz/oO4tm8tlz4ftdNDNVgmREG3Nc95SChyNqiXIRzWJSNe7yhHb9VWo+qyG/ZnhkyT2EGbdtrJ0ZQJNhL8MdG2Yb2bRYPjFdzF7BdQzAl8cJwlgGx/krgcQIGLqMLhKT3UBgLL0KB8v2hDmgx9Nq9uVodk+wLHmb8f+r9nSQgfJwAvAOtj7zr3MbSr9zcMIGxaMPJ/wAcNJqsHFyhRChAXE5TNBBeNPgB0Hf3oNEgApTK0J9lCKPaOIgKbBiAKsye88d0fQufUvM4xG0TLipGun7KAhnF5MCBLhtWdrozAgefjfMwacD7uFeugd8mDK2QBZ6MNbgtKGh/PSIAZtOHwxd7/VuILPkoXZvQQ0HK4qLE9/DJE4rJMxpTmSiAV2DCnoLvTgeah8eP5dPrjJD9cG4w6NJYywGaCKA4SJiUUiVKyzEX1SobsiTHCAOxQbRsZR4js5hJhh92smd9+af2aGkCcecGIK1pyCBAGMpyRNRdN2ax1EFdAfJehFs7Yj2NhkujqjEpQBAkwanTtYRQzd9CKZCgg0c/iQOOgT1CC4NRGTe7EaSHXNnJnJUZfhIpKnUGIGPNmMFTghgkAoMJLg1rkxYCBcae13LykzszDztsKQ4YhvKVvBMDhOBv/t0ed1evl7O9HO3B1YrWfG12xMgl2lIxRIVOyYb7yWSRuJDdeorfHDeugWVC42Sf6kiA8pu9uYbnItP/BZh9CA3G12a3RQSQv8k6w87gvwG341TnM/9feysy4ELqLVc0Q45Jns45EI+kmkEAoHuObkZLHcgA9SJQ+xJV3H8NH7dj3pdCvHQI+x4EvH1APBV6GoH3VgGUHbc95QywYIBoRiAJ9BUYCzkzmD9ps5QO/cYcBpAjjZ00F1rN5hWkppFHAFh6iAGkLZL7Bsm1RGSjHDcbp0elAyiAHZkijdXOII4VpnBI2gwtKGOA8Zw3oGAKwAsIIPsvAeQ42gvSHGM+UULeFQDN+YO/P/c/wLZCXgUUJJSkobo548NAYoITaQS9nCBw4EcSQRlZ6j8gbrziCdibSkyHEwiQyc8SECuCLwlw/W0iMUheTReBmdfpZLhFt+fHIks9a8LTSva7ubYTxzYugX1kDOFVm1ZwRLw9RFynIxK6mXFs6OBM02i5hy8dcFLyk/O/nYHNQTDzf9VK5n+HRb1auynshTqBN3J4uKbHYX+/jv19NoGFvD0m7j2iSjYPgcHKkJFDlxO8GJyUEGoWluPEi6KwKHfDACxlKNXsgHkt6W5YVtGB5h/PCQAmpDJhsZV6Lt7PdyvxYsdRpPWeMAjRUQivEf+9kDUCZ5HYIdg7zHa/D3N7muQ5UoMOZIlpORxaKzIQegkzoz+brN2g8TUB4KCsGCBsZPU3WDjYUrhtCfr9UJ9BQS2c9jd3xUql9V8qHjdJLCUC4UWVAny3Ch50jRjGy+azv8E3c10Gfg8bff319+2/t//A9qB//SgO2KoDrcUcCqn0MjS6wBIGvAiDmz8Pc1ukCJG84iskbZSdUxcoTwrsudRNc+ssdiN3asGxISgQo8iEOHJUWmY0XpDlA3sF5zsrHYd3qMF9kN9Qyd6Bk0dyN9nAVOR0AA/qJBosOcUQC5Nal6OB3RkhSHbZFBfBqzxIEZOv3L2cISQSyG0cXMoLAvrmQgO6YiWXWDm1+mBUDH0nCkPw4a8OPzb2JosmSZTqQfRe0JMGFMwE9onH6H6oEiT5xWeH1MSaz4+S2DZk81TftBgbgXLgUwiO6X/SvYYX+6hoghmguYTFETTBMdtAsVvOK4DqIwTKRO6xg3a69LOBM6lpo82q49fMERScgVkxvRuO7wuzfM1glkIX5XgPmRfo/J0aBH8gNfeEE8N6QMXBjPRC6cBIHFnHejz8couQtI0ps/oevR/iBc9xbQS2ZH+db+0rv2Vz5LnbzDV+XBSYMtChoBOblP6+/ctbjFss5yq1hCKgYBRisgy4m4w7kSDow2M1Rl7dQJzZAQx92XOrNkaZ0gIpDwyXOL51lYN5mnee4dj6M9M7MG+hwa2W4sIzj0mF5dmb00J8SeTZLCXtJxmUFzF+V728dpmUOhg8npdLNm+SYlyIizqD+M44ovnQnpcHm0hSWTjt8wVPo+0zwrQXAz359jqFyFgSztkBE/7A37yYEO/GXOhc7dvrzEFMBUFJ8JDCAz5zc+0M8zM8vKly4voOkgFSKAMYxWAl0G7VBLVggBgBiQglLE5CYhBLzHhRzlKOkHJd3FWdZRaObJmAopwzfJ7NOIbipGAJABHrn6f92trc6hwBOAxUL4XPM2mB0oHUQeyovWkwJwea4/wMfAgNefB10yxIHhLyGgOEGAcM0ATSGw1k/D5x3ZoS98aMNB9xMrNqj+cM2z8khAa9Dt2w+cdxERYbXM2Wr0AKmWNjO4tpUqcOUzua5MYoPW6Ztvpix4PtfdeH92hrQ+X4P20GYswC324sYqrxjaRkGDUR71olGjAjEmPnHJWMjdIx+1BXj4JrhJjm1vYjeTF7+cfPjWwt/u4f/OgymP7unS26Pm45J14v5jiJ4ds1QUwBZQEHA5OEmHnxj5qBAByjhEy5TUL6Y+da18TIvwRzmx3lFHvm81fk8P5AxgJ+uQkdvc10AmWi2TiduFIqHSftPcNoeyQIPOAqQJzofJ4XWctIqPDQ7CLd4gxk1gxUaMy4GuaF46zPDJSO9uoUDr+hXI4xJP+c7m0RdgcwJN/hvlQRHlUU1gPSiE+AgKiCOIITKJIpJksxPJ+OsfkiD+5Ks7Hsl+CL8u9eAywlUNFCZ9kgDHBgRGmijZrYQVQVALrpigkaTAQMYQP0emgA0EygWRbbE5HuFyxRIFaALDEixwdCTKeKNBBXaglELRi5QyH76F1EBwSXj/oeMoJjNKNcuMeUfIYSQ/RBNditguKENKnwZaMnIhEjWgMcJHQB0YcCEK5UBnAAIbfS+uYRqAijLm9PsYY7lD3H4cawVUBQhcyxzCEMB0Q2JDm4gsOlSeeaIFFSbpZvELQAxkgCaPKbQEgscDbYd1OwIs5JlhQhLHpxHNqMwNwVawIDKgLtzhs0yOqzkgF/BCv2NNaAB67yi600mNixLgIaZEVugtmhCmHgwIMD3LmvtXwoc928cR8HPQdsufBx2cqiigXFjCVMr/tHo6lavcPOI/+sZ/rtCKPDS4w8d7YDRe6QA6KBhcVgd+xxgamGaUmAOmGX8wCLvlYjCD7SaupehtxzsoBqUsrp2bUqnexAwAEGoxU+1lxohFjv7rdbjzLdZ4gB5t9hO5GeC5JCpP0uE4GgJFJO7R+AIbhbajLXg7Xa8dxWd5Lk4SXs4XumQXjDYTzUfDAK9NB3kikOTOzNg2cAH95Q2O7nOPn32dScqUA9xNxnZTIFtpRN9H4T/npAA1klQETMxmvxVDLKEuaPhw2OV7fgFnuhnbgf/jsXgA3PjKgB7gvNnBWAsGmhQGSAN1ByhT44F7PqH+f8wGaYu+DcYDdQXQUGIsXhqDILamGXUjkDmj2lWOoB4MI0C+1q6cLFPYzo6RKQAgWUFkT0pTF6RqADHcfCQW2ZqXQ5xWpiSp9RMEIAVEHaiwAHaCRD4QXu4s316YA6Yd9zbbL9OAIEnJqCwu4SmNQTQERp80MOGgD9hAoivx9AnX1woIJEwVll+3Vte/DAcGEPAQL+vcwZbh+YDQQVhfWGlyVH0fGw5ZfEqAPbkIA6xhMQYlBhcwH2acX7oDFGTn6X+xApAevKHUM/Vvs0r9LfXALGRgZs4KXChAnQO4S6o83sduWFtjU6hJY9E65ahixQtoETzPeqlKel3rGg30PZv43G/EBV0udygb+BE+Ntjlt/xXy98e1if787bPfNwVMASaY54Idmw8iFcwxiZeBuIGHvl+/rKXdCNIMFs6h8Eqyn5Ffrm7lEtqLGfV+HsL+65vz/mlZReSnk8+j2321Fn9StwS4JZHsRy0P+hSyI6Rm9obfSCbrpkC3qyQcEwOvr56DSAho8QdqyJNz5TxsCeMIQQf9Q1EOBby8G8aSUQy7QBIGuUh333MsClI7t195WLbnY4elgGQs4S8c2APH5JC41DNYkXIVZD1zK2SzLWzR5s6MhfvhRfgoj/rcaCz3l7T0bQy7h88X+e8iCHEGDLiB8igzJXyZTAyjQ0MTDLAK1ujBjKCUB5ACoJ9saPK79VvXAXMiQAgNnY1G42UJYhEiaFGe0/8V1wQ7UCsqyYWGK8EmNucwQAEsALItJXMg4lpYs8nYfACUszHgiKxxDwwP/Uez3vVAPMMoAtECYDRgXcRz2HogKWMDjqGCnY96LZPwwHphyMdmG+CIIorFCjq0gv3xbQ14XrMwsLi3KhuC+bIJsJABd/6i4LiFZ+VlqAzhnzB3VbCH0EFTVarLpBwdlO8+UQ54d+ljpM+QE7I8isTfdFUOu/9mr81TVg1pkSytKGbtYRlmmpdRCmGCywMOdkwkdSixhvCliRpaXkAjoQWKGFW6Bs/v6I+hqhVINWpJxNm3XEp4ag+feTqEAG0x/YgD7ybbuRKMZeZXRnTBpkL3YQd0HzL4MmfKAMvDJKDKIBzge0Bfewle6aEa4IM/WBOccTkNQsGOPt7C+1vuDob0dt+cxlVgLjCM1j/0R+GoYHcpSwF6rZbEKJq9rWxt7N23EMGCRKLiBj0WIqLnMH62LziMHGF6Zk+xcEbQ2X9Q0nuvU1CtiKZ2Wtmnu7+RBtK+ESxABQCRjEdzQNRKUNZ7G+0JKacaGMUZMzcnsMcc+F+5Bz/W++DvpIAfL3NCz2j45+TX0mCTYiUHD6PK1ANROcw0Ku2mIBDQ4E8gcN6dTCnXaz51UAMDf0YByzYEblFK70To4flMDAfju8Q4rMITgELF8gUELFCvWBQIZxUITNX4t4TPMubUgvJCCZMx0zzlptEoVJDzxP/wfs4d4qCsAbxQHvD0DBDaRReLeIERSXQZsepH5qAni9hR8O3uYHJoDbDRPAkQfOGWqDY7rAAFlqGNkE5/64uyxg3uzv1eihEqh+ephWxjYy7PSlDU75ogAd7lrKR6JHTqI/BP5H3CAlyBNjT86wZycdSLa00zX2Z3OIKzbs1y+CfksNsJR5s1W9JGoOCWgjJByDOyLj19AcG3ijQtN6mb0uqL/xlrAFAkLCZB/5ib5wv/9OV+czObp79ZH25G/38Ok1/J/D5Bv35n6izW2lJQ+WminZJSIFeRxc+o8hShL2Qie6A3BDe3ydJ3uOd7oM4dqn0nh4BVKoQObX+gTjtfhexiwD749GnCffSp3NRQGUgxoAqhRGgZOrf0WMZXq5ZUDE7t485Otgq3q4KkI5DM3vgLcG7k73ETIHIWPucytTIkudTuxBwrXWZrCMjsn5ElsAfUh0oW4qCkmRpN39cvl1qEjQRTKS9MkKHMAMgW9MoDK/gWxyNIscNZjBXm7eW+YBaELDj9HE/w4gwc+t/j/f/vvTXQTQhtZB4ykWuFv7P2/M09t/qZrU9T/A0tA6yCcAwwPURiQRAQxK5Fufglm5K5bvMPm8rKHJATV/UDLdYzQo2IhAlhisLRBa3HklJ2aRrjZZvhSZYAAgARCBmNM1KAgYdIZAPOR51pN4wONtjgJAAqr5Q7RRq5byY0HBakCWRQ/Z3kQCbpwGDlsKKTisFFvOmCorB3U4gkQqgrF4qnCweh/xfYx3rwR3aoNRG04YWe66MAHRhjqIDlS21MJrKQRlEqJssvw0UQeUujxkuCA+6Dw7ggaC3PyY/QgFeyXoo/8jagDFYlB22QRgHCEiw8MsrbUI71QwkR1EFUlW/13pURbkJIrcTvoFwbApD4X9Hpw5wRGCS8Z4zEL9AG6Vw4qz9hpAC7n/OsO9YD2nfc47D3Qc5QgqwN6/yhOHfGE1vMmz7KkViK99vAsmquF1zK5h1ALdAJaJtCNt3SCB05NFsYJtNJibF0Qcc145zg6+6TnP7na0VB75dlTwfOabDJoQpSCmWsMmiUlgVQJq1u9IJwgBttiggLF2IC+VsuFB0z4S+rUWkGN0HFfaaVwLG2G4NIBGUya6AmqEHGHWWMATN5EQYm2U7TSpCGvRD380mPTtsEQ5VC3OJlxUpKHt05AMBN+Ubnhsl7kDHGYXg2/JhxT85bRvgf6FQYIvrv73T3ZNZt74+3OFwTxjAJcOoHIaoCcoAYAhws8w8ZfWPiNIEcbPGBnUKkQ0CoH8heyicUJXYm+hQz/qiaQAjDkqbK4QBRJNEqwhQM4QhgckEwQcMojOKXjWoTCAuhZBMa44M2QX93aC908cmC3/aVugRwMMUPvbg+5AQI2fbKLTRgfCEBCxBXo9jAgkm6AXboRcGmbhLSs4vvuyV4ygB7PE30kAMVXwJg8WGtw2KnQOtvMpyQMDhDdEWwFZeD3pP9RQy04uKbRS2zEmxsgZ1EaBKjR4c4tbpKBnaVj/DRfnb6kBtg4KvgsaazllZWp+98dA7mVlXaNfZsnMm1TGO+1kG2rFSODnwDZv3MJ8xBeagCrq/UaQCHRPqnYzN9y7jeh8k/58D//9En9osvO0BzwkGrBiXCVIrke/YdFZyY1uM67lOQe8QOUBjRjahIpT/jWHh3yEzqD4SXGBunO/pEd/wJpuZLobneecWno5w62lG7QC6Sjn7YQ9UqH4BvZBDfhAQMvzoM7KwuOx5sMn0zC7fmfjDG6ERj8fnPyUqBAIAbpqzI5+FAQxNETVGbJ0E4rO6edkR154NCgfzLRjrgBaaTPD3EC2AB8a0t2M9XNtotzKqfv7Lzc6A7EHJxhlFsS0po9ob4QkB54i++Xt0D97Mfj63v9ifw5LlnuSgPn2v4e1+lcNIBhgofDkAs3ncJ+iokrqX257UnxcxSBVScBQD6LKA3WFvT+9lSQC4Wt3LoZkCIFOiSr7CPwONOWhbMhkQijudo0JqhucDR5kj6XcGJqtrUE2CZVlBStplVHGZ/JIy9nfz9O/wgr0hChMZWBOAA8RQ+v9AXvFx+hw6aljBcdLzCgplnpt9HDH8gWyJ7eDOuFDzBwCdMnEtsO9YfAa0YJsvpp3qsDuVIE9uAu6DpmK6OCLjbp5HtuqOV+UUAOEAUIkekczOTjbYjzQUhnnJQsA/ZgLbYKkCZAjZ974oOkpOVKb3f6PqgEXO8gggSQ5aY+XibSBwzioSk8nlxdZztDUPcGWA5TYefiDKTUbZ/hGkCwFDAA5OyTt3oc5Llk0s07KEJaB7htK8fjPG94V+khbtszDtnXxsAuWb7HbiChgUnNAoUDsuHEjRLIpro9Gh6mDsA+yKQwIT2NBpuwXKmnVJAzkNmfmMVsVgMMHk4lKy6WWYw55uKZnuesMBpUjIE1BewYqwEY6aasS5eIZrZ9PpRQQJBABmagHS5Tg83CI5Ol2Nmo2BxTHEykdi7xLTfx/svcvXBZvogGPNOgsA8lDMyK3orq4cEogrwE1RkRQnVmNW4MO6B1DBblBRTd7ktzIikFiZKXyiePYnE2GXUIXTvBhR/RhMvjj14OfO/effhv9k7726csCem2AiN/75me4D4T2/nXZQmA05UHfjAZqaDCg4KREMJsDogHFJxPtpHe09Omwbiit9sRW6IfXgKh9qk8AtGaPlyrYI4IzwYDk1CCYg84KkJJtrAnFURU8r6TkMAD4oKS3kr+Eng1JkfUkGgBNAIaA+RF0oPc6GB9PVTBJmS1sBUCBkU65Qdd/bEe/FQAYhR1Uh5GVPz8OVzfiI6BgvkwPBQOouax8NNsCvWM1hDXRj6dHB+/Z8TIHBfMwwgKHDFkYIiQrAwVYSJZBUJ7nHysAzwPEFyCQhxahtOA0aZjiw5oM44IXgA0N/m2MoN9eA1QGslTVY0sWk3FQMKEAv/UC9wjgSNC+Jl4D3Mgk+UYAGzlIMsjtkN4cJq4g2zyGgcOS2KLANrpi0sYyuoZlluK/3MP/+wP3P9oFqakHrjsP5Wj/LK9icW+yHVGgxRVmh73QRnTWD2DCVUc/fluH8U3npfPgD34fYb3OOATpLDSvj1mh5xBwT+N9/iB5NhoRP9FJ87gHwiK5EcLProQ1XSqzd8N9g84uIYWTUgH2zjEIJYYvy9EP6H+GRgPcaYOSC0qzO9PGen/akSHg+Waa/2iVjzrM5vH01Wil0cOHg3Jf23B+Uu86koO93E6ac26UtbHCMDOWqfoXB5OxKWLgCkhxpyjfIjjJIiw67syJY4Sx6sAHr6EvIgR/QNjgK9/nl6W/ns88LjvQIcq/TQDK8Xx2AxX5x7hAOPeX/adIPieeJOoAsICjuBUzMF1AompD58ttwdv7a679T5AQzE2hsQIa2v/ccA8NkReVh8j9Dz1xuAtS/pUHx6N9me3QwR2s9pt0fqHSAOQXCAKkB64WFdkVE4aQSJ7+6PoBBd+xBfrp0e8AByAIuNMCg5roLbQrmju0HKGx+r/x4w4Fqwwc6seBRKZs7IVg6DmxlCE0mO3/HAJwsBAPGJ5cwnPmJy2C4gUDLFXw4oDmlRhjc0CUT7WQYSEmMZuMTtjvkFFopJU+JQJVguGkzMg0NqPQlRnwGxhBf28NGGJSGTLMjXXUliUqTKaYPmC+oAYVdbb/uAYiEXGUw4r2fx6gGXqxG2TD/ZB5Q/dEAc/fkYOQ2PpXyBcTBX6sQHSFCvzJkeF3/iO3bvHFlCqObD4XCpZhiQ50Em2YEF8OWH+8sIqAJzoLyUGaKYyjUeiFDfRmswicTUCXG/mcfTJMhB7wnhvvt5YfGPpKqQdbpfkk0h0qKC2yzyp5RjfYNcaP2fqgcVcmJEJnRrjdsBF6PB4iBSV0ZxuICLbuoeWBF4FbGA+I+IXfpqtksjecF0/BMiFa5RhuKMRK0FQ4oOXjDIG1cSZmiP8qCEgc5kN3qBCgzWd5N8QB3zWMxNDamOeT3PGGJcq6piVZ2iUhQj0JzhkdH7HiEL6AJP9fqQo/9+U+X/SPJVsaq2RuhSC49YO/pO4D8aEGiAVE/VdwMij2P1fAXXDyT7B6gIV7iCYDplX5aXaxeoOGpgHbBsZoEwBJEqJ+YmSfzZ7hwACEb3KCC6wEMR1mDWSGEMXVACSDHge3QDIUd2+4NOQIRDcWpdZUkkFxonesgCossyr+71HP+2NWArCA3h71/jjJCxqPB4cAAsLr3Fun8OG7IMNg6RDnRqFQBrzsSACDw1Z3IzT4JLnqMa6keJFN7gsJIAPl7YQxwdIGKwvLKKGB//gBDvqeWkyFMPigB+hAkeYZQdsoCkKhDiOnxuzhtAiqAUuhFpIDwmsRlFwWoGvlH14D4BuRjOEh+vcQs7XDKSgZrbUB1uhg1tBvdl64xfTPTQ6zs12ezXi90XPDHKSbkl7o99BtXVMY8Yh0I7oJnd2IjLIP+stb+M8be/YKyQa6AKbBzH92Hu5q9hUpnFwBazSh2eREQscNVtI/HGix3ju9SOFCRWco2VMzUaB0qSpdLrAIQpWKtoK5ZP7Atwfe4OOYc0As8FZo+Tx5s0g6fybio7huE6N1ZL0X8JIOcPHk4e+sr4GWCn7wdayzczAqZsgzqlHEK96nDfdFit2xyYIbR38gNWPIUMjc4e187UuPTXBAAxdEBuIImkAuamdBxTi+hrQTZA1aBiz90PUl+PWTHAFSkhNptGJglFEBBHE8qYptMlj0oZ1b+tVi8IcQeW3nftg9f8bm/nZR/i8VmPi+QytuWYEqCgbLny5J8FAlYI/PRCDzfI5c8mzFoLkurHXSb8IVWeRToPsDogPtqgGZdKDC9p+8T3mu69wnHxT0sETjS3JAkwnBaBHKYpCUkn17iclUwiSA8jqAeZZctNwg2tNZ6AxamRR/Ps76Vh9AgM/26Tw/3ds7k/sehILribywRx/NPaLjignjOWuNfwEZ9E/HmB/5iD+IFKQhYPbjZTOHICMOIQEKJ9cTLZbrmGf9Ow+Wt3q5Rv/lzrvBs2J0V8rgwBDgcNnSyZuIT/qtpOVSh9QYDk50iubCHO0/NiiqBAoPWNxQbdrDFR+vPjwqMvQfWgOCrKRhTRMXQYgEEcsI6MERbQTIIzGsJnn4c8aE6JwU4dIgPQyI4kW3njkKzGFtDPj5dHQLN4b9omegAlV4ZvPGVYHvf30Pf33l4q9ey7tHRdjkg7LhB0xN4UoU+Q5puZG52mzLVjBaESI+PF5aRGGYvcO8+OgoV0lULfQxDc4UCgQeIsvSvFzmT1se/ROsaNPLveVcXogKzHLANOgTOrqkkeikeou8MOx0eTP1RncNdNV0+Rd80eflOuAjhHWlVFpwgtaqnARPxnwpfwansy3iPQwvLAm7teSNET5nUBnwuqJQgG4LpJN0OasKXRUvOXdRZFNlV1EoEPQVeZzRqwjHhzOCiv6Ovjr7BeOTdQ3ikWtEu5YYemY80riKwU4n/Tn7uZ+rCr9tPvjGGvPU9W8Mz+fP+B4ouOvb2v5fq/+NAnTVgLrEwI1e5t3Z/RYIowM9KRqMC59IqX40FtCQCQ/mP70K9YkFtPKBGaIO/Zfluhvw23H6M48jyvMYYwH1X7KGTqYGkEcoz7NZAebkikVH1NQnYIvOoPzeVACS6ECwuT7NGw75YCc8IVq9nx1DwFnpElrfHlwKzQkAkiAQPepyN3FBVvbV/2uxzY/5At38cQy5hOqR3GqBw7Sl6sgMjgbR0AR8avENIASh4JM64WFboE8eGbYooXAfiJcb3W2DItyg1GBOEMcLxQG+RmMuGOlAHhpzui6MJ0dpFxdIHq4xbLBwa/U3n+S/vQYAFqYH0K4SYDObutuI4jGyaQU6V13MnTdLqcGUBDQSbR5IL7mfOd1ap2aYcEpccg/8Vg5u+MGbKTKGa4Y/tfDnt/Afrzi+3+QYcZIXDN0ZUIE7J4k8Lndv1VHxNJfj9HzD5pMfmsVDi318p2TsQcZYLTjhqhpwD6wIVJDdlZwA9lMo99kgteOW4tmOB7S4s8rx3UzKhTiYHs2fyRhzhU9gKQpTOdm3J7EyI8/4ksu49fvdPCTk7zl6kTWc3dfW6TlFlPt2OQQZ+piIHaCnJ5UIP0ZVurCJgeEhod93+9foMhe7Z9ZbQHkZ1kMuWirBBqUw24ZHTNTkZCFmhismidMA20QaTQyPWF4AsdsUXXTgn5GYfcuJ/ztODL8A+canXc9CgMO+9P/Q/oflAApaipY/HgtsAli0vPGCAfj8tBU/N0I4SbUIAv9ncN3flhvEnMy5bBSA2jfciKoZU73EIc4P+zNJAYJZrWMIiJIEz4MOK36auWSd/oUrbXOFwxYIBSDHsFKCbQKQKphzwLYForMpQGBgwLAC5f7nfL/XT482J4C3+xwF2jseIGjee+di9nJHtpjYfHGBhAH8cOM08MInN88MIE2oEAaQY/Nah5pDXNe9H9+QCwZHyNn7z+P+UzeLiAddIv56f8KizSh05cZEgZp24h8bPACHOO3/zTBah5FkATQColscTXdSNaPQaKNAeCaDrkzf8duHgL+rBsiykEh8eCoD9DZjV2vm1/P0r/jZuQec52BUXLzWgznnBrDjAGuSwEAHGHCs7F8+aegqb6SUNzaTZ3jKfJ+XxY/v4f4Ij0QRxyzXx1hI74Pe4ic5bk2nWVzfNb8VxNcAugFvbMBW+qXDD25eQ9AhEyJ+6bFmrPsrUYoxNitTMoUTvysQAHJ4n3NA7bezQi1ygPx0OxMGopOyiEYuQOe9M9Ly1UqYIuoZ6RWXrEXHQoUB8POGPo45II3745506OvkJCWUDqHFXR70MXGDP8Tqj8MjH235ojIwFmH0kpBFpdi7EFAwcbR2ybZpnDqCmwcSZyymS8C7krsrBjzmoPNnLNG95mKMHn9wKc4TQYTg0TRaMorhtOuMw24h+CuP96/PBL9YLT6c+AuWse9nF/kalXZx/o3HLp3XZgTUr0oQlhEQLaB5d1MCBci060AfzY9+5T2w38+eCYPH8Cf6DNxGGo72PjZ5Db8VOjlitQvS5/wreIhG53GuyPcVODyEW9EQU/nAW0x8kPkxYADEAyg62C7upP0PNQGgA1WyQilTIL6NLVB7dG6B7o8HsiHvMId4P09TBT/a4zEelbYQEASM3R9UtqQpmyo4e0LUK7XBL5smQO257PuhCXBDyt0mWu6TDxcG0ykoQhzAtfDpucH7EBAXFMHvAUjDgROs0P7nuB6CgiPOOtpGYw9EfZryixkZrwJQAAhbdHAGsybsmoBdIcz4+Nb/ni6n/D09EUaBnN1p0q2keaLRNZrIMD7OV6PaKEDowxxlu1D5QmONzlSd86XMV3yOVGCKyUGI49V4Ic1tXjuPZG7UfkLZNf1jC3/5hPP6pRlHCIMbcyK57jdQIUkXqRcwuXJ9XuBHRM4c4aBXRhG8EgN4lWkUc+QbBckdP4xdNPJyNslYpZ6ZanxkhM4W4A4EvDxm73PCk4Qu4XGe83hheOeM099PQmnM6C2UVbGvF84+GudVJUAe2AgN5cxwPMiU+HI8zJTyjic19ZWM6lJe933SIV/pOVTEGBnhOiQ4DDBmksxRA0Ay0wuIF5CSOn9uTkYDdkbJGtVMoQA14zz6h4ih0oeltM0EXQc9xwHSkuhnEW0mGE4iipcM1I/+zefumg/2Q/nnssx+7d0yPgIRYd/x72yf7euupt8d/8Nl/LCZQLgGOOwrIB1xzSAB2fpbk9qgXY0KN1T6YxX/J2ivEtnh8IkJg8fSsFqjmC41YfIx+qAUfWG/0RlBstQq6msDJwCcGMyxiJ4Jo6QY94SYJeCwDRBpoAqn5gSAdUAO2gVpAqAZT390OIEaAnw+hANXeMM9GqhB9/5W+7si4zmCt60ARLMFvWLitfR/9f3PK4eAVyrF5m9vNz+meQg5jdpQlAfFSQYCc6X8ro8dveC7K4TnEHD69biiarVaMDUAdxg4T6I7ICSiwZybjigfzZjtJKRTdLrMIRwKJjXoiuY1v+intIDf6g/x+9WA+QvOp6YvJPWmL+uIxiagwhsHHmuEOErFgVaPQJX4nAnAJMSrVzqqAa6yDl7QPMdPsTYdKD49HCYni3bJW9wPc4/Cnx/hP08jCCFizHH8lwpUoHTs98l0s1WSOfwlmt02Nj/6ovwPQS4GQSjORv61GhA0u4lGN4vgp2ILhpVWim2xxkvjnD/2oz/4bdwgCWG2zGNW/jkHP7LAs5aPDE0gRHVR0wjfXVp5UkRGyj0Tu2XgD7C1Z9GEaj216glmxOA7mH6MsBGBhsHFYS8MQ4cjKw3Y4g3vwJoG3FdjKDFACoFcYxdriSgxT63OHpOdo35b1FvycC9KvY/SvlFkBLpRB9cpmHDBih8NxGR2bdQhmeBFj8n20JHhIHmUiEJE+/iBYLpKwn6Cj6eC8fVTfz/rfXU+vlAYxmdPrr2/zBf8xLe/0W0sU+s5Nvg3DPd74OmPyAYhwCyrUZ5VpHLpbcKRCmyA0svhVhA2B+BeYcgEX5iu9yDsLCDRsLAIOggGkPYzzByUv6WuBjFLTERUDbATTBp/O80cCoYp0A1qgGQrIXYOJP85BkCWKs46eVr0E+kAna4QOPxhC0EAAFwg0IH4EWPBgyBwxUc4aG1hYXbUZveGu9kuyDwh1jr+MH3AygtbwuAxNoM9YnuPU4BiJBAd75UfWR4eARPA386rH9A+OVIefPOFj0XVHvSosO8NQSkHtWmlgBBf2PLRMU6ts2UGwIk42eLYnKI9R34vALssoLX2f60GuFCguGAh2OY5GirAdEnl4FDpxD0XVGOxMj4ZMZKpNqTsFizEjz6vpAg0mHk9N/oz3xbftpDp75nv/dk6Yr6Xf60YBf7jRlQgx5c6brB0pkoAuAQvAkK72rsvG1vSuahJZrv1OGwCOKkRl1H4gyABtOmsDYF5Z9idVjs4O1dS6RyEyTBpfnqAXpEfFd39Ecssl4UFQAqBfM72qGhiHpLXR8G7yU2fhf7ylkVDqADWeRnPYQD2MbVaJIwFvNglGd1izKHT80IItAFYEHEykJB2RaQc8HXttiszIYYd5HzFmixKozrXJgLSsIEIAwFmJIA9nRQASh6EDweZZGdVnkRpNDOOV+qzP+nEiEVijB+KQRAJTS4Z0XwrxqY4e6oBK80sPgflfNPef1wc5KdpYGyr/4+Zj2MPfvGC0Dfz52G+U0axJQDAIHhd0Rf7E++o7Ou7AN7OaC3Z/tBxnJ9MMgXqZH+CP4qbz2Li+Q5qUTfWK6EJLJB7gBlsdC58WAOCOKCYDOR7nzkBlGAe0WpekzlDqJ2lQhg6H3hCZDFByVeg+5lJglu6YAAR+0kGnc0S1GCzAMAI6I3Y70+P89M8/e/tE3lB7+QCYQ/DMlCH8UEFA0QLibwOfSABL2r/DQl4vQ1BxOWwRVBK1ylqATqgjZhF6F1G9DClwMc3PT8xCtzP8Ld3/LUQLhgAe55kBJP5Yr3mS5l8UUIZF+OJMeJSmTiMUDBZQAk7c88Lk4dO1kZoPC2C3J6Otbb/fQXg96gBrSEVbakEhvH+GDI8v/sOE+nIXMlIdJvrP+biEigyoQD4M+jQS7yRw3MUkUTB1i/uJ0raFHz+GumYPGCsGffdVPife/j/Hhz6yBM99DEPBsUMQ4a7CR+XhRwJjPT64Hl5G/GViXGV38xdTqLyDzmDMiUqh4Z24ntY074SZnCxznvkQWwg9jdI42Zta2iIcO+c8s72IFHMQDjlMmW04lUgpoyMJSY/tq5NEEmpXLHPnkvhAbEbMBs12aJutBU8te2st8MLY7iHRRLcJs/mtFQPNxZdwdzgzw5d8zirCCoHCBq7yJ/sYuUeMQ8OQeToXovAlyiekyT0BDcSoSD6zySagutWUkJEMqjefecSC32yNyqEsUKoBA6vJf8lMVtLoSsKRMZKzyPCL6x9RthLyDYHOB9qi3hc9WBtfszuZ4iOOfo1EJj9Q7BdEI77Fn3tIwZnZIfD4x7XGsphtWM9cW9BdjWzInBjIdwF7B4yQdEqDLsQJAIIexiBbJvlCjf/s2NwV8/o70ICp6t/Ecaarfe3FHTw2nl6lZSMCBTtkecIUGavy2LNvFjmoETx/2gOmmp2tyJ6w1UY8DQVgJPmoNgCzRrw6T6LwSwDIgVxC1SxBZqzdV22EEsQQK1vFu3ywHH/Jz/9RQl9PSQKi8fBsMJiYiMrAIoDkSZAagDAzniCYABGE2ogAMlwdpYPeBUH17aLkGoOEH7QI7Y+m1+0pdhjzzzPtHEcdBBGDaA8mNnxQbagkgWQFUrXeQsQ5mdUBuKyWxL8rkbsD1AD0Av2nNO1vx3ykRa3nHlDgdxQ6qMyPaVTLxCwYA3d6JKAT3NkADgwe9wCeig4QvN1n+X0kWnpnJDCddLELTbjP7bxlPvzYw1/fkfxxzhW4ysqOWNqmqkHsAqUA5YOfycIxUHSJ40+bgj6QrN/zmuIATVaRNY5Ib6A1HaeZJLxk9m/jQUOg2VdYf5RTvlbQAVdbvNHa1m7wAStQCCoFkigy2Zqp7U/XsDS62Azndnmw4EPvyNdlEjuASuh2Rw91D2uoDRNJYp2GSFsnXFYq3V3kA7W6Out61w9K5d+0DjSXaNjVH9KuqqddJXCNEkHqEsCUwhFiWUhKWEMYgcGZ6oGMK+pDLGxGDVDShPjzASHgIHODtICKQkoaESJyYNwTF1gU5zl12sxFHxDFD7CyONLC6KvV4LxJRRh9fzRNz3xmfWzb35WezA27DcM+fzYzsfOfQMDuLivXWt9eRVaNgeQAIrvKp15NSIgiTckR4D57yc3wH8ygYgaJvXladmp5c8QC6ggzQUtGk/8oVATMIK0xMbSRZZwXgDWFogRwTfkw8jqMJr12fweSjTD4zkBZMUXa+kCc9CTBYDpYAwIwwroXqUJeCMd6O19TgOWFQxxACjwYYXdJbfnPK6IGEgBZgFQGXh94QNDQLzdcP7eCNKmuAJQUWdPum2cbPXeiQRICvBOKYA0AW8ndMLzG/jpHmq/+ggRUnNYjtDc/yRbT8EHM42NDoSDX8uyLL9M2krwiC/NG3/Zw3lyJCoBw2MtWWxNALr6a+v97+a8/b01YEOGR1iGwdzt0jiadUxjzpBJKMpaJvYNF2WaiSJOLSB8sQFJzbcOahCz36gVaEOB7yejgx/yGRU7iLwk04sPM/7+y1v4r9cxLwKAObCDjoJ33lgMMstAIQSWuhcA0RVJv4FmmMtBqBNkFyVVSA3nDQ0CoqVvqAQPGZ53g1jVoXTRy1jTHw9G7c0vitR58kCPIT6FuqicT+ZHyzkwim5BzPtB0a2VenlIKDC+a9uDdx40ofmV74RgZCZEF89CJo2so0fcjjOeTIf7yYkWaJ4FXNEbdsjJwEVoutyTTQ1NjTamgdS1YrKvZX7TIrWSYA7FW1gR6Fhx9Wb+36QH8EJfbFHFirD/xbqBvFWOBW5Fkrwn14iwNGUXIUFPx+Vn5GUgPm1vvmUOuCCBTdi1XsN4gb0qAWHZvflk0EX/uWoAgw47I1jChQN3a0O7n/V6rr2/vMtG2HY+w1Ff938eQSsgkIIGvdisMYsX+0eGREkf0fXTq62zR49yhO4UgmEFBC+fTkKDOUJzMuD1qsDDosjz5OEwSAY4btHPZUsJjspDhCagRE4A4VQBgDv0PNU7bEEb1ADnAzjw/e1eP52PtzsUYagE93a/j8edquBzzIH7soXYeDhF238d+kWHvv/2RbBwfDnMKBTEvDxWt8T0NbzWxvZp8X5q/8Ma0BcsPOgVMX46kVs1wmYO4SH1dAe61j40kF+isAiSKHlBWENpAOAiiRplyQKgfAUIjAUxFkFVAGp4cgn1W/F3Q4N/vxqwkGFT+8s3fihVhjUg8eDFEVCxOeJWBH0ubKOGzGYxHLSCiaLnUm6j1Y7m/exdBs6toEQvyKUW3DroMPsFF6q2YxS4h//zAwlCeIxblWzYdkEvfMsFLAdu8YyKSF/mwnf0EBkUlSCCIDSHwRcGEnA99bjhC90Lvnr2+9hW4sHw4bPiNprXU3kwhCB3PhrT5WkWDq5dtniZFBXL5IkQFFFzH870PWAOxFUTz88hD4n55Y7jZX58PO4mJ6NVW3f6ADhM4Vprs+U/V6Cwp8ZTsIUdDxobWHfhr7bg1vILKCbJsw+vFf5vMksM5wi/R6acoMBy1x35ojg1iBmrTEIeCKlNSXFmLMfMc8WamrljXZ5CmRCF3Oa7Ysk8tCjEi4t2CSZNY7a8h4iuXABv3EaCr+HB29m5aXwvStVw9YXZvS0oeHFz7VoYxvjstnVQYehDUK3hvQIDePo75EsQeOjEB6+CB30UIwh9oVz/pATm35GxN34jP86wzS1oDxhyksjZhRsErQkPivaKtfzAgcUELYwj1fJHBQBSgORaMIOzSO274ddLDKYNUDQYCSykgTJXkMHF1RzrxgN+z7QFbbP3RzrYgxKw9v54vL/PIaDOkvDGgeDTibTI1gZWr2TI7t5wlzWQQgLKeF37n+IlQeagxxAXqLC1SB6Kp9u2dWeC8nx4pybgne2jhoBlDvHju+WFaZDI7mVZooUEvNIX+iUtLHrcPK0MYEBhVADQYBBE6brh7PnI5hhloDQVgz2ePeWPrNDfCQ3+3WrAhQyHLVgmXCRRaIZ7qwxYRiIkG0BMlIM+04PBMuQag0k5X6HQLVaMi6CXI74zHPjWYI5+y+TpExk+uZFP0ZnPvCnn/fG39/DTA4SwN4S8szJXbGZuvBTeuYVirk0QdSLHy09U0QI3KQYD5AKKFQMaPK+Gg3vDiqtnfr6zOHXPt+leBsBiPmE+Pv/F+0nSWIyf4AfOhQiQkZO86kQT6Ki+oETO0JJXqpYmGu7gH0BAM5yWkDOQhkRd5iYEe7hZBlKXITOplSYA0uAQL+sdUgK740rdEwF45B7AeIUomG+058yP7iSqoMWFTBLxN9PwBcP8NBhM5ioxONSZsa+GtRhkIsQGPxhTaG2HmvpIosdsdiQj420rTwxbEPnwZsRXTQgLLVD3P543QuPXqYWvzc/FCLogFR+d1rO+IALPmuuaCpr2PFr9Rw1K2vvrM1wERbqSR/cBRRq3/N2Gd/3G+WGMc6P+a/guqOm9ttkj9rgVK0IziU4iaN5np4ZSSpEWgF+mg8ELlhIwf9AFKBIMiMqHyS4JNo9opQNHFoCX223RFC0IXcpPJ4OKDoQhAJHayIdBBGQ/ZQ19xwRwvuPQP9/e69s7Pv70Vt/nEFDZePU5L4Ran1NikiGxIvxQDGxboJcFBmgUcJ8444Mm23QKO9yHgJUSPPv9t2b7n08nJ4MHqsKnOxKrVkhA3kziigG/iKXUF5IggJWAsShpKK9GQmpNAASEM98f2OUIAzhBLHeDIBhuukFQ2F1Cfzc0+PesAT4JrAJgFmFdejGS4ZuKAVbl0ovhMAT7mDtQZE6X1ng4zy7xyHMUqDcsxZH3O8/xeb3Pd7Tj3B+K/J3/xAv3DX3RNP3y//EMf/405nVQ6B5xY1U/OE8AK8Y0wM7HzURtQ0iEhmgB+J2KmZwtwOvLoHmIpAMmEsGIgEEXttKFPCVpoZpZfwHCSuJJ8V+e1wcYUA9WvzkNIMK0FlpvFUvcA5pWUnRz6bhyz6CxG5yXBJr2sZpd8niStGPn+fBpAFmP0nL1ZNFIDtqzvU+9X3T7xJqQEDcmOx+sbWqwcHhbJ/UtbNYcJmxRZXRDrDIy281OLwpSmQh5tSCwkdsgZEYEVLOkeTrK9dSjdWhRrwoRyTB2LjQ9JgY9t/lq/f/svYdyJEmyJOgkIjKBHnknsv//gSf7tnkhM4O4+7mqmnkEqmtWbmWb1JIeCAZAMZBMI2pK+PWLTVSc3hVHaHQzHzT30/LL+P+fNiCz1GZfns3z8RNe1EbOmpemZq6pmvxV5aP7/0QTFKLoR438bZB/glwPeO+1VUDir0jCc5LdG5tBoJMU/yAvwKS0iLLFX42ORg7MPCgKhgwdYHzVOKDBXvrjYeEeZvO+UlYpBs4jIjgld4MAk8EaQH/ILXQE0n+8ALsY2DYARp4EQ4Ga3YFpDa10MPwHSdhr3V7Cf3bQgTa6wq1bf133Ffv0Uc2sd6gB4CbJPMi3/AdDCL70igxniLm/jvMsSTDWccfx3Eqb1A+8WDaALwGKjEdALPaD/ku/vfA1DFHCsDBY/CaxMLL4zCmbzJ0UB+EJdMdEw+gUhQUlFwbb4F8M/5mkDyAjKJXhDDHiYi7a4PJd9QDinTXldEqSopLEk4cKoPRPsagBmJsQlIN8hFk5QKxL/3umVqcZoekE7lEip/6DbBUdVcphroFySFG+UXFHRP2A+/L480d4v+HH83DX1okOgr349t0QwS+iCTfzOwiecqKIg1m6QXiI0p0LIwl5QTQQ3cgLwlWA/1bjDaB/aI9OEyKJCIVzteEReyhCq4uHLPEG2h9EaQOTNO8A1fFk4680A70FCkHBxUxkfJr9G0NQqDLoSyh44lAGEui+SemlNmDjMbvxuGSxwh1cntRjtt5nSXE156DzgIryTego+xwfXEcWNXie43GjoxnwBHxqmZalFdgQ0CM5HmdyQys1YZm3A7CK2Y8in1M0tQtyd43JFgLLgXYUCF9zaY4IBSNIJLlO6NXnteBiQTdgov8RLIjKCzfGGLSgNmb/ojDN2C6B09VpoH4kitW0TbFYP3C4v/I1abiFJq2U1nAhoO1PkygsqZGw9AfawGnWzzZyhOtpkOW+sSBjeOi9vFIDHMQCwh4w8Sas1ws34YnJomT9KxYGV0yFPsnrfjJTaDaAvgGYEEDyP/aAbGcAnH9T6o/Z3WLLGHRciQKVg3KwHeP/KtgHNFCcAR4vvwaDD4oxdyche3S15MbvqPLuCQE3iBue7D/gGgxqEPaAWyMjCHx8SHaTGRoMWwh995UUv+1QAhP8aY+dhqBkgr4kFNjDlxUS1JOPlNwcQqKwiyxgMakwc2rpDZd1LqZtPCHg2QMjGRQTLaj5CCYNo72mXYnbKQtwSqjbqdT/OW3wn98DfBVIlxxZkkTZwZi/wqsAZtmCuwdAgImiQTiJJhpjUW5elDU/kSC0TH1TO5Yab8wO7d11n3gQ5ve90MGtZArHmvmhBGdqPo7wG7QCqPtPokDI++1/lg5QvZ1sB0kCFMbQltv6l7zkGi0TZ6abkS0KghCjhWLvBy8+NO+cUA6m2RUGEZdm8QYDEcI3g4eP/jnkNbzIuoBzOm1j8wQnvam/hoY4wukXMQnaA0gpsogePByaf36NOQqMGhBnR0Sg3NsAes++mSK0L1SNuAu2ct2ukzv2x3pyZhY2O64d1dwe6O0mBudOFdjIAbOKY7WG7xLuP6LpTps4iaAbWmaYhxj0zxsXoArBsP5OUlNr0lXAiaHYBArdmKboKpygtZnXSCvxdhtIQvwrr6GxGemPKJLTfsdh4HIKiN8u/Z9kwHHQaozj2c4xo1WHxcKF7aOVXZeR6jY8ZsbDOYHHd0s/rHbOTcwCkz8HWBGa7kXxhOAL7E9BSVE5AbwlS4Ztx5hPVFgd7cn5YeMsSWkwLPc0Bao6/PLkS/DGke052kIwmwv0SQP1sSVmOILeFpeCYQMIhibiU4LXPelAiIrEA2TnorPRFGg/ynYoHUxMUDYAWAO9DhoEMTt+bb0W9/Ef27a4QJ5llDgXKKV9Iey+3PByu8VbL/q9AfTXN+wH0APfWP2t/jbLtHazYfCoXPfzoifYeQTu1X+zBvCiXURfAixEQ2LgERl21YWNmBq8xk4g5+oFkytYL4iLycltgiC2wGRsS8BEpovxgoqlhn0KDrtSQlVv/6zS/af1gIubdPBsGSFC2GVwAGiVmmGUvkKZGD7YH2S4CsBalA/NzF5Z4RrUH6GFCb2F/KqZMQDFru2oxbhqAXLJTJoMnBFKO43kfqGLHBChRFhwxwsC63duGDxV50k+dJhZZSRreZN4ZmAiWuhLerfoJjhG9KfyOwOMNsUYFQOjBJcoWiBUnwYPFqodTuXrJlMIbP2JQpWEQOudVItkipfEGwJXbitj0VAddKbMdGB+eWSLOvtFpNKU+5MToq9jU3FSyqOdvZPsHeZBpwcPxw+7agz4yzxT0jzbQD7nfJplcy8YJpQLNESMO7kArZpXXe0PZloQ4zKc6WLNlSSVUikT8zYjyZiaFX3sJoYc9hG00l7bQqiEC6VghvQcWqORpQY7qPmyHO1tQUYjxf4r77mzBwwcvZ0EoWZtLjRzRxpQ0fmu13eKMhTRIwiIYzuQ/eDJjHb1bRR8iUBVmL5WTOiSqplAmOFPq0YBavTP5amGGZA6LKsBaNuTDJjcKu5tVd/bjBFJsE/vvCXSYXBy5EfHALOD5irgLgYhDR0ABxFFAqB6TdNyv48GMJJ4yTfKJevG2T9bZgXHsDG9bgv1OOoJAcEUaGXRX4+P1/7Ay/Gx7tsLirBtb0ffA1aGxZfzDJBdKLoIBTqtIPoS0N6xDbQ37gRvfNbzGDsSg09BgPzeXQ1gHNDHOALTC+ipTnBgP/j96e5ATgcK0SznJrkPTa4J8KQwdoUoPdqMNoC4mIlMWjjEBDUAZOni+9XsEnCoJTTThVVBQDb7X67BkcLCP4MR9Cf3AFsF5CYdFIQSmYwDYqPkzklCgUDHHN6He48sMA/RI68yZI0EITz6Um+hhSdZYC/wliUOQ6HvyloMAnOGsKskQ+RrOeNleg//+dF6G5h5BwaP+DBeEH2YWtYlfvj3XQTg/Xs/c+veFwSyHC0SywxvdFTY9PrAeFuICPWWVcspVqijilAgVLAGk0HZHzpYW0Ke97wmnN9IFo7wGOIZNBvimJXBnQ0CpKQTyFgZ4wweCcke2VbLg9pA/6B0A8pvbJ6YjVKAj85Di+Cmbf5lxyEpSOTwGeO+VRVeoJSVRwI/Ng9vCddKR78V20JWGT+r2dmijqleLkSlqbMR3BTIZkLURLODsPkwuiCUDjTNZa7pegbQxdjvKGdxbydz9MId+gYvKLY/YEHx6vV/3SBGlqjAOU/+snt8cJTft0Gb6Ov5tlaBZCcBsfs19RPeGjtBC2GY/4g8GpJIwaka+cgP/eMogT0T6DnqO9c0jv/U6gaw/nESIDuL2XqAcJh16DoAsiLobBWGDiCNPQA3AG4AbtYmUyA0MHDe2AB46kNwlN0AIqQAtVAOdqAHAAUCENQbwAY4iKvAc204CextXyEGXo9WwkkGDe4LlMW8zOGtvxbsg4SAqxrAKKEzUPgmf1DSakZoA+lANe6UfcEEgmu9pAAiho7G0Cep/sFfV6OcJGcBDRTIs4KbBtO7O1d7YIAJgzPFAfrPHOJpwU1NgEyBWIoAmDuXUoygcKEDjciw/zmn6L+8B5RMJzzh603YbCJDMIqNeTC658D4X6A6xyQxwVW6Hkywog4diFidj2nWTRhW/pTs0rjNhALFNPXHzPg3DkmH2WGO1QQ5D/968kBPZs59wl725IOD3oGBjblxM8MzaXKTNdN2JRjJKeQCfl2x8XFNnVpjnjW3BMmVzUaKP53NJkNen3jkW/tbt1g2qze02jvIpSJQk1whm40QpHteMqVUMJ/zZCdK5X2A5d1ytHzN6HfAPG4D+v36JdpJDHFJ9CuxS6v4zeMsDiCowotY30LKr3BEBrmfjE5hHRZh0+JlIRinY461/BbwY3hDgbRRp8hg/QDtBcnT1K+CuQg+jPFKTERGBZnUbKwDg3uGn5uxg/SRZHNHjOeNf6A+6YILfcNMdPjpxwH/nMJg0wQY7D7ebWMJMEpwrCYH44wfbF3gOM/K7ptBidE4P3T1qcz+bDR9I8UhaRVgYh6+5RSCAWk5LX/SWfQFvoE5wBLff1IxVgL9/eGBfyoT/6Fjh+IBWMd0AwiKVacojDfhRPMfSIKt+ie7X6kBZN8A1ACIR/WllhsAlcCJFtZR1zryelof/8tejk34T18CAAE99+e6PZ7YA17P8nodrxfuwFIFA1zl6+YILZ6qQwpwR6F/v7c7530dA96GJuDmUQFiBBFD1BMhuOnSzkuDuP+93OMGsPmL3vZ+0JeA9fDJMFpu8Owbyc15R6cxEZ2CbhQ2qV3xPDBlkcFZbkoYlwDSgaAJ6NWfL8CC6BgadGRP4WwABgsUOix9pz2A1hHMGR6rQEvCI9QA6K+M04cLhvtXC6+J1Gd6gNeQQRKAodqllQl56u3W4jaRUzaBKWx2cjyxie+PCwEpQ5acEn0MR9J2+PUR/oNk4Smjq097u+2BJtUR6m3hcK4c1uFTwzXhGeaoEu7vC8EtyDUIqTI7uQQymUI/KDha9GIlI+apqCDaToApLiNhpn9jVsoL0wsoy8STZ+LDVNGmZMPz6YUzLBkETczrNA4sKC3Z590Si5SPybcBnAnQBvpv6Cs3KojuiUynJHwEgxoO3iD9FZCegjlAo6IA3IcxKP6BohwygiFOMyUloZk3VBXGdPGdPpkpbVSsYI2IqQNF6ASqJMZV6MVJTQEZSW5CiQVdZHb2gKh7AHuxtGIAogdCO+IUsiNFSlg4b8InNfS/exL22OQWT6eNNry44/CcYFlv5z0ghlH3ZV/UzO/BMBo+BHDOJRUQ9Gi5dhNUU0h45OZkx14ehO3fklisus2qsJ5wfob9NxUltYVmFtCw5uPVqVd/xMIks4SbjPlcdfhNxv2P8zj8Olt5disIkhRCmikEOBuANlPa0iVuAEEbAH6YuzWAPghVbu+1LwHbdmwrraFfay/34AI9n+XxLM9Xfaw76EAgAmEJ2Dak8tXLKdgUYTT8uTMAQLzPN/aDt9uQhuEqMMiguMdO0YJi/Jl4coGKmUA8d/MHtWbAtIC+H2AdWcEyH3pBSSfyZJ/J5AKx2+zuQNO4CiBRnGzRKHMILQL8bCwuBqWIcAivwTSHICfxcgPILfhEeMkMKKX+uUX7T+4BDJapya3hjY/elG6VJKjiAQSl/0BhNL9sKBeB8JekFAsg5jlPde6/u9X+bT2YH9DLVS+1G0W8+5CM0UGoD417Cl9RW/o/3Fe5Hx54uGS/BCy6BxxIgc9SD5KlpPFRdummGmM0aOE/rXsAU7pR8WEwctBtityZUozBJp/fPm/RCMZQG0w0O3EYnEzC8+WIE7N2DImyeJlojlbmE2vVzEzTXMsWqmLg+VWWSVBxoqVENKFDbwNRugEcAnnzSDayQqSL1YxVh/YTBFikCxtuwwoVJi5pOLWBPlWucVSGWaxwCOeteHBJk9ycuKEFi7whqtRcOpyKrQWhEMnJdKGDmyzH1YPO2Ib2HMqk5FTXms9kgq0s1SxVV9hZ7I4F7Z0eeSOreDiQfnUVbgMYsjAEv0j+4QAQpNOUJs9YwU0hH7L9KclIy2bRRkJK0ZGc2wAP9gwQVAPAD+Ooov8bGbJKvKfbcryQf9wSMFh2Z1CKc3/YTTwGwIIrkgjUZ396AUmFN5nJTZv1BlAK2lmxjU7JsyEF/hChjZj/b4uzQFnHknJj4QmaSWIE/pO4AUQegSufKDCFBhcIdkCAfTD7QwTw3D9evfrjFAw60Fp5hm1uDcR7+iCDEnVBZRfe4sT/u3B/7AQ8BZMLJHdocYFw6ks6ixswW5oSIpvshJ96YenXy8e4BGzAgn594bed4sMLK1QZYTb4X9MiQUZKMAdFekzMGD25BCQiD1GYA83TcBOdxJQ5xAviZlDixSDoQgcybxccAr7vHtAYCZGmyWTNih+MowekYhLpzHOV0hLoelgPdllkVOGIDoVRgp74lqRf7K8XIELttUSkBCcc3G/8W+DOObGZ5ouh/5hDK8xE/+Mddf+hHrCdxxx0AjgZVaqVg9senfY7+nSVYEPPQ6QLHAcJo4fZQhyEpw7JAtx8tBTbAEbAgKjsG+Jv+GPfypNIZf/kyQCl42hyACMbADSJD5DicEtILMGZ/BJjO/TnOYQAdOFp4x6TwODu28C+2Y/hzJWcEF5QC/H7/k/2LyK6YJj3ddTNg+lUqn8GR1bB1hho8e/jzJ8swtK+cc3+/XRSh0gOjSd/kc3goDxDQzMdBhv5otVuqYyliUyeUXdL1bK0M8djAtHYJCKNM/C9ylW+WoMAqzc8drWdIQPpm/tAdK3XyNsJ+vuqydvGsTz6l8IeICPmOjLUCPTLyxvHMFsFSjNhV3Vxszg/VcdkLn6Fx/HS3PCHUJiQvJguSWXaPhIPv5UVv1f5xKmfq4D1A/rB9XI/EVibtH7h3TArR5UMg5mGXdYhTLEvT0tmA8y3ZZlPIRh2VqWaB4z/ifrWPv7ndCD2Cg8eBRts0AEwHhJMUFpDv9b1te7ri1gQ5WDIC3uVPqW8XhUWzUwIqPVTPEBKZgmnAIBe3G8EfN6MEhrf7rgK3Gav/kMO5oKq4HIMxoQ1xcQ/GRT82qM8QZ8bisO60yiCTKHHGn7bPn0a2KHoOORRkVaCIBGYDae6mUYs0ucmT+YQZ9YajbizGgDNQRPLz9RL5qHbgNfJarKAYQ5hFhHHUf70GO0/uQcMkqhWAc1rwcQ+l1WA9xCQdPA4Jf6bJmKZJMgGMKka0nj6E2BC6e+PjQrTZiiz7KwPaH5j+vw9mKHg5KpNFd/B9HiU8NNHuE8U8h1h5vg/L+CJTvAWbTRpbWAnyW2Go6llHjLAUuy5Plj3B1CfOPqogjyDg0uvP7y4DcBmTmGTym1iyo/LUjhJp5WzaGpZewDaDyf3PBhVditVvW90btTnY2B+iIa3WQ5wRH5NoAOM6aN4JSUfZZoXfhs2c31ron4ioRKWPa2QnQ+EUrygZIGQ9ewEfMozYfwwXiqdn0tWfhindcq/5XhNSVqtXnVF3cTn2HSS0FYhOF030OB3AkiLibVkcZBQTXgo5rCdeMaoNs4bBYhICr9TNcULDVT/vBFJ2zVppv0bQKiZDKG6I1ASvYuP3zY6WGwnQJSUsAZirELZ3F+jmAeT5NPG7JTsC9+nwqWKzBk1ZV5AU3XorJqK210/08lI4s3GaD/931SQxcRhH9kSwX1AAfjg90xRuD/hRg86nKQGMJ++nNUAVPSjHwD6L9AMbgnJriyq/qKBZqRjwxS61yUY3ccdXtZB4cAwhJAWDJ6g/WWFEdDrdTyfnP2f4AJ9rOVFItBrxSUADWCHEKf5GUAKEdEuVdmFv7/RHdqiIpemIzCOBI4U4TdLg+oECjnzKSZsJwrkp+Am6B91v/eDHdDQtmEP+OkRBugSeQD4dAceVhCzXwXoTkpVGjjl8DKCfxzaQCQlyONi5JgraRhtISAOmswsOn42CDo1AbYE/LmXgL+qB9BVfqwCrkTFhJeinQQUMozoRLymeRysd9pRM1yF+DRk4jye/XWe61ynJR97/6a3ijF8NvHIragKg30FoyxebyQcK+FMmOmPAPSABZEODyeGahsQosc0M5KWSnR/NJfhSpkysQ1Qq0yeNg1wyQ09hAVRPXCQs9QsBJZ8wKIziW8D5A7BSy7FJxH1tNZHdOtooMP9Z79iO+8tUuIAzrIT4XhvA/yGMpFLTmw5zx4WBbxEHEKu6ygqug3gRFyOoRsTaC5OfrGcGYdJOHBwDPYGYMFjCm8p5k1se0fGuTjbFaDKsMKVC4N/xCdS9QOBwtxqbafzMn2p6cHaHEjk6ZjHD03kOimLe+uy4eGk6DTQNgTDLV3OvfEk/1wdhP6gERAz9uq058ypQcKxn6RLkMm5D2fd55feXPY1GoDpyISh8ztKYqh9WtVO2K2Ga97vJTGbfweYpPyjdNrAp4BhH50XGW75qNydLRSe43+T6RtLv8Igg+Rgk8XfGv3fKUBqDCAxIhJsmmcb4qKuVvhica/P1ZKvIsf/hAbQLByYYDuPwDtjYbZtXdft1cf/3gMAB1lKsGxB1xfIoPJWKYcJrw3pS+YJOnPGvy2G+8sKAkvA3WigagP9YW5WDcAZ2gjNUyjPXs0cdJMnxIFCv3L2lyLsyQbQFwIlhT33MLyBstpAtrAaWcXd9OJn4SEQu4GS1BcobgBorHQHYmyuMlYJfmADYBuYMf7TPrp42spFE5CGaukvWgL+kh7AS2xJJhjTk9MMJIQ7nwQhiMVgwk/LJE0i+FYQEaJWoM/IhIymo05MGL7xDgypcKFuy+6x7cg01SX3UTuBRnh18sbsl18/wn/ciQUdOAnA3HUOMG+gBfksmXa5iPLCmWwyGWXPOEKgisL8UP+6jgSN7o52FTh8pd08ual5AP1Bmsy+nub+PNUeyVkzNBY9SM+J8aK8Dsb1FNudMEWdtT3QGSLzRMxLIINmmPYi/7CoJ/O+94fR3gYazh6izLKKEsx3UVYPHj3l5UlKIhm+BsZgZjws4xAOb1A+cyDlMTMUv8lUm6RDGBiUfyFwRGhN3+VqbPys9YPDsFzkmltlNPJl9PUr7kCMoBrOKdn8r5N8Qz1HIDqMf7qOfvMR+8kbL7hXhN+6XTd9xYLMe9jXAvOEIDuHR2CLNvBlKWhdgYmCQCTPZhaOpS+mDjGy+uRIxuS3nrM/78pBgE+gH7OdgjOxGUhr6NxMHwhsmMw1aWYRmpoZQogClIyBPJkEzGQBSATDfzho4lPIKbppTRP+w7ZDOyAowphlPxpA2043iGMzO6DX8eIG8NHfePR3AQE9oQrGBgCa5s4zQPPji0NAmU9SSYLflvjWp/43jPyq/iQIxdu93S0noEFFBLimScobHBJgSjCdvtAAIoVgnPq3kxH0oiS4/4bHRmugryzq6FGh5nkb+fU2/lsnuGEJsJQCCJsmRIgTVLPASOj9QAQikSXmvWYKZu0sfAmO54HHT8FyTfwTzSH+jh7AVaDYKhDcQYiG8s1cgzANHciW6+1ftkvYKwse1PCQJgmb2TItwd8BphEFZxb34wbidtSFRn0IFZBaONtFN/N2KX6xHdda+PUZfvggcZhUOLpHUOsBo6ZeJRt/UvbNh0E/CeKWWE2O0Mztvb8svAzfMe/jOEwSH6bpvoiUw/ig9QxqsaWkFCMn9PcBuu9WXAyeBhrlIgXrnvJQQ02a+W3Mnp2kiJCoaOUTF4qDwV65WdRqmBAeTbNJe/pzE1+MXPv580A5xoxXWIKyW2Yc5PKbd5uuvDCpFyvFbP2LcWgik05aUba9EA+v+7WK0xLD9WjskgKVT17zgZvszKyxXYFxmpnof6FbNbcBVnb0mapdPwdn5lt47aD0x9Mrwg4D7dNh+BM3tFm6oqnjWnWbaXMxjW7G7fxXwjHU7YvAo4ZTHAUKBog1giSBuY/4Vd/kiFbGmlxiOfpQvKjRIo8lBH/4XQLUw0ie/m0ptIrgXK42kCt93wrdQOH4loj+K+mEzB+qMon46/Dr/j/MM9LFl5GQixLBmOSgbzkhOdlBM9kw0Q+eX9ouHQCZoHDVYjg8mKB0AF1fr/3xxBIAOdhjRek3RhAhoNLKq11d4QQB9RcM3S76Jf7Tet0HDfS994BIRVgcMjG6R8QzKzidd7iDT9KNDWA9Ikb+FdW/1/rnGh4rX/MeINfo356AecOIqXFJcPbAel0CYEmUG4OC+cEUWZow9vfXM1jyYgVxm4dptVRJkxLH9yaX0CwmqEwjvl4CwmkkfGhL+l+lB+gqoFXgsqrHFv0sjG9pdWoQaULcDBJUUP3hnKns1rtIoZshi83IIGsw8qTCmwnvaO8MHC5k7s+BEgP8VKr4OZdA8v4g+/H3gFGCjqTTziUgqRnAIQ5He+BSvHdycZ+NFUjYg8fIWe4tMEXDcFFw3ESRLTKNgNn1aeXVBikomEG/tSWLmiGP82ivLfhPXMZhNx7ZqLxNdN4n6s2Z2PiHyb+pZkZJ5LvZ6/7+RJ44o3ur5Yfgs8nT7YZdf9s2wx9IV6yIdWStgdNl8RTK/o8WBsEXAE+8QIvDQ1w60wmyENpWWS5Ermh/1mhHmvWZAfEqKbTwyWeCWQh1xNxaG2CraaKBkjVZG13vaJ4g24yq8hsIdVCFUE3TldQQyqCGuYZOYrfsKEyK3/KK8LnPrVQvYIz5pNbxEc7HtbiDtEhQtgfoHi+dCDtJTLYKFgYr6q86G+TFodtsq5q6K7KXm7w/VfcRyqKWwISuknwn0BIgzRdtCOEK6NW/CW7NPvgzwS6Qnq0DwHCwiuSAznO6igDUACLPmSj99ALK0gHszC04mAq5tcrcVTrBHTgB7KsOv4+NFKC9rwK97r+eJAJtSAbeXRRWXXfuww9HaZr+L8D94/0ODbBtAAvvwPdIXIi+QOwTlhOZW3DIVLsVtnMJAjwh8nnE59HwmvjPgyeBTfTQF9yBwkUVjCTlGbMm5n2xgHK7JVsCTBmgxGAuAbde+7EBTElLQN9KIosLNQFHJe7fdAHmJQAz8ew2QRd3oItLKKO6yl9Uq/+qHlAvq0Azup6tAgqWAu+HVnkTRmdZ6VceHAtF6orGhuYMD3BYyKUZVm4F9kH0H4HjB2JJUXYXciWPYnBQ5Ud2Tm2HECECDv1n/NPv4V83s5/V1QiuQRMIvwjqZffRHBEpRJ3SmeEsW+lZAaQRcoH+nD5E+wChTcx5cgDZPA5xgSythQdOjxkomvf2M/7dnv0mZME/fZC/yVEe/5Ye09OpVnc0WQ8VkWkOevFEgUFw60vhdDYgkT7PNPvqM1qtR9QEjYpfxRFiG5EmuFLRG5n1ztciXza154OEFd6yi7JhIPrG567HscRQRPd4yk2qcO7l/DXBjVFldlF1gztlVJZqRhPaUXR3SMFMq4Xf29/bZJdmjuBn2GT0Q61AsPJvtAHNZVfmoBHr0HqThDTopU0ezUaRlVGIPpJ0BgpKltM3S9AUvwWVlq81udm5xTf7D5/Wy7ZFgDdV1QBY9wtJ1wxuo6UQbH/cCoLgDylAirkF5sNHa2qCfXjOjDTjwwmYv+phkLKCSGm6LXNfAoZVYbalCz2MaDYTjKkFY6QBL8CRoWBEgSAFIP7fqz/cQF+gAD0+KAPWKvAoL4jCKuRga3tsaAAgVpQL8MKdWw2Ax1VyQGdAQG9qAG/hh7cmVmjvBKDi3FCLp0WqzyYuhZQUdGQ1U6DVQH+4yoMJyj3gA6/jc8Na8FqxCvzKU/CwJhcXSA4Qt2xFfxE3aTEqqp0iwFlKtzn2zwQhARPJVdKg4vs4aQmohH12qsNomuAWoY4CuT+EA0HRloD61ywBf2EPuK4CbnhjMZMsN+wEaP+9DUrJDhxFt3fOBIXVA0nvIG621rspTrKQnTQpT0p/zfB3sTOrglk1klezaDmKTtI+wtFE6P0LKEczQbj5sDeWHdVsgakffurkcRkvPLczwS2R0gjf2ohbdCUNApEfsBdtbwR4tB5j2D8weWLk30AkFVVmGIuWakkt9INAyhqmSMxgu68F5naLch8tqisY4i07XG05zawy8Q3DyIsZEh10SsXo9fq3I40j8BDrfSCmbU/HsevhVt2Rjl55qK2Z4z/Y+oFXAXzptKpDszukFIJXLN6F8x4ezIf8JAggGaOKDFkcvQiLY7OoEu0S+6ktfgXR+93Y1P2UBFhwTaP+mhuA1fPs/J3iW5KVeiZhEpY6iapA4m0tuIQhhPPyd1pkpyvuzz9VL5mc7Xw0BdNwqcm0Uq9Qk1IRxPHHgjLODdWTCfRtdajK4mfIha3JKFOAd2JSA8C/QPEXoX/RQPPoAar7UFxa9bdLrxx5NdQC8RkNgJRQ2vBNyAMmkzFEMwei0DsyxJDn36p0W7o6MhMmCv+hFux0hIYWDHpgQkDrk0fgF/TAz1f9AnlwAf6zYQ/YdQquF78+EfA5kEnkpSiYm5tA0AsIOwH1wI0fZ07kZEh9cl8gscMrbV1WHhHBBeLOzWNAL/os/XvsreipS8ARfv9wVbCcITggZtqOUhdGrGlp5lc6XuQSwVPwPGWahvJ5bHQg7AGmClb1Z9HHMSBaaMy5BISxBwznq792Cfhre8BlFbBTv/xEdRkueIxWGtU74BYV6Fuj0Q0npuVlzjyU1WNBhok0g8AiNd+488AuoioUwuk6XLyL0iIvRaaRJNBXgfcbyV4TOdJ7yxs0w/3nNW+MEDg4EiujKZlS0RJmGhUirMI3ggb3qkQo6TutG0nmfhxt3KVPg496igYOckk2fn+eT/lOVmqddmOISsAlurjgAvh7mdtCtuDdJi8g84HDH5zg0YlPD3FrcOFUKAsrGWOKK4IoKTvYto2cUJZts/iP8HOF3KwO3ZebNFDPhVH6MKCNKTCsdPxrEkTfNcsKohCNqU0SAgyPgLNrkmKNlFHnDtVBIgoKlKkCbdIArc76qwNA8md68W0pOhfI6vPhvnA1mATcnZPqHzlB9ep/eGZJjovz8I5uY0XQHK+UASq4UjKleUkn37TqMmkgj9Rddg1JAqzZ6ICA0WsOsA+JnuznJdtPvTB3E8qvpHsvfNd1IbAFFQ0g2wFgEIFSdhooX3gKHigQD46Af6YlT8wD5uMgRfkWYlTDBpA4vOJtbQDcwC0VoG+TagBgAZEGulMEsD8fB8d/8EH7G18eaADbq71WxsSTCcrt2XqpNoDBtoTx552lnzeAH96cBQQUKNzuZguBBrAYZfPqC1Ql5yQXSL5AL7ODdvxnb7wBQByw0iX09xdOhl6qbAlIzk+deXpUWM1tvrhEQBYQl1sjVbRXuwZjCDsFTzoFkxA/0aUs0alAewAKj+LWvxkYeb0E/HVLwF/bA769CgQ5f/Uvu+kGKoIQTCbtJKD5RfF4OmfhacZsgTbXhIWqf6OPujAJAKFHBy4zfSeYZR3BQb73hkmwa8WjdVi591f9EaB0gWnFE4XusqD6iouWdCumNSDtKy22SjQDJbjkGW6mOPzOsomB5EkK4a1aqACsre/ShgbpRKNuwvs5qoi4xjhYRma9jH+Cqpf2aNY4HN9ZYYzhYkIkbVYWKBaFhYsvRE+CZpcDAtLg7USPoAxmrQMB473/9cex4SclNZeI6UGD+jE1mdpUEbpkj82oiMRhXIolQEM0McowkY4i2BYrcvSSJ+MnVyak+kYjX0xLHhrEJ5kRjYOBVL515BaMEh7d0Y3GZdVYm2q4ip9PPNz4iVeJYw4I1W9RgwYDKMVLZg6PzAPWv/w2JpGcuV2VEgGLNdVXMVJOoz/8/EfIw5WcI0SG4bzPaFLSI2ioB8MIDuK8zwj0jyz9IP8A9qjKWkhyg1AD0EmVM74mY397+P+Q/9M/DRSraVmUBabbnUMRbABNFKBg438hB7TCdR9T2lZhBYHXvQEcUIFt6yoUaHvZBtDr/tZ7QG8A66usaACkAG3IB671jOA55WD8pCH1uhnln9RPWkM7HcgbQFQ8gMSeMlyxw73k+jSGc2sgCsFWNIDXCthHLqHbZn7RK1Gg2k4UyI7AHhDP5tSMACq66sQVZAH4Qz4S8J95huk9moByAuhB06T/ahSkWo5Wdh4iw8Lst10uAX/XEvCX9wDxmZCkMFzkqCt1M1EaRvsqAOdMwZ8EgiKtVBJB0CZD0QlXgYVq6bLQ1JMITH/7YIwMyi6hoXK6hOPRmnaz/x7H4V8+6B4B15mWiALlmaJcSujTxqeBtgGZV9LjQWR0dDDanc1SwQYuH8qmCKZNq17fBzBsiPOKX5UYcsQMHIfFUPVHUjiZgdDxBnFmFH1H0RC+TGpHF/6+mRtAapY312hNSiMw2O7gNaRZ2BEaTTn61Ig5vHrUSgj0gYkHkz0S6d+RVB7LY+GIr9OmRFTUJtOfgGAR04uh9cY93ahE6O+9cRXsJpWGEDX39hCtUPfSBbuiUo32SjeKZDwhzytuJvCpLYTPeFFNtiJc6P7CVGTAZn8VjHfcWZMQXE4n1zO1b8kDmgM11TsBl4IykIqxQXAjrMVaQtEpwvMTnEQa/e02+F/mmJ1k1iG+aBMpWBlcsRkKZON/qs4EJeBDzIcSXctrSYKAxPcX7GNGe0gxESSRB+vf85qI//Thf5pRraRDZ6ezjpya3ItzRKUiELTL31Q3uEiVpG0AFAEc27a+qATu1f+DjkAPNQCtAmwArz56Q9u5r3ReqY6KORP0xtIviP/uSuC3t/jDW/vXD+GH3gPe7IO9H9AYjtfgiSF97qzceAZAA6ig97zc++FjIwREItCHXQKoDWZUZG8Az+OTR6l0dPKAUz7M7SJSY0plEwp0n7EBIC4YlCTYrZo5BCSnnFpxBJYiTHAQHHD2lotZh9op+BMQxIXgb1gC/vIe8JVs2N0jOLjFJiMGwggwEyVzVicBrAXEgirRHfwGaIdDmeq8AEU+tlrmivvwUts+wRC0yritP7ZgLgTF1kT/5yZCTrRhUqPHVsL/+yvCptMC/KeXzFffLXiMwkzFq0AuZpPTknmttYviiNRrVjuGD1MkCm5SZTfioZjhYunsB4XEIf0tx0GOTztjBhRMRcoKlZ4vevkno1GSwHmZhbkZzEQhzB4+i6pYpF+NYMCy5LBWYQ4/shEaQ1XKLn4GFB71Bph5B+/TnAkFSL80DAPLLBQDSAjjn+VCkNn7kvD+pJ8UiEhHtWyTCb2BNtG1T5H8ZdQ7rhNIOY8it6oxwPaGkaLaMNzF08w4/aJzYZk5EOM+zrGanWiwPAO3qkgDz7mwfcoVD0rh9Bv/3BDsl+OnM8ApEjCTjCE8jqeQICqup131BzBG5b2XFhd0CK1N0qsAmjRFfYlOzMzzMVdmqn8jzrz6U/ASU/bLRMOMKTcb+YUCpWBJJcQjJrv6KgZAwmCQVub5NsuL0JwIjPvAcsQIE3lBRxGBIgmNFII13eBwkjvqsUEHoAsA78CPJ6LhwQV6QhNAIKjoCPzq439vABtE/vXzHTj7cA3jZe8B70T/39/bOzUBb2/h9oaPL6SEwhl0kRzMaXLDYI8osUyB1sNSAXQTfrHu9+r/eg2L0PblcaJAGvVmRhlNkgdz1bj4wZlD3E2rgHlEJ9pEY7NKzAaR83sT0A9niMl8gXgH3mVNELJfAvInVXDQUvZXCYP/7h5gDkLzZOORBJ9R9ud4UIIgBHRMGy9IC+wKeOAXaSKJyDD2ERwhPPZD3wZAbudDEqEkB0vRfqABsAc03QMC6Xj9q8SsPUIk+FTtj4kff4XOIFPBN+0WVB35UzfzBi4KJtcApc7GjWiHgWa+jtwGpBLQu0fzHhCNAVOG6Mj/hn3Ixy6hY3SdDs1GWftzYhO5gWQbO7Q+YilQ5ADGkY0ZxeGHdx2EAIVcFHgI8ycgizb/hIg15dsNnLY+1PVOELR8BRkKcTPAVffgVhPdgVFu/rzwNwGw1dx28DkWGl/jp8wloOgYRLJnIQOGqT2CBHjL708e+nEmkYkqP0nGSthJpl7utwM+UpJBc79tUXTMXzOakMwJvulzSMCJLMVvScZatbXv0x87IR2WHuyXebjMpbEB1OEWYUKC0azwJVZStsi1SSL/0IGDfnHMZBwNAKtA5io2cVbM0U6+KRiLbXIQJVnpv3L/RwIMlV5G/5+FWHOeycEG/ygeBKFpBkW07AcAbAAHDTfFwjsqwZ9yMBEAgTBYAtY+8rP0Px9aAvq7xwomKBvAq+17XaFVb1dHIHHzhhgY2S9qAG94+eGOBvB2xz1A1CDlBACEmc29Jw0dpcT5IgJVuYGeQjCpAb4AEQIohEvAK65b+/IKP39xDHGExVPndZ+dDzpbNoApwhbbQmRhJIsItIGJ/tDUWTeuX9R8TTttyeCV2eZDzYBJurwGC2K9mEN8ugSU9hcvAX9HD7iuAtHiTJpJxlA78LTXKsANYD5kHN0fKrHy1jtZ9ADp3YlWWLX3lIxAzWMmRRlJ8RiAFwl3JyML3VhMtyxmu18thwNAgBjk7QNKE2RGblwA8ZCK88bnVtazQvnPhMf7LBzNjlxgBVSzAGSaSPLlFBIb80epdbU5ZaSGNLg94fQ1sqSBot6AJ+Rr6FsbHUibVT3nVmIkB1Z4r3OU6wC+VUp2DQ4zg6oY5cFmMV0UDEx8uiRDW8689f7mLLOwnQsBwXhtA8X881DUZYGhy0hqSgEDr5fSAfqQ9h8OwaLMnPrEzSFx9seNEfhRpQNQE8myUgqVlX3e5FFNHgyClmRNHQcSX7M5Jw8K6Uk5/VTL/eNh8O4vXeRbAQLeALzWp8ELsrTOM75HQL99/A+IUrTbgf9t6gEV13Ai+BM9I6S6tQ2ABnDBUSDS/zn1E/SPPPbyQG7oP/bmGFzry49YrpesfvwIbMcApdKlPFMALDVwcLqzBVQkw6XZAGBhmRIJc3QE4sFLHFCLhJQVBDMhD6BAz/7SG8D28SjEgo7Xh3Iim1CgXs1gVrJdtGCDCUoISCyg5WbxAJYSLEpo3wAGHYhEIDBBQb8BEU6UMc9wYNDIARRokEEfG8g/rzV88OVBUIhGEYiQ/O1xcoE8sdGtgWa7BNjsPzsAlS0nEmJgIEV9j45qAIk/nMQewD1AtB8eA7wZ0B/C3YGCi8KGMPjvXQL+ph7QW9lxlGWZ/ZyWooK6dRtoTJoMzhPtD/dExQCPwxwqS/+JtLyIjph5eey1Ye7bQK3Agugk2uvnwtyJlekCvRMAe8k4FMuJJjQj55jlDPGZn3+D/lCho5joJvKCVj4x9PZkQQ74yBEov23RZ8r+ENT9eqFEiOVebcBm/+ZmCNZ4VN6cHyixWHFUgVQioUPN6gYPDHQf2kcGMPeAXkXvNEDEyF3JwkGg+8RUP1GNQcsRCC+iekMrKxqcE2lb5i/qokrFQOfllvpGu/UtvxxmVGOU60oWpKw/epkvzU+eSgFDrwGPtUhXTNiftFEcFaYCL5tKamkG0VBnIRrQV2nYmENs4ga8UcklYGyN2b4Ekj9k4OzbQJVr0cVErw1V4ohHsw0sf5MVZOrUT1eCq7eo9Njhaj8k/zdPqUx+aHZ2v3IYoj5CsC9ynDfXNWT8hiDDXPsguaOQElcb9kH6NMgoidkpFhAjX5Kj/7YBRApSOfBPhPedCGQQUKT/D1qAFbvsBoFOSU9azrKsi1H3o2jrmv3TrjAAyK2QB7nuerUeG1Rg60vn3weWAOkARAN9vtrWN4Ct9w1mLnkDEOfi2gB0Bri9x3ef/fH6HS+9Aby9mSp4oesXzZnBunR6NJ/U2FCY9+dqAHnAvaQH3uLHCjfQD54EdBbuDeDj9bVH6URgCqtANMPqxfUKMoQABWhmQgBOwaKEJnFCFb2ABkBBwFHtBqDU+N09oukbmr0B5GtQzFgC9uP4G5aAv6kHaBUARSgNJX6ynFUcMzM5LMrIBui/k9rMW7FkQweJboV8cDjk9KLRi92Bb3NaAP2HDREC9Vbg2HMrZK653f+iOZZcz+pOOe3CEfrPn7HNJaY16JAz7sOyEqKxM9mdvBGh6LgQkT8+HBJqlDwYcWOyFepf2U7Tg+K3AcJETVY37XrwpOQ0hAso1P9bm9mIeowLBbr0DCBbvdZXQbMTuoUKSmwKULFEysKFWDD7kLlUBrnrgzQMnXST5UEyOpHetgxqhXI+AAwdsL/wkC6W+2QtgW7m/gY3AEoGUDloA42jDGYZDEdo3jSBiOoEKKsZ3y08BuD2lHUwaFz3pLylRLjyJMZ/PMPeLpoHYbQKLL1FEuyWzPsT/1z8hO3zK5NOYJiJfZUd8DliePB/WOVz+ERLupD66dLn1kEqpN7hxa60FIVMsJNjCKd+RQi3ZOBPESRDqKeg0Ynwg8UpGPOHchEnAhlxUVowPLPc+NNOvuT/4BEN8hfMf071bxzuLVwZUYUmw394CsYNAB6x0SEgWO4fMIGo/bGwFUwH+9arP42g14cEwNvzo+AU/FF4CcAGgJdnLTCFdgjIr+tS4egMgBH7zlvrO6mfRIHe+zbwztm/bwC8B6AWswGgQOti5xv52ADEApIr3ErYp9d6ScA+tubvBogD9vZ4hV++nEk1lhITzBdoUX+aQT6UJ+jNXYk8ooC8RGRuYnlmSphOwXOwJEhj/ggC0g2g9wCF2FadgoOCYoZJmQWF/OlhYf98D2AbqFDNOVxNoLW5cpigEFeBHfzn2os5aUKDHtqoHxa7vZQJbnIzfLfhJz3XeBcgXeUP1XZTMVI5LMlZdbBeo2E9a+7vr/Djr2CXTtSnPLkDQjqw8akmz9edDKKCnSW4PNY4ZGTmTLKEBzWShwFW5UNevywXe3H7ipG4WF0QNYSzV1AowVcuinXEAZyXu50uzXPhtjEuojWSZ4R1iNsAzegjeUH0LubDDMmYwTzuOQemwpGc3CsXwFLGTJYl/E4WkLESd/5mXp5SHVuoAHm+OAMcxIXMDqOlyTxSE8+8MFJikyiJraLA05LuD3Ui7xBvI184BeVBF3LScT9uUtbSTCeFEXbMsx+XSYIJ1UH96FIDfAOifWPt0iYPo28axv0hS8aWALcfTy1cM4pTuyA8zLHhPVsfFA0ZXErK0rgBsElYPyg5+ArMJpGyeT8QySnkpFSlI8j3LIn/Q/c30oANQZnI/TfWf7J83+Q6ADWDPp/26X/uP0M5J+krjdn8fHUAIPHf+D/UAZQo/k9k6JYCgasCgY9iVqD79kIbeD2YB6Ci/1ofj7K++hJQVf37IKsjsDWASyyMTdwDW5fa69ZuOv9iCcDsjzYALlATCr8gG5xczOShq808wSTSRA+gFcTraOYGOo4BL1sIehtYqQv75cHcDI0FrqpI/KwGEWi+tfkmMXC73aJWAQrT8DnPiosBKzTTJVqlvBf3uYZT/8VTMN7YSQ9lA0iKFLY9IHxKCot/QVjYd9IDdBcwhtBoA5VxugWwppzRSRJFrmSThJimBeoBRc63c2+TS6h7mZe6sKYUhOtEEs4iZIt0L6uqaMWA+K1ZGxBwPAIG4CP0BT9m13VzynCmRXJQCNJITk8YqrnSZjd3T80ulovX5eqOEVQTce93rsqgGLaBOdDW4jhcweCgkLXI08HSstdBrzPWTqU8DUMaq6yNWjj+zkAQcjazF0wbTcl0sw2AoHdWfO9gOUBHt2rriUTHqrmwPemte88HS0AOpvSOdsuoepdn+EpEudLPoDgIL/2cfj/WdR5uZKc8cfCXb8iEv4ZSA/oMlUYHOZJaq7hL/LQZMZM+a8piG4zarCwEHjrlcVcvZT1daKb1DxfgUd9Nh+0bhGXA6IYTHAWiipZQT9Okb+IBc5fFlyXjBz0gEmNSBfvwT2Xd7JPR/2HRqmwuheRkIxGxmres8Z9PHd5QSe85NV/xUwOg23+ayf3hPjdMB8JpQyB2VmbzITmF6D/t6ym+HD4QUACUAw2g7GUjC3SFDuD5Orbnzh5wPD/29UE76EfZHvW5tu1ZN/hAkAW0+xFYZAoCW8BbbucG8N5L6nv74c1OwWgA7+39BxOFKTVMZwDM5nJiDuf8RB4gpr0Nvm/x6Zkwj91d4V7mDbciqBLb/+8feNf2wmRMULWl+RIN31+/TWdU/Q1xBVHKNbhPLkiL7CtWzrrLwJmDGZBsqoT+iQXNpgtTbGIbPnGeF29Ys61pvZr9bUvA39oD0AaOo/fN6EZydlqTZAy1mm0A42qv+zMbQP/GFQpFCz0MeFFkWgyJV/NEw7g6lTJzGVzw7dub2bcBIuxrQsFJa2LFmv0afDA3qyTzhOu/+affIAIEL2iHdixFQ4GQsrcqB5TPNk7g+AnLA8mPSJHJw5V8Td5nMfTeFSEg2ijdhOqg9/hQa2fhZFriOhYU0px1G8Bo+OItWj7KdgCgiYLtFlV3iEoDz7l/uRFfcmNpkdAILSkz01zOpTBlmhgMA+Q90YOsGivTcBNebPGZcJbs/wMSXHCfFh1odALmNQIVKXR8sqwaufbgG1dR+tmIalT4ZmN4VvCTRSPpX/EHQIcoTVMUHGfsSRnRSu1tstBk3GSz/aTyjlebn47JLMrD+aHZrGc6bb8lXAg/KQy75vrZK7qq75200ugyYUnDs/S99hFO97oNaLoXzd/DBUys7CKASFYgHeeQAKP5mMI+ZjUGQf9Mb8RTlcQekjuDvD/H+B9s9ofDFZRfIP7L+nM8RJ12qAMA+4/0ScqwAvsOdtAIjTAXIOA/EgEcsAKVDhhRML3urw8BQaW/8XwqF75vAGUlC2jna1goOgsoXo7AAtzlCdHn6LvgflcC397iDRsAj8M0ZlhucaYaa5k8kNHP9U0GAfQL2FztJSsI7CIvbgDyBPUTMYzhnrgEWFuKp0G0QB4Lgl9gBH3PpgbgS7uZX1CiKhgNQN9nmERPMobjHbjJHxRAECJrG8/rDC/XQdj3AGMExYs9nOrk31mW/94egGDtOmXXQ7dBExJHyFLGGApZD1g160KQSzDlsGKvY81TIe+GY6PyfrG4Eko46NsiqEQR0iM1RPe5+TCGfqtOFW0YE/4bqKKoBrZaZ3/NHxOBO95QCd/Rjofumv6bibZYPTKbL1ZhBfeW5mwS55uPuEqUp8PewDZQlV9loFB/uvenU54JC+m2gZf+vwjifQ33HaE9WJewDzWwZmnFXmfGR8EDAyAMaff6dBjbKJUaWDZQtKNEp0w5l5Kq5OesGAby7fsXugAbKqwHpVq6TRudAIAeLpmy0TvIQqVbaf9kGHPWSPbn7K80HVH52cIKLTIlUgU6RFGU9igFDbQkOjFtIK1atxFZwzs57zRqCcFzaOgoVOtnlVk8FQbpeg8w6UWLJ5XT0H8O78PxugzDVfslLZipuZdTNblasqAwyparpfDa9UV1mLSfYFQUWjV7hB0DyJnW0OIY/ElRnnwJiMkFX2L6w/htmvv/YAukXc5LP9jGzJph5REFSLVI6D96ADxso6Q1bAC9+uMYxAawMg8AB4BjffYesL0eGyr+83g9ej+AF/S2leezHb36P2kIuuMnJR3AVw1guTkTFBIw3gDebQN4e4/vb3j37c3C4m93JnbdqAWblcTlGwAbAIa80laKfpEKYLh/e662BHxwD9Aq0NvAlyfOAKXYw8B01bQn6tW/F32f+psRQM2bGnwkvubnvyRqg/EfEyNxh+d1V0lUk/aAHfgPqj/pQKmcZtEyksshekiIOgEx81Lr/7Y9wFaBNCezOrsoh3kLLF5CqRzubYA7AaUDB3PazX2Xgxlut6CJtmlKMyJcYMo314Ybzt57busjee+5s1xFkQBMkYYyr8559zwb/raG2xcGivFQP2W7CXsCBJmXeLyENHP8nphe6bUiWhR8nGV7lNqtSfXQHHxgAbYhc8Qd4r1XwOdpv+0Igz6h9JsczVt5Fc9HlwPArbmYaKB/eENxrXzeVd0j0OPgIg14s0kvxtG0QcAl776CQwY2DkjJWM0T75MkDgWlavKmILtTBWT3x/1GHQGbTkzBOkE0pAjvgsLLPDfKymgryprAOl7FpG1kvaCfoXNwyEcTx1LIMMlJGZGs75TIAd7qxbHgIx7x1jw34HL/HXYTQ9RrBb64p8b113OLf5QLmyGQSXmj0fwN4vfEMId6VNlJ19UROEbb9bQKREs9E/JjPQB/A2Ary0bmJaDZ4EFCraUwKd4LH09O/1fAtDUAdQD8UGaM/4QUgsXhRbl989og92IOoMVgH3pWBtN/YQMQ+xOQqo3/kACUlTSgdVufvAE8j+1Zniz9zycRoSdVYK8G/GeDGwQ6/B8yYcQC0hKgBsB7LzYAgP79NTqBNQCr/rKEW1j9Zb4QT69vjkSkhFQmgh1O+mQY5GtQgCQJXi07rDeA7fjkFZhcDnZmk0zQAJsdKaAhcoFymrmUwDwOijBAQBM9mSLvwCHOCLSlP6h5w5k2WIWH3nBW/a8o0HDqoKLy710C/oEeUC+SsQHGNgvg1uyXyZmY/DUOhAFuQsq8VsB3hQUul4Ze4+baB5g+9bYb5ah9kimHVFrYRs1OjuySMhtfs/FCe8oFJAMt4acvZlhIt86gk2N0bqhA5SbhmM6BvIrmdBqLZlh+xdm/WFNtUU5c5XzE9F79be0aFh6Mry/nUemMBBb1/tb/xBqQXhD4RSmzHjLyCuvtSlCd+WXIiS8Hnn+FxNnCvPn+PcqZ8e1wfm8oAShXk9JYdHvl1bt/KyvRG4kaLPGgqYx7K+vf/Nutd4O98FCobHq5RFT5s8kxAnhO5NfBqTgqY9rgIDpc8FOCjA2CAvIDxJNBa890+zemE8u69gD885knBeOEixHEicIzu9Qcirkzu3cH14IWwzdvAad7t1s7XCMgL/fhaIqBQewRxYBo5mQZ8kqMN+sT7QTRktgt4jiLjtWSXnipTR6hKPsnI//kwfIMIvacb6v6z3ApQ2cWq8R+UvaYbMmIJ9KilpZHGyD3H4d8gD8WtSICaC02/uP4W3AC7k2APqAAfOgD8Xrs26uuX4pC4VfqAPaDENBuj8aRCXPqACQGpt0b6357f6cE7B3vvr8rH4agEHpA7MO4mKOzUKDBBBWDrtEQQhrgDXKwh8/+iAF4xY9X+3iB/YmD8I6P//yBt824O9qzW2eAyUlKdyMCYfx/l2yNGwDji0UTSqSNJPoUISvGUCBxgXT4bbhr7tYDiAK5NtiFwUS1pNIOpyis/i180H+yB/gqQDXdeRyOzpXQYQBUlT3O0dYCew32S/TbQFXqJINT5zCLno8kR9hFHDfeKEUHcuqY03XwwcyTQssGvIQxdO/hx9+wEuJsZYkCtpnrp8Y5jeFKdLMXR6bN9vSVAHgyAqqg4GZR4gIJNJ8nw6BkJ9f8VL2lsxhtIsbWSx59g3xMPJaNWXeFq/ZhORlN4Ta8Okz8t/B2f2xXZssS9+kVaMJUD0+TKtyHA+3M+ABEXTWZQyMlJ2MuKUSuxQj1E2ykwAP+WLwSFN6LZTIRbSewuo/QY0nF7UyOeZ4Qtkq+QCH8GJKiCpAapvQd9QfLBbXNQFQyXoYbpwMj9KHJBqkMTucHXRHqaQdx+lR/FokN7v9pO2ol20f+duqSAe+MOOHK7Mjqv6EwqYbWbyz9fhOu/lcNGWgVwyfabsZx3dbIc5/UsH+Z/b0HyCQwefVP4v3oV4KnEGo9sqGTN2tcg8j+VH4JeKxE/0WiBpOZzJq69x8oG4BkAMf+OsACAv5TVqRC7i/xfx77+qhQWj3btvX20Y5nbwA0Sw8XIRjDui0SYDEriNst3t9tA+gvN3aCO8f/O0MiYQm3EAIiL5PfBTcFGgmR/Ql/MEhqi/KBwBlgkykQraGlA1jDyte/f+BlmMJaZLHMn5UMPAHnuWlHYQ/gp3qmxveetIgLBLIVOaEs5SSNwFS+GgVoMvyHcJBc6skTzSYHM6tzkf3GKbj8/UvAP9MDWPuq2Mp+HJZqTGMeZhU9aQ5mQuwWgCeOUKMxL6/IlbaK1NIsKKTxRgb6rjGZvo2kDNnUzNxyZcuFOrzZqsWyD+ylP27+6y9CHh1Qjtc9QGWYhPnczNA/EbX1FCQFT1aIbtkQ+JurnRNs/6vUFohbKJ0BnrqrfYtWXgDLYfjRMJpOercC5rLlpiBmkaQrHcd4GigVLhpHW2p/Ax+b2623gjwXWGBlOpORE5JUHSrZ/WnxgJ+M71H/DQdRsEZsK8plwoCtaJHu/W9YIFrNBx6/BxcQ8+2nHkE3FzWNIIEYIavW/A5Uk4n8dd4lJy7p1wkDRgVU6hbezH+J7TWzEziaeF4FgqWQ0fc/nTY+I2rza4XwtQeMVC/ZRRsLKAYP4rEDgOE85/mXvzm6HEznX3/bJCG+CmhgEGfUyPrJHmWs79my3aP7XxjzR9Fe7AwJNvVCog36iacuOuqCZZEkwajXQqGLSn+EgJz+hXYA0PgvEwgCQP3/VxhBb+vBDaD3gLJ+7NSCHeujvegDsW99HKl9A+izP/IAjnYNhAliAWWTgM0WvULbn3t7+8E2AMbCkA96dgJERd4WY+mQC9VsAzCBfewP7/0gEYgNABzQXvcJ/X8844MbwMMuAXCG+HiGX78Ei9ULRvvOqvsygeif4eJnYfmVohn08b/dF7JChQKBC4QGQEmeG0QTBaIUgCwg94bb2Qw4/icJAvTabozxAiCgRtUWwv8RPcA8pVM6j8PuHqEEX5EVKo7puAckSBWVNEBuKKA3PVkPhmNINFtnFp3eXI4FdefAubBizim4SJahEihmwfPCuRhLWiBdXoO2KtOXFcIxMhB4qkuUpCOi1UNd5MowRU/PRTHKrrwX4QT0tRLtHBjafTyCo1lJ05NSiIJ5TCreIHgKUtJtIISxVruFJf7C+dQxVYLrhV8gtnDwsgGK1b21GzoCRvS59iF/gu12m0EISsUulVEoJZIGkFiMQFoaOdRs03XJ1rWqnogW0iuzexMKgzg09R7DRoCdQO28ySfOONz4a0ksrRTwWQhXi8aB5Xg3kSZET6Qo8VUwjCeaXzNTJPjNyqIK0YGDZ+Q0cuzTyb2t1/E/tW8sAfGTF5A6QdacpkTgdjpDUOHlAmD+Bgt3JB+Qxt9RqfIMC7CabL2hOfQ/qv8ZnhhV/T9X/LP06zaQdI2ZeIV0xme7Vv9ogLOWAIA/EzvSVAz5of6rkgXElHVSi+sB/de+28EfQWBHXwI2UID27dnn/YODP/YAvgsf0P2JGEiEwm+8AB/iq/mULSRLIVyzNwBQPBkMySPwm14gB/PqD2toCAUEAU3aAJKFMJsvtMTA1Q0hFAsjItCzPV5440lXuFUbwAY52E+/MyXYbUHNpDqZF/TETcUsgLgBaD+4zZQFsDcQBZpwCYDrHn5YSTXC3KGtAeAm3HAKRkyYdgLjArlBdPjWKfjv5YP+8z3A2wATK1qzpyytCogGiNbfeCXO7iY0ucaLsaqoWPSPznzaMWWs4mizL6iBYSHvpE84y4GCu3MP6A+C/qMl6QGHYkXNSMSrbUBk/v7P/4b0+cCpi15szg5KcleXM0EmSZJRrwtxbJjKDZfIZtZAGb8anSBkktOmPYCn0uaXIeEV28vIizu/UYq3vrYBg8F7vbuhsRR+pRDzst2BFwtRfv8u9K+xf2wSOFsQZNf6RlDh5AyibFZEFAkrkKJhQJlI9axQFoD6UxE8kKql19ZmgjJCQQywjKY6MD/YLFEq4WS8orm/UB1yPrl0JAf95Cjoe86AefHbs/6YeeVZWII16ToZb7/5mJ8UbN8GHUhe4ZXTRfaeNVhY4atgoeg+2s0NQYeZnKyMmgno7CfHPDxzgxDGN7hA5vHEt0gANbHFGQ6bDE9TCW/RBb1jh4zJDQMGTIB0twnAT6/+0f8z3ZqRf1T0Qzg3ALIT0eCb8gpxa2NUBTZtYukk/7ABlJ0OEIgCwwaAKICD5R4UoP1RnkD/y4bbL5oBqj/xH12Ajz30H3W7OMHZDWBU/zfPX0Shb1b63zH4v/sGIGkYCi6cQQnQM8ArJ2OCisaN9sXqP84ABHwijKnXhiPws9kBAEsAEKG+DfzyG/6I/QBIv82s/soawQsNiDIYnwYKCfzRC78K8j+x8vIQkOCsBRAVFgITCpDoQM02ACkD7A7cmCFjorB8shSup+B/qAH8kz2gErKA63bwJZvQOk99KhD1FAm3uusUTG1loWca7MU460ecw7AI0Lst35hQ3feAQsecgwGTB7l9IukfxJMDDeZsnB5Gcu2MdumPm/6Y6Oth2uxwpEsACXaMsM1hANCIE6A/co7WBjAYcuidTDVmTsN6pmh2a8YbbHHYELjFzaZ3KUlDN4h2xzZO9I7XO7GVmd6C2mP6AnDDOTjDNhW4EO7B/VtDcKz/H/7DL1fE0U5TybQFBpwUZ1hVt4W3yUK1w+QKbmiBmRbG/EI48Mnp3ox44nCzU0gDevvSfyRsPzoVVNHABjW/BRkENTrvDRhQA7/3g9jCmTLSLMJAd3WTTlMNHDWnK1XeXFdVeHO9VHT9qfQtU4h2Mc67EsVaGEU8+ucRTPllXcExH4kh4rgcWD9wjXY8+cCG59h+EM9tIHrWnnYC/h7CPnbynS+dJA42ebOw0+CObxo3i8F6zKltWUuAmD8F3P/IXa0B+mcOMNEfVP9j28oBChCMgID2PPcnCaAbSn9Z1wr/H6jAGjIEno1anE8NQIfWiTHdvejPcoJbaPtzbyT/8CD8A0hBmv2hBuilH0fgMIsINEXx8eLFh7WPJf3f2tgANpF/NsSBrSj67fkk8iNFmCkD+pqCee6xnrQL6wGk/IkINMkU6NZ4/jUy6NtJCVVkccRBuLfiJHIcZdp4svQnV28AxHyaUKCZx4C8c/w/jA4kWwjr0uGPp+C/lw/6XfQA4BzX43C0w0AwL0lsTIXVn6V/ihY4PB0iY7cp8jYIZ0muDDOryAytUd/qyq0/slHA4HMov4KABGARimlcMHN1OBcTpM3U5DEDvMr+9AumAHt2ZnFSmgylm28D0gosyffxJIbkMK7hccN8FngihnFkUyaBTgvV7Qoiz9TJeCG6hdrQEHf58hAsambFgE94wx4w02ejf3RBPY8Vwhw0P5lngH1ZwBXCg5QHgwnoEHtFhdQC51XIliZqCBCt5ppfjD2wN8hEhA7JALgKVF5ASrJonpZ84HWPov4TynNDMsFRaTRTqnLHVM596tfyp+AzQfvmKWCUKFsCmpu9Rgb4jJZd/aJEKcaw91FeUYyfJ/540QfHf3OqGiLhYQM3vqj6qT1oD7D+5+rzOLQFeluDvwfcm829t4Rkq186U6MscY/e/xOYh6Kd8CwQLRDUnitB8u8YjPQpqWVT8K/P/oH2JvR+AILCAxlcFQj9a/zHT8b0X+vBKJgKJ7jnvpED2tsAVWC9R7SVYZDHKvAHUTAygbjmQUZFtEbMzlEZLyjuPPaSBXQzCIhKYLzGbQBn4QUsILoyKIzFpHHD06Xak5cbwEYyqMx/+h7wAtwvBcDjZS9PqgF+/Qi/fyHWHC0luE99FgSmDDJgPgD9oQXziMq77sBAgfACsyA0ACrCgAmjgVhWsGb84OffNm1NpCu7CZOJpZfhDp2+OgUf/8Qp+LvoAWwDJS3JQU0zMeHMaIiQHmCQslq8cJN+KZIGgm0ggOKSmTEw02ygz7w3GtkXlqeDiPRB7sguN4WiCY1D9+ZPYMYcb+lyhmXGwH/+FJj2bilkSmoUwEswR/ZsxjRuZBmDZVmd/kuny0wE2F8avU44u0Y65lEFBI7pZGxUNYC4Ers88InBuX8nECQZhchCh9GcqnMfMf4f/AioHRFeSXsre92OesPLvN+mXoyRxIlmUKa5t4EZbqMT4R7a+9DUsxBtmyhOws7ABzb7AfPNweQpOhg4IqRkGtZQovTAlljcoUbuI1dvQ2oGWADte2hhvIb5RN02FL8iszwhwIMux59fbO2T01vzymxng+SgUhicg/Pt+NkT7tINrhSg2OKZ8C4+6CctSbQZX4N/GpbRorr5PkFZhHa86BrQ5gfc5ntAikNvziE6U3qaLOFLCZgD+UkeipwYm5PcvciKjE5pIoByBIpAfqrU7eDK4fzLn7yqP+B/4D9r7wK9vvMG0Ev/aqV/Zw/oH3/2JeCF2b83gINhkPsBc8fhdRjiZxHAHDjLa7o3wo+ZgOIITHNQ6QDemn6PNFkSgkFyO24Afk0qfaahEAwBkDus/8H6J+zTNwDU/f76SXNQfvDjFb58IBugttMW1EQAs/0rCw8Ab30DUDzZYj2AFkaRcZVoD3gXOZET2kDfyzC6ZgpZ2ACawJ/+rJrpCMTX+Lh7wxH8bAYPGxfGNkC4wpR/tgj/wz2gb0D9WzAbIuRN34ZBrQKq0BMlY7OqfzAnGMiOgtlxkeM+VzRiUOOxQd/wcE83klDKhJkRl+E9lAUJw4yZjM5DpNCgGU0oRYudBU3oFX782dI6ksdJBkkHJiG7WlpoXcCfMmpC0aVAT/lAJ/hougG2AUmOCgsImPMcERIDBHUjcgJxSPS27Q+5lXMW7uPtTKUvh1Frd9EhSY8lSRTLAc6zWALCgrEP+uGZHM4ZiBCQ4N4J8ozKPGFJgKMn6W5yOQBMhKScQj5JoVl7plXoAZ4Tju5w8kw0Y2MSGG39Ti8kc63WZtDS1NeCMLcFbYC2iMCpxqW8JUM2HJCT293IIPXg3aka7v/tTnBaK10FAP+GFfrVf6rRZ07x9VAcrveAc12I443g0H8bYXNxGJbG8TcYACyXeL2jqBzAzJkNYKD9zXVeg8to1iosKYqCAzuKRR9FJvIGIHOiBDSUHPpC1wfJOHY0YJR/ZEAeG2UAcADt83/dUf173T9Y9wH97x/lteIMsL+A+B9rPba2razI+6coGHdL8+o/uxiYRM+3d3tN/Rc2AF2Ab2+N6H+80xWu/0HcWtkAkmPEZp9eQQTaKASD588GHwjBPs8H3gALiO7Qr4EIPcOvvxm57jwFEwLKlH8uMoK+Nep+iQIxJ/KdneCOZBgcBoD+TLrHgA7K5GIwFVugIoygfx1RkUYJxWXYUaCMa0Gwo6JbA1lj38vxD6JA30UPGByhnPzCJRd3PLhyNXImeT5t1nnuIEwhTEGbgaX24eNzonsLDGD5/o3ulTz9KvqklRvQ9RINlgiq/lw3wCf0nazV08+n75KWVSRjzODivmywfh2hsD4v1mBJk+mklvI4mSkAY7GRTQDnA3p/6VwkYy94T+HBhtLPB8yWeSU+zFYoROPJ6kxaDpGmQVua+dWCF7T3p01Ere3T05EXcOnqsuHJPO/5BmtzNuClTHXCY3ZCP+jbVJ/zISVLDOCFkXFfVXAtAJG89r6woF9VrgUVjs88F2caSij0IOnooXvwGIqDmP24F2AdBzeo0iKX/SDFsfSfd5nol2Fj94tMa4df/VI863Rr18yAoHm5WuDMv4OA4h+7wJU61OJl6v/0wfRVqxh/WbR91sq+IClBQ3H8DhF6EJCak/8vWe+w0n+6apnZw7B65qhBa5VY5UEJFIjRzQDq8uYyZZAhKmUkdP7x8b8/IpADRu7/ehyvfX+Vta8CKP078J+H6j7H/170H0B+ylbLimV0I/+nfj4ACBufZhMB5Nu4AOP1O2Mg2QOidGESAVAHINI9kZlZchwDyzT+I02wBJydWf3J82ES5Bqfz/ZgAAA2gFd8PJsgIAFEv/wC5qggWd0AJjH6eGqGJwQZqyf4Q9VC3wksqWbWawsJyHNSWjzR65mbF84AhUUfvgR12us08J/BBTJfoJEWeRr4xX+QC/R99QDdxJHEbGc7dzdHUWUbUBQtKhCDBcEZmWQllNrM52hBaGLis4DR82DTw2QQjpT3JsUspAOAyFu7N8XUYmQGYLK4tQA82zBuj1HuvA//zpvwf8FUHrmVJF69xOTAP/06o255lsAHUz2vj5LtZMcDCmJnWjXCShsTYVPai6MDo66oCMTNiY8rwW1BQxe5GZtZqzeSqDKS1NjPCg4AJcNwA4PgtBwZCwBq8HyUBjnxXPKyTK0QFJr4RtY3uSKVsJf5mWzQTCyLfRa00SKhPXwmCoUSpA9pVWvRr6MqhO3TZsDckv6TnMjtLXyhy0UdBCGOvQwPaCeHxwt1HJcCi6drwy4inpFhrhcLf0iQ/EZDiCcoZG+ehf7SaAbyY3eCc+uJ52+OHlUxDIqiXc4Tc4hYTjJnH/+2uEAtppMnIZe3piUZ917cfisqfgnZlAhN7HNA/4fiV5tFywH359REUzWTcBxlE/kHRNCd/j8Hjr3H9lGOFfYPaAnPUrEZIAT4WFvpb4P8cxJAzw0gGmMCubs3Aiy3kO50erir9EMOdjM5WMMe8IYDLH4D8BbcAIjMxPMGEIdrFhuAtGAwgQAE9BIRiCM/yT9oCYwsxnF4Y5/4+RccA2wD9Iktuyk0MmFkQXpmA9AL6CZ9QKSbBar/tOQ8xzxZPECOtI4JFAQY79P4oLss4ZwPCi4QDo7GBRq6sPhJEFBaa/+3B3ySC5g7s55sTBdxeT/LXZv04Uh36NhcyhktiQOinczM3D5Z0Me18ix6ZzQuSfStKM9V0SlKsXFXSIAzFdbVzAQwGLE5kf/nX08WeRSAk3m9zO64HO1OINPQpYnSFI3dzG5RFQFFXLJZipMeoFwWJ3Av+TwPaTLhGM2LaB+ME5TfMOg1bRb51Q4YpZiT5VaY/HrDQoDnz43fiJ1v73kGmQ+J4EsvC/2Re8N0OC8THrz99VJzYUJDm3EonrIOHHrdnw08cpMw2qbK/Ddqt0UZAnFKtvgUsLGJBGFe5CW6fXO73FoROMAVXdpgHq0bdQ61iTsUR1seodTmB918btduEM5eYabcIX7WiLV/Jw+zd2OIF9egs2ldMaexKET/h0dL8KHfGKeskkKAzNMNZT9K/yU6GVmiOmL4DkGgXxQDk8/zI730g/5fJ3JMIri8vRnQ7Yf8n8C6T80XWVPFeJ8Nwq0i63+4wB117T2gHL364w6Mkb+P/1gCHgXV/1Xx8WfbX62+QAAtNIA7NssA+Ar/oUU5jKAzPZZnjv+zZvx7ePuXqQFE/vkBFqE4As+avhdiQbNJMlM87YCaBrWCxzmWj7W/RFR/ar6gAHhg/P/ADYD3ACFCfN0bwPOSDoahLbPoT0YGxYIymx00DhVLo3kRDgMwqLCTQJuXxMSYDNfcxFROhUyRCMSKv4gFBDlYs2OA7CLMHDTka05ktIPwPywI+B57gHOE5hTjSd9m1JRFz7fsdBNAPbTPB2rhEe50Qpa8DMDEjB0syxN6WvDMOOhhz6xH5uQWSZJoMS11XlF4yxLqiBQ/fLATMbkgeBIWchEDBQg/c3RStvmPWAsbavByflye9rolQGLMaLRqU79BSZQaWC+JLjeze3mWmgszn0Hu0hkUy3I8cSGCX/tASJ6oEtgS7qSJ3iGjK2SOUkMciA1MWylL/z+8HL0T1DYzw/DAkJ97qQcxiJ2gwCELl5CcLNkBpQgDKYxMKSOA+09kYIz6QRNjXo75Bg1dstzEk6TQDctfpnJQogL2AyYjKB4h2ld5CrviqfttoV1J/8EXhU8i4U8VP35zLb1eGa4tIfpe1q435EH7HJsB8Z9gbg9W9pPHaftWIGCI6NnFQ9CQH1oOtazINDpknGYPIvwwgSc59VM51mDE7U4RoJ0flz6UfySAgfdJ9W/fA+qOA0DZif/sJP6vHP/xQVr/V43/G2igeJDsJ5frVABIRDnh6ZCJq2COfosLUX5lQN7pAi1PiPe3yMYA/J0XV3JAdQPIlglzIrHMGefjE/fn184bwCoxMGmgTyf/jBduAL99MUegQQaFH1wEHWiZTBgszRc5SHYHRgOYkQ2AZBgylOY58XQ88VATCQFxCoszFHeVL31iJP6zVx4AzB3a94CLIsxfDAVivO7xndTe76UHKHPYj8OOCDU9QyQXCGWIBqwTBEbN1GSZJEY8ZPAIsDqY+UMhEMSQpNcvL5qMaZdBQXVDodJMSNwfLHu4qHObg0JsKT/+wqdtZgJBZjwKuYxmg9DMGTmwL0nNuyQ+CqzK63EJGGTKfHhkD0vRAwyLY8Txle6kkUMWcl9e3BWgRwn7iwydA6eCtJMIFO27M8yFjOsEfwhQqvOBLb7ssa6xP7G3W9i33J/qy3bM93nf6rTmvU9n/RG9TPO9IPjuBlgNa8FUiVrzQhCZ7AbTnMRY4Ckg8gty6lgnnuMRghgOli5Ji4tysvhuOzsBqUT0kxD8m4yPb1XeLHEc+iGhVEhRlSVEref4H072qA/+50bQhkTsK5OIC0eo/RvEKIb4yfrgTKz5BoaUFNauDK9k4q9L1bRPxU/IuniIU2DxxGR28ivCsZcfN8angsrc84fv0ui/b9DVAr/00Ab0rxHz6Fse6WFA/6EA6CM/ekAp67a++h5QNvWAXv2fDaKwRzmI/jdkvzQYL65I5irHef49DfcVtzdb6N5CYdeNZ15CPaT80xDCb8LgAiESUr/zZqmQYGdSCGbNlU3MTKGhA+iLSNh7fRfs86QWrA/7Hxj8HzSAe1z6wZcv4ePL15n1WbmViiuYpFUeptAo97dBCTU7o96c8m2CJGNSUjyYoHOLMpDBDQBZfnHm7VdnAGJBaAP0jrYzgAuDL9V/cIG+BxTo++oBnwwk4hBQifTN2HAlDxO8OejeT8hwloxnYv0AGBGV6th6+WpFaSl1hkU68HcSZixuDF0neP671v3N4+7YDJrbNpy5LjSV++kXkpf/nzA/+YwWAcjlDVFqB1lGG7KPwjlhgOYAqzagESF6Zkmi9U0ejgxRMS7NKaeCjBqdhvsCsUWAs1ARy2aMV+5aTEqj/UB9TgF7M+2sbO/pD8wdeoEDF4Jctr7ml+mOo/Fx5PmGjyOgrUx5PnJd8nTkZcp9tp9SojySBCBFGBa6jU7k9xece/F21eEGq0ChBzeWhCSNsefrJh16hp+aczEpwbXjQXQBGLcHALLpJO+wDbTxX7B3HYlpV7wnfmUX2r5WiZ3bQoyfYJ/wSU187R8q9+RuJum+kjF4/DARTz5RTNcTgR2UBfU0f/AQ9K8MTiDfH/derQLC+puqP+Rd/FWGGVHyqBxroP8Vt7Wyg/uPK8AB+5/+3rpvfdGD/QMuvQgD4OzfP9in/v3Z323r2rsCau7xwvh/7OwBhwUAfHKAcAFwlJkPqfQA0PsG8I56ensnCuSvjRHUx/87DgYzzeCUCAbLi+m0gtDkgjMTRhbkz0gMvHHGh+hXsTAigz5xDX7xbbzesQH8/jBLOHPgSwb+SAqAeAB50kn/9QaLULtLAxGCF9Bir/OcqQijJgCS4EyFF6x7SfqsuAOTBsrX4xp8tYUIw3BYygTjvXw/KNB31wOECMU45+TymoEIhSEelufCLDxfsmLezMzoPRltG6wJovqMGVBNx+tyLGkRR5qCGZZF9JmiSIrJIn/n6WQaHu10+AlIdAk//mQmP3SEtlQAP2USLk6tmIUwfsNMMByzfhpToOACgOvQl0F2aAgSFwIcEyJOClgO5G2rk8CU2sahps9H+KU17PT4QYbyqpBz1zdwxSF+hC+vzGCO9j7Xn+F5ifselx13v/VV5/s0vdVjDct7Pe4l73m51X0rvfRPd8gHci87EzCiNFXcMsE/SXgtTCuyJTD0nOps0ITw7Zfzdzt4HqDHK61fg1lSi4NKY2gtB3LtH/B6ayeHv0Un2ehduMTRK99rra0WZjVRvW5JZND8VmDDVwx/HMI8VTgOHF+YjfE048DwZd+cvGnYX21+EzbbmwGQ/r0Y3Bs3NDvwkvsryhR7QGsjktinfiYqKWybjqqwrzsw9aci9z2mfdlay4v6wVc4+oLvBeJ/hf8DdL/9BVDPvhn4c+Dqe2AjfOEgDPIPlV+g//dJaG1fkX8G/R+UaD4Us/x8XAKGgyo1wDeagN7dEPRNMuA3/R5uAPNlA4B05mLUhM011oNWEDCiCNuTZ94XNwCygDD1f4AP+sGPqBn0p+Svv4UvvweVVo3/kUxQ+ZVOk2sCZiQBEAuiGZxVf7ybpQqe00xTaPmxkrjV55yZEl9mA9S+BywHiUBHHU7RM6xYCAGRMGqrvU2Flz0AON13gwJ9jz3gM0doPI0MJqi81RbJ9vtwnyxanL5lmAGnyMPAgBtAE4KrurFEDkmMEinuYtrJDIaiLfI5ivsHF8+/LnRu3J0qqjLTN9D6o2TAPpi6slfsVhBkghluNosVizIaUFysuTxSJ9uHjEWyYW4DJIZKBWq2QsnizILyLFEa+rsvPNC1B1QzpoT6oX0GsmiK4YyZI9BaD4PKjINHn/VifwhTxTs3XP/ivk3znstaprcp7cd0zMuCI0Gepr30dyY+M3bkDGMsRT9gvlXvBEfi5wc/p4RKhmaQ6e3Ufw5gkRZ9L5irTs8HYkRU+8kdXBN+HNZ6Kv0j18WcBeMg5PiJxdEWP+y2b0jA/gf/O++9F/z/03XBaZ7t8z/qcgI+Xjy7RnouUz/Yyoj8TDv5CvPRyJ+ZjBDUAHjGQsSmRbCR2kC5NmZ/qGsaB5tKoQ2ZP6XK+nPrXZxIEAb8vgGQ/v/qOwFcgJD2hYXAwJ8DP3oMBzvNf3AoqhdtXvScs2zsGqP/E80X/+f+xmsqLwH3f3kPuBk39EZ0SBA8rDc5xCgnczRHynciVSzgdPZWtL3M83l9xdcDLCAdfvseABEAPIssIrhvAF81gEQtmEo/IgHuPAXfKAeTZk0bAE2KgFD1Tx5uEMjKQ2rNTHeOGfSHmGYGhnCXtlNwNn9QA4IsJNIuAXSmv56CByX0++ECfb89QIhQr6ez5nBzRAzju1bD6eAFyRhreLSAXJ/IGVIsBQ1RarKL+haHwyVMl+meVWmtQtMZuh0zb9BCSoSl7Fct227MywEK9Ufnf/43Bxva4C2iRRT63VPw2kZgmfyQGD2v9GlLobEQd95bFwrNmP7I0k5liWGaM6nN8isFTBnWqVnGWV8CXnjNURskCinn6uH3DI8QBlhWmnxCKzeDZaf8eAtp3ctbnrc0QwVap1vlbSDP91Juy4ydoKQ99zqT+yowp1wKMKL+r/bXzTtBpCFjOiTHARWWSwDuxsS5lJ8OKlHhKby4qsKagSUsOlLkNE0dDKrpz2Qe7eEToxq3K3s0hn9zDI7f5IjGT5fkr+7D4ZMU7RNWFB17ir6zxAtzifCO3B006YvS0DjvN+N90kw74gKMck+aP6+7RP+1DQRDfhp5bc04P+wBEl3DK5y8z5040MbZf8cFuL+x97rfN4Be7p+Fdm/9bQTFb+tRXkD8NyjJwf8Bi2z18b+eX+/g//B+y5ebwfqLoP9eQ4H80Arifu4Bi3oAmUI3OTMjgYvQvEdCuiBQbqCEgKgE3lf0AJA+H3F9+hH4QQHwBzYA8kHxNPzyJfz6q2dDXjLrZTghGuhC0uptVi68tMFsUfQCmnkYYD5M/wx7A6A3NCevxIx4zwagGqAa+AMWEN8ute/JhIDa5K6tTu8bS4Arwr4rFOg77QF+GMAZvslVxZTDQlqzSkERT7Qyhh6z9TxsCsQYT4IVcFFOKW0zudU0DG13FPwJerDo5JLUFE9Yh8K04kETVmPmZ7aBcPHv7K/7Q/DHH4Pcq4XqyuesOmoNPzg/VSo/ZTYdGSp+HCWKtOjMZMAlESVQPkEy64ik9MpJ3QOJdWZXxV/CZSQjjrJvmIdISgf8hUK4XAjcfAd/pD/TXoqH7BsAuM1li/kWQQF8i9Oel61m9ICy3HrRT3kr823Ky5xvZTl66S/5RowUO3PJ8IzAZoCMh0y1Gwh0Ew8GRIqYCgrQC5Us4w0cipnlKxZplQNd0lJWvR9EQ/Xi6Onm/3A6N0QRyf2WK65Nu1KFxpz+32UDDRTn80c/7RPO/oyXjh+GSZFBk3Fo2aJN/TUbwiV9r9Ix9asti8uAMZ+UMO0Khb8qgv+Y/ZkVHWSbQi8oKewLQX/g/0fdsAT0qb/sPPb2d1ccAA5SfXAKflYxQfuKgMF/JekT4V/cCMn9r+V0yDCxWzZUPRFVTwsw/cy6P98w+JsI4E2KMIuDf7vZ7M/XpADhZkAjIF6AYw6nJpAbQCX6v6v6r3En9L8S8FmfUoGBCbo+oAVbiRH1DaA3gJ9/tQ1AhXYiBJRIAYITHGmgNxJDBf2bLcSbvcGDcLovrS8BQP+XRFu4nDH+zwSS+xhJqKctRH7QBmAOUSkJrpeAMDsDTAoKPvmCwSNivr8G8J32AHGE4oxbm2zFxscHIiQ6IbLmOVolOqHQmRnYeFaOFfEk2hhkPt96p6hKX1kECtVSb+CGMpSO7LciaWIoCxrDIq+3w1yrd/OSOWfEPpX8538NmuhFMNWJOHo8OZ7lFtIur0lJiPERmgK4Nphjc2N2uMCsEVljYZYTP8i7VCI7SKcCfLXEkTIPxdGFkaU5ZzT6hSAoz0Vu+9AQxDlkhu+UDWZX0BWXOG2IcJvuZd/jvszzmuZ73e/UlW1T2VJepnTAOnG+HaBNzznlI2F3LlD4pyMlUoYQWawYrAnQFqs/T8fZMnd4BAf+pXj6Ss6RPNTE9iKJSOQiUw2rMRiE53K7pOT5qzogXqq4i7ha/AaXp31LMRbblRd6lnsXibUU3BbIhWyKk7Oe4W/bx0nyMcynjQZwdoKoXy2O9jjsEz0JqQn2gQ9Io2yCXm/03d3YA1ZwaPcVBhD9bRJAeQPoS8Cj1n1fYfR2lCc2vOPFe+/a+jbA4BcMN9WZP1+P/9F20Mw5OlEF1itpuoH0CZ3XG07Bt3fZf8oHNBL/MROIGRAQLsDk2LA0e3iC9VI+JqFh29AADjaAbe3VP7ye2ADACOL5F54Qryh/0J1xwbAD+pV2KcOvNNrAJEs4hgP39QWGELdsg78OGDSzi9ONGfGggYICRJxqykwGQFakBYSJ8g8KEOo+TIF4DGgc/9uJ/1wSAswQwmOdMTh8V1yg770HBHOWLhY7bGQKEqctf4r3YRv8+XyxI0Ebl7cskgF5N33F5mDdGzRMk2c3OuPjvirQ5BiRk8qqZrifrPmBPcwmImtX7g3/zT6bpJ9sdQgWdR7Jd7fZ37zl+en2Dy781xfTMcktxphQihIf1T/kS3jZDG+J5OBPmExEpotxnnAoxuP2xTAYkDP5qa5UBgzT6fFSSSiXo5wMXriGR+Qr9BqBTjCtUFAf27S96nJP073m3hjWabrVtOE8MG95WmAt0RvAdODywoxthlyB8l3IgO2fLm8WYBNl0WIDoWD2A0qncS3JwZJY8BuqRfjG6OfieOGV8pvr7puNJss1xtHzWhxtIH4u4Z/8HL6FC7VPuoDLNSBeKn5QTozxltr4pWjW1nbjHeff5L+UGE3Git8M3/d5n/gP/5JKtKfwwFUsNZ1gf6O7EkB/2e4R/a8rlwFU8x01Hdm/jALj1N83g/WF1xtOAnUn4QfV/8AiuBfZZwECaseJe5kKIp/8n17348Kx2iGgWeffBRCQuEB3Z4UqIwyF9a5kriZQvr/wL7RWPB6H2AB2HKKxBLD64wzQJ/1HeH3A+l89ACgQyKBoCfg9TzSAX36xBqDk5eiOdZkPaTUAfsJUJEzDEAIX4NuNwuC7/ErjpDYwm2cTBAviayfoACr3AFb8mVKAWc2g6Boc/Bo89MCXI3A0d+h/3hfof7Ee4ByhvoTyUTOCXv1pWd2KjFnks2XTokJMklIhyXGgCQH1ceIsPCkZMNbgdvL9b7iBrmL2NnI6aPQOwrN2bZ9cyKpoNk5Z5DPnyxcJEMZTCOWoUOVsvglNJHg/ZQD5wNI6UUCWFBVPERnW5MJBWVRRnrYwO02eP8G6zyUAlyqzWDEFO3OX1nCwJcQVF+Ne6/u4l3Zt3J6VJiL2MTJzGvyh4Xj7/7H3JspxXFmS6F0iIhNaStXL/P/vvZ6pLpVEEUBm3OVddz/nRiRIdVWZ9UyLJGQwWBIAKRDMPIsfX3pYqc0pkAUtKxayvKay5+XW8is6AXQDl5y3WkvOtzx+iSUAkvoCYi/eCl5G5PmCJN+5EOjEYQBRtlhElv6k67ElroAF6dnruqfTP6b5/d2M+60ZBP+B2oMQZxhAPN1npzhAPiT983fix6Oul/63l4HwZsy3f3Gb9E8f93Kvj7Rj9g+IleVn5f4nYx+CQr0J9umKhXbQHyxnmewVCn2J+zcEfrWCoo8bwP5awekE/X/sBDspngB/xi+l9gIJ+DaWvEbLT+d9ykb31ABkkx45UohRk4n/rLygLjLTFwF0VPzvpydEdP4PQ4A5eiMJQNLcVU1F7iFK1TYjoEYLCvQANoCdDeBVdM9J/RwN4DfzB8WK8IxX3N9+hYDAona4hS8aiTj+j6nfav0TUgGuyge2C3DkBTsx1QBk0NEARhtQOvNCxRosrcZLLm4dDYCWcGgDSgcbzSBLGcDlIFdvAOFoADa7CQWiQWv5w1baP24PYBvApfGgitoqcD4MuAt9I6BAPgVeacSN4O3txAzhMzyago62cAvlK1ClPpKAcZjDVxlC1H6Wjiam1FqT6MfoOB6POaU2YxPRB7nvDQW2NvM9t/h2Jr+X8eSiWxG805gTaNKBaLASYIOMNrDOtOrVXpZ4vzHVcsVNeF8ZA7zyXjfG9lc83jdwt2WOiBc8LZ8B9e4Gdh1uy8p65y0aI+GKfppuPV94IdjGK7OPP397xZU4jW3ghT3gigtBfa1xlP5LXtaWL/AAT9im1QYYuE1UNeY9JiptyCJCM4haePggijQNI1IJprXQ25YAdAj3A7Lq/AzAzo4ANMeF4unjJxmXt+MeD1Zoj2/UYZ+jBJ3PAL0/KscM3sEk0ebs7+Zu3A8Sn4VO/Ld5n5wFIT/0KeEHXWJIriezlDnz4+O6+/La2yj8wtS/F/A/EfmF6R7ID1j/ffxDjHZQAPRj3m939gCa/Aj2AdaP6j82AD7ezfQ/vLn9Cv8h5pM5W2SSebKG+tEGnnhfveIUTAtonoJl/Cn857ugDWBZeQBY7DBLbpv9q2glbZQBN+E/YwN4jToC35957H320v8KJugo+h+feR/mGeC3D2YIOq2KYjQ1rgUDLKYBXuVHvZknBMUBBKyu8aLMshzH+L9tyLlYGBHJiObMCWttIJRsjGBaKyEgPwhvRzZAnBtANnNQCQIeyKD1j1xm/9A94K2dHBtAnM7y+NEzRAQvmpVzuEj+eB2uxGFMjETxfYThytoxl+p8t4yqcoEzcvIxvxMIMrDn5p7FMg4aX1W4I4c7qKLB04CDW2iNJ+h//sWsM9kqCAx65UGd9RwxTX2b0cbpiy2nAIkKyW1Y9Nk5UvASELk7xFewTVIWVot+gsdMALsLJroBisQGxcc7QVIMIrSeJkf2CO4yMQGimpmyWSEtHj9oXAhuMY756IqZUejQcsFBeLnlupVyXRJaRYav1n28mNLYBsZIhQsBdgI8YBrUqAQV5Z9dgPYJpNyh/GfySnXQSJ63zkT1bl5LXBf8Ptzz5Ai1YxUwmMhtnOObNJvDIfYkNThX+x5PB4Jz4rztAY9t4Mgy83nfL8CG/Ei0AqzNP2jEHtEV6vyl1OVdPYClvxDsp4iI7aDy+gulbx+VHbyfndnvkH2RAvTKgzCqf8c9AFAPwl6IC3n1h+K3gfVfeOi6936y/QmmUzEgxdTp5P5P/s/yBO7/yh6wXeH/Qz0wz63fsQFcOf5fbfRetr5YA4g0anYjaMG3vLc1CBK1bnIDQDYZar2OwC/PbADPugrY2515Yb9+CL/+wthXPwDADmg10zoxf7bVtAhXnny/I4GV9KSIRvVERyDExMdtiUyupzE0ojoZ6IHZjLagvASMfbiy9Jc63rad/qBUCay2AUxFmNDbIyv4D0oG/ZJ6wCNV1MBfo2FYdRYiRBUxGC6K6oJRPtOY+PrKpGhKP5xos5iQABr8sLq1Iu4Fx/9OO51Wm1lHdGrELDGQkz4o0hIPg/DyACyPUeU//nfQ7F+UVExdLhP8KH8nAAoqDnHfjR2ErhM6KuNWOrkraTG5AKp/FQQEEYQOAOP1mUeBfo3LKxYCBqLy/YaXytgSyg0T3Jitxlfuu6nJxkKgbUCHjakhUBZNoA3o2H7i+L1r3BPgIFgRb3HNvYyX96UvoyVs7XYZO0FfcPQb28C6XHHDH81guRALGi+pC9aCHbLiEu10nEC1COAUaRtI8k/j6Tio1sdkXr9R3UFmEV76iRqpiMOuQj3D7J3TJ6vAwx4Q3gA9n7sGHweCI3bGhQnx0a7OvA2bS3wxNtiAH4KfdvVAy2nTfkjmgUJ/uuo+nqMo+IXTPwo+WArUsoPsz7wvIuac+pHfiMeNyq/6yrWAtv7l3jpxf+P83FBk4fpwM8xHsdJn5MeUX/Eg/mchP6uRfxYO9SsTHxfWU3gBPekB82G+i9etyycO3eISDP/hG/7wpc/LukUFFSYC3oHqVIoAmE4zHsRR8V/GHsDqj7eP6A3jlzdtADc2gL8ZEyxOIR6JB8qHESV0NcsHswPaLjIIivjeFBA/qr+ShFdsrgwGoBosgAsEFIjVH4fEtrbuB4DO8R8fscyA9qkk2Izh/tBk0C+sB/hhAGWkH2L7KRrIzW8EKLliiM7jcDTz+W5UBJYKmG3BRoKkyoBLAF2nWzA7S0bO0Hhe513WlpQtIF4f3IsZm7RqJCS3n8Zz+q9/wVPzR/7eOgWo8aAgXo8XoQYjzBKETAGDM13R24CcA2DLoBoIIvn4ExcxghZJFzl/4JdxbK6RQNCotrdN/kIxvHY6YntYMVtXZyqZ0IA476HNjEgtzC0yiwanEVyk8/hdqDVEil5Du8Z2y22MUlvbX9Mo+nWL5ZLhtH4Zk2lKm87DeXz3tF9PkU4TqSxIR4hsADWbMRAwP2I+UZcDCXIzEXxZLQJPJg/IHDP8EmACgrkT8CudIGRWbvER9o//FQr0cB7wOHsTMR89oHvwmDvZNTsG0HykGV7YDTjscimUhLkK7XfMB58t1TyeYfQJt7dOx88K3GYn/R+Aft3vuAPjI4D4W3kl0XNsBjwGIGV696svgCAax+rq233bm13vxPwBVnOxHrCw9K/0f94uXu6/C5n3ANH/UWG/o9PyE6rqSrwoKwdYDkL4pzPgth+ECb5eFAaw+xF4bACvdgfG+O97AOXB3ar/bkIwbADtYAFZMAAP15ACbB5asCmenp4QlCY8PQHwwQYgo4hL35aEo8VCRyBsADnRCZGoDtoASj8ylgT+AAti4gYbAHlBVPGdN4BsG4DHPUuz8ccvsF9ADwhvPCQUsdEnvZh+oX0x8KgZBR+FnScBKQZCdDbPqEzMBFviTtFS29C9MaO7bFh89BRuTeXCsKBz6Xi1uwOcJHanlp/NJP5izjwXtgeM/+RrMteV3i4k8Y9XxEamUKYRms69ceU2kK2gJWtO+I5X+lpnWknjdrVxFdgoFgNzAyS822ovyPwCaGgs5gl3Ar4yb3jhIQmkAIpFySi2EDSXEXSpydjeUB0qykokQJxGlRkVe/SAW4QV3ctYCMoo98gMvqb7eC1dxzdTsQpsLYEyFNOW7TCw0WqIPSAue1qYy8o9gKZcvOVDEwLuiIGpkaCQLHnUBuS72+3UFn050KsuHQY9UR3PxAH9U13A790D+uOOMK/EfWoQLGQSU3+YJscz/djkYDIlt+pPZyNhPvI34kAOS3+yfoAVAPHHybdz5McBAILdUdPxS5x8xwNwdgn3c/AfvaGD/4PPIlP6RpQfsE/XPf/g/LxBfiYJTVwa2qBxp+QzhOdfyIDH4C9s58kuwKtuvwoGIDokkuWqFPjVsPgsJaMTQGPws3ODqhMJBFQA1Hu8q8o/8w5MuP/2HLUHvH4ECvTywvcfIRv+7RdEOQECeuStrjRQWekHpxCYy9afrpP/w36Ae3VnWtmo/mgG64aiv47n5+gAeE6KVrGo+tPsQexPWcKN6r+pAVTPCGsGFuVZ/e3b8qjIP6AnxJfdA2S1mrb1bBlswyqBGlvY+XosvMiZv0+Ez+SiZ6INig0UmgQqDLXI6wVFTq4MRcu7BOzEI7rMfWN02fKsHneTDcNJYlrLOa4y5he0gR7+/K80dOsz7KWTI6LNgUkDfLzKapRTZyL5JenMdXgSyF2dIVPYBiRdjLoTUDhmGde66UWuupHGXmY6JC7pDh3ZckdA8fjdJZM8uh8hBFNTJomZJYJ1AkSZVhMVvSThjBbHDBhHS1h7ukfcpe+j+oM8mtc9YdCC4gYXhdEDSCHFHjA2AMDEBYoHIbBLdlAIQFESewhbAgUiuhI72U6nAr3MQorumEd0yGt9CrN5ulVbnxbP/4h1xCk4+JxPGftBAuh+KpClaWx9+kU1DftNxkVBRT9g6LeEHAh+wfGhw7/Gf7qbV0z03QZ/rAYVmA+Q/UZ8HzgRXJ1HA4Dmq2OO7hj8Cfrzj1JEBKu/wz7HKD6T7FVAVwtW5PSA6r9yA1hY/der8+h1AX6yYACxgNAAnsC7B/izdrPmX+1GBYLDlNHYkyp2QkDlzrcb7IAw+2P8B9Hz9dnUALePdgmgRQS6xdgAfvkbeEGtHbHAi/NWYV2XyFbiEkDVAleBq6kBvuMB44o9AK5w1w3NYKUlHOywQFZYuavKwtdYQFwCDP+pOAPQHVoGQWIKBUuTP1tDG6OYA+OoV3/wM8AX1gPCKXlYacN6/UUX7zDZljzR4DOZZrfqEl1iO9HVW/KTAu8fNzpoAYHNp+Y10LcBmVF0NvvZAJq9r/0YrwrzW6bNVud+8Ne/YNb+879DB0+JJ2dFvNijJP9M4nL6EBfR2ruCSj2NqluCsYKQ6ERkk8cK07BIahFSJ1fYd8ZLTC99vJ7HC3uMV/HlWO13IryZ3OqxBIyvGe/Rvu6kpVYCRNVc58JJDq3NQLE246WL4rziYICwsQtOBeNBBI4a13X0aYAD8ZLwLY1vZvSAS1rWigawESbCvIWsN/SAtYCMQe9g7gfEh8bvJJuUizVuL1wEbDkISfac08otU5bnKYz2iRzjg+hrXonPkP/bmv+QPTAbQD/riPlllSzkoPf6SQnkCG5j6nA/H5Do7zwfqqEqZ/+qqi3MB6TPgJzHUb4R+WUHgJ0z/pj02QNwJLgD/MGiwDKKltBh8TY+I3APXcZn/wfc/zH1l2ih3VHz1ao/3rP6L6fqv/n4vzouZCoBkX8uFs4u/g/+0Y/ruj2L4MnIAwDpSSjr+6s4oHzjyP8q+wdB/zwISyY29oO//YyWoBe7mcFp9s8mBZAREHoADtQwgLvOHrA+HoGhCcD4j4CwBRaIPAPEaITrjcDB1mgFyjaAQA03hDBvuHocgacYOIvLYHaCY9Aqf1w1wBfcA47DwJINfIkSi6ajDRCLJUNv/LMFA2YJBi3JTBtnbjFZJjSsXWGCDLYMoECB5OHgT9La0mycgxVEvfbvJcx/6Eh7uLGG63Q8Y37HCDP+++nfPQqhqUOZXkzEQNqcchvgJyTxBXN+laag619JOrmsa+SoldV5aIwcMNHAHdzQ9GJEUkzclLvnF7zI04U5BKP6c8Ia49hyw1eOV2beSSFV+diJr9QjNzF43AJhM5Qb2XMUngoqAw9GTa8Iku3lBt+V0RvSK3b1Uff30RXWPUOOieAfNAxciekuQfoQESEQpGBPDTope8DCRQD3PkOGhB1N5+aezMTTg3jjtPt0s+aHLPnoVqTxRPQ5ZwiYo+fUfZxdRyetcYKQlnKmwm89Af5ThPgrqT7UeDHzoAj8V7S7KAGg96B471wFdOwdD26g8fRR8UchQd2sXasA8oCB+cDarx6zv868oxnYDkcQ70ETlw7XT0W+RLLIRAAF7r9Z3V+fpP+iFcSTl35jhcaF47/4NosbxuESYP7PdD9MB9NMOsym4Ip70Ft5gQnEnTR/FPoXvYcl3I2l/3ZTMCSbxEf4tN+eLbhNDUxYU2YP0DewLt6iSARSIhgNohkFc42WWIDMMjiejB6QV/DXEtXuiU9H0qLhBqELcKumAiv0zaI/6Mr7sPTAuhxMPbAFA7gcrH4pKNCX1wOmcExWQtEuw3oZZz3rQAqyAQ2+xUbDi05LJm8vTz45LwvZiN5Kh28bg8WUA0Nry1A66UTxOCjqdYUJ+mQxT3sKYjjpQGBHVf35rygFP41X5vdEfhhi3BiR6ob+HdsAoGHcYBciC0tXIrUsJahvOLmNJumes+li5OE/ekbaI0iiKPckDvF9Itp7v+OMkXn6Kxs4o2MnyK8czRYoipNWmZ2ubsVNJtzTcaIKWqySPkWAyMrK0vMrxAphwZwVcaWAX2gfe8AWqR6o+UKiLzoBDsWR8pxkercVf1O0ARJH2QniQowoS0PB19iiNF7W9wyRQLQL8hLig/Fz0B3hHPT+j2JBdgl2SQGtBI9fimfaWHBr6O5MbQAf6r1Snc0DgR9grhefmoV8552bwW6fGpN+FPRP3ifAnHsPFH9BFsAaOr4Y5rU3tpMdhtHjn0yD/8HuPZ0zosOlx+zvJgq2BPDx8oSnx3Y1CVi++PuJ+D+hhi7khpr090LvT8pT0qqrbLfrwlQgkv4fxP4k+FNhAYS7VOGkf+f722u8/TaqPBoAegDJP+YF9BJ+/k982SFd9k4G8qbyADYLhrzwG5MMeBNtibj/hTcAW1y2Zd0gBl4X4JS0QCcIiWeOPEEREVwIBM0GUCrVYYCAcAwQF8iY2hISu7GX8EmQub6oBvDl9QC3EkJB0H1YcoEZyC1j0Wan4DV0UwSbtIfCHQP84zwroFQsXJU3qsZ4vdvpMRd00UOSd2xt0htsprf0seh2zbxGcBabjjUsnb/+DHp+/1fG2aPu43VbmvlSVIt/DVvBxXjVBEnEcSH9ELRREGmmN3Ww0wAX0EAnHsYcIUMSnQBTXsyovC1dKCLb0LHGqx2E0RV1Pz0THVoRnzl6Rl1xKoh3bAOZOtIpItV9OLQDWdayoh8sjgSelQT3oTuaAYy9ATXg0pturWAdQaHPV3Awxkqd1xogzU+7OgGAILBLtRnAFQMfybweE+khacibAWeAxPgy2wYAEXUuBCY6s4Tn4CkAxoM/s0Pj4w5wUgET4Xc6Y/RlYO4GgWFmRvW0pwj+Fc3XhwYQ8vcJKvpK93K3f3CAcLDlBrAT2EEnaLz6lg7XBID+gXouPDF20rGQGD9WT9j8BZX+anr1Xh8QrXkyDckyqOUwGLJRh/PVegDokk89XQzu374TGRQoP1S+dv5FA5BTtL2xiygAErh8OtjMltlUwWHAAQAetHiylddYqAAAE1QlXlP/S3/9jUX/N3aFFwQFjwcffwsf/wb52CFecwqQ8KttMwEaLYn65tmQK5vZSpc6xlWaLejlspAGGpEQOb518EtwCyYhAxcz+ME1TPrIBqg6BuDBeN/qjAegGLjPE1yabTYaR7j/YU2Bvp4eMA8DC+UcHgOe/McOsKTpFd2ONKdO2qReJRAHSM3jJzI6Va44acKxZjxzxmv3PgpqavvhPYZ/98R0J/6uJRx8sAgRVreQSFTS3R1GD41xD88fUFjHNvDjT/a96XIgwGBsADt54Qy6wUfM1Ihup4uRVRktoNhViXqkfaKiOFCPAw3cQntSEL07OwEEO0KBysq6r1MBXCX6+EjhQlAv9iqlfyQaRuR5AKbZzbKRZe91Roe0/cQisyNePGRiutK3bkXIGtpPBIVp1Pr42rENQIOJPJ2yxUB1MbrFiskMX4NVAH/TrDbAnYAjFwQFDNtBI2hJjl4o/LIG5HbQKS2YY7BDRJZFEeyofj4JPNpAHCICJpNNEEiThT0W4KP1gPNCUEVm3Y9Ns7ll+naSPmuR7ydG+H5vjHkvAT1g/LRbEM6DJQB1s7Ho4yOFDeZOpj/HahA9nbjVz/fe2dbkMxis6GeH/hOJ/1l6cnilYUdUoU8b8r+E/jPniyT6UVtRTzs3gMjUFwv/ko4s8zolNYet3X5Gws/GHSDG1N+pABilXyowbQB36wGgAJERZC4Rd4oAPv6CTXQSWOVctGTbXehBTfLSytyCjYrljfjVEzLrERJAHQA3g3TZ0nZBLAzaAK/AsIXDE2tFQecBrvaTDqDqjbN/sz3AwmFmA5hysGArp1zhvqAzwBfcAyQcG+9NOEbyjlV6fxE3Y+DY5p5lwiinFz7IxvhsKJYz1pvO46AHbwvyVkrul2qvsSQ3mFi7+Va07tWixqPzO15Uqr1QUzwYrGPVrf+HGpl/IehfguAEMEcLDbxU/WvYuAcw6wDfTxUNTebPYke6Ma3jQmp/9srfVl4F7qPCovQnIT+XsF+J/2gSvHRQRZ/DesfLD6z/ZzYDyvfHWlBlLMFrnvpBdz3BRIem9gcX8sTNYCddS5sBSYeQJqS+ULuQ6CQduSVE5h8EuvVq/A8UkREaSnTIEC7E8wD4sMySzJINcAngWpCTRBV8OZJDRFpiMt6Qpw/YP0ySU3j6/HhB8XSaX2zczoP+Y7Mu/nVgEK5Y6qo9rkACXOkbRcatJTx2Fnd1AjBbMPjTp3PU/hsigcdnx7Nq32kLDfs2VPzITmBZ2NowdvP+07/CA8f1TPg5mYoL/BHnBz3gycVfG4R+i2idV475rKHrE0UAF98DJu4v8s9qqbxC/2nz5Dd2GZzy9ju+6cZQioKDUywv8Ke7k/yz0wVo5w1gPPFAAaIA+IUe0e0VjtAf/gYvoH5Wgbl5tTUATwMez6iVZnAG97OHPcERCNHw14vBVsyESeuGSxMGxzxmHz6fmAmjO7Ao/32Ue1b/ig1gqdWYoMYUsgYgPqiUwHYH9ojgL0AO9vX0gAf9MBpAO7UBEYayT+KHSLS5jNSJhW7ymAgb8KmcSRCinUswV2eYmDHIN8sgLJpKIWAUktknct5vMB7yowKNJaLRmc8Lwfiyn/8CidlP/0rVMb/mEnypl8C4TW8BlJ3qbqbUoihLgfEygRoxH3XloCxRscGVeLqCiBkpHAubii+TsW98fOuGC61g/WMT4rEu3uNoCenOBnDDD6os5j2nYJ128koKJxWQsW945FDqiBil45sD1nQHb6ThHoDrBewheAnIfFnRpx2CHdnhYarHSpHRJzLDejeidjkJg2046WkxYqYzhWaU1BlHQ7O/5MadLk/xbBT0yQ4w/SxnuK8dNikHrjSB0qmAEbuI9tKmVhj3WxHui8tuJM4Txc+hGKTusEKlgSsAH7SKUTIZ2BuUBr/3W6Hqnb/Ux9FNdlM/Bgk46jnW7PinN+grm9cbPD6zoUCLeJ94iyB9jupPepjq+/KdrsFj5Cecgh4A9B+rAGCfSFJZl/mPwB+N/9Hd34IMFRvxHzCdOOKQbjCWgMaoL0jAyPtUJ7h7D3jVAeDFpcIfoQGeFCDbqpWeJCHYJlTHWEALMynNqVRSANFA8V6Z9fGyLNsVqQDrRV5WmCPwCqElXKDlJ7IB6mYVf/SAsuAGUDc0hkpPiLa4Fsxc4WL8hAhUv9QG8AX3gEeakMJDxBlN4cgD6fJr4yVggR4H7nCjOiOyFTaZ9O+UWVuKhzlpW7t5Vo6XHqROrSXT/mDTbUbjidmrnxkS9LLx16s5mdRkscPdzofMc9xxHhhz35//LXzHq0DBEIHvc/SGsXhcmOZR4KoYK1HgjKRqeFNJvgKSvrEizWIiZBcQKKtsMQUaKj5RftSFi0g7BIXueLzc4C43HqcrH4+PP+Gz4wWZwT3Hfbi+MqlYouI73yrFcbsh0VIXh7MPXZiYgPVFYDs7uYI0q5Dr9fhurR+kqLq/Lh2x8zwy4yQAvKjdYANJ9AeHh8imj1o/egB8L+xgntx6Lp1enm7jneKcBczP/TQWiPffuP+5KqC5RphmJN1xIeMEi9SF3BfgQMidYA8QLoTajVtSYFeQ5QPNRtADVN9l2wAeGm7C4FkF8vpV6Hk6NguR0A/RyYP3dTwk6zGftL6Sg1jRN8vPJPaOZn8JgC8CzbUEoOIvV98DAKPb+C/wR4O/qJ9Z1M/44P5PnWScDhDYI18jOEvk9uzPEYrfF5R4KQD250MTcGcPGM/J52e+KPwCrOqvOLBVzSzb38jeaGRtcD+P1WABXeEGqoMw/nY8OOGoBENoSNXFPE7jZwSV73iRr/CDa1vXAaCsBH/w1rqOwHgAsCgyvlWIpFnCTcHKl0cE+np6wANNyF4c6bju4VIstmj3wVW0TvcvgYu0wQbTMB7IUEVuu7m8oXYWfkVJyWwImmJtUhuTsnZBLg20IUrhzgV2jMyZsY57Qrms7jHXXXv1/Cs/++/hh+AObtoAiAIV0UYxLMK4ZBXszM82DyJMzemxOdjhONOyjJFk/AYFCHSNhGWFF1aGLjlkmMHBHxR/vxsiQTDvX/toAJoTQRtdSOrY8HruxIiEyRZajS46Guu9zDvqKXG3m5KvO2PK2DlkELbsP7dMYQG/w5TjjutlNO9FnpET2VAt++yVU1ns8egDexb4o9U8EQxJx6x2UowlRdano/y3ySLwYTaFEwTEBbFNRXCVhYYHiJH4SYEfVjZsbPiXIxBUuCgAE0PRj0ylKJQe4j1aezAz8Z1L0s5/0+I/Odn5ldPRJXxibRQPc2Ix5elxYIIvdFNy9jX7A/GT7EuwDx9rD0CJNCc42AJutP0xm2gw6LvY90R+okJM55HFkuka1dI7WWRsAMUsgHpVA3iN+wutIAj7iP9zZ+nnBThoS3j+JXykEXQ4R1dG/i0uRgOVjHnz0n9ViLEcrbEHgAZqbqBP7gi0jYkBGfFLXlYelkgDXXUAYCLHqlMw6P8VfNC9mj/E7ATmCdotGCC+iQf4MolAX1UP0CGeeYU2zXtqlHLigfcnSYZ11qvHqp/5stbUKJNXwUQ9a7zeBTCzkBWqb6HoCuZA02KiNspcq6JVt2ivzDKaAZ/Hoyjs7WAktn7YtI3Xw8//gTH8h59C/QFp2it9dO/cBsYesBXcI9Y9rsir7nyPawE2mAuqJ9ApeHwCW1cZswgb5NTz9UkMp2/k/BSgz+UOZW+59fyK/xe4oWMnuGk/ADrUuChkvm/81H4nXwjMdBT9RIcJDX2Nf/LhQFf9VNDOCitXVERjsFj9CtwP7lBOYEGPMj7qtABDDDSnP0NyyAZCYU4q8QtxIWB0FAcor0z3AHfu0noU3PEpML62x6OShvBJtnD3c3FzbMv1gKAJd8+RaFb0x5CfzGuPTCGxxHQ8LwbsYFLhdA9FHhWC+pqmoKLqW0ebgrNH5doj3G9jMq/uMRtTHoHSGxgNcbOwl8zZP3H2j/R9y5s5P6PHmyjMEP/t4iuCH43HQrbQiD9ng/5zcqCvm6NUF/5z50ZY6E7q1E9W9rjrFPxsLCC96SqgHiAC6PPPhwY4eW/TAWBlY1tlYUQh2LIqv4zgjwwhmF92uXTuAXAGJZYVt0VaMEBAC21FyTVGA+B7dgI2AKBAdallERMU+E91MXBbTndgY4KGw/DcfKG/OCLQV9UDnCZUQPolW9QOA07nRqmPNICQh2iinSezx7CML1APM9NEE7RdC9ADIm0SorzARvUpCDvJNJJDAOSYjFq+TYIpEOks+PJuakY7CWhf2U8j56yPHXPTL3/hBj1Kxk/cA8Jc/3kMaHGTr4xWBHoQCRHKzdKroKpF4fSAjugp9tHsppERlokOFTKhpdLagm4A+x3UnZ2gwaj7lViBbsjWGPZO4hBOfLDV2AH47pVA7XhM3KlXCyzT4yaqeH+03umHkEKMWmMcATQj6c4PKqO2JII8u7IzM+mamcM9q1Jnz8D8y79j1gxPclR3iYb6TLIfhY39x7wf7GwT/LfqQ/YF/k9w9IBgWFBXS1OwRPFdgZackR6z7ssPhAe1PhiJszX/AzuZVIGms1N+ER74nUf1d5s/ERZMBbGYz49Sc8X8kadTlN2/c0BH9UwUAcgKYnUJGCCglS6wF3Ltr0T/t27K4SUKr2M3tedV9FRqYyWVSWHiBkAK0M4esEPl2/k+7B8J+MxO8DGYSuCG0j/G/9tv1vbOPcAwqOxt6WLj/7rCC2jzPWDDBdhuAAwJ8AYADij4n3AFWlT9yZ7G82OVDqC3S9MFuG5sALoDb5VSACYHZJLyZgMQwugNIIoJWr5EItDX1gPCg42Es0VPm71AiYd/qWKfytW5/YZUtOA1VE40C2077SYMbAWphlYzGJGlMHFhQXTFx6soMtIoExca70Vzlsfh7kXQ7IMY5vXhr4zSLuHpTzgASClW9jim9RU2kLEUDlk7nt+jWyzjwY7zHa4FTeFUkAQnmeboPmIYCYmwup0uNKBuKAp1A+KPDeCCTjD6FlrXjRlkFA+PX8ISDvcA+M8UPm43ZP4J881kkXYaAEgKJLeJ+f7YDNoDl3RWOvtl9fNsOsbzbsd6ohwxVo8gr8TokjMyZOAxXuA1enz3EqekyKj+yVuCngbp7THglC1p8cumNpTNfTcZejggRgNzBN9H8oCIifvgUX0NUlJEPQ37J4HF0VHenHnDoVyZ3j6UAdLdhKTbpB6wiKfPnm3OnSfftw2VXVIAcoGOPWA1X2i6/Mvsgb5vWYHv2f5fsv2ZPywTimPFiXS1sydAu0U4lQr8eSHD+COkXvszPUGJAhU+livceFaPHvD8W/jwM5884SQCSPx7JUsvkBRZtnQXOkBsq1X/C4lMygPgHsDIMGw26UIUaKEhNFKuk8jFJKJ1TEC9QcDSmlGA6AaBBtCLGsAmIhCdeN0TlFZWZyYogej6FTSAr6QHvGGLkilCRmDP56nKXJH1Wq/Hia376w31NKXz6zDRh6hlC8BbwCYmTh8MZGgWzevWFd0yyJgkIymzvcZ3FqDoNmbNzYUFRr98oKPn2Ab+bPO+3N7xuMBbdBTZ8fy9wGQeFwIKCPAFcIzY0AmwohAawrefbfbtPuKCywFcKMoXOkoRtgJDaLQMSlCQAfZZ+JIePeB+YSfYcNeNV2wGiJQhX2i8AUTyGRANYOdtoDh9SJCIGKW7l7z+SCXqJ3bpcZ89oUZGrOo6s099XLWtwO5zzGs8oBLKiGdTt5j6+V/yvtOTSy78D1Zz7+zT2TW3MDqOYaZVnDijygvldKzfyLNwPIQp/leuv4PwnB97Z5q+DnrQFzf3T3YR7bR4A1zOXLlMrpfU4JkqEMXJbazyiauAkztHS6DF27XTa5ZX4iUq75eGz3Tl4OwC2k96wMys24H8wwx6DhCNT4mGeHpMCbtuv2T631/j/ozH9stn8D4RGPBCCdgvlMvUY9fRP1l0EUBWBA11AKsCYZQFPyb9J0gZlqtSYvrlkrgiRNJe07rmsdDkTEUYAyt4E6MbaNcNYGljA2hA/9EAwALaiP9sTVJhbABLMDJ2NthRlOQQJxN0L18wEejr7AFntmintQNBoUYLNPd8F6DbwnR9wLxZNDvalbjbSOIJVLgNIHfMeKJMNeSTtcmqkymMrROvSCKPMjpjT+buMB43xgJjNueouLMIzfIxDRjGS+Xn/w+L8w//Fq6Ie0VXGO+XsRBUVOdtvPDG+FNJH6IAR7yOUedgJIpUC7YxjIcEbqeGwDHl8XWZvFmsDgtl1ASImC/Iyr7TiYw7AW4DO9DbzKmfsX8AhRrJQs0PgIkmEzQzoP/ozp7BtzZ96CRx8on4rC87SmH3nSw8nECPi8LUdR9ITj8zZDwyoLcUZ4CofgKz1h+K2hRmWHA7DOBO1IF6OhlMXfgjn7Rrp5wnhGZCkIcS3z+5OpxaXTjp1YMIndOE+Eg1dxfYzRqAWXlL+rcCz9EesFxs5J/8n8UOAAicyFdDfrKLBpYs0if+8JQt8MvFFSeTKDJ/uAGQKnbnkwHVn8sisZ3dFQA3VH+cha0BUBSGlsCcgNEJfvsrnupGAI2HCCAqv5494Mq/KYr+iif5dVqWXsbUz4+Q/HPdovkCXSJDxIQCjR0A3uTRbEZWhmzoBjBKPPXABRBQIwd0bACNG0BrcgQ6HQCmK5ySYYK9L/XraQBfVQ8QTUjbQJcYtB8zYNeJUAri1i2lvho0tMyvWR6gAzkPgF/U8NQkXlEZcr6vo8Hs0UVhTDNJVBko6CwdQoQZGqtP4X87w7zm+KlTQQkffwZy+tP/Ck+FodtMs4beaLeS2igiq+gN8B3aKH/LROfHZ8dICFif6eWdofNhUgndz90Ccmj1Nf7u0D8IWxi/cfyNCtUDF8TOtB3agtFsIov+GPbHpyQaGL/E0RjulWHhfZg7Qaw7Ls+RoyL6nM4DDDK0HnASmrWz0Kx9bkB+4Oo8ltb4SSjAHFyTl/dkF4A3B2AsEd28wOUIovIdq382nGhOQcaDR8d6+O7a56r8Gdt589i/sZNVCSfL08gvtk/Q1C/QXw2AVJ9Ihcf45YUoUPTMr3QxIs3iWFDCg0hQiED/PPzmnteD8bkCJ2Te6uk7nOuaiP/QrJWoDaC9jqdErFKVP+v8CxmwfCDGEnnDDSCO2b+4889+A1Po42/h+W94qkz+TzJ6mFlOLYwC1l0a/M4nHACuV2N/ys9udU9QRgXg/YolgCYQzIXPOa0L1YYo4huwvb61toDx3agDqBIELLXYDYDnXxcDH0IwZ4KaN9zhCfqlE4G+5h5wFg0wBis9DG3dXKTj47DZyd7J/tic2aL5dJJsNOoiKAJioGNaplE68gZIS+2pwTUX9FBuA3oNZ1vYEX514zS6k8CSUftuCQdVSyKrB0gyPnX/GH6+h/u/hB/+jCq88PJW9ggtMdPA9z1ue0cGAOlDGYGnGOsgKiY6lNgSIHRbaZu82EZkRYfdCKsDhyQeim1sT+IOjd9VVO57uo49wPhCkYtCu1sPyN9hF4mcCiPFBPHWBQrFu0FDYhBNmKjzcgB6a3WdgW8G8bQfvFWfhc+N0v2xAZyuqZ8JCoufN4vrfjzo/ROc5mS7f6BY4Xdq/X/xXzyoUOcPqtx35tN1CXqTO/wQ6w/LQfm3w6/5fxACIlVmmRDQCQiyVYA+UcuFk/6FvN4tTLpndk5Rpu+s1eIzWKdbTgXxP9wN/yl8GiCv5t55/o3lORQ1gBdLBCsY//mY7CA1gNEVnn/FWtDqXEmDhw24+QTxHyWR0Qe04z0PAKr7cv5heD3MQWkQFDdegCEZQ0YFDCFoUE4aqPRfAnawBGxNCgBvAFUNAAbROgIbEYhzwXEEDuZb+zVIAb6JHjC3AbaBFqPQ4qNoeKntVv35pCzdJMS5xu6QvSnhkxwH8ESAihXPYiUVFqS2g7mTtDJmnohbAg6lXV7Mim5QUmwZfJZ9IWLeHRQ6x+x5WYGO7D/HDNX/9O/hieP/ShFm5dtCuAZ8PvoKrHT4Ga/zKtooNWVLVRpCkAF1ysS0U5gm2OTMaDuKmH/XrrEd3xIfwz+voriXHTeAwk4wXeAbsSO9NTaMUejvN2wn/W5RZXggx6Hd9gDxCCO7VGMbiOoQwYH17t73wfaGM3bylj8Tfn8A75/DXkL458p4/4erffxcv+GzLTrSbS81oXSTZ+jv83n2F9STnf8jzIcc+cgSKaA/LUxxWXu62OHXCPUiBa1dANFKzygRftJh9E/0kpR/M8H1fXTKvgT9BxjYiQiAW24j8gOvWaBAvRDqKegB1AG8EPx5BtWYVwE8eOb4X14P9F/JrJLZY3HJRgSSHTQ3gK5USNB7ntAMrtP9DXZA6cIAy3VjGgy0bDb+8wyM/ZfyH7WBrY8XHjcADPs7LeGKsgG2Xo0FpB7wCAHlhwYQUylfYQP4OnuAOFtTO0ZNYzoPjzJas4UgmU9DsPxJPAXQDyrDrIDx7E4EYGKRkiphx5zieEII9yfpJ/FIgG2S24D8GvMEYcZrCjoGDtqePDEKaNXxoHpsiRtLjO/q9Ve8cn74t/D9v0AxwIxAXQgwgG87Cn1hOitEAzui6secvhQC9KyzqRnUM2qEcjJidE5kdMJkN7F0Gb1r4ZF5hXh1/BY84TeIgOACxE6AK/EeYQOw96geQMiI73tyrshYHeBudsdtQB9BDyj8WVZLO+n8PmdXCP0YP2WMQx8Fw+viccx9bAb/VF3/x2nc8Z/54CnrbfJ5jq93sFu0d2VWpIn4M+It0XLViLyL/B4wjwoCQu3emNvDmm4dYovi8yRWw8S6jxJ/gbgXXoFmEN1X+jIJ+kt+XYB2Jjn675iWKNOd1R9pfEwnbtzzKqW/xdH/SvRfv7S6/2JXgULwpzAieAz+L7+AA6p/LyP/ZEu1y9Fgrszivi14W1j0V48yXreuJAPjhm7x+oQzAC5htCjHKoCyD/xfsaUWp1dXnnbHIIPzLw8ALP3eAFrBPcAhIN2BvQHIjPfUAAANcgP40qUA30oPUBvY9zEhL+c2YDRn/q3nwttOd0CdiLvllBCs8AXZTaZjg3Nl6geLEUW9SzasBO3ky4Pbl8GfgjvlTie1fjsCMe7Ur+Z5btRacEIeRrX99f+AaffDn8J3P+E+3ApIOzsvxhels97juuNlM2pxfoIbQaJrI/pUsWsh+sGiF7m5IvQ0s3TwKWbvgF+Eb0j32xU9ZvzlgCwBzEFZh8nEnbzSgn6w41wM6ipIpWxOmhkbG0bjuTjtdi6W8X1widnomDhrF4eM6JUUvTcYO7MZr8aonr4oxDPTpp1Or/GTS+w5/S2+ZWG+AZF+Dzh6U/z7m1RKN2oO6ZQt4Y2WzkhHDwinDYDDuAZWvPEc2i318+IouZw+HQKycAhyZjT1zy8YZTQSTN9Q/bs2icUTV6b7Jt1+Jm/YfzDVPH+iH2/E/W8M/u2voAgrAaaIBvoCwKc+4yQgzGd/7moAxTMgR+l//Rt+abk9wQ8AWpqJ/it8Qj6gKy/Ai1JfnkQE6pudgu0IPHoAra07kgAWRUIulIExCQCikkUHAEpFYAVBNwhqvmYP4AaABkAWEDaANjeA5bMNoLU26slX2QC+2h4wtwHChEkkBGaIHX/xboHxKizxTFYMFktPXIiyYU7Q0c4DqeRgLsSsuHiSAEjJpN3gWdRg1GPOxuCYQXZLM/1IB3LdFGwlT7gNgLZ/t/tifETDR4l8/Zk+i7fw/U+4D49JH2fYqwW0LjNGvOCPXcj6X/gYPaBYJ0ARaVQUK2c480KQTVbWzW6HYTmZvCopD6oHDnPJiBdmg1ApBkYpMOJoUgNyxhVVD+CIgFXgN9B30xjX3QQEagy4OlQsB6OLiCsV5ERNWpGKfjfmpRPw/Twb24mQM8/7p5bw9nKb/uE9ID5i9/PDrmOI6bE5eA8w/GC2ECf2SG2rPayxEHdU56jgHYE/XRPx6ulvtPnTPxPYMmRzxrXzPcZ8nXzVG0Dz1+C/kCa0UiyyWNFP+bD5dPWcg2/yL5lEXlqf2uDv70f1n/hPee5TCHZ/7lWiXxBDrQGoJYzx//lDuH3wRLNo3g/JTUCtb+kuvR7W/xe+xy/hWW3V/2IB8fR+4AEAENAFPhDrsmVkES1wxQhrYrhdN2o/gP6mC3BZ275OSTA2gIIGMD4LmKh/0w3ga+4BQYa+8GcJKZurpkChPv/uxJstbZ7P1m79gJokz5vB0wElPjo5OMiJIXt6BgoovoBbAd9o3oKM3+x57jgaL/GeogYx3FHzgSQgWEYjOGVcsXoucTsUxR/+Nzbu7/8cnn5kKLy0WmOUHnvAva90ahxT+XLDTjBGctjE34laOW8EzYAjZ6y6OtL13I3t3MPHNpxsafK4D4/fonx5mh7zgFyinX8xMFI0UOxyOOo7HCZ4GU7VloDqPhOxqNyQjWqumTwV3MVAN6VxKFabSrOU5uhtIPSTKcU8YLYHgqZFwby5H0yKaHhsGOGBRPR28k8PjSGmE60zPMz+9tOb/6yLl7zFtwF6n/Uk/31Uee0BcEjVhZYlHhxNd32IIu9TzyVqELXBbAaLQUML7fbmCQFbAsOfE435JuJ/bD5NdnhS/EaGWQqs47pGyi9OPjfFv/A9LKAxiBRW+Uqcp7AH7B4RUxgR80r0X5aCNv7nwwFU7VCzf+YNQEx/AP3O/EHo4xXa5o2h8MqJXE0EQPAHwNHoeVtK1ILBUzwT/ScK1KD2wgZA1v+Y/UcPIAGUfNBR/cdb27QBKD9ARrvxdxrAV+AG8e32gGASYso8cgynbeAI3fPqoLGSDj/7JIYktQS3CvRsEpqTpZ2wwA6rosQgRqAtDfxK5KCo7keZ+2eh/8lvxXBws94QXskfBcPIHB1AsU9Sh4m67oSNGl5/IfY62sC/hO0O+GWrXNsJrJMwChVx5akg730lFJPL8YbiUmUpilMBym42Zjr+F8nttYOZ7SQ2CVgPUSKNHtCJGNCACBW/xOL/l6L78A7UaPwt8m5wvzYACYt0BK6qOHc3nS+4JYAvpEXBOkGULTONOflzKHY3dhM3V1fwohPbcVQwDVc7kXx+9ynySWOYSuN0QvnTIeLtyVxmLTdUD6IDPtkpWJDd0tyCdWYa+lso7hoVAho3g320ByzrYfGdtQdsugdgaUiuDDCYaI2cLbg6ZK/7Nm4b2+cBuHI3p1rdskJWprv176B7/g1VXu+PHsC0iTI7wbOh/1gLbtCxY/z/FW4Q/ST+siB4flco0qvdAMzDboVIDSlmq+XUrz71r0/9KvUvGgOCIeFmsebxYFuB/SANPiNogqV/Ffkn2nV37UR+7BJQtroT+sdH7AZALZjymSij/3wD6F+NGPjb7QHeBgpmo+SXu8c2EPvBEHcYAV9JUGR+mWl3ojz6vSwwxgT35wI+GibkCD5mTXAf5bk4MrJEdzA+VzXZ3RfDB1YOj5i8aDPXOEWKKpOy16h2sBXHV/72f3B2u/4UvlPs18UiO8YqgBX7O1hAj0VhUXIkcmNgDJmvOCQsW4wEkaEk4ELQhQvR6EI+EzRMPfRlvCIA5epUlgXCx3CLq5YYHmgljbJCDqgkApnCsaab8G5KtMi3zm6kTlA5hKoM8SBJrmpVJ6Dvwu4i1cL3zUTIqYfDrYE2TsGVB/FMKm0PKbv9sz0gvcX9bcBPp34Q3YHuFNY4wR8N2qp0nfN+n25rZjpgPSAyri4qQmf1ruBHe+sBrPW2PrLiLwwFUpx6mkEu/OySojGIkhlVGewzG4AbdVjq5Lz6VvwzCf3nCSc2qEC6V38oACrPvzMHWIO/Hs8GUDn+3z6AwmDeD+eIjkQiU9Z+Y7M/L7oygejaADD1r8o0VgAkc83A+zSeKAXAecmjGdD/YYUCAGvA2PGb2JzUAOsGUFZTAhe94QAQqnNAbQNAD4h/pwGUr74BfBM94GgD8BGP8hf9ZBsQIiNwHNnB4NWANBqCaQRRl8xIlI+6dYRCvzbF3OMmxcQySLAQGcjUSkJNMiWN5j6UmFvJyYgrMz7Tuh2H7Q6dzFYoZ4t3nxj3+C37b6Hx9fndqJ7fBx0JxBBdOI+vu8ijUv9iOcCd4BrKBbB+opiAqwBvsKo7SxRRCgY4SziiOFndpnfyeJ3VhbhVkwQMmgtpwcwsSG7yYKl21X1+kCSo3dAhAUqFCFIvRh/K1XyHZhtI1TaG6KVflkfmws3NAIsKv5mqJPce0ptYm3Yy36+HUu/zV18lEbGGGj72SP5RhBT3gK4urn6pUHVYeDrir6K/+GNbBfwQqjE/q3wvR+ijonqTH4et0Gt8zgffTL9cvPTHZHFy1qIe5RNmeFqM8UnZdtfPvEn4fTtXf75/6XMJ2Fn9C5tBIwFU7+ETRxXY69+wFvRTln2a34kvLtHBLukVsAFcrAHI+0GxX6spA4D4b+KGogGk9TLKPsLmaAMXc1rBAlJSUsT4j5oOfB+FHnvAjjwAYkH8SLUNYDx34V3e2ZY1+8wGIDugb6wBfCs94GEb+AwoFCdcwIlSlRDhAvM8IO90iavGExASK3nW01suQlyYLM0LT6GxtRY6tTUU+6WlG5jKGTOKz313f1WMx6+90K6r7OR97tgGEOyegY0gnTgRBonGh5EhAQzd/or564nQ0PUplkvIT12Ob+sdHmGq+8sddA60hFfYBoyFINELKG0REQhaCDx1FgYSFI0qDxItIXoAS3JvbZJgUWFXxmxXO2O0IuAeo720b1H13ck/mYoBG/wrjxZaCOQy5OajEqzpDxFTKLj1pi4luRkclNzZP9IuSV+m4Tf2U/px+y/lZm9QoNkALKz6NNvyZqQSL5oj2jldRtQD4jR4OL1fVG1Y0M39bTEOj5E1lyP3kSW+JzsOk8mzzGj4nqeuSh8k5zg9lv7gp63uyI9wf5l+k5TVpePD7H/36k+XQB5+dQo2IGjXKjCnfkgEPCD+BdA/qr//eGeWvVxO5W8x3SnGX4fMHwuuudK4Ynsyy5ONGjduAFFkUFi/mQA4rAugf2wA/A8yYJIuet0igh7X8ZppyH9f676GUfeLUCDBQTgMUCVAEQDFwGoA4Ygc+kYbwDfUA05tIOtE/AYU0rVX9YSeAVFKr2Z+Ymai1elkXM2ZTruA/qQSTmM+583RJwoKJJzuR+cYz0l86jWF6ygcSx+l4easQb2k8z2CcJlhkFl2o1KM31Kr+YxG51DOqPoiaOhjuP65f/8TzgBjrBt/SL8ZryOhHwAFgiHolcxOBIfh/7VsoPcsRJPghIFDGifrlY7QC8/gC41R8xHD2f1UIEvOseGgYzUsWEKZQzEv5VasBumGTM2Rnx+r7wTkBWHj2SlM41+wu+NQqdFsmX3PiFIXyyyvme2SdYXuYBHtvqwNNIuH1BKTTrefz/KAUjpdff1zAhGTd4XgRE85hKdok/7RA1ZSwvwCpCqvVQCfipwDMln8nOtj8pZg1kDKUINrv87IZiCxcF5V6rWxD4LCUN3C3Jocs234k6fWN5DzY7eZO/srcP8YwCPoRv/n7N9Y5XddAmgFITVAeTF3aF6JQQ99/YA3qR31g0oz3Ibf6qrmt9EE9AnP8G0To8lDgOlnt1H3u3oP2LZERRjt7ZACn4EXYfZPaABsAVDpGLNtYRowpF69OtxP2s+o/p0Q0Hjfi8yixx6AQKJu/J8lnmJhTg2gfQs3gG+0B5xOxGAKySj4aANn45pErnSyaMoTsZAvt2gxtkk5hd3Z/mlP44lGw7KG12jVi6EDZmlxwSBGamDfl3Bfre5r4huvw9cxH3EhGK+TAnN/KIrhwcBtAPtrxfvI0jlDCNQJ7h+p1fw1XP8VrKEx7I/X9kIX6DRetBdLj0IPGLPVEx0gnnrZ0HLKhl8mWAvwtLYZGA1uYjZfPMBDZqB9XEqjoyVM6SEiwoqfkL3JXaGZ9o30f8Yh7GYhp5hJRah3Qj0zi8YhJp6XGc9btA1IK1B9trUCZ4/TnPfdrZrZlWwYThNSHi8tnd4SgoLbhHTXUSePtO2q9TOFTPeSZEXflF/psQcsloAmD7jZA7J6ajJ7HKgBkq2Dx8UIpbOL2Wm/l3hgNLV5tytrfFA4xJN0ruonUKPJsHV+Z8wvlF/3MftDvtdI+qx3Wr+9dm0AfBx2OwJHqsB6wxIAN1msAncwf26/MlOoHweS4NTPzHwbwT4LHY3Ge0bWyAcCFqdkf5rsa/SAxXwg4rI5DfTa4fyMMEj4vkABlqGfMxOILkU1kJ9Iu/9O2g+GrN1EAI1HYDUASMAqN4CWDyFYnxbkb1lA31QD+OZ6gLeBTlBI2WOx99MSHeU8SdS4yVzHTgDmRoZ5N1FXyz0gW4yYKJVsDAVK+LRnxskjMT0V7AEgssHhE6X/BV49N2K+CgOpPGsVlpJw66IVRjKF0Ayi3KSNBd+TZY6HUycYvxxz2Xj13p7D9cd+/dGSPaDgvZI2umEcW3gPyEwKQ6QwAmTQCYLM5uRGcGEP2HEkoO1uJKWja3tWG2gniqSH9tjPRRm8tJyMDN01Oj8stXErRqZKoh64NuMFdcJHyhtILhXGGZmFLOMv262jFCM1tmYtZ/zbbAzdJPSBu8rSzBq8O3coByMOVf9xxf6A/qsHSDEyJWDKyJzuGi4vsSwz7QG6HHSn4U+PkIMLTxBf8L0Ew/7GYT8S+UlK63XfUH+AfTVKhG7CLpN2nzzwpgNrl0915VHHCLhd13h5dSgJbpRyJJrdsClqqG8TBXqhFQRxf30KneDFRH/jwetHPMfGB7sbfWsUyMma35LtAKAHq0cabLSry1SBZaaAqe4rxBjgD7j/jIq8Iv5l48EArM81MQsyQgYADihFACj93FWl8mUMpO0BBQeAjjawBHBDuQHwBmCBwEH8B94AzALmW9EBvPeAcxuAihhP1Hx4CsncxTGizA/H7sSKSBpF78dHMOfrhdkp/urmKtIB/bCYxwLSaCw0FEINizv/UMYBp1Fe792fhBj/u6so0QBG+WYFKV5zocZqMp7mMhFN2BzaA8l1vFxf/xL2X8L9X8P1+7D9CMyn3cDfB838FvZLXG+YxeD5PIYvPma8MPcAOtG3C5mL7AThyjCyzWjsQUwKBni1pAdHAMOxTdmZBRrjbugEky+LITnVOSraD5bxZxGA7boDN0N+Ak35KxsDkt9K6gpaq/ypyHapY1FAP6AjIP5p6hHYGf29hCHMl/68mXOKR6qMktODkz4zm0GOYg+A79v5LzWaY41GBk2zKySzf/Ae0KdQi32dLlNLkIhE032O1gCyu5QL4ifrtKd4uFdNiqdRoVw4rWQIh93Ex+1ifMZdiY+Y+rs5/vMUTEJnecFa0F7MAqjfIkRetAbCV+I9Dvv1Y/j4Ae8Pq9foIawCrBZvXZungPGULTvr7WpWpkoru2AWYTYk3YEg+7rC+XmlDRzuwOPZuK5wfgAElHmCE/0/gwAqaweg/1mlP0gFRiwIKFAl/sPZf3wkiAY6TSDs/bSDxoNa67fZAL7RHhDcTAL8F3MYbWwD3ThC2gaclNmc69xsWgQS2y10MqYl9aqEuWQZNBISZBQxMIhgxbBjG8BpjCyWpd/XBgnV0l8AvMBvJ9AVElfBG0WeW0/GDIn6AzIT6hMJHruCCoqn186grm5Hgvof4T7W7T9jJ1h+AE1otJmNwfHj9Q/H+SeYqdSbRUqNfhD4Qq3XSAPq0TYiaKM7oNe045vZScIe3w/RNHAxGNLJnYBvNZjZapzTNJEitkx+dyQUJSVldqH5UUI9BEg2xqy3w090bQb6i/S5UCuAAzAassnW1hpeu4V/QZRdLTrBfyBsy733/rsHYb0GpM2g13e4cLYt0fCfyQcNHuerU01w+WvKBzWzR/8lxk0sT4uFpDv0nwzb0d7A3xgd4ennE3SMD8nHB4n5dOzF/4+LlLR1An+aC7Ph9srqT+OH2FH3AfqXVwuBkRVoI+UfmM/dAB90hTu6yO0jxv/ygbSiE+8zOvhj/ri6aZPeusrNFDwf0P8p7zJTa7mBLroEXCPqvoTBl7QtkU0iZZgmpcwQmJy2jNdWxnMRJhAAf6j/Gm8JYz4bQN1XU/8W4ULGEdIdOPTDCCgeqZDRc8CjzOC+zQbw7faAMM0kzGE0sQ0E5QqHAyOK5lXAlMbgEBDZ1uZ/VYOyx2LPTormFTjguAu3wXWUN5i3jVqpNMqQS5N1hF5FY1C7GVkwMtoFCEy6+2CFu1eMdGkWBFFmXFc2Yr6G63iSR4E/KkuvX8P2p3D9U9i+w8t4oZx4IS8osgeMF+TOEJLxqfrEkGH+cnQLzLNXolUXNIxoTPYue8sg7XSWyqxLLdXdE78Fw4seYOvEn3v3A6bwa0XfKNutshHXaQ2Ef5bgBkFgHDUNvDF44uN4u3ZkvCvFzZIJnBe0eF9sTpX51AaiBWPlquKv/OZ17xlvJZ4kAhSPm36CHQ5u4fF0KYlGpnLpgPjEPXq5ZzOIyVUF4hhPNa/AKKE9Ru6cC02wg0eVT0ad2mkGFzvoj5mAqhF5ejdSA0bRR2PgAaCR31lupgTWmVddoXn1H80VneAjZF/3D5Z7PEUxcdIBsp2yFymWxXO7mA8EgotX2H9uV0uxX2ccGKCheLlGRkVC/7XluKyckRgCgxUAugdYKDEXjvyEBlwSXtB1DSz03AAoAN7p/7Oz7lsD8OrfTyYQ8wgsyT8bQP22G8A33QN8Gxg7c1fsDMt+f5QUxemn08bnCzCf1hkWw5ctaJSgxFissB3qsg1wowHgVyvLVkotF6G9GUqyNFrQ+M1JxPw7ot5FDYx0B9tfsQSM0Xt5hYvkguQmfKTApt884IIsSJ0z05uZADd3HBofGa/k/RkM7uuf0QlwFuYekJ9Y92eI/BXHwPTK4zDiBi2fZHw8TKuyCw/FOA+Y6VByAVSQX2+2OqiTm9k0pdMBNtn2NPmL+pEn1mjKvvCBBw0wQCQsB9H0wDCxiLz0ZreTi/5Xrt1QIxVNxYjpiGIIdmMUpQ/++q/StG3U0pz8/sOCoXj65I+7/dvakaDSnSCRmjlvwvZbKB3PiqQ2HInabx/2Ddtxfw61JbkHPmwq7VjymsVSmlrbvDQU3WyufHi6iesZdzUA3ns5+ENq9+omELPu6z0JP+oNMgYHHPQh3H/jCeoN6z+Zhjz7E8B6AJ+0Gv83pVfylxstH1aF2m/WBlD9L8x/xx7QtzWNog/Nc0roBGT/jA7AG8ACE64uF2gi+5Uie159UesFAanu8wDQCvlCuBZYInwM+cT/MTdHBUOWvXyVdtDvPeCf+29uA6YJ5TxmZifKFTAFmeRlkySKpxKsNvE1BgFFY4oCbVSuWJSODK6Ge+JXxlRLbn0tfU90mBkLRJOX3D1BkxBPxHBsCRmvT2Lx/Ai3AWV1mdEbtwFQSI0Jfvhrzn5WX8LzDXSOC3eCMe/jMrwS+r8gLhgZ8XYk6KMxgJikDeAmUTH7hHrAaACbHmAvlyaWWn33oSPg05wmq/2gnS0LCBBJgTen3WjrSxeNZ2HVM3ETAbgF7tZoAA06NfsgWKE88ORu+onwRifMXKhajyf6pzoBkb6yF2L9DYL7hMtTeN6KMweA7JCXBISZKRWSkKdwNIDEvWHxe8niqmP7YSSBjsZbzf3YS5L75ckrKdPCj+qHflB9Kp4DgURPgj/w59DjJnLwq6NALxRhcCcoZH/2mwWC4iTAW3FjG7jd6Fj+G30jwlH9QzyO1RJPRCb9MtaGUz9HhMysgnV1tddKkcoJC6I/KKs/xv+A1N8tsYXg/AsGELD/VWRqoJBB4zzwH8D6gHqy8B+Ue0BAGQvBvumzraoBHBCQl/7sQWDWANBS3xvAew84twFtA9TyslKjvtNLrXNRd/8ZvjZ5AeaVuHXJx3aCDBzwEvEDFI+CGzL4QIkG/Fgg1nWvGAgLoHz0gxaXOvpDxTGtj+Ug3Hu5jTG875s7iN2BtFZqyuo0DxBzY1T/lY7NiylspasyyLgexBi1hPIRr/yxEyw/gkK6/YC6H+Ee0Z05CuFYfaKd2ZWv+Ssjq9QD+Fm8MC90tcQ3HIOM77cuvSvK/eoxfIux6RuTlufZoMdHVmY4coOjx5lIlKENXatF07rgWL8+IuJ/bJ6P5gawC5GlxeN+Gw8Ghb9xjv/nV//BCpsfSfgC/iWMNRS9fotHEkwqbhhOOiKCrUPMP3LeSOKD6uD0/+4HftUJixnpq0UlKJg0hHxZmW/HnRbfd3i4qu4HQEAxMOzFegBHeyFC6AEvzAJzICjeXRVMN6fx3Hj9De97OTg/5nd9ivxNJybrqgawybiUPYDssovJfbkHXIPdA3ArRt1fN12D+wbofwz+fVEA5JokBI50gBg/+LEB8MnE2V9ETwq+wj5xf24AO7/AssDIsTMIaJ5/RQBNmv31NxsbwNeUCfzeA/4b/tMTAlEUKVoUsUVRxikgALbRjBpE5DrOi7Hs9zHYLXzRiDKi3Hr7Iwu5R7CZpo0QIgeoIEMzSGMz2EcZxUJwz9GGfZOP4c/diYjuKxResJxjkY07csQkBGueSJP40kWxmNYT7dgJwMh84Tz4a1h/1J2g00MC1QHz/taJPgEswkZyYwe6eg+4MMx2wkSrWZ6JOESkiJ2A+0HwtaBbQjrSF7rnvIdk1pJnv/7kgHij36T/rL0rdBuWW//kvNusN9Q+iVuon1JYT7fYojr7SRpM9Q8+sZfUdHw/O6sI+4E9G/L8PuPp2/Dqro3HgzvtKZBOd91j2Gd7Tl73gwm7oFNNU3FdDfAJu3o8JXXjr3Enm/bGdfAeO+s+JHia7vWRm1X/9qKbMBNgeC3o5AgVPgDo/wvEAf3E+Ynnu3SyS3g85RsrsIwQUFRiZbIMS2d8qjdcuRmgPSTaRMeVEBAlYIj8WtaMEGDSf5jNARYQnytrF6UHAw6hHtJ++o5mgB6wqyVk++z5AuwOEAf4c1KB8RBY3xvAew/4fBsYz49pK+RtoJkzAKdBPx1F9QPShzKIeCIL4VSQQefjzYB4MJ6OPYP6QWbomPgLAoiBd8IwmizDMc2M+brmPWPU2lp6TXlrN24A7Q73GBhzvjI9ZrxuweaEw8SY4xDdxSNZVMgxSz+cqJlabPzLysLUTmm9dGUYReH+AfKx9YewfR/W79AJxqu6EPPJL44CsdznuQfI2n6zrjDWiEBlWWAP4FUDeWRRMa4eldV5lgOVKEVlafEV2u2MnD6TEd+8nh7jcjxtCWeLNzP7ti9cfOSf/2WyfdbZCX7v2c/MtKdP10RnB4XDFhrfTOVfoj+iSekQ0vlfxCXK3blbNdgZPxHUEg8qVrd1Owdt0uQnTtM9kT5luXqH0Bcl/t6DLsCj9MvzeXyNPTCcB/oA3AOi0oD1S9yKPlA3cMb905GaZ1ffaM5FOgDoDsyTr2UYXIzzww1VNg94Q84lrgKXxB7A+N+lI/hlbAC5ofqT+qMEmKSbEtW/UZbObfX6Pl407AGc+luxNqCnPtoAN4BOGTD1LClMAuhUgYVv0QfivQf80/9NP4kMqzacJ9kGutHy4jwMNO3/ugwHgkKkmNYodKjx48SFxnOSbUB8IRAOx0APqIRS5PGcL3gJtFG+KSfOkJeNfnBHWOCYde43vuruIHdmxrZA9kUZzk6kCCwJugztvBb0IyCeQ6xUzp5cHx5ZpGNsHH/+/lu4PYXLD9QTXHEeQPW/WT8AQPRKYApnZO4BCjC54P+VZvXfbA8oVBp3at+6X7n52uwSvrXsl+RkE1tL2qMcdmdLaOkYmUN8UPbWk9A3h+PMK6hHit8SjyVgYjUigOZTX1k+RxP67Atj/gmzi+TfexYF46fqZ28uT90G/24sA4Uq46AkkmttlqEWPUQByQqAfXp3e+dAe2fvAd0IoL4HdOJCtPRhYIMaA6/BFgxwwxco+b38xq85+TwHN3tQQ1Xy6ET8p5XpmmlCdTEaqAmAvQdkAv2IANt63tLKr9wYcbOA+5/4OOZ8GbMW0J+sxFW4YFMgQTmibQDsAaz44v+gBxTyfwq/AE/9rA1AF+Bw6ABSPFOA+KAhD7K+N4D3HvD32wC5QrwSd0sQMC1xd4V+Y+UnzoNiw/skegDfsBOQLATyD4l/4DUECoHo9oBDQCyd2pcIEKemBReCMaVAR0bv5QXcB5JE5RtMKme8MV1gY0zjgqyupEPfnbLe1cPc6QrQxdokjHCIXSe1/HwqYAupH8Lt57D8EBJ3AqwFo3s9Qdhsl4mL7wEXawMTF7LQq9U+klYE+UVPSdTFGPOZWXV1Xvuogk70cHTOnl2PGcssV4bgcLzWKtdChfAJgh/CZ0Ce5RH3lx3q/ukl4O+9KvLvcsuO76L56eLQb09mZ42C+EVhis1WsdjMRC+6q3Nk5HLYrQfY8R86r278H4Uz3wj33eT92e3jt8jS348NgM4QZuL9G6p/e4YLkN2KwlH6wwz7pbW1UjBzNCe7fDHSGur+AvBnEZ+Y/J+VMuBlM/LPtnYqANAMMmmg1gPM+AFngAwD0PH0ogCYxuVkGXNhJMOHt19W+dED7nT72YH/tPGRPVP6S4zI+T98rr+VgM0e8M4Bfe8B/9x/kzN6JguxDXRZPXNq5Suouo6TxgJwJO/72AMalMPEhcYznIfRuGCo66KNgv2TUhqTH8ReUMGQPGqqpzz6Qaw5jzW3owGMitmXe0t3kOLgJHoP9B8FYTRh7kZvMHNmXo8FDakKIM0xH+6bZj+XDiJpcJ8ZiMtoDxn/Fu5PYf1TyN/17TtbBcZruMLzC1mtna/8pNI/e8By7gHgDiXq+fWpJIkPqaX4IfBaACFn6oKJup8NmtHt4+wHUbeVHO7U+6pfdGf01xP3dOH4/6AEjm/bwMr3sw3sn3zqs1W++kul+p1FgFZrRmylqZKN+RmBcF0kgqJfQsHb1X1l6pCd2SlzJCyFRYM/bf15+OUNACrfqH9KrgIwE4SixPYAmCndTPBlRkCs+FwUkO7QXm3wHz0e54F26p4q+vGAgDBzMPArkPW7zmgzFndTA6xd6t+0me/betUXIPh+xbE32nJwgSqYwb9ItF8WigBg/zlK/mgLijdm9YdPYRb708BN+r6NlwHklFgFsg4AQZTQylFCDaBNVvJkY8lO6Z0C9N4D/jvIQphWklIH0rTwN5Ew1JkM2LLjpT1oIozgfhdMPiYJrZQEmegknrU7mYUlmSd97Q0J9SwzLY63khoOBxUZNWsiGosXeSRLIlI90PxsizRHvhzgTnqL4kqAMLoLLqEVKJkkuhOoE8R6WJBOjoqtBb8B8b//GNKPpHko3RDofxfyw+qgRJouYwlrAzgVkM89l4PREVlBmPMBNlHkKs8LQZSXOztB73kew8fL3DYDB4twBu86Evj76oaZ/eT23E7e+T0e9W7340E94/Xx2Abi6QuW07EhnB2lXHtRu6nGmxFYxVK1GT/6sjX+0SV+xiROVVfiWrBbTAK5/E3zPuMWPKQTh18dAFjK5fZchQXtdg8A6M9PyQeCpT8K7od4UJafz5j9LdwxHLN/CJZzSW8Ud7NYyaNkD0jrvPqa3+fCA8CymfFDctmXbgPrBeCP8oFR/ReeizfM/hnub0neDwnEf1yWIwO45T0SIQCG9JfwDpCfA//Z2QAcEeKWkA/+jxoA5fgnC6DzBRgv5PcL8HsP+G8lCwUmvlhIE3VOzUVEJh8TLpToJb2zbhWi1MlhDiLViXp7+IHV1iEq9sCWsSEg/C6UttJZDGjsXsQKjXfYShduADgUX6Adgx0Q/UELH6ND6AbIDcAuitWwcKmKms6P0e6QllZ2DlNr9Asba8FfuRb8EPKPsHfPvBb0TTO+R59vRwNgEC6n+wMg6kYcYng6MaKOgg76kN2Nu2nNPOk+edRrsmjGKTWwa8H5kpx4njfSqN1tLXs4xn669/b4Fgog9xfD8cV4O1HsnfLYA5Y+KT3s/C261LkL/Ikea1NpZG1qXnhcw/taoe2Rbqn47aXLP1VuH3CW4vjPrM0eig3+XbFrlIJj5Gcgc79NRIgsoD1MjIiPgfwo2L1/5JcdgXnWAKL7Y8/84eDVX05HQH4WM/0XCjSGj4WFHtV/pfnggfwwrUjlnmkBpP1ERdszPAC3XzQAyOcXTkBLJATEVTGHCexI6lVAgIPPz070nx5wrP6EgIrkAhofssGI/UwBMvDnnQL03gP+e8lCpysxi7WfB+wYYM85A4XQABqrv5HIG+cU4UK9WElb+KRt9IZGP6hYjpnD0hPGHvSHDLPrOPrBnjAqjvaxygBuNAkkwMxrQaXdtLB7qb2KTBwLfKTxf6CbmHyqMT91DpVKsY8u0Yq+CoTTWjD61wf4xsT/DPv3vBZ8zwnx4nfgTPxnOa4CTCPAN9N5ElBjUA/ATYQdQgdGRNY89oBoOwHHu4U0TYLU4aQ4U1cosz1w4VI/2P2w3ObU7mz9OtmaJ9/NlaieLol3riL4B65e/adRj2c2mACtkShAAbM0I1ksfr4fM37utg20YuamXWHIu+l7De4X9ZOzfC8WtGlJyyzrkd7aVYmPvAnz411XAVE/Oy//DAAwx//+SPQ8B6IlJ/xY3Ve8pcecKdZGdm9jis+bJRiLCISafgUQRJQfywFsHjj1Z6H/K7lAQP8z8y9R+vMq5Vdi+mNOUk9zA4iVu+H4N56336qrr9X9DuhfHyc1qOXjADAbgHFAo3NAg5TA7xfg9x7wf/NKbPzvZnYIhkGwGiXDJuAq0Srk7uPxqMRqAwC5sz0YT+K8I++xUSyQxkuhUGNQx0u0wpi6AibGq7RhA9h7XloqEazQmscMnlHc4TeXxnJAyhD0vQQBspSZ4JL2wOUgER8IpIRWOg2oTyzCKCgdUDTj4Urd3KdMd04yU8PfGH7wHd6wHHxns2Tz2+8o943NoLLid14IOoHmzkVft+LqgbrjN2Z+qi/OJlpo1Jx7P/eD2QYypRZy8vbGEHhSmeKDSMKquoJSbcbjNR0LwRnuj34JOOj+7VAvTzrpTKhfqfyIMiHy0IJGEUZ2qbbMfHJzcqcFYVqtD34H7nWC/nbyNQHwJP/s5gMaBfXwVtzuVvotDZiO/11wf30o/XIhDRJbzCUgG9fT2gCjLALD7tfVPJ/hA0otyLKpHygEuJsd0EVwUM80+6QcDPZw6AFLWqn7Ze47ewAo/2AA4SFoEgBwcKapKug8ABjgswSD/mX9v2AnKCIIndB/yEwWr/jpYQN4vwC/94D/F1fiGJ0qyiAaPwN4KPGEqAl4ylOI0gHojzuxbeaNiUgqLSa9WCrN4hkTg+dxjXyDbL5VJZHVDKd86AlKhQE9DKjJKB0jGzOhxqQG2edYqUsw47mbcmyIR5ew34lmFQeCZD668wYhX34pUcVqzzbknjN28I64RPsQyl9C+g5vaAlPwSihsPU1yZgl6G4+4LPiGBx0Yo4W1f3FAu6DGb2Y8Dj42JcMI+KFPuoHaY0h6fRudpAntUE8QPCeTSB2Zg9NOfHsASr35x6whKMZMC6tS63WHPDRHmCGbtVIPoEm2JVjfpwXYAa9RXd6aFWzf9djDv7+wf1oANoM7Fa8m4AAqm9N/S+n0h8OhVfwpDPrAdmc7EDFzxJw8K4j6S/PNujKm3N+nBIq/AegP6094W6ryBcCPkB+NnJ+tgi3B7UBjv0JGCq7AGk/lM6MUr4iiLWK+08aqJf+yFVgzP5jDwgEhUKj+fOE/u0CnHhGPrM/jwNAoAb4/QL83gP+b12Jx05wZNMHPxT73NUFOjQ2gJTkKgFF2HjiLoCG4Hw/FgK+taVIOMtpmQnCeN0UljGCxEm3YiqpEr44Zfgpp9LznvPa7CowGsSOjRmqA1oFlA2dYLyY651xMfKK2dES+gYYIbASjf/nSrAiF8tzBzmdEyIAKPoTiEsqxONw5CeiIh0T/ke/sr4/sRNcKTC+2KTZGI9uiFAGQCQMOhACku+YtAL0BjZEwjhCj7iQ9QBxQOZ5INsVBkuDl37Z9ZgfUTJBb/YLgeIBtBnoH5H1mQ6jcyHwv288ZdHMzJYo4zZd/93+ujPTOHjCZVDyJT9SSiTu33WbsWjM4tLfOekTrLPGcJekg8R/flnjxgDSl6d99Zuz+11N3SfmE3h7yu7gNPON5Xe9muuDsLuEQCXd/OEV2J31v8xjAHvAohQwlvvx/gr7EPSA0RiAAi1RPudM/eLkDx/10QoWbAAGtmH2BwfADwBCe4JgHx/8+67DwBhnyP/hBTg286eNim5QAyCfKZ4OAO8SsPce8P8GFxpP0oW4kDHAu91WdSQIDlHXKRqgqZhOBRrDPJXM8Gw2BjYDwB9wl5fCaVT3MadiEIpwkxizP0ZNjFZbSXcUPlAw9zoeF2qJRwMYkz6ix+7NzBs2FJTxMm53WFAALtjMd6yskdWH14I97OwHyq3MPDjbxdj1xsaBeWO6NrPLd8qOEtmi7ATpGtYnUIaaMjUzlQ2LlfJAFCi686gUAyrxdfWK718sJUG1DPDjSqw/R/eAmh71xmQNFV3ihdyd1oJ2ogM1H/+z+Fv+9zJGEBNvlunxQAuHpZm3D/cAdQKTZEfPOg7G/Ak7yT9ZjWEnW1Q5mjselGI5mq2a/3PclaPJEOBiVj+jiwfavQVPaT54TU5yUvak8X2z+wySd7u4yY9k20r6jasYB4i2Xi7GAe1EdZaLGQEtuArAI4TB7ilf7FSwrDJ6CzR76HR7SCD9g/vJ6AQYzGYLfmlcAhj9CEIYxnzkrkLWWHT7xTLYzQoiRzphYUs4Zn/V/UkBcv+fqQF+x3/ee8D/IC4084adM8onZZOzXOphhtKmBsKocKHxkigxZ2XG94XcBuhEGc83ij3ixneKBzABjg9VapZBFc1QFmAn2Fq+t8a5bNnDnZoARM3ce74hCqbczRGs0lIYMuMbDGcqmeb5KpMZbACBFJTqhgQQLa/0nHCkm9bMFgLc+kMDOGAiWV2OP+2ZbM4cbleCRas5UZsHEUf7iiyarnXh3AP2eDwOzgBMgtBYyOr5OKw517O9AoNfbFEIFgFWfCfQ47O+TMVzugkpgTKfDyEtTGtr3QOSpdhj5Iye2x6d9KkzQGlW/Y9rcLXUB33QHvMHPp4RhRGbsotoRH6aCD/c3vpzmM5xx0F72le4M9FMdDmybpRjHC3gdzo92JkXSxh//qT3ZA9+CTR4EBDEct9x/r2i6G+rrr7eAzKfeEtcafYD+Gc8hPBr4QKLf0IIgOmegoZfljZmHRZ69ACxfXZngpLOjAZgGQB5Uj+5Lmc7APRJ/jk84N4VAO894H8GF4KXfc6HuZB0Qj1YCKUN/m0GaxHDZgYj7sCoaj2TqI/AXKgN8FzPEE3FpaTI5gHDB6iKoXyCUKCikrVKtxmMnWm8rDC893pFMBl4/QURYOU6toG2sAcUKkUrj8b53vkRTJeJDWC/WT2KZKDPICrNpAunTvMireZOmrvZGodP/CfmiiDfG9hY/sp+IIshng06T46dhNGyGC5hxWsJiqiclnMpH6fgnhmuOav84hUQSW62HMR0MmzjdSZGV5PNqFCvoccw7XLfdtoDstxJmz22v11VNCYbwOkGkLkuKMUhifbjETfy+4xu7GoJMDW4HxwSN4v5P5udZ3+1829oD0D/PHiESfPPh6d/8tk/eC5pMuMmLnaraTiy+LuLJz465T9w8MeWIDfQaQnHiEdM/QuXhpVRX2ATwedzVP28EPeHCQojXxD7JdxGs/+YWeb4j7uu0J7IIzA+WLKdgoH/LBr/44P9g4nIPb/S+D9qAKMZ1/pOAH3vAf8T/42nHc4DHQioUqw8o66ZqZwuBM0GNgoLzDkTwqFGnAIk0Z2Tzt7JOyK6zEty0jZAXIgNAH7G42WGHLKxUlRkWKZaAS411v4+HkBklEnpW1LZgA7R9mfsLiACVYVMbSQmwjkS3g9tt0PlKED5Pv7/+Mi+G3s9eP1qvBZ0DsJytunpiLSN/URFbw94EarhK+pa+0DEZqW2GY6SdjHu7kfWzUwiTGXAPAWbr386vWVHQjzcSr/lYTqeDYCSKH2/1a09w2MPmDtB9PMvgJ15GDC2KU2kTilm8/yr1hid89P8s73ZEVj00MxjDLi5d/4Mxf0H1GOnmn5Gs89+09PUwSf9vrjJT7TGmeyi7pnGq4X98vwOnZdKP+V+gO9R093mIXLwj9vMgo+a91dARnicgYEmRb0D8AH2Y5ov7ACRMl2ovST7ZieoTH8E9J+inD4rja5KajvxH6JAskGPJIniN1b+CW3yPsX/MfuHwwIa+A8UYO/4z3sP+J/FhZBLzOQjd8EPD4diFvTGA1+EGFiuEokzKnCWHUsAFgI0BuzIK8LogZbmwvsmXwmj3qcC0zW6ztFBZsxcyClO8qDukBHkEvfa17Xt1XAhwEEl5r1l0sl3mosl0ksSBn+sBY3MUfORv4FTlO4GUtfdKIl0s+HpuDp9qFtdk/nBNEIwF4ozWDT7gUfJw9Ho1/ETkTsNQghwPLjE/IRDePdEGs22cw8wUM09R+dCYE7UvgH00x4wtQKLq4jnMeAo+uHkAH2CtrJ/zw+5NAouPjWARR5wfgyQCzTwNJ3NW088OjfbAPBvVl86Al5ew85b8bFCnZN2Tvkt8++Y5tQf7cgqkx+V/kygHz+9ZP0gO/hD0UZ3p0923DHdL5gVJvszihKqaJcLHoPqox4A2GfU/cZ6D7v/RGIE1F+w/GSkJg2wiPwsqv7ggNbs+t5F7M+o2y9OwUsQH7Si+gP84dngIP8E8wzxun+QfzhdBTaAd/znvQf8gfhC1JGdYJFu3JO5EDSf4ujmDIaomzZU1v3xntmDXTDRgsKWcKItDaAMpn6+GPBia5yaxu+R9fDYnUd5aXChbC23Badj5rqsNKHbEwCHBQbKqBE72OjQRNGAqF14D2DdT3QhrauNrhmoEVhG2LhLWHkqEOqNCzPtoHtxjk016OuU4nVAK0awOU9s6iK1B64IhQSXyEUhXKI5VINpGmeagjCio757kO90lwunJcCbQZ91P00/6pOfRDytAvPUkU7fdqzxvNxEFwEEWoEe+WdCxlj9gad1snxLF7Jvwb/7YdX39r83IE9wO890rDvJXcyDo2dG8kkG+1g/IG4TV1Ng2OC/GtczXw5ZwOJdQcqAUf1tD+CfkFa//QL2QcIXgx5J9hwbAS8CdMel6wPfUkvyfMYUX8DsjCr3wvqpfWQPwElAH6cAOIdz9e8n8x+nfp7Pv+/6r/ce8MfkC3WEGi45PhyKHxcCeAy0Lg9MDP4s94300DYagIgQBa8KQAaUw4wHKwHQRGNJnBPGywvn4k72HFIIhCnVBOfRVtvaRlNKZcz+rYwdvDQTCW8wLUVYDbWm0cf/5lR07QSSm0lTJvuBwF9KSTC+nSJG48X4LQZtczkQDt774e/c53Iwp+xuJKp49imyn6PJaAGMCHBTERcQRBdSzb9hPaFDSzjOu+ltJzjP1y19bpkLDlidVpYWzoN/D+eqXexCDggoOLdU/qzK9qru2n0gSI+1/nHqj1N0GDyP3h38+6z7i8fQJzNbDYszPt3yIVJtR7s3kDhl8RaV97vYWX6ZnUDc/9V8gdYNWZcbAaIVqXAIvifZH51As79CfvFYfp/O+p+qXXn+RPI+4XZ1sD/HL4H5tJ37gcnBmBNQBP2nif4fsq/+lv05z79S77+Xnfce8IfDhR4PxXH2gGMh6BY+wzbQBGGQNaFmYLdigELoAfNuTFtd0Ph1JAU1iKVdIGzNUJPt4zHOY/jTGK66pL3CdAi4RGvqAYFVnmojBI9kFvpCtAdeQ5MXpB4gC+JizmXRBUq5GoXRTgXNz5vlsEQ+7KmrN4bJuz+n2YTjqnyGQUJ4UKVZVX39ZEAWQ2QNk4Ae51rgq4OdD3N4cwRQP7A89/awr9D8h47hHO1h5lwPMn4o3gas0Pe5FoT+ScX/dNgPR8c6rJvnkiEG58ndIbpuTiBYdqJtWE+H39XaQF/MLyS73X+igSuBHesK9IA7xcFvUbYQqO4weND5F0deqMayoH+afYYl8n2ybLw1i7mP6p+jAt/rCf8prP57lu2P4f5FX/Pm9kvRzNvw92j8Hw+AfD//vveAL+hQTJ2M+UikUzM4yKO98kiQ1A9oMIc2AHYQhvsFeBEeI0Ad/FEs3CsOwowUwUwGa9JYx/+oAZDFWkDyS80N3NE9tTx+71LT+JLaxuoMXfGltXvcx5owXo1aCPaeuQTEK24DafaA8cEnysr4y/mp6i43MLFpYSqYolROzXWtzXDzVk1h0MpxaA1urxbDQSp9Uyepr/ikJbQQ3pbZHl6mONZCew/fgEwVdlAuLu/1KaT5PxHdU+7TjCruJoNwp4zG+q5+4PZB2hEO7XT8ZMx/E2OQHv9i0fEcN8AwN+rg/E71BhE9o90AkgspcjZALM49YDk8++T2I7hfBFBhRAsdIOLqXWGhvhc6YVx68Yak6LjS1GeUe+P74+IbFqL+BGVWuD7w6EzYR8xm1vEqVZeonzbpm9MDZF8UglX2AFyJs6H/IvyajQq5/zINn9Lf0/g/ntTv9P/3HvAFHYr33LIZjpqA7DwiHsYSAJKTkh6hrcR20JPRCdkMYitgEFFDAOycyTMBTOtEjBZYT8QlAGNUw8GgNgzqVfz+BO1mQVGrra5YCxpIRKnt0BvzDgxmOtYCnI6pSt11FsYZANYOJC8mszCLXBHoRVFkhMD+MXoZl4D7HlYC36Vbb+D3Yk1i3lSDM4taOCx3QnvsAekUb9Df3ksfekOcK0Xvb5pG/HuDefh7M/vfHerffFfx8dJwzo93nGoSWBNFbZjf3drBCE6+xyRn+CQ7kkcnUOG0Mw2fAeLThXu5dMW3GdYv+a4fA/gWdQnIhHp4Mc5Mhkmg9AMCQvVfQfcBJZ//QbCSefWV7CsqG5pTvBE68TR0gv/OSX/HQiDvT5Z+7gSa+ivrvkH/U/SbTtZvD+P/u/3new/4kheC5dOF4MjE7aQHUf6EUEHzPci8EIwG0It54lQ6SeB0NvaD3NcFR+Ax5HceiqGmxaGti62Z8hQTjBdYSXVpWCdSKjubRyoQF/RtVO2aOMVXx/rHh5lVMrpG3O+N4z+WjTQakEJpaleYZXR7gy7JqxyPi4VWmjNad7yomTaqOZE0cIFIbk4Houoc8081NznZpvffwYhOPeAz9Tp98pWf7SL/SGV/8zHtBJ9tS1KDeLlPAqb6w5UiuhmqzBsM11ps/E/B6bBu66bBH6ddRrAlt9bIcgFSTd9I+5EbK4+6iRI8eMAJFwLHH78FbqCgdXYdezH4L30FrAiLt7jA2p+Vn3afJCPjVxB8yewTnOXg4A8ZyxQA76r45Hdi8JcXEB7EKt7n6erbbPyP0/Q/HMqvg/zzPv6/94CvYyHI4lIclKEoD2pqyngkiMwkSNSUQQ9sDqOjhqPuZ5b+VuLYBjBGVbSElajRWA6qoCAcDGA8hwEbC3tNuFrCLCDRu2ys+6O3jM+vBe87XlqJpwKkTWHxqOMDdewHO+zslj3pXAzSU5V3cWy7HIy7XI6T2d1E9gN8pxs7yk76EC4alctEt2tBYXauSY6reaiBUH85efKcDgZ97genCmD+ne3tMfk4MLzBZ/o/uQf8lz3APiO5Wf4E7QknqZr3gHb+suR0/uxvM8t3EfMH4nFxPSs9/TsZnJkf4XVXVrI4/EpQjQ/mKGq/vB86xVxIG12M4cNtoAPXh4NTXIEgjRWxi+S/wEUOkwrBH7QPM5nmb02C+zn7Q/DF/N6I6T4J3pHns6P//KAyjHz8xzO5pnk5sBtYz/FN6Q8P3p+j+r+j/+894OtZCNAJSBnyepR9G+iuIWAzSHSEGJVvBxM0zNsAbBx4H24Im6SajEjPmMWgOl7QIbA6jJcpZAKjUqY8/ohRJ+r/z94VsDdy20qCXDn3//9tT0vicWYA7kq207ymX5vmyF4dWVrLsu80AAaDwcme5kzY4GtW5zsLK+5nqECS90ALokHaOkMCNt5PoO80DiIphDVVuLOXmEZmr7iysfzskIqyDvBYd85PfbCX8ZRqyKWUh99ZN8UMOe00Ng/kogMK3sOPyCirr/1mPpH2OGY3uM/9l7i/X0z9Gzn/hSznj8eA+s0FNaibdbHdrrSV16dZaW0XRxQbu3K+tx4RJ7pqAt55AKy5eZpubl0eD7yY5L5rm1BrYfisGeCD26fDCiJWD5mopIM1wYR+mDlgxJf3g9pXclKD/C/oAIPwAa9oaCeVUHzSJu8B10J2fUPWecr3nzee2PvIeEDcf2qn3VEX8+N3/ufW+F3Qzx0aK/3f4p8dA/5uBcGaIUDHLaqBF/GoaSNibCOsMKVE0jToHkFuePQQYza0iGd+jkjw6HjXHTNvb32+ZzEPdiJrIy8Efqn1JsvK+RGIy/k09AdkCDcvtvMB3RAKBzzrOOZTYnatD86InfhqdCXKadxn642dAMlj/IxRMnuGR4KaB3JHqLQY8nBOhu5JoK8EX2NTo8dWXm7ihdmOIp2lAN9LCDFXYz36ByvN798j/vhdIsg/ob9/GwPsdv+Sb4Zbw7resjtd076/ZrnAAPCo6ekfIs6IAY2YGQt2H2mrhyQ8TB3W1p0Y9E0tUKlc53J42MA17vVtzo5xjRsP1hbY6BI6H+I96R6k/shNUBe41SD9jWNfIPQtpDtAf7g7QJ5w1BjvwiYHfz5a52Tv88iub1D/6Bn0O/PDXaBa+P5aAbym/1v7v2PA3/TMf9Y/fw4s4uBYZbl6xXbVBHIZMrFDLAvklF+Ha/cAZhCe5Hga54pPzIZ2kKb16ANV/VFB/PRZs3M4GBuJ57t2wrhh0njWG/NTkDSozwdmzdr8ALnOQMGABjJ6Bud82oFlaB8ddcBJBC8MABboH/6jE/cP8j8t12CVsL2MHSmOoQWSPyKdUlC/fPYRY3TDvcUNXjNyl2/PTQYeRYMiROhNx9VL8Nuyl1Uo/O7fyrcpv9nLQ1ZeOf3czeISGtk1mFY1k3xc+X6M9WrOCbtEoYyPLS4t9P6Vtv6gZATxlXuba1gAfVz7Xiym/yQBqtr1yOy+wuAT4PpolVwQzdsai4AKQx/hPya7stkL2VRl+5XjvrLZxjbrA9k63X7spNqHhL5uh+6ToI992LJ4OynzxyL4an1J/skjeV3p/9r5/k7+MFWS9+fGih0D/s6HBUGNDsFaRxPUkF/+BiwF6DVTtZiKE5ikchpJodbVIjYEgK5IwHp8ONy8cMH8Fn4MQDVmmNlLgP1oW9BbGpJ4SImcWk2k2ywS5leB5p9RY/TYhmhoG2AlltPZGL4U4Ww80INoZ1lLstauxMIgJWVRz8pAQwNlrVccbCnfpwp6LkXxcOQf/dWZLnG/hn4/vd6+bB3710n/da99wQNdDI99qgMsVJuKAUpl78PJtWYMKOF10aUCAgvExLx6adeOBDz0gJsFRwFcBI6l/89yga4qC8j5tCPuRw7/waGBpgYA83vS/U3zw9g19GiydEjKn+scD2PijygDaYI2vOO1VrV80fUF4pvavGcT2xMa/2j20t//bNEZDp3oRf3f0f+W9QcFdCd/xP7v9H/HgF+lIIgOQaPjVmDboobsqgk0WTYqtf8gi+YbdMSAMeqAmTjNFMzgE4H3UBEvNN+QbUaCjnZhn/UBFURIxWHhiHlj9mSxup4oi0LD6HoJ+oJGjGPMPBLvyJljniD8x4l+cqfkn29VrDc5Rf7M659AedpQexQBEQm4tAAJHtWlPeRA4ZM8tHGXLnUKBs/A9JIO1Z7WmzDw6VQPnTlV4HGZD/76PFdg3iH/dezAx7cU/+fQsLq1t4ECPiR7IupZrgqgeYQF8iWliNiJkKA9mtXS14FI6JJ4VnqCaLyLX0JDN9MXmrQ9/HI8esBbCckDR4JnrdCitVv4b6nQxBOvodVY4aU9Xsz5mXXI2oE2txVSH6iHMGKI9B+SfxE4lZEgGr/0+CTDoyKg0fIzQgKuZx1QBf3CfS1K8mX2mU3mUtcQx5384T/e3fvdMeDX6xXPf/kTnu/UkEh6vk9E2cNqFBuqDJMExsqgUunJoUnwu4BPKPa7oRrAIiXsosEowGkHagJYTM8ssQ2YDtFgroXlDSMBrIfGYM+ADev51tWYbMVTj9Ef84qKesFnrgYXCnzBWekVMcMCCo+aIlHsRpOIaNAM6fSalpnwotBurO4nv/kjxscQrTRKNigoYpiEF2phe2BgUQJ+HYPPea35JSOEHS89bYG04tFvkeCVVzD/uhqwT12BmgyP15uNTyJ+LQL9CBI1LDwB6C2X2ovlv5b65kwvLm581o8YAJ5f6h+0ByQj1EjpFHYIDqo/5f7PTq9Dtd+cllGOaV6jxp8ObooudrDNS7wn+h+cJte+Us2c8TFHDGhK0uFP2zjtBRoHhM8A+k+gb13TXlVhwJ4aB6vB+6NFXI3ob2L8qWbm0O/l9lw+yX42+bNjwD6RbcL6dmADH9+06BbbQpqXJkEV4GUkqCT60cu1E2EEstF2QtOD4R86NjASzLfujAQwlDtOiYjA7qMPwImERsdpbisreCtj0R86BxiM7TCnnuWGY58VJKsYVQONMdGaTbuZu2EsofDJtD0GdBLJH4wdAO45f0DBqqk3cLoy/aCDPHawYJnBCPZLylGJgmoPil9DBteYccaAsVRDbx6f0hrdfKH1C/8nMcAj629rnksq1bSluyCtXn6lbtfAl9329x56iKSQGH/Je/BX+0FEfDCK5HJHzG8U7vjVPSzLJu5bTIr5A6R+0fgup8PqAVDHqnYg/sTcA7xOE+NfuNHX4e7PrAEtWVYXuIE2kKvli4YRakfRODRyoMTzqCclQE8NAdAEonPJFzkicT4MANqJxHBykT92p/5z/qtkHcAeFujFrfzZMWAHguHP8YSVQ0MKdzNcbiwLtH/AXfpRY1ngIR+qKAKgup+5PhxeBlGzE0Qf3GjOlkA9zsFggDK/siDglXysc/Mxs3xMlh1GjsjnbZAsnaNrYP6x/obY3IEgiBuVtFElmetsT1Q2nqEunZGNMlNHh7k6E3kMnXVMGzStYn9i74r8qMEUeaziKrmPVzNl8iPitANnh/NOUT0KD+VmSId0vIeRz7s19Pha9P/SBlia/TeNUFYDtbxM+cbO3tXlrOFovW6gRGgWnQPu1kpih4wMeX9d+eBiOuT7H5T/6/35UQt5JHp2ItufFcAHCCLOoMvRgZaC6DKx6UzhT9HYL0n3xrXUTYpPgL6H5qcy8af/LG+D9uFHgD5JnnP+nQfvH6WAugLz397F+9+g31eUfGv8JvpT+D/RH4Ym++wYsM/VJOjjZ//ZWjQJbvYSV7uYwn4tJqummgB6IUwaA8cHvSKSHaIWp4FSOTv4JrBOkJCOx7yqYdE9N89gMWVDPIAGiR/RIZhPS4kmCCLT/jPgeXlUOleMNsFhMBh4PTtpebxGlh0IJTMgNOL7DAzUFw0T/9OetTGwlBge9vCTeEIvgzKGy9lP1gFNRkMlpoWlI4Jfv5ssfWip5DZuNYFzVcDIMqrHNC/KDouoMD71AkaGgkMNXku5aUqD6s3YeXC2ldHCqpYMNFyPzk6h2ofrfI8a0QJbgg4sig5SnAIeQLzYf1QADQiuoSy4NGPJWgiEkOXzGx1qADRYuYH2rxgQG3jowEgC9zha7HFsXmO+10Ppz3QBAN1GED5C/2D/z6B0SP3H5JdawVEKaMqX/WGgPIuGQPzxLfq/qf439b9jwD5/rEnQIdak11B0idESuNw1IxI4I0FQQ0Yn/oGxT8AtJ4cJqGCHQOwfDZr/4/SzY53Ao2EcgAqiGQkMkWCC1IkdlTM+cFiADqdysKB3HQRFszjAhoITzYMB8HWQQMhnCxfszm8FQdH8zieJ+8H5L7zmftYHqH3npJiX9Jc+3DVW9mTdwvUHILdkLtRYiqjs6ckaNfUACO3zNT6ha0Uf5Ojlp9YCE/pHWrxpEdiZMqFRXrYz2rgZSmuvTwnOZ/UGvMW0V7kaxRB0NXn6F+EbRrmjAiBsGvsBWBZB/mc+7YO9UiT+ZjJnbtDk04jhMCx212TBQ+6h1mSfhu4u5nghHCLDQ1IfFWH7qLlJPmyWH5SgymiOLD+TdC137ioC0OytkvrAT4SwPgj6GvHtlYFcBnA1mJ8RzE/ttaysP8kf86X5uaP/ZfmAbtYYJ8e+9nt8x4B9/lAkAA6zJsC7nnsas128tEOVXA05XrhRiyOagEEolfQfrWAKgSb0o13ckPLPSPBs9dHRJW5nPbAFjWXBAf0oIgD0oaN2sUwz4gwGA24+GB2joui8no2jn9zEPiFhvsk/gPE0u+h8KVDsYIJ58EnHDG34wVBcIMF/cvZrcGUvRqFNw8ONSxmFFSxCOKSm7b5nsPzokDx5Ae20W6pFG1sng+qguhi1nnNbIppu6M/ln9cO4eB2PKsDpyUDmRTzqCcaWzOtBM2E76hBrSNDBgPDQ5aA8Ni0B8CWnm4AYMAzZsEPMfRNCxL9o5GvMfUh0Nc1JvdoEVPWU1lIVN4P2GeyPxAjGtetNA/WBZog4jK4Gsfsx9Jr1qD7qf4k2wPaZxD0GQAkBmWEaEvmr6IBzxDQz3aCBr58QX+9oP8T+nc6vu2h3x0D9vn/NAk4WgzHaJ6oCXzFAIUENSUHHYe0zB6RAFzQhH+ISBFK2CE4lIHbxFpGAhQER68zd31OnG6Q/qC3DM/ROiMBiSMsLWbHGIRLYx1AgSlLAGWDmDZg/Jnfx+l8zcCA9WYQ8jgKigGayunGjzID7WXEhRMTCbR5AKmBDYv4ArSR57c6EEVm8k6t1AmHNO0pOz3W9j47PfdYFnyUtCEia1RuPYDGnS6HjCXsihPRTrC4xnPDMF50Ky21ofP7npYK9mULkc7+aI9TtIMBYOOPgmoAk33zl+5osOMLxm/jARH/jBaQZ87v9cGEv5HAg70POrbA9GNWCggq5H/Q+p0QC2MI0vuoHPQyMfjF1BspwmAwQFMCLhJJzmBAeP5Ft6G2rdHmAbjPsfEVAOj/fNYaG31J/Z+C/mj2Ev3bK+Nvv5P7lyX7oQNWP7flw44B+/z5SDBT6BqRgM3hqyawWNeoSMBSoLAsiD6Bs2kMNSlafBMzBuH7IJTz4ywLGoYJMISGyTKiv+sGWwXgbrCcZtYbHQ6kE6EB8Rg2hnydqp/5nB3OFEgRnT3HCmIIxnQPQDpkpwOOdfA7BVs0sfy3+d+jYzqNlcHHONnGPdG5bbAvNeibfgL7tHR3RN79tH8Uek6g4EC3+TDOIw/s0zk654sHV6wP/NAf2OTolmPGxO1YK4+7GzmepxYMMAzwxm+DWTm3Nl8xg2n+b8jC3Tln8QFaHZgJswXTlC1IooYioEUDgNO6s4xCI6DhL+9ggl94g2GiciUjuXsWWfIUPUACVRYr4RgEnBXFXxggBtN/59QHuf5CwQ+uOZmnn2R+KO+qZ+o+VQ2cQfsE+YNqAHMKooAKKSMTC+h82pHm/n5ZvH2f+xP9MViy0X/HgH3+fCSYSfN4iQSqCSzYjpGRwKNVUDg9QDhmMs42AbL6oa4rQHa+xfuJggB7K5FXV46VsRoguY76APiB1rExGBxcVgnjOQwYV7SEKR+aL7CxIesc2GKLFn2DCQXtcOKHeHV8DfcHczEO/sDOAi8L2NvQZAbzBD5pAq2fkLo48J+BomkXzQT1UP30I4uienAwywjtH6blafjN/QD0Iwfv0tN2F9tTaZxU0uxnPusPLhrGckM6ueFio6NPjSrhh4glfjFpfKC2nCI+1KUG4990H6obanQgy2SrOTq8RmYJaInGv6X5UDm4qZE0z9BAMTkiy4XBQt4qwoeZOAaKO7GY5Awbv1gg1DD3TebnrJHad6o/zwvryQjl7UHQVwNgvP55z/1ldsFPL9K/ZrN8o/+OAfv85yNBdIyleRksuikkhTU1mARnU1U1wXzTkx2CoJP0Digg5OXAdNQBgf41PpoYoTaiGkCtQMkQmp+sISamt8E5ZzD36NRWEkX4fHCjC+a6TqSUvAlUxUMIA6gUThE0p+t1gimi8gfepk8/SESx54s5CHpLAC/HLF0K/K25r8zpozGMnWmGRC8f84/hR0WkMHBB4tkxTOblH/x9nQnrsyY5KBuVx8PBATHhOPN750RV8kUxR5cTZBSG/uayfoZXn16iRgGOCAAoAjiXlfvhG2KbS+YPKdD8qQ/tTJGdBHSdKbGvQl6gPAcGhuC4VUo8SdTFXG4LuOenJ287yX1Cf80KoDA8gOQ5tQcmwsAd+iPfz9yf6G+B/n5f8bjRf8eAff4rkQDaoZeOcbmYbY8IwCMjYyooURYAL4F2uE35D8h97LInhLAggFKo/MQeSpBCiAeME7ytqAA7usO5XQz0kWOLpWoCKEKLcbUNyCM4SgCx0GFGl5oioSFIw/aDcTiFpwcXpIHwf5wYT52gbewMn6M85qPoKudmSQmfoEOqtMj7iT1sM4poQhWB4XBOEYA7as/5BCSbGlbqlB9cDfmDOyV/EtQnGP/oGAnoEFPi1weDH3QwBNMxMsZ1k5d7XOwDriDyEag0g4vQUR5BxxXteuZ+xJjrms/KXjFis5Eami+XqiCCvp5Diy85zMVZPeX+sPM4lO87R3wRi00TXkvo2RQP6N6j9m/RDSp/qPXEKw46yNUoVluHytGRcL9yf8Yeox220N+W2UOIoXbXd8eAff6LfYLoGNcbO5Qri69ugYSklTPIrAmMQcKosa8SEbmpCABlNCD4n7D95D1sFcxsvDMAKBjgKZsayKOxgEDzgI6k2IGGZjK6E8zqnRTOkBE2FvSifRwNA1UQ6OOaGhowRxi/uQD8CYqdqILhNb58VAwT4tv4GJDJgCYaP5iLPjo8SZWnS9DJFcFcy8hbI/+ta/jrUSBFvbZ98b9Da4dHCEPZ10VV8fAUhpZ0kpjPlmkwLK9ZZTxqyQX2sbaYCxK1CwCvgqt4pT3SyAH0oMj3tUeRMWAExR9ZP3U48IbAr7bAF4qruKj77KwSnkjwJddhpo9WMAIYo67Rxkfa/6b6oKv3qy8xGRHaAn0waqw8PPZ5BfV0Y/yL9LG8vdF/x4B9/hKRgNufOFlGxoJvyOgbUzujMWNXR1ExIJukEO4whR+Y7K0MEu1AJOCsAPWjiAStZkho1OIA+tlCYC/SGST84XSihiyxV3Qo0ECmfvXkZJFsfcgFdRniMRyhm9AZorStnewOmqsAN5gBcRAL4DNO008H+WeHogjaqJMAz3/KGB1z2NapsxpjweNa5VWUthfyP2Ul/qUsAqMurJfyx8T/x6aaouWHg63aSsJNPQGl/DBlZUsXgk2gaos5sYJ9va7x4bAKDV8JznMxy4bV2zFI++AvUAO9lpk+E39WABTtWL2sGiy1/PiIGWBRPT0ZnpNeDj3rhuB8jNqe5PpHVgA53Guyq3q1eLOQ2ca0F3jFjf47BuzzX48Ea7KMQ8bxdk35EBFI3QL1jQG8VTGAGqOoDLBgsrIroH4yagLkrxwfgyIoYoBhEKwzABQNG/MCTCs8MVc8MBML9HJMFUBG3o9OtSjMJeIeelEM7k+jiwSgjkBPNyK1FEb5cNc0mGwjihQ6jBaFu7YG93LCfYFqI7A/LIE+SphsOKkyRKxScqVzWY2DspietUYgF/jwNysgJCfkVm8zYrUpNDBIUEaq5kzVhq4wmBO4Z3egKwLhr4eZftEQr9gezBqzqcvSQ2ocoH/rBH18eeOEBjN9qTbP5HN4Tx1BARUpQRUDJAztmenHM5PlVwzIZm/SPoR7fzH3LzFfYSqhEMD7nvbaMWCfv95RJGBN0OQVfLMeCoJIf1QWaKM9YUdeRBNdAb/OhkGXRV1lMIDxDD9tRPbGioGVgaSiFJJiHgkKUXYINHKMhyqVoJAoEog5gQwdD4MQAgNDQtPYsdwk6T3KVz24MxcXDM6hPbDxniaqXlQu1FgiOSDQ5GBykfMe2hKRb4sMAmelBB/ynxCHCt8qg2MtyyOo6sa1DT7lLyMrCVOPgOu/OI3czNcGSXBBWbww63d2BdjdbUUBAEl3vYF+FeGORm4DHzVkyGPJ2DDlP2n1c6oPbFWpfWp7Yi6sp5QT5E+Ek/rC9dt1O9YVpdTHL3W/lTv6s+W7Lf53DNjnr3+0nIDWYy33hXi5CCJR8BEMsETEVQ04MVC0PtCVOh9m+pX+PqoM5sejlSf4HxgCcSYZHtNV7BDcCaKNLDvSiofidmM+Xvl9DypJoWuBBURvco5gaaKoQIsi8M3VpXqKWWSuOhwlSB7WDYWzxvIMRZDoZeX2YROqOWIZkA4hNUVUIe5JTIsRLHYJNEKsL6/pIFfCH7pYdBLQFGeHwOTsSvYcMaFRSkRlfamZZVf1g50ungi4fIjpf4Pglj+l0Jx8fSPJ4ywIJPG8xPtEf3z3zPo1FgBY7xk2XB+T33eLwa4r90+Fj5e3lV6vtE9sd9+0z44B+/yPtQqQdjMS0Ji6ZleghH40mwSMCSJ2WRMwE6cGUHS95gwSzXuofeTu5ggAnTuPVRwQxw/VASwUDj6F7q8YZmUBAW3jCMYJ6MgNl86uAGBHqXLRFhmxVTU2xDB6oZ+MsKTc3LRyeNBFDSNj95gY/7fyBXnxFZ9Rs28sNGeyXMq1kJhkPTVYgv1aNJ0RdH8punEl+6aZY3SzIcsp/OFM7j2ueT5Tu6TQyJPJuxJ5C+Je5A9nvrICiDBgHsk+4oEn0T+S27lDf9zJYGeL7Sl3xv+e+ENWe8ohfNM+Owbs8z9OEJ3dsLvym7JgjZhFt6CIACf09yqOHuJR9pLxKBP81Uymyp0XIwGG2RAKhRr4PuhU6S2gn+5DHhokg50QzYDoGgFBPR9lz6AEO+TRPUaNUobWF1iqoLJP4JBaopLI5q+oJAiHAq+NTYIS3kAL1sdLNwBPqtxYmqK8u5TlOeQyDY0gRY8OSnr462QNIz5dzkGKlRa8Pwh9jher2dvl46+QkOBO6C/CdwI3BZ1xw+jZWunlGqS/4sfI7H6sIbIr2bcXnc/F+N+c3W6M/0r8t9J/x4B9/j5lAacKVlmgbkHaToQfmqf/xBUMaPu2YoAoIw7YQv2vyoDozxYCkB05+0H0pwyUqqEIAB60UkUzIK7HPSSI0NeN6xufEKGiiH0C7jshzaUPze4xaws5whHpOalLKqmUlMoer+uE7dPK4ZHC0HvxYOuDgoAH6OensixlEq0hAxYjUAGJ+mc8qAonxP3mmd0H+x9pPoqGUy2BaNiK5Y/Z6lDvYPq3xtfWxfNE33jdyEw/A0Bubrlre76G/pJCT+99J/47BuzzC5QFWi0uEVHQv0W2c+6fegYsGRAPGAn4h8IhEOdp4+DK7rnpmJ4Q7jQwE4kEQAfucwnZfOgnL2DMqPpYO2NGUfAgra2msVPS48r0dY+ayUMEPF07Pe6M9kBJIekIJPfVORAns/Deb1HBrkc5ZLHCgUeT4GYmncxPpvwOt05tedB4FxGcF4i34ZBXpPyE+BTjo9EutofQnMsahPscwVajuOrRoHSygVzuzH5WG5ewx26yTl8MT1mk/5vUZws9dwzY5xfqFiwRURz6I4d26LU4uIJBqInYPY4pZKGzNEYD8h0Ngs17aP3jpFQ4d+bYrhK1gkeHuWWRsTgiBYmqHJ+kPwsCtWJ75P6uZD+6AiUKAnV/aRuktgFfvF1dgfu2ML/RQdeNWzQoqxPgQZFIVVSU3Ut7FIy/KUhE+5dzEYoBJaa92HYWZc8cnyO+pSwOh5HASRbZiCJANFFwOLwzvlC2ca79lqwhyiJ8UsWfEs9l6FbsJeW/cT5x9ptix4B9fsWz3v8RCDhyrJFc+yYYKIRkfUAh/4oEyPo5p1Yh0mR6Hnl9CaMICPkrp6Fo2JZUD5fB12gdB6aP6AqoaKDFp8X9ntsj5fsmHVEk++KCQmMawiDP7czr537/RcT0b32hg0KemilzhM+ijQ1xzcr3g/mp2c/m5f2G6UNsEpH9IvGDLOKnGuxLiB/ZQljEjivSpILTF9AX+csl9JcvoP9G92Ody7mhf58dA/b5FAzOs9wrgwgGHmqc8qYrlX4ymCLVBC3iQYaHGkrTyPe5epgIfhLZe9LnFj2AhHgifjQGRlD8RPxxSUIjNih7lxaILYQrAATcZ16f96zlwmGp8RoJYj3ZSzAopYRvWjyBprqEy5b5fgQDjYOxIAhaP/FdEqDroUX7xIRc9ABqPlUI9j2Bfnm3+U2+uRie8jXXv7P+fXYM2Odfrwy4ryRWwpYvGsghK4oc35MvMu1wFGmTH+n3tooGKXzYwvSoFewWNqyoJhC3Q0GjqxRYuM8JZ5E1JfoBNyJ/3Xaio6dSSLn8nfOxe0dghYkoMCzbA7bmA0q2gmlFkXitjZQ3fLeUCZEIugWJcYsBnig/XkC/hLJo3f6E+/fs3m8kzyv0s3E/od839O+zY8A+/2IwgAW+rQaygKWEhHShbVQGAZ+iioI0upFFVwpviAeRrSseJPRfiM8I0VZIuH+M7vRF/TdLLM+oUF5wP274ayXw9fG3CiD+e68DgnJxWyHhyvpL9gwumkiEUoQBBc0byVNKdnRLBJVgfhb0X9zOwv28M7L8N7aHKt4TC3rG1nfus2PAPn/qQDJYLjXRVRwo7y9XcXCLB9eNq31Qgqz38h4Y6vAc+MqkPlgdX1Cu4BH1Qb2n+b7yc0/otzX8a9/Bvvsb21PeWKEVOOyFGnK7RRZb818W88bB6lzon7hfYx7jVgTkswn3r9x/4Xt5Y/Pz4hfcL3eiv/dI+bfCZ58dA/b5dweDVBOt4uAlHpTyShaV6CF7uUeFlO94orYvEF8xQN4F7BysUFEu6efwle97frR4qgvtm3Seqxp4z/X9E+pf7YIrKrjdC4l1p62y4B4Dsjega2oufr7D/YoBec8XuB9PaLam2RbPE5/dcB9wH6i/U/59dgzY5z9eHJSrc4C2wYoH0U6+ZDlrOHnl4Cs4qI28cvkMCSsw2NWULjf+p4TH3Ms9N6B+AUR+mrY/5t/QQbaCgC6xTxEiWwWrOLCyVEDjdmWA+4Xv2TEOLui6bBnzrCsT4L/L92M/2m7w7rNjwD5/hXNHIkYCu9UHifieMF2uOd73eDAWa+/py/AWGN7Jn3rhtt/y+BcJkL/2el/Yny8jwdsigXs1sBL/+Dnser4sCJY6s1wv8yoUlsY08/pbPHh76BYK9Ev2JHk27u+zY8A+f914UDiNLATLkEB34mo3VY5H7lsu/uYlKqz/s6scF6zU3pLtvm68FgSvNcGdzvqnP4LZbVbMX8JA+dQoLjf/oRfovxrQK37YvaSQ0CjJ/lV/XKDvxHyZum5+f58dA/b5H+SL2D+4sLLm/1gfVOj/kyO6RwXYtl2+PhdrEyan131eXjQ/5Y3l/3zPv/Iz3Figl0LB3uKBvVYZn0H//atC6Hl9yaBDErQ87pvc32fHgH3+diGBLYRl12xRG7A+4JJ1q5kaX8YNvhLqoPNvmO53hPfXIiDKCStfN4QvhP4doLXymUW6M0n2frF9DgP36qKsJjU+MMW/8H74zvT32TFgn1+rSvCu/Y+3qBDR4B4Z7syMv3Zn/RPPY/YZs/9tx77+xK+A4Z8ihNY7c2FmIv0I16X9b2CfHQP22ec1KmgL8Gv+fD/c4RI3q9VPef3viv5fSgH/VAnYH8L+cmsL37vLHqYZI72U7mf/5e6zY8A++/yJwPAdOq/AkBLLkE/aZZd2c04rQS7Zneex18jgt05CVBowLh1X2bEc8+KSjfL77Biwzz5/wQixzz77/NNT969gn3322WfHgH322WeffXYM2GefffbZ55c5/yfAANIiefzzO4ZxAAAAAElFTkSuQmCC';\n\n        this.displacementSprite = PIXI.Sprite.fromImage('assets/img/ripple_displacement.png');\n        this.displacementFilter = new PIXI.filters.DisplacementFilter(this.displacementSprite);\n\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.displacementFilter);\n\n        this.displacementSprite.scale.x = 0.05;\n        this.displacementSprite.scale.y = 0.05;\n\n        this.displacementSprite.pivot.x = 513 / 2;\n        this.displacementSprite.pivot.y = 513 / 2;\n\n        window.HTMLGL.document.addChild(this.displacementSprite);\n\n        function redraw() {\n            TWEEN.update();\n            window.HTMLGL.renderer.render(window.HTMLGL.stage);\n            requestAnimationFrame(redraw);\n        }\n\n        requestAnimationFrame(redraw);\n    }\n\n    var p = Ripples.prototype;\n\n    p.ripple = function (e) {\n        this.displacementSprite.x = e.pageX * w.HTMLGL.pixelRatio;\n        this.displacementSprite.y = e.pageY * w.HTMLGL.pixelRatio;\n\n        this.displacementSprite.scale.x = 0.05;\n        this.displacementSprite.scale.y = 0.05;\n\n        this.displacementFilter.scale.x = 100;\n        this.displacementFilter.scale.y = 100;\n\n        new TWEEN.Tween(this.displacementSprite.scale)\n            .to({x: 1.5, y: 1.5}, 1000)\n            .easing(TWEEN.Easing.Cubic.Out)\n            .start();\n\n        new TWEEN.Tween(this.displacementFilter.scale)\n            .to({x: 0, y: 0}, 1000)\n            .easing(TWEEN.Easing.Cubic.Out)\n            .start();\n    }\n\n    p.destroy = function () {\n        ///var filterIndex = this.element.sprite.filters.indexOf(this.displacementFilter);\n\n        //window.HTMLGL.document.removeChild(this.displacementSprite);\n        this.element.removeEventListener('mousedown', this.ripple);\n        //this.element.sprite.removeFilter([this.displacementFilter]);\n\n        //this.element.sprite.filters.splice(filterIndex, 1);\n        //this.displacementSprite.texture.destroy();\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.ripples = Ripples;\n})(window);"
  },
  {
    "path": "src/effects/twist.js",
    "content": "(function (w) {\n\n    var Twist = function (element) {\n        this.element = element;\n        this.filter = new PIXI.filters.TwistFilter();\n        this.filter.radius = parseInt(this.element.getAttribute('twistRadius')) || 0.5;\n        this.filter.angle = parseInt(this.element.getAttribute('twistAngle')) || 5;\n        this.element.sprite.filters = (this.element.sprite.filters || []).concat(this.filter);\n    }\n\n    var p = Twist.prototype;\n\n    p.destroy = function () {\n        var filterIndex = this.element.sprite.filters.indexOf(this.filter);\n        this.element.sprite.filters = this.element.sprite.filters.splice(filterIndex, 1);\n    }\n\n    w.HTMLGL.effects = w.HTMLGL.effects || {};\n    w.HTMLGL.effects.twist = Twist;\n})(window);"
  },
  {
    "path": "src/gl-context.js",
    "content": "/*\n * GLContext is a part of HTML GL library describing rendering context\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    //Defining global namespace with respect if exists\n    HTMLGL = w.HTMLGL = w.HTMLGL || {};\n\n    //Defining it`s properties\n    HTMLGL.JQ_PLUGIN_NAME = 'htmlgl';\n    HTMLGL.CUSTOM_ELEMENT_TAG_NAME = 'html-gl';\n    HTMLGL.READY_EVENT = 'htmlglReady';\n    HTMLGL.context = undefined;\n    HTMLGL.stage = undefined;\n    HTMLGL.renderer = undefined;\n    HTMLGL.elements = [];\n    HTMLGL.pixelRatio = null;\n    HTMLGL.oldPixelRatio = null;\n    HTMLGL.enabled = true;\n\n    //Cache for window`s scroll position, filled in by updateScrollPosition\n    HTMLGL.scrollX = 0;\n    HTMLGL.scrollY = 0;\n\n    var GLContext = function () {\n        w.HTMLGL.context = this;\n\n        this.createStage();             //Creating stage before showing it\n        this.updateScrollPosition();    //Initialize scroll position for first time\n        this.initListeners();\n        this.elementResolver = new w.HTMLGL.GLElementResolver(this);\n\n        //Wait for DOMContentLoaded and initialize viewer then\n        if (!document.body) {\n            document.addEventListener(\"DOMContentLoaded\", this.initViewer.bind(this));\n        } else {\n            this.initViewer();\n        }\n    }\n\n    var p = GLContext.prototype;\n\n    p.initViewer = function () {\n        this.createViewer();\n        this.resizeViewer();\n        this.appendViewer();\n    }\n\n    p.createViewer = function () {\n        w.HTMLGL.renderer = this.renderer = PIXI.autoDetectRenderer(0, 0, {transparent: true});\n        this.renderer.view.style.position = 'fixed';\n        this.renderer.view.style.top = '0px';\n        this.renderer.view.style.left = '0px';\n        this.renderer.view.style['pointer-events'] = 'none';\n        this.renderer.view.style['pointerEvents'] = 'none';\n    }\n\n    p.appendViewer = function () {\n        document.body.appendChild(this.renderer.view);\n        requestAnimationFrame(this.redrawStage.bind(this));\n    }\n\n    p.resizeViewer = function () {\n        var self = this,\n            width = w.innerWidth,\n            height = w.innerHeight;\n\n        //Update pixelRatio since could be resized on different screen with different ratio\n        HTMLGL.pixelRatio = w.HTMLGL.getPixelRatio();\n\n        console.log(HTMLGL.pixelRatio);\n\n        width = width * HTMLGL.pixelRatio;\n        height = height * HTMLGL.pixelRatio;\n\n        if (HTMLGL.pixelRatio !== HTMLGL.oldPixelRatio) {\n            this.disable();\n            this.updateTextures().then(function(){\n                self.updateScrollPosition();\n                self.updateElementsPositions();\n\n                var rendererScale = 1 / HTMLGL.pixelRatio;\n                self.renderer.view.style.transformOrigin = '0 0';\n                self.renderer.view.style.webkitTransformOrigin = '0 0';\n                self.renderer.view.style.transform = 'scaleX(' + rendererScale + ') scaleY(' + rendererScale + ')';\n                self.renderer.view.style.webkitTransform = 'scaleX(' + rendererScale + ') scaleY(' + rendererScale + ')';\n                self.renderer.resize(width, height);\n\n                w.HTMLGL.renderer.render(w.HTMLGL.stage);\n            });\n        } else {\n            if (this.renderer.view.parentNode) { //No need to update textures when is not mounted yet\n                this.updateTextures();\n            }\n            this.updateElementsPositions();\n            this.markStageAsChanged();\n        }\n\n        HTMLGL.oldPixelRatio = HTMLGL.pixelRatio;\n    }\n\n    p.initListeners = function () {\n        //window listeners\n        w.addEventListener('scroll', this.updateScrollPosition.bind(this));\n        w.addEventListener('resize', w.HTMLGL.util.debounce(this.resizeViewer, 500).bind(this));\n        w.addEventListener('resize', this.updateElementsPositions.bind(this));\n\n        //document listeners - mouse and touch events\n        document.addEventListener('click', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mousemove', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mouseup', this.onMouseEvent.bind(this), true);\n        document.addEventListener('mousedown', this.onMouseEvent.bind(this), true);\n        document.addEventListener('touchstart', this.onMouseEvent.bind(this));\n        document.addEventListener('touchend', this.onMouseEvent.bind(this));\n    }\n\n    p.updateScrollPosition = function () {\n        var scrollOffset = {};\n\n        if (window.pageYOffset != undefined) {\n            scrollOffset = {\n                left: pageXOffset,\n                top: pageYOffset\n            };\n        } else {\n            var sx, sy, d = document, r = d.documentElement, b = d.body;\n            sx = r.scrollLeft || b.scrollLeft || 0;\n            sy = r.scrollTop || b.scrollTop || 0;\n            scrollOffset = {\n                left: sx,\n                top: sy\n            };\n        }\n\n        this.document.x = -scrollOffset.left * HTMLGL.pixelRatio;\n        this.document.y = -scrollOffset.top * HTMLGL.pixelRatio;\n\n        w.HTMLGL.scrollX = scrollOffset.left;\n        w.HTMLGL.scrollY = scrollOffset.top;\n\n        this.markStageAsChanged();\n    }\n\n    p.createStage = function () {\n        w.HTMLGL.stage = this.stage = new PIXI.Stage(0xFFFFFF);\n        w.HTMLGL.document = this.document = new PIXI.DisplayObjectContainer();\n        this.stage.addChild(w.HTMLGL.document);\n    }\n\n    //Avoiding function.bind() for performance and memory consuming reasons\n    p.redrawStage = function () {\n        if (w.HTMLGL.stage.changed && w.HTMLGL.renderer && w.HTMLGL.enabled) {\n            w.HTMLGL.renderer.render(w.HTMLGL.stage);\n            w.HTMLGL.stage.changed = false;\n        }\n    }\n\n    p.updateTextures = function () {\n        var updatePromises = [];\n\n        w.HTMLGL.elements.forEach(function (element) {\n            updatePromises.push(element.updateTexture());\n        });\n\n        return Promise.all(updatePromises);\n    }\n\n    p.initElements = function () {\n        w.HTMLGL.elements.forEach(function (element) {\n            element.init();\n        });\n    }\n\n    p.updateElementsPositions = function () {\n        w.HTMLGL.elements.forEach(function (element) {\n            element.updateBoundingRect();\n            element.updatePivot();\n            element.updateSpriteTransform();\n        });\n    }\n\n    p.onMouseEvent = function (event) {\n        var x = event.x || event.pageX,\n            y = event.y || event.pageY,\n        //Finding element under mouse position\n            element = event.dispatcher !== 'html-gl' ? this.elementResolver.getElementByCoordinates(x, y) : null;\n\n        //Emit event if there is an element under mouse position\n        element ? w.HTMLGL.util.emitEvent(element, event) : null;\n    }\n\n    //We would like to rerender if something changed, otherwise stand by\n    p.markStageAsChanged = function () {\n        if (w.HTMLGL.stage && !w.HTMLGL.stage.changed) {\n            requestAnimationFrame(this.redrawStage);\n            w.HTMLGL.stage.changed = true;\n        }\n    }\n\n    p.disable = function () {\n        w.HTMLGL.enabled = true;\n    }\n\n    p.enable = function () {\n        w.HTMLGL.enabled = false;\n    }\n\n    w.HTMLGL.getPixelRatio = function() {\n        return window.devicePixelRatio || 1;\n    }\n\n    w.HTMLGL.pixelRatio = w.HTMLGL.getPixelRatio();\n\n    w.HTMLGL.GLContext = GLContext;\n    new GLContext();\n})(window);"
  },
  {
    "path": "src/gl-effects-manager.js",
    "content": "/*\n * GLEffectsManager is a part of HTML GL library for applying effects based on tag attributes\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var GLEffectsManager = function (element) {\n        this.element = element;\n        this.filters = {};\n        this.initObserver();\n        this.updateFilters();\n    }\n\n    var p = GLEffectsManager.prototype;\n\n    p.initObserver = function () {\n        var self = this,\n            config = {\n                attributes: true,\n                attributeFilter: ['effects']\n            };\n\n        this.observer = this.observer || new MutationObserver(self.updateFilters.bind(this));\n\n        this.observer.observe(this.element, config);\n    }\n\n    p.updateFilters = function () {\n        var attributeValue = this.element.getAttribute('effects') || '',\n            effectsNamesArray = attributeValue.split(' ');\n\n        this.addFiltersFromAttributes(effectsNamesArray);\n        this.cleanFiltersFromAttributes(effectsNamesArray);\n    }\n\n    p.addFiltersFromAttributes = function (effectsNamesArray) {\n        var self = this;\n        effectsNamesArray.forEach(function (effectName) {\n            if (HTMLGL.effects[effectName]) {\n                self.filters[effectName] = self.filters[effectName] || new HTMLGL.effects[effectName](self.element);\n            }\n        });\n    }\n\n    p.cleanFiltersFromAttributes = function (effectsNamesArray) {\n        var self = this;\n        Object.keys(this.filters).forEach(function (effectName) {\n            if (effectsNamesArray.indexOf(effectName) === -1 && self.filters[effectName]) {\n                self.filters[effectName].destroy();\n                self.filters[effectName] = null;\n            }\n        });\n    }\n\n    w.HTMLGL.GLEffectsManager = GLEffectsManager;\n\n    //Reinitialize effects on elements\n    w.HTMLGL.elements.forEach(function (element) {\n        element.initEffects();\n    });\n})(window);"
  },
  {
    "path": "src/gl-element-resolver.js",
    "content": "/*\n * GLElementResolver is a part of HTML GL library for resolving elements by coordinates given\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var GLElementResolver = function (context) {\n    }\n\n    var p = GLElementResolver.prototype;\n\n    p.getElementByCoordinates = function (x, y) {\n        var element,\n            self = this,\n            result;\n\n        w.HTMLGL.elements.forEach(function (glelement) {\n            element = document.elementFromPoint(x - parseInt(glelement.transformObject.translateX || 0), y - parseInt(glelement.transformObject.translateY || 0))\n            if (self.isChildOf(element, glelement)) {\n                result = element;\n            }\n        });\n\n        return result;\n    }\n\n    p.isChildOf = function (child, parent) {\n        var current = child;\n        while (current) {\n            if (current === parent) return true;\n            current = current.parentNode;\n        }\n        return false;\n    }\n\n    w.HTMLGL.GLElementResolver = GLElementResolver;\n})(window);"
  },
  {
    "path": "src/gl-element.js",
    "content": "/*\n * GLElement is a part of HTML GL library describing single HTML-GL element\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n *\n * Please, take into account:\n * - updateTexture is expensive\n * - updateSpriteTransform is cheap\n * */\n\n(function (w) {\n    var p = Object.create(HTMLElement.prototype),\n        style = document.createElement('style');\n\n    //Default styling for html-gl elements\n    style.innerHTML = HTMLGL.CUSTOM_ELEMENT_TAG_NAME + ' { display: inline-block; transform: translateZ(0);}';\n    document.head.appendChild(style);\n\n    p.createdCallback = function () {\n        //Checking is node created inside of html2canvas virtual window or not. We do not need WebGL there\n        var currentNode = this,\n            isMounted = false;\n\n        while (currentNode = currentNode.parentNode) {\n            if (currentNode.tagName === 'BODY') {\n                isMounted = true;\n            }\n        }\n\n        var isInsideHtml2Canvas = !isMounted || (this.baseURI === undefined || this.baseURI === '' || this.baseURI === null);\n\n        if (!isInsideHtml2Canvas) {\n            HTMLGL.elements.push(this);\n            //Needed to determine is element WebGL rendered or not relying on tag name\n            this.setAttribute('renderer', 'webgl');\n            this.renderer = 'webgl';\n\n            this.transformObject = {};\n            this.boundingRect = {};\n            this.image = {};\n            this.sprite = new PIXI.Sprite();\n            this.texture = {};\n\n            this.halfWidth = 0;\n            this.halfHeight = 0;\n\n            this.observer = undefined;\n\n            this.glChilds = [];\n            this.glChildsReady = 0;\n            this.glParent = this.getGlParent();\n\n            this.initEffects();\n            this.bindCallbacks();\n            this.transformProperty = this.style.transform !== undefined ? 'transform' : 'WebkitTransform';\n            this.init();\n        }\n    }\n\n    p.init = function () {\n        this.notifyGlParent();\n        this.updateTexture();\n        this.initObservers();\n        this.patchStyleGLTransform();\n    }\n\n    p.getGlParent = function () {\n        var parent = this,\n            tagName = HTMLGL.CUSTOM_ELEMENT_TAG_NAME.toUpperCase();\n\n        while (parent) {\n            parent = parent.parentNode;\n\n            if (parent && parent.tagName === tagName) {\n                return parent;\n            } else if (parent === w.document) {\n                return null;\n            }\n        }\n    }\n\n    //Notify GL parent about one more HTML GL child in the tree\n    p.notifyGlParent = function () {\n        if (this.glParent) {\n            this.glParent.addGlChild(this);\n        }\n    }\n\n    p.addGlChild = function (child) {\n        this.glChilds.push(child);\n    }\n\n    p.glChildReady = function () {\n        this.glChildsReady++;\n        this.dispatchReady();\n    }\n\n    //If all my childs ready notify parent that I am\n    p.dispatchReady = function () {\n        if (this.isReady()) {\n            var event = new Event(HTMLGL.READY_EVENT);\n            this.dispatchEvent(event);\n\n            if (this.glParent) {\n                //Inform parent\n                this.glParent.glChildReady();\n            }\n        }\n    }\n\n    p.isReady = function () {\n        return (this.glChilds.length - this.glChildsReady === 0) && this.haveSprite();\n    }\n\n    //Updating bounds, waiting for all images to load and calling rasterization then\n    p.updateTexture = function () {\n        var self = this;\n        self.updateBoundingRect();\n\n        return new Promise(function(resolve, reject){\n            self.image = html2canvas(self, {\n                width: self.boundingRect.width * HTMLGL.pixelRatio,\n                height: self.boundingRect.height * HTMLGL.pixelRatio\n            }).then(function(textureCanvas){\n                self.applyNewTexture(textureCanvas);\n                resolve();\n            });\n        });\n    }\n\n    //Recreating texture from canvas given after calling updateTexture\n    p.applyNewTexture = function (textureCanvas) {\n        this.image = textureCanvas;\n        this.texture = PIXI.Texture.fromCanvas(this.image);\n\n        if (!this.haveSprite()) {\n            this.initSprite(this.texture);\n        } else {\n            this.sprite.texture.destroy();\n            this.sprite.texture = this.texture;\n        }\n\n        this.updatePivot();\n        this.updateSpriteTransform();\n\n        HTMLGL.context.markStageAsChanged();\n    }\n\n    //Just updates WebGL representation coordinates and transformation\n    p.updateSpriteTransform = function () {\n\n        //TODO add 3d rotation support\n        var translateX = parseFloat(this.transformObject.translateX) || 0,\n            translateY = parseFloat(this.transformObject.translateY) || 0,\n            scaleX = parseFloat(this.transformObject.scaleX) || 1,\n            scaleY = parseFloat(this.transformObject.scaleY) || 1,\n            rotate = (parseFloat(this.transformObject.rotateZ) / 180) * Math.PI || 0;\n\n        if (this.sprite && this.sprite.position) {\n            this.sprite.position.x = (this.boundingRect.left + translateX) * HTMLGL.pixelRatio + this.halfWidth;\n            this.sprite.position.y = (this.boundingRect.top + translateY) * HTMLGL.pixelRatio + this.halfHeight;\n            this.sprite.scale.x = scaleX;\n            this.sprite.scale.y = scaleY;\n            this.sprite.rotation = rotate;\n        }\n\n        HTMLGL.context.markStageAsChanged();\n    }\n\n    //Getting bounding rect with respect to current scroll position\n    p.updateBoundingRect = function () {\n        var boundingRect = this.getBoundingClientRect();\n\n        this.boundingRect = {\n            left: boundingRect.left,\n            right: boundingRect.right,\n            top: boundingRect.top,\n            bottom: boundingRect.bottom,\n            width: boundingRect.width,\n            height: boundingRect.height,\n        };\n\n        if (this.glParent && this.glParent.boundingRect) {\n            this.boundingRect.left -= this.glParent.boundingRect.left;\n            this.boundingRect.top -= this.glParent.boundingRect.top;\n        }\n\n        this.boundingRect.left = HTMLGL.scrollX + parseFloat(this.boundingRect.left);\n        this.boundingRect.top = HTMLGL.scrollY + parseFloat(this.boundingRect.top);\n    }\n\n    //Correct pivot needed to rotate element around it`s center\n    p.updatePivot = function () {\n        this.halfWidth = this.sprite.width / 2;\n        this.halfHeight = this.sprite.height / 2;\n        this.sprite.pivot.x = this.halfWidth;\n        this.sprite.pivot.y = this.halfHeight;\n    }\n\n    p.initSprite = function (texture) {\n        var self = this,\n            parentSprite = this.glParent && this.glParent.sprite || w.HTMLGL.document;\n\n        this.sprite.texture = texture;\n        parentSprite.addChild(this.sprite);\n\n        setTimeout(function () {\n            self.hideDOM();\n            //Notify parents that I am initialized\n            self.dispatchReady();\n        }, 0);\n    }\n\n    p.initObservers = function () {\n        //TODO Better heuristics for rerendering condition #2\n        var self = this,\n            config = {\n                childList: true,\n                characterData: true,\n                subtree: true,\n                attributes: true,\n                attributeFilter: ['style']\n            };\n\n        this.observer = this.observer || new MutationObserver(function (mutations) {\n            if (mutations[0].attributeName === 'style') {\n                self.transformObject = self.getTransformObjectFromString(self.style[self.transformProperty]);\n                self.updateSpriteTransform();\n            } else {\n                self.updateTexture();\n            }\n        });\n\n        this.observer.observe(this, config);\n    }\n\n    p.patchStyleGLTransform = function () {\n        var self = this;\n        self.styleGL = {};\n\n        HTMLGL.util.getterSetter(this.styleGL, this.transformProperty, function () {\n                var result = '';\n\n                for (var transformPropertyName in self.transformObject) {\n                    var transformPropertyValue = '(' + self.transformObject[transformPropertyName] + ') ';\n                    result += transformPropertyName + transformPropertyValue;\n                }\n\n                return result;\n            },\n            function (value) {\n                self.transformObject = self.getTransformObjectFromString(value);\n                self.updateSpriteTransform();\n            }\n        )\n    }\n\n    p.getTransformObjectFromString = function (transformString) {\n        return (transformString.match(/([\\w]+)\\(([^\\)]+)\\)/g) || [])\n            .map(function (it) {\n                return it.replace(/\\)$/, \"\").split(/\\(/)\n            })\n            .reduce(function (m, it) {\n                return m[it[0]] = it[1], m\n            }, {});\n    }\n\n    p.hideDOM = function () {\n        this.style.opacity = 0;\n    }\n\n    p.bindCallbacks = function () {\n        this.applyNewTexture = this.applyNewTexture.bind(this);\n    }\n\n    p.haveSprite = function () {\n        return this.sprite.stage;\n    }\n\n    p.initEffects = function () {\n        if (HTMLGL.GLEffectsManager) {\n            this.effectsManager = new HTMLGL.GLEffectsManager(this);\n        }\n    }\n\n    HTMLGL.GLElement = document.registerElement(HTMLGL.CUSTOM_ELEMENT_TAG_NAME, {\n        prototype: p\n    })\n\n    HTMLGL.GLElement.createFromNode = function (node) {\n        //Extending node with GLElement methods\n        for (var i in p) {\n            if (p.hasOwnProperty(i)) {\n                node[i] = p[i];\n            }\n        }\n\n        p.createdCallback.apply(node);\n        return node;\n    }\n\n    //Wrap to jQuery plugin\n    if (w.jQuery !== undefined) {\n        jQuery[HTMLGL.JQ_PLUGIN_NAME] = {};\n        jQuery[HTMLGL.JQ_PLUGIN_NAME].elements = [];\n\n        jQuery.fn[HTMLGL.JQ_PLUGIN_NAME] = function () {\n            return this.each(function () {\n                if (!jQuery.data(this, 'plugin_' + HTMLGL.JQ_PLUGIN_NAME)) {\n                    var htmlGLobj = HTMLGL.GLElement.createFromNode(this);\n                    jQuery.data(this, 'plugin_' + HTMLGL.JQ_PLUGIN_NAME, htmlGLobj);\n                    jQuery[HTMLGL.JQ_PLUGIN_NAME].elements.push(htmlGLobj);\n                }\n            });\n        };\n    }\n})(window);"
  },
  {
    "path": "src/images-loaded.js",
    "content": "/*\n * ImagesLoaded is a part of HTML GL library which is a robust solution for determining \"are images loaded or not?\"\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function (w) {\n    var ImagesLoaded = function (element, callback) {\n        this.element = element;\n        this.images = this.element.querySelectorAll('img');\n        this.callback = callback;\n        this.imagesLoaded = this.getImagesLoaded();\n\n        if (this.images.length === this.imagesLoaded) {\n            this.onImageLoaded();\n        } else {\n            this.addListeners();\n        }\n    }\n\n    var p = ImagesLoaded.prototype;\n\n    p.getImagesLoaded = function () {\n        var result = 0;\n        for (var i = 0; i < this.images.length; i++) {\n            if (this.images[i].complete === true) {\n                result++;\n            }\n        }\n        return result;\n    }\n\n    p.addListeners = function () {\n        var result = 0;\n        for (var i = 0; i < this.images.length; i++) {\n            if (this.images[i].complete !== true) {\n                this.images[i].addEventListener('load', this.onImageLoaded.bind(this));\n                this.images[i].addEventListener('error', this.onImageLoaded.bind(this));\n            }\n        }\n        return result;\n    }\n\n    p.onImageLoaded = function () {\n        this.imagesLoaded++;\n        if (this.images.length - this.imagesLoaded <= 0) {\n            setTimeout(this.callback, 0);\n        }\n    }\n\n    w.HTMLGL.ImagesLoaded = ImagesLoaded;\n})(window);"
  },
  {
    "path": "src/util.js",
    "content": "/*\n * Util is a part of HTML GL library\n * Copyright (c) 2015 pixelscommander.com\n * Distributed under MIT license\n * http://htmlgl.com\n * */\n\n(function(w){\n    w.HTMLGL = w.HTMLGL || {};\n    w.HTMLGL.util = {\n        getterSetter: function  (variableParent, variableName, getterFunction, setterFunction) {\n            if (Object.defineProperty) {\n                Object.defineProperty(variableParent, variableName, {\n                    get: getterFunction,\n                    set: setterFunction\n                });\n            }\n            else if (document.__defineGetter__) {\n                variableParent.__defineGetter__(variableName, getterFunction);\n                variableParent.__defineSetter__(variableName, setterFunction);\n            }\n\n            variableParent[\"get\" + variableName] = getterFunction;\n            variableParent[\"set\" + variableName] = setterFunction;\n        },\n        emitEvent: function (element, event) {\n            var newEvent = new MouseEvent(event.type, event);\n            newEvent.dispatcher = 'html-gl';\n            event.stopPropagation();\n            element.dispatchEvent(newEvent);\n        },\n        debounce: function(func, wait, immediate) {\n            var timeout;\n            return function() {\n                var context = this, args = arguments;\n                var later = function() {\n                    timeout = null;\n                    if (!immediate) func.apply(context, args);\n                };\n                var callNow = immediate && !timeout;\n                clearTimeout(timeout);\n                timeout = setTimeout(later, wait);\n                if (callNow) func.apply(context, args);\n            };\n        }\n    }\n})(window);"
  }
]