diff --git a/tests/AppHarness.js b/tests/AppHarness.js
new file mode 100755
index 00000000..a8b76a44
--- /dev/null
+++ b/tests/AppHarness.js
@@ -0,0 +1,337 @@
+//---------------------------------------------------
+// Application Harness
+var AppHarness = (function () {
+ //------------------------------------------------------------------------------
+ function AppHarness() {
+ var _this = this;
+ //------------------------------------------------------------------------------
+ this.tests = new Array();
+ this.counter = 0;
+ this.sourceVisible = false;
+ this.loadDefault = true;
+ this.initFrameSet();
+ this.initInterface();
+ this.previousBtn.onclick = function () { return _this.nagigateBy(-1); };
+ this.nextBtn.onclick = function () { return _this.nagigateBy(1); };
+ this.sourceBtn.onclick = function () { return _this.toggleSource(); };
+ this.dropDown.onchange = function (e) { return _this.dropDownChange(e); };
+ }
+ //------------------------------------------------------------------------------
+ /**
+ *
+ * Load a test
+ *
+ * @param classPath - Module and Class path of test
+ * @param js Path to JavaScript file
+ * @param ts Path to Typescript file ( not yet used - reserved for future show source )
+ */
+ AppHarness.prototype.load = function (classPath, js, ts) {
+ this.loadFromURL();
+ if (this.loadDefault) {
+ window.history.pushState(js, js, '?test=' + js);
+ this.testIframe.src = 'frame.html?name=' + classPath + '&js=' + js;
+ this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML(ts);
+ }
+ };
+ /**
+ *
+ * Add a test to the AppHarness
+ *
+ * @param name Name of test
+ * @param classPath - Module and Class path of test
+ * @param js Path to JavaScript file
+ * @param ts Path to Typescript file ( not yet used - reserved for future show source )
+ */
+ AppHarness.prototype.addTest = function (name, classpath, js, ts) {
+ this.tests.push(new TestData(name, classpath, js, ts));
+ };
+ /**
+ *
+ * Add a separator to the menu
+ *
+ * @param name
+ */
+ AppHarness.prototype.addSeperator = function (name) {
+ if (name === void 0) { name = ''; }
+ this.tests.push(new TestData('-- ' + name, '', '', ''));
+ };
+ /**
+ *
+ * Start the application harness
+ *
+ */
+ AppHarness.prototype.start = function (slideshowMode) {
+ var _this = this;
+ if (slideshowMode === void 0) { slideshowMode = false; }
+ for (var c = 0; c < this.tests.length; c++) {
+ var option = new Option(this.tests[c].name, String(c));
+ this.dropDown.add(option);
+ }
+ if (slideshowMode) {
+ setInterval(function () { return _this.nagigateBy(1); }, 15000);
+ }
+ };
+ //------------------------------------------------------------------------------
+ AppHarness.prototype.loadFromURL = function () {
+ var queryParams = Utils.getQueryParams(document.location.search);
+ if (queryParams.test != null) {
+ var l = this.tests.length;
+ for (var c = 0; c < l; c++) {
+ if (this.tests[c].js == queryParams.test) {
+ console.log('======>>>> LOAD TEST');
+ this.navigateToSection(this.tests[c]);
+ this.loadDefault = false;
+ }
+ }
+ }
+ };
+ /**
+ *
+ */
+ AppHarness.prototype.initInterface = function () {
+ var testSelector = document.createElement('div');
+ testSelector.style.cssFloat = 'none';
+ testSelector.style.position = 'absolute';
+ testSelector.style.bottom = '15px';
+ testSelector.style.width = '600px';
+ testSelector.style.left = '50%';
+ testSelector.style.marginLeft = '-300px';
+ testSelector.style.textAlign = 'center';
+ this.dropDown = document.createElement('select');
+ this.dropDown.name = "selectTestDropDown";
+ this.dropDown.id = "selectTest";
+ this.sourceBtn = document.createElement('button');
+ this.sourceBtn.innerHTML = 'Show Source';
+ this.sourceBtn.id = 'previous';
+ this.previousBtn = document.createElement('button');
+ this.previousBtn.innerHTML = '<<';
+ this.previousBtn.id = 'previous';
+ this.nextBtn = document.createElement('button');
+ this.nextBtn.innerHTML = '>>';
+ this.nextBtn.id = 'next';
+ testSelector.appendChild(this.sourceBtn);
+ testSelector.appendChild(this.previousBtn);
+ testSelector.appendChild(this.dropDown);
+ testSelector.appendChild(this.nextBtn);
+ document.body.appendChild(testSelector);
+ };
+ /**
+ *
+ */
+ AppHarness.prototype.initFrameSet = function () {
+ var iframeContainer = document.createElement('div');
+ iframeContainer.style.width = '100%';
+ iframeContainer.style.height = '100%';
+ this.testIframe = document.createElement('iframe');
+ this.testIframe.id = 'testContainer';
+ this.testIframe.style.backgroundColor = '#9e9e9e';
+ this.testIframe.style.cssFloat = 'none';
+ this.testIframe.style.position = 'absolute';
+ this.testIframe.style.top = '0px';
+ this.testIframe.style.left = '0px';
+ this.testIframe.style.border = '0px';
+ this.testIframe.style.width = '100%';
+ this.testIframe.style.height = '100%';
+ //bottom: 120px;
+ this.srcIframe = document.createElement('iframe');
+ this.srcIframe.id = 'testSourceContainer';
+ this.srcIframe.style.backgroundColor = '#9e9e9e';
+ this.srcIframe.style.cssFloat = 'none';
+ this.srcIframe.style.position = 'absolute';
+ this.srcIframe.style.right = '0px';
+ this.srcIframe.style.top = '0px';
+ this.srcIframe.style.bottom = '0px';
+ this.srcIframe.style.border = '0px';
+ this.srcIframe.style.width = '0%';
+ this.srcIframe.style.height = '100%';
+ iframeContainer.appendChild(this.testIframe);
+ iframeContainer.appendChild(this.srcIframe);
+ document.body.appendChild(iframeContainer);
+ };
+ /**
+ *
+ * Selectnext / previous menu item
+ *
+ * @param direction
+ */
+ AppHarness.prototype.nagigateBy = function (direction) {
+ if (direction === void 0) { direction = 1; }
+ var l = this.tests.length;
+ var nextCounter = this.counter + direction;
+ if (nextCounter < 0) {
+ nextCounter = this.tests.length - 1;
+ }
+ else if (nextCounter > this.tests.length - 1) {
+ nextCounter = 0;
+ }
+ var testData = this.tests[nextCounter];
+ if (testData.name.indexOf('--') != -1) {
+ this.counter = nextCounter;
+ this.nagigateBy(direction);
+ }
+ else {
+ this.navigateToSection(testData);
+ this.dropDown.selectedIndex = nextCounter;
+ this.counter = nextCounter;
+ }
+ };
+ /**
+ *
+ * Navigate to a section
+ *
+ * @param testData
+ */
+ AppHarness.prototype.navigateToSection = function (testData) {
+ window.history.pushState(testData.js, testData.js, '?test=' + testData.js);
+ this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML(testData.src);
+ this.testIframe.src = 'frame.html?name=' + testData.classpath + '&js=' + testData.js;
+ };
+ AppHarness.prototype.toggleSource = function () {
+ if (this.sourceVisible) {
+ this.testIframe.style.width = '100%';
+ this.srcIframe.style.width = '0%';
+ this.sourceBtn.innerHTML = 'Show Source';
+ }
+ else {
+ this.testIframe.style.width = '20%';
+ this.srcIframe.style.width = '80%';
+ this.sourceBtn.innerHTML = 'Hide Source';
+ }
+ this.sourceVisible = !this.sourceVisible;
+ };
+ AppHarness.prototype.createSourceViewHTML = function (url) {
+ var html = '';
+ html += '';
+ html += '';
+ html += '
';
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ html += '';
+ html += '';
+ html += '';
+ html += '';
+ return html;
+ };
+ //------------------------------------------------------------------------------
+ // Utils
+ /**
+ *
+ * Util function - get Element by ID
+ *
+ * @param id
+ * @returns {HTMLElement}
+ */
+ AppHarness.prototype.getId = function (id) {
+ return document.getElementById(id);
+ };
+ //------------------------------------------------------------------------------
+ // Events
+ /**
+ *
+ * Dropbox event handler
+ *
+ * @param e
+ */
+ AppHarness.prototype.dropDownChange = function (e) {
+ this.dropDown.options[this.dropDown.selectedIndex].value;
+ this.counter = this.dropDown.selectedIndex;
+ var dataIndex = parseInt(this.dropDown.options[this.dropDown.selectedIndex].value);
+ if (!isNaN(dataIndex)) {
+ this.navigateToSection(this.tests[dataIndex]);
+ }
+ };
+ return AppHarness;
+})();
+//---------------------------------------------------
+// Application Frame
+var AppFrame = (function () {
+ function AppFrame() {
+ this.classPath = '';
+ this.jsPath = '';
+ var queryParams = Utils.getQueryParams(document.location.search);
+ if (queryParams.js != undefined && queryParams.name != undefined) {
+ this.jsPath = queryParams.js;
+ this.classPath = queryParams.name;
+ this.loadJS(this.jsPath);
+ }
+ }
+ /**
+ *
+ * Load a JavaScript file
+ *
+ * @param url - URL of JavaScript file
+ */
+ AppFrame.prototype.loadJS = function (url) {
+ var _this = this;
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.type = "text/javascript";
+ script.src = url;
+ script.onload = function () { return _this.jsLoaded(); };
+ head.appendChild(script);
+ };
+ /**
+ *
+ * Event Handler for loaded JavaScript files
+ *
+ */
+ AppFrame.prototype.jsLoaded = function () {
+ var createPath = this.classPath.split('.'); // Split the classpath
+ var obj;
+ for (var c = 0; c < createPath.length; c++) {
+ if (obj == null) {
+ obj = window[createPath[c]]; // reference base module ( will be a child of the window )
+ }
+ else {
+ obj = obj[createPath[c]]; // reference sub module / Class
+ }
+ }
+ if (obj != null) {
+ new obj(); // if Class has been found - start the test
+ }
+ };
+ return AppFrame;
+})();
+//---------------------------------------------------
+// Common Utilities
+var Utils = (function () {
+ function Utils() {
+ }
+ /**
+ *
+ * Utility function - Parse a Query formatted string
+ *
+ * @param qs
+ * @returns {{}}
+ */
+ Utils.getQueryParams = function (qs) {
+ qs = qs.split("+").join(" ");
+ var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g;
+ while (tokens = re.exec(qs)) {
+ params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
+ }
+ return params;
+ };
+ return Utils;
+})();
+//---------------------------------------------------
+// Data
+var TestData = (function () {
+ function TestData(name, classpath, js, src) {
+ this.js = js;
+ this.classpath = classpath;
+ this.src = src;
+ this.name = name;
+ }
+ return TestData;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcGhhcm5lc3MudHMiXSwibmFtZXMiOlsiQXBwSGFybmVzcyIsIkFwcEhhcm5lc3MuY29uc3RydWN0b3IiLCJBcHBIYXJuZXNzLmxvYWQiLCJBcHBIYXJuZXNzLmFkZFRlc3QiLCJBcHBIYXJuZXNzLmFkZFNlcGVyYXRvciIsIkFwcEhhcm5lc3Muc3RhcnQiLCJBcHBIYXJuZXNzLmxvYWRGcm9tVVJMIiwiQXBwSGFybmVzcy5pbml0SW50ZXJmYWNlIiwiQXBwSGFybmVzcy5pbml0RnJhbWVTZXQiLCJBcHBIYXJuZXNzLm5hZ2lnYXRlQnkiLCJBcHBIYXJuZXNzLm5hdmlnYXRlVG9TZWN0aW9uIiwiQXBwSGFybmVzcy50b2dnbGVTb3VyY2UiLCJBcHBIYXJuZXNzLmNyZWF0ZVNvdXJjZVZpZXdIVE1MIiwiQXBwSGFybmVzcy5nZXRJZCIsIkFwcEhhcm5lc3MuZHJvcERvd25DaGFuZ2UiLCJBcHBGcmFtZSIsIkFwcEZyYW1lLmNvbnN0cnVjdG9yIiwiQXBwRnJhbWUubG9hZEpTIiwiQXBwRnJhbWUuanNMb2FkZWQiLCJVdGlscyIsIlV0aWxzLmNvbnN0cnVjdG9yIiwiVXRpbHMuZ2V0UXVlcnlQYXJhbXMiLCJUZXN0RGF0YSIsIlRlc3REYXRhLmNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQSxxREFBcUQ7QUFDckQsc0JBQXNCO0FBRXRCLElBQU0sVUFBVTtJQWdCZkEsZ0ZBQWdGQTtJQUVoRkEsU0FsQktBLFVBQVVBO1FBQWhCQyxpQkErVUNBO1FBNVVBQSxnRkFBZ0ZBO1FBRXhFQSxVQUFLQSxHQUErQkEsSUFBSUEsS0FBS0EsRUFBWUEsQ0FBQ0E7UUFPMURBLFlBQU9BLEdBQW9CQSxDQUFDQSxDQUFDQTtRQUM3QkEsa0JBQWFBLEdBQWVBLEtBQUtBLENBQUNBO1FBQ2xDQSxnQkFBV0EsR0FBaUJBLElBQUlBLENBQUNBO1FBT3hDQSxJQUFJQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQTtRQUNwQkEsSUFBSUEsQ0FBQ0EsYUFBYUEsRUFBRUEsQ0FB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QSxJQUFJQSxDQUFDQSxXQUFXQSxHQUEwQ0EsUUFBUUEsQ0FBQ0EsYUFBYUEsQ0FBRUEsUUFBUUEsQ0FBRUEsQ0FBQ0E7UUFDN0ZBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLFNBQVNBLEdBQVlBLElBQUlBLENBQUNBO1FBQzNDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFDQSxFQUFFQSxHQUFtQkEsVUFBVUEsQ0FBQ0E7UUFFakRBLElBQUlBLENBQUNBLE9BQU9BLEdBQThDQSxRQUFRQSxDQUFDQSxhQUFhQSxDQUFFQSxRQUFRQSxDQUFFQSxDQUFDQTtRQUM3RkEsSUFBSUEsQ0FBQ0EsT0FBT0EsQ0FBQ0EsU0FBU0EsR0FBZ0JBLElBQUlBLENBQUNBO1FBQzNDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxFQUFFQSxHQUF1QkEsTUFBTUEsQ0FBQ0E7UUFHN0NBLFlBQVlBLENBQUNBLFdBQVdBLENBQUVBLElBQUlBLENBQUNBLFNBQVNBLENBQUVBLENBQUNBO1FBQzNDQSxZQUFZQSxDQUFDQSxXQUFXQSxDQUFFQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFFQSxDQUFDQTtRQUM3Q0EsWUFBWUEsQ0FBQ0EsV0FBV0EsQ0FBRUEsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBRUEsQ0FBQ0E7UUFDMUNBLFlBQVlBLENBQUNBLFdBQVdBLENBQUVBLElBQUlBLENBQUNBLE9BQU9BLENBQUVBLENBQUNBO1FBQ3pDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxXQUFXQSxDQUFFQSxZQUFZQSxDQUFFQSxDQUFDQTtJQUMzQ0EsQ0FBQ0E7SUFDRFA7O09BRUdBO0lBQ0tBLGlDQUFZQSxHQUFwQkE7UUFHQ1EsSUFBSUEsZUFBZUEsR0FBd0NBLFFBQVFBLENBQUNBLGFBQWFBLENBQUVBLEtBQUtBLENBQUVBLENBQUNBO1FBQzFGQSxlQUFlQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxHQUFXQSxNQUFNQSxDQUFDQTtRQUM3Q0EsZUFBZUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsTUFBTUEsR0FBVUEsTUFBTUEsQ0FBQ0E7UUFFOUNB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QSxDQUFDQTtRQUVEQSxNQUFNQSxDQUFDQSxNQUFNQSxDQUFDQTtJQUNmQSxDQUFDQTtJQUNGRixZQUFDQTtBQUFEQSxDQXRCQSxBQXNCQ0EsSUFBQTtBQUVELEFBR0EscURBSHFEO0FBQ3JELE9BQU87SUFFRCxRQUFRO0lBT2JHLFNBUEtBLFFBQVFBLENBT0FBLElBQWFBLEVBQUdBLFNBQWtCQSxFQUFHQSxFQUFXQSxFQUFHQSxHQUFZQTtRQUUzRUMsSUFBSUEsQ0FBQ0EsRUFBRUEsR0FBV0EsRUFBRUEsQ0FBQ0E7UUFDckJBLElBQUlBLENBQUNBLFNBQVNBLEdBQUlBLFNBQVNBLENBQUNBO1FBQzVCQSxJQUFJQSxDQUFDQSxHQUFHQSxHQUFVQSxHQUFHQSxDQUFDQTtRQUN0QkEsSUFBSUEsQ0FBQ0EsSUFBSUEsR0FBU0EsSUFBSUEsQ0FBQ0E7SUFDeEJBLENBQUNBO0lBQ0ZELGVBQUNBO0FBQURBLENBZEEsQUFjQ0EsSUFBQSIsImZpbGUiOiJBcHBIYXJuZXNzLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXN0YWdlZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEFwcGxpY2F0aW9uIEhhcm5lc3NcblxuY2xhc3MgQXBwSGFybmVzc1xue1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSB0ZXN0cyAgICAgICAgICAgOiBBcnJheTxUZXN0RGF0YT4gPSBuZXcgQXJyYXk8VGVzdERhdGE+KCk7XG5cdHByaXZhdGUgZHJvcERvd24gICAgICAgIDogSFRNTFNlbGVjdEVsZW1lbnQ7XG5cdHByaXZhdGUgcHJldmlvdXNCdG4gICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG5cdHByaXZhdGUgbmV4dEJ0biAgICAgICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG5cdHByaXZhdGUgc291cmNlQnRuICAgICAgIDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG5cdHByaXZhdGUgdGVzdElmcmFtZSAgICAgIDogSFRNTElGcmFtZUVsZW1lbnQ7XG5cdHByaXZhdGUgc3JjSWZyYW1lICAgICAgIDogSFRNTElGcmFtZUVsZW1lbnQ7XG5cdHByaXZhdGUgY291bnRlciAgICAgICAgIDogbnVtYmVyID0gMDtcblx0cHJpdmF0ZSBzb3VyY2VWaXNpYmxlICAgOiBib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgbG9hZERlZmF1bHQgICAgIDogYm9vbGVhbiA9IHRydWU7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblxuXHRcdHRoaXMuaW5pdEZyYW1lU2V0KCk7XG5cdFx0dGhpcy5pbml0SW50ZXJmYWNlKCk7XG5cblxuXHRcdHRoaXMucHJldmlvdXNCdG4ub25jbGljayAgID0gKCkgPT4gdGhpcy5uYWdpZ2F0ZUJ5KCAtMSApO1xuXHRcdHRoaXMubmV4dEJ0bi5vbmNsaWNrICAgICAgID0gKCkgPT4gdGhpcy5uYWdpZ2F0ZUJ5KCAxICk7XG5cdFx0dGhpcy5zb3VyY2VCdG4ub25jbGljayAgICAgPSAoKSA9PiB0aGlzLnRvZ2dsZVNvdXJjZSgpO1xuXHRcdHRoaXMuZHJvcERvd24ub25jaGFuZ2UgICAgICA9ICggZSApID0+IHRoaXMuZHJvcERvd25DaGFuZ2UoIGUgKTtcblxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHQvKipcblx0ICpcblx0ICogTG9hZCBhIHRlc3Rcblx0ICpcblx0ICogQHBhcmFtIGNsYXNzUGF0aCAtIE1vZHVsZSBhbmQgQ2xhc3MgcGF0aCBvZiB0ZXN0XG5cdCAqIEBwYXJhbSBqcyBQYXRoIHRvIEphdmFTY3JpcHQgZmlsZVxuXHQgKiBAcGFyYW0gdHMgUGF0aCB0byBUeXBlc2NyaXB0IGZpbGUgKCBub3QgeWV0IHVzZWQgLSByZXNlcnZlZCBmb3IgZnV0dXJlIHNob3cgc291cmNlIClcblx0ICovXG5cdHB1YmxpYyBsb2FkKCBjbGFzc1BhdGggOiBzdHJpbmcgLCBqcyA6IHN0cmluZyAsIHRzIDogc3RyaW5nICkgOiB2b2lkXG5cdHtcblxuXHRcdHRoaXMubG9hZEZyb21VUkwoKTtcblxuXHRcdGlmICggdGhpcy5sb2FkRGVmYXVsdCApXG5cdFx0e1xuXHRcdFx0d2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKGpzLCBqcywgJz90ZXN0PScgKyBqcyk7XG5cdFx0XHR0aGlzLnRlc3RJZnJhbWUuc3JjID0gJ2ZyYW1lLmh0bWw/bmFtZT0nICsgY2xhc3NQYXRoICsgJyZqcz0nICsganM7XG5cdFx0XHR0aGlzLnNyY0lmcmFtZS5zcmMgPSBcImRhdGE6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgsXCIgKyB0aGlzLmNyZWF0ZVNvdXJjZVZpZXdIVE1MKCB0cyApO1xuXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqIEFkZCBhIHRlc3QgdG8gdGhlIEFwcEhhcm5lc3Ncblx0ICpcblx0ICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0ZXN0XG5cdCAqIEBwYXJhbSBjbGFzc1BhdGggLSBNb2R1bGUgYW5kIENsYXNzIHBhdGggb2YgdGVzdFxuXHQgKiBAcGFyYW0ganMgUGF0aCB0byBKYXZhU2NyaXB0IGZpbGVcblx0ICogQHBhcmFtIHRzIFBhdGggdG8gVHlwZXNjcmlwdCBmaWxlICggbm90IHlldCB1c2VkIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSBzaG93IHNvdXJjZSApXG5cdCAqL1xuXHRwdWJsaWMgYWRkVGVzdCggbmFtZSA6IHN0cmluZyAsIGNsYXNzcGF0aCA6IHN0cmluZyAsIGpzIDogc3RyaW5nICwgdHMgOiBzdHJpbmcgKSA6IHZvaWRcblx0e1xuXHRcdHRoaXMudGVzdHMucHVzaCAoIG5ldyBUZXN0RGF0YSggbmFtZSAsIGNsYXNzcGF0aCAsIGpzICwgdHMgKSApO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqIEFkZCBhIHNlcGFyYXRvciB0byB0aGUgbWVudVxuXHQgKlxuXHQgKiBAcGFyYW0gbmFtZVxuXHQgKi9cblx0cHVibGljIGFkZFNlcGVyYXRvciggbmFtZSA6IHN0cmluZyA9ICcnICkgOiB2b2lkXG5cdHtcblx0XHR0aGlzLnRlc3RzLnB1c2ggKCBuZXcgVGVzdERhdGEoICctLSAnICsgbmFtZSAsICcnICwgJycgLCAnJykgKTtcblx0fVxuXG5cdC8qKlxuXHQgKlxuXHQgKiBTdGFydCB0aGUgYXBwbGljYXRpb24gaGFybmVzc1xuXHQgKlxuXHQgKi9cblx0cHVibGljIHN0YXJ0KCBzbGlkZXNob3dNb2RlIDogYm9vbGVhbiA9IGZhbHNlICkgOiB2b2lkXG5cdHtcblx0XHRmb3IgKCB2YXIgYyA6IG51bWJlciA9IDAgOyBjIDwgdGhpcy50ZXN0cy5sZW5ndGggOyBjICsrICApXG5cdFx0e1xuXHRcdFx0dmFyIG9wdGlvbiA6IEhUTUxPcHRpb25FbGVtZW50ID0gPEhUTUxPcHRpb25FbGVtZW50PiBuZXcgT3B0aW9uKCB0aGlzLnRlc3RzW2NdLm5hbWUgLCBTdHJpbmcoIGMgKSApO1xuXHRcdFx0dGhpcy5kcm9wRG93bi5hZGQoIG9wdGlvbiApO1xuXHRcdH1cblxuXHRcdGlmICggc2xpZGVzaG93TW9kZSApXG5cdFx0e1xuXG5cdFx0XHRzZXRJbnRlcnZhbCggKCkgPT4gdGhpcy5uYWdpZ2F0ZUJ5KCAxICkgLCAxNTAwMCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGxvYWRGcm9tVVJMKCkgOiB2b2lkXG5cdHtcblx0XHR2YXIgcXVlcnlQYXJhbXMgOiBhbnkgPSBVdGlscy5nZXRRdWVyeVBhcmFtcyggZG9jdW1lbnQubG9jYXRpb24uc2VhcmNoICk7XG5cblx0XHRpZiAoIHF1ZXJ5UGFyYW1zLnRlc3QgIT0gbnVsbCApXG5cdFx0e1xuXHRcdFx0dmFyIGwgOiBudW1iZXIgPSAgdGhpcy50ZXN0cy5sZW5ndGg7XG5cblx0XHRcdGZvciAoIHZhciBjIDogbnVtYmVyID0gMCA7IGMgPCBsIDsgYyArKyApXG5cdFx0XHR7XG5cdFx0XHRcdGlmICggdGhpcy50ZXN0c1tjXS5qcyA9PSBxdWVyeVBhcmFtcy50ZXN0IClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nICggJz09PT09PT4+Pj4gTE9BRCBURVNUJyk7XG5cblx0XHRcdFx0XHR0aGlzLm5hdmlnYXRlVG9TZWN0aW9uKCB0aGlzLnRlc3RzW2NdICk7XG5cdFx0XHRcdFx0dGhpcy5sb2FkRGVmYXVsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdC8qKlxuXHQgKlxuXHQgKi9cblx0cHJpdmF0ZSBpbml0SW50ZXJmYWNlKCkgOiB2b2lkXG5cdHtcblxuXHRcdHZhciB0ZXN0U2VsZWN0b3IgOiBIVE1MRGl2RWxlbWVudCAgID0gPEhUTUxEaXZFbGVtZW50PiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnZGl2JyApO1xuXHRcdFx0dGVzdFNlbGVjdG9yLnN0eWxlLmNzc0Zsb2F0ICAgICA9ICdub25lJztcblx0XHRcdHRlc3RTZWxlY3Rvci5zdHlsZS5wb3NpdGlvbiAgICAgPSAnYWJzb2x1dGUnO1xuXHRcdFx0dGVzdFNlbGVjdG9yLnN0eWxlLmJvdHRvbSAgICAgICA9ICcxNXB4Jztcblx0XHRcdHRlc3RTZWxlY3Rvci5zdHlsZS53aWR0aCAgICAgICAgPSAnNjAwcHgnO1xuXHRcdFx0dGVzdFNlbGVjdG9yLnN0eWxlLmxlZnQgICAgICAgICA9ICc1MCUnO1xuXHRcdFx0dGVzdFNlbGVjdG9yLnN0eWxlLm1hcmdpbkxlZnQgICA9ICctMzAwcHgnXG5cdFx0XHR0ZXN0U2VsZWN0b3Iuc3R5bGUudGV4dEFsaWduICAgID0gJ2NlbnRlcic7XG5cblxuXHRcdHRoaXMuZHJvcERvd24gICAgICAgICAgICAgICAgICAgICAgID0gPEhUTUxTZWxlY3RFbGVtZW50PiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnc2VsZWN0JyApO1xuXHRcdHRoaXMuZHJvcERvd24ubmFtZSAgICAgICAgICAgICAgICAgID0gXCJzZWxlY3RUZXN0RHJvcERvd25cIlxuXHRcdHRoaXMuZHJvcERvd24uaWQgICAgICAgICAgICAgICAgICAgID0gXCJzZWxlY3RUZXN0XCJcblxuXHRcdHRoaXMuc291cmNlQnRuICAgICAgICAgICAgICAgICAgICAgID0gPEhUTUxCdXR0b25FbGVtZW50PiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnYnV0dG9uJyApO1xuXHRcdHRoaXMuc291cmNlQnRuLmlubmVySFRNTCAgICAgICAgICAgID0gJ1Nob3cgU291cmNlJztcblx0XHR0aGlzLnNvdXJjZUJ0bi5pZCAgICAgICAgICAgICAgICAgICA9ICdwcmV2aW91cyc7XG5cblx0XHR0aGlzLnByZXZpb3VzQnRuICAgICAgICAgICAgICAgICAgICA9IDxIVE1MQnV0dG9uRWxlbWVudD4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2J1dHRvbicgKTtcblx0XHR0aGlzLnByZXZpb3VzQnRuLmlubmVySFRNTCAgICAgICAgICA9ICc8PCc7XG5cdFx0dGhpcy5wcmV2aW91c0J0bi5pZCAgICAgICAgICAgICAgICAgPSAncHJldmlvdXMnO1xuXG5cdFx0dGhpcy5uZXh0QnRuICAgICAgICAgICAgICAgICAgICAgICAgPSA8SFRNTEJ1dHRvbkVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdidXR0b24nICk7XG5cdFx0dGhpcy5uZXh0QnRuLmlubmVySFRNTCAgICAgICAgICAgICAgPSAnPj4nO1xuXHRcdHRoaXMubmV4dEJ0bi5pZCAgICAgICAgICAgICAgICAgICAgID0gJ25leHQnO1xuXG5cblx0XHR0ZXN0U2VsZWN0b3IuYXBwZW5kQ2hpbGQoIHRoaXMuc291cmNlQnRuICk7XG5cdFx0dGVzdFNlbGVjdG9yLmFwcGVuZENoaWxkKCB0aGlzLnByZXZpb3VzQnRuICk7XG5cdFx0dGVzdFNlbGVjdG9yLmFwcGVuZENoaWxkKCB0aGlzLmRyb3BEb3duICk7XG5cdFx0dGVzdFNlbGVjdG9yLmFwcGVuZENoaWxkKCB0aGlzLm5leHRCdG4gKTtcblx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKCB0ZXN0U2VsZWN0b3IgKTtcblx0fVxuXHQvKipcblx0ICpcblx0ICovXG5cdHByaXZhdGUgaW5pdEZyYW1lU2V0KCkgOiB2b2lkXG5cdHtcblxuXHRcdHZhciBpZnJhbWVDb250YWluZXIgOiBIVE1MRGl2RWxlbWVudCAgICA9IDxIVE1MRGl2RWxlbWVudD4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0XHRcdGlmcmFtZUNvbnRhaW5lci5zdHlsZS53aWR0aCAgICAgICAgID0gJzEwMCUnO1xuXHRcdFx0aWZyYW1lQ29udGFpbmVyLnN0eWxlLmhlaWdodCAgICAgICAgPSAnMTAwJSc7XG5cblx0XHR0aGlzLnRlc3RJZnJhbWUgICAgICAgICAgICAgICAgICAgICAgPSA8SFRNTElGcmFtZUVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdpZnJhbWUnICk7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLmlkICAgICAgICAgICAgICAgICAgID0gJ3Rlc3RDb250YWluZXInO1xuXHRcdHRoaXMudGVzdElmcmFtZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAnIzllOWU5ZSc7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLmNzc0Zsb2F0ICAgICAgID0gJ25vbmUnO1xuXHRcdHRoaXMudGVzdElmcmFtZS5zdHlsZS5wb3NpdGlvbiAgICAgICA9ICdhYnNvbHV0ZSc7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLnRvcCAgICAgICAgICAgID0gJzBweCc7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLmxlZnQgICAgICAgICAgID0gJzBweCc7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLmJvcmRlciAgICAgICAgID0gJzBweCc7XG5cdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLndpZHRoICAgICAgICAgID0gJzEwMCUnO1xuXHRcdHRoaXMudGVzdElmcmFtZS5zdHlsZS5oZWlnaHQgICAgICAgICA9ICcxMDAlJztcblx0XHQvL2JvdHRvbTogMTIwcHg7XG5cblx0XHR0aGlzLnNyY0lmcmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgPSA8SFRNTElGcmFtZUVsZW1lbnQ+IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdpZnJhbWUnICk7XG5cdFx0dGhpcy5zcmNJZnJhbWUuaWQgICAgICAgICAgICAgICAgICAgICAgID0gJ3Rlc3RTb3VyY2VDb250YWluZXInO1xuXHRcdHRoaXMuc3JjSWZyYW1lLnN0eWxlLmJhY2tncm91bmRDb2xvciAgICA9ICcjOWU5ZTllJztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS5jc3NGbG9hdCAgICAgICAgICAgPSAnbm9uZSc7XG5cdFx0dGhpcy5zcmNJZnJhbWUuc3R5bGUucG9zaXRpb24gICAgICAgICAgID0gJ2Fic29sdXRlJztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS5yaWdodCAgICAgICAgICAgICAgPSAnMHB4Jztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS50b3AgICAgICAgICAgICAgICAgPSAnMHB4Jztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS5ib3R0b20gICAgICAgICAgICAgPSAnMHB4Jztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS5ib3JkZXIgICAgICAgICAgICAgPSAnMHB4Jztcblx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS53aWR0aCAgICAgICAgICAgICAgPSAnMCUnO1xuXHRcdHRoaXMuc3JjSWZyYW1lLnN0eWxlLmhlaWdodCAgICAgICAgICAgICA9ICcxMDAlJztcblxuXHRcdGlmcmFtZUNvbnRhaW5lci5hcHBlbmRDaGlsZCggdGhpcy50ZXN0SWZyYW1lICk7XG5cdFx0aWZyYW1lQ29udGFpbmVyLmFwcGVuZENoaWxkKCB0aGlzLnNyY0lmcmFtZSApO1xuXG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggaWZyYW1lQ29udGFpbmVyICk7XG5cblx0fVxuXG5cdC8qKlxuXHQgKlxuXHQgKiBTZWxlY3RuZXh0IC8gcHJldmlvdXMgbWVudSBpdGVtXG5cdCAqXG5cdCAqIEBwYXJhbSBkaXJlY3Rpb25cblx0ICovXG5cdHByaXZhdGUgbmFnaWdhdGVCeSggZGlyZWN0aW9uIDogbnVtYmVyID0gMSApIDogdm9pZFxuXHR7XG5cblx0XHR2YXIgbCA6IG51bWJlciAgPSB0aGlzLnRlc3RzLmxlbmd0aDtcblx0XHR2YXIgbmV4dENvdW50ZXIgPSB0aGlzLmNvdW50ZXIgKyBkaXJlY3Rpb247XG5cblx0XHRpZiAoIG5leHRDb3VudGVyIDwgMCApXG5cdFx0e1xuXHRcdFx0bmV4dENvdW50ZXIgPSB0aGlzLnRlc3RzLmxlbmd0aCAtIDE7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKCBuZXh0Q291bnRlciA+IHRoaXMudGVzdHMubGVuZ3RoIC0gMSApXG5cdFx0e1xuXHRcdFx0bmV4dENvdW50ZXIgPSAwO1xuXHRcdH1cblxuXHRcdHZhciB0ZXN0RGF0YSA6IFRlc3REYXRhID0gdGhpcy50ZXN0c1tuZXh0Q291bnRlcl07XG5cblx0XHRpZiAoIHRlc3REYXRhLm5hbWUuaW5kZXhPZiAoJy0tJykgIT0gLTEgKSAvLyBza2lwIHNlY3Rpb24gaGVhZGVyc1xuXHRcdHtcblx0XHRcdHRoaXMuY291bnRlciA9IG5leHRDb3VudGVyO1xuXHRcdFx0dGhpcy5uYWdpZ2F0ZUJ5KCBkaXJlY3Rpb24gKTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdHRoaXMubmF2aWdhdGVUb1NlY3Rpb24oIHRlc3REYXRhICk7XG5cdFx0XHR0aGlzLmRyb3BEb3duLnNlbGVjdGVkSW5kZXggPSBuZXh0Q291bnRlcjtcblx0XHRcdHRoaXMuY291bnRlciA9IG5leHRDb3VudGVyO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqIE5hdmlnYXRlIHRvIGEgc2VjdGlvblxuXHQgKlxuXHQgKiBAcGFyYW0gdGVzdERhdGFcblx0ICovXG5cdHByaXZhdGUgbmF2aWdhdGVUb1NlY3Rpb24gKCB0ZXN0RGF0YSA6IFRlc3REYXRhICkgOiB2b2lkXG5cdHtcblx0XHR3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUodGVzdERhdGEuanMsIHRlc3REYXRhLmpzLCAnP3Rlc3Q9JyArIHRlc3REYXRhLmpzKTtcblx0XHR0aGlzLnNyY0lmcmFtZS5zcmMgPSBcImRhdGE6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgsXCIgKyB0aGlzLmNyZWF0ZVNvdXJjZVZpZXdIVE1MKCB0ZXN0RGF0YS5zcmMgKTtcblx0XHR0aGlzLnRlc3RJZnJhbWUuc3JjID0gJ2ZyYW1lLmh0bWw/bmFtZT0nICsgdGVzdERhdGEuY2xhc3NwYXRoICsgJyZqcz0nICsgdGVzdERhdGEuanM7XG5cdH1cblxuXHRwcml2YXRlIHRvZ2dsZVNvdXJjZSgpIDogdm9pZFxuXHR7XG5cblx0XHRpZiAoIHRoaXMuc291cmNlVmlzaWJsZSApXG5cdFx0e1xuXHRcdFx0dGhpcy50ZXN0SWZyYW1lLnN0eWxlLndpZHRoICAgICAgICAgPSAnMTAwJSc7XG5cdFx0XHR0aGlzLnNyY0lmcmFtZS5zdHlsZS53aWR0aCAgICAgICAgICA9ICcwJSc7XG5cdFx0XHR0aGlzLnNvdXJjZUJ0bi5pbm5lckhUTUwgICAgICAgICAgICA9ICdTaG93IFNvdXJjZSc7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHR0aGlzLnRlc3RJZnJhbWUuc3R5bGUud2lkdGggICAgICAgICA9ICcyMCUnO1xuXHRcdFx0dGhpcy5zcmNJZnJhbWUuc3R5bGUud2lkdGggICAgICAgICAgPSAnODAlJztcblx0XHRcdHRoaXMuc291cmNlQnRuLmlubmVySFRNTCAgICAgICAgICAgID0gJ0hpZGUgU291cmNlJztcblx0XHR9XG5cblx0XHR0aGlzLnNvdXJjZVZpc2libGUgPSAhdGhpcy5zb3VyY2VWaXNpYmxlO1xuXG5cdH1cblxuXHRwcml2YXRlIGNyZWF0ZVNvdXJjZVZpZXdIVE1MICggdXJsIDogc3RyaW5nICkgOiBzdHJpbmdcblx0e1xuXG5cdFx0dmFyIGh0bWwgOiBzdHJpbmcgPSAnJztcblxuXHRcdGh0bWwgKz0gJzwhRE9DVFlQRSBodG1sPic7XG5cdFx0aHRtbCArPSAnPGh0bWw+Jztcblx0XHRodG1sICs9ICcgICA8aGVhZD4nO1xuXHRcdGh0bWwgKz0gJyAgICAgICA8dGl0bGU+PC90aXRsZT4nO1xuXHRcdGh0bWwgKz0gJyAgICAgICA8c3R5bGU+Jztcblx0XHRodG1sICs9ICcgICAgICAgICAgIGh0bWwnO1xuXHRcdGh0bWwgKz0gJyAgICAgICAgICAgeyc7XG5cdFx0aHRtbCArPSAnICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAlOyc7XG5cdFx0aHRtbCArPSAnICAgICAgICAgICAgICAgYm9yZGVyOiAwcHg7Jztcblx0XHRodG1sICs9ICcgICAgICAgICAgICAgICBwYWRkaW5nOiAwcHg7Jztcblx0XHRodG1sICs9ICcgICAgICAgICAgfSc7XG5cdFx0aHRtbCArPSAnICAgICAgIDwvc3R5bGU+Jztcblx0XHRodG1sICs9ICcgICA8c2NyaXB0IHNyYz1cImh0dHA6Ly9naXN0LWl0LmFwcHNwb3QuY29tL2dpdGh1Yi9hd2F5anMvc3RhZ2VnbC1jb250ZXh0LXRzL3RyZWUvbWFzdGVyL3Rlc3RzLycgKyB1cmwgKyAnP2Zvb3Rlcj1ub1wiPjwvc2NyaXB0Pic7XG5cdFx0aHRtbCArPSAnPC9oZWFkPic7XG5cdFx0aHRtbCArPSAnPGJvZHk+Jztcblx0XHRodG1sICs9ICc8L2JvZHk+Jztcblx0XHRodG1sICs9ICc8L2h0bWw+JztcblxuXHRcdHJldHVybiBodG1sO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gVXRpbHNcblxuXHQvKipcblx0ICpcblx0ICogVXRpbCBmdW5jdGlvbiAtIGdldCBFbGVtZW50IGJ5IElEXG5cdCAqXG5cdCAqIEBwYXJhbSBpZFxuXHQgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR9XG5cdCAqL1xuXHRwcml2YXRlIGdldElkKGlkIDogc3RyaW5nICkgOiBIVE1MRWxlbWVudFxuXHR7XG5cdFx0cmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gRXZlbnRzXG5cblx0LyoqXG5cdCAqXG5cdCAqIERyb3Bib3ggZXZlbnQgaGFuZGxlclxuXHQgKlxuXHQgKiBAcGFyYW0gZVxuXHQgKi9cblx0cHJpdmF0ZSBkcm9wRG93bkNoYW5nZSggZSApIDogdm9pZFxuXHR7XG5cdFx0dGhpcy5kcm9wRG93bi5vcHRpb25zW3RoaXMuZHJvcERvd24uc2VsZWN0ZWRJbmRleF0udmFsdWVcblx0XHR0aGlzLmNvdW50ZXIgPSB0aGlzLmRyb3BEb3duLnNlbGVjdGVkSW5kZXg7XG5cdFx0dmFyIGRhdGFJbmRleCA6IG51bWJlciA9IHBhcnNlSW50KCB0aGlzLmRyb3BEb3duLm9wdGlvbnNbdGhpcy5kcm9wRG93bi5zZWxlY3RlZEluZGV4XS52YWx1ZSApIDtcblxuXHRcdGlmICggISBpc05hTiggZGF0YUluZGV4ICkgKVxuXHRcdHtcblx0XHRcdHRoaXMubmF2aWdhdGVUb1NlY3Rpb24oIHRoaXMudGVzdHNbZGF0YUluZGV4XSApO1xuXHRcdH1cblx0fVxuXG59XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBBcHBsaWNhdGlvbiBGcmFtZVxuXG5jbGFzcyBBcHBGcmFtZVxue1xuXG5cdHByaXZhdGUgY2xhc3NQYXRoICAgOiBzdHJpbmcgPSAnJztcblx0cHJpdmF0ZSBqc1BhdGggICAgICA6IHN0cmluZyA9ICcnO1xuXG5cdGNvbnN0cnVjdG9yKCApXG5cdHtcblxuXHRcdHZhciBxdWVyeVBhcmFtcyA6IGFueSA9IFV0aWxzLmdldFF1ZXJ5UGFyYW1zKCBkb2N1bWVudC5sb2NhdGlvbi5zZWFyY2ggKTtcblxuXHRcdGlmICggcXVlcnlQYXJhbXMuanMgIT0gdW5kZWZpbmVkICYmIHF1ZXJ5UGFyYW1zLm5hbWUgIT0gdW5kZWZpbmVkIClcblx0XHR7XG5cblx0XHRcdHRoaXMuanNQYXRoICAgICA9IHF1ZXJ5UGFyYW1zLmpzO1xuXHRcdFx0dGhpcy5jbGFzc1BhdGggID0gcXVlcnlQYXJhbXMubmFtZTtcblx0XHRcdHRoaXMubG9hZEpTKCB0aGlzLmpzUGF0aCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICpcblx0ICogTG9hZCBhIEphdmFTY3JpcHQgZmlsZVxuXHQgKlxuXHQgKiBAcGFyYW0gdXJsIC0gVVJMIG9mIEphdmFTY3JpcHQgZmlsZVxuXHQgKi9cblx0cHJpdmF0ZSBsb2FkSlModXJsIDogc3RyaW5nIClcblx0e1xuXG5cdFx0dmFyIGhlYWQgOiBIVE1MRWxlbWVudCA9IDxIVE1MRWxlbWVudD4gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdO1xuXHRcdHZhciBzY3JpcHQgOiBIVE1MU2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG5cdFx0c2NyaXB0LnR5cGUgICAgID0gXCJ0ZXh0L2phdmFzY3JpcHRcIjtcblx0XHRzY3JpcHQuc3JjICAgICAgPSB1cmw7XG5cdFx0c2NyaXB0Lm9ubG9hZCAgID0gKCkgPT4gdGhpcy5qc0xvYWRlZCgpO1xuXG5cdFx0aGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqXG5cdCAqIEV2ZW50IEhhbmRsZXIgZm9yIGxvYWRlZCBKYXZhU2NyaXB0IGZpbGVzXG5cdCAqXG5cdCAqL1xuXHRwcml2YXRlIGpzTG9hZGVkKClcblx0e1xuXG5cdFx0dmFyIGNyZWF0ZVBhdGggOiBBcnJheTxzdHJpbmc+ID0gdGhpcy5jbGFzc1BhdGguc3BsaXQoJy4nKTsgLy8gU3BsaXQgdGhlIGNsYXNzcGF0aFxuXHRcdHZhciBvYmogICAgICAgICA6IGFueTtcblxuXHRcdGZvciAoIHZhciBjIDogbnVtYmVyID0gMCA7IGMgPCBjcmVhdGVQYXRoLmxlbmd0aCA7IGMrKyApXG5cdFx0e1xuXG5cdFx0XHRpZiAoIG9iaiA9PSBudWxsIClcblx0XHRcdHtcblx0XHRcdFx0b2JqID0gd2luZG93W2NyZWF0ZVBhdGhbY11dOyAvLyByZWZlcmVuY2UgYmFzZSBtb2R1bGUgKCB3aWxsIGJlIGEgY2hpbGQgb2YgdGhlIHdpbmRvdyApXG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdG9iaiA9IG9ialtjcmVhdGVQYXRoW2NdXTsgLy8gcmVmZXJlbmNlIHN1YiBtb2R1bGUgLyBDbGFzc1xuXHRcdFx0fVxuXG5cblx0XHR9XG5cblx0XHRpZiAoIG9iaiAhPSBudWxsIClcblx0XHR7XG5cdFx0XHRuZXcgb2JqKCk7IC8vIGlmIENsYXNzIGhhcyBiZWVuIGZvdW5kIC0gc3RhcnQgdGhlIHRlc3Rcblx0XHR9XG5cblx0fVxuXG5cblxufVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQ29tbW9uIFV0aWxpdGllc1xuXG5jbGFzcyBVdGlsc1xue1xuXHQvKipcblx0ICpcblx0ICogVXRpbGl0eSBmdW5jdGlvbiAtIFBhcnNlIGEgUXVlcnkgZm9ybWF0dGVkIHN0cmluZ1xuXHQgKlxuXHQgKiBAcGFyYW0gcXNcblx0ICogQHJldHVybnMge3t9fVxuXHQgKi9cblx0c3RhdGljIGdldFF1ZXJ5UGFyYW1zKCBxcyApIDogT2JqZWN0IHtcblxuXHRcdHFzID0gcXMuc3BsaXQoXCIrXCIpLmpvaW4oXCIgXCIpO1xuXG5cdFx0dmFyIHBhcmFtcyA9IHt9LCB0b2tlbnMsXG5cdFx0XHRyZSA9IC9bPyZdPyhbXj1dKyk9KFteJl0qKS9nO1xuXG5cdFx0d2hpbGUgKHRva2VucyA9IHJlLmV4ZWMocXMpKSB7XG5cdFx0XHRwYXJhbXNbZGVjb2RlVVJJQ29tcG9uZW50KHRva2Vuc1sxXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KHRva2Vuc1syXSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBhcmFtcztcblx0fVxufVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGF0YVxuXG5jbGFzcyBUZXN0RGF0YVxue1xuXHRwdWJsaWMganMgICAgICAgICAgIDogc3RyaW5nO1xuXHRwdWJsaWMgY2xhc3NwYXRoICAgIDogc3RyaW5nO1xuXHRwdWJsaWMgc3JjICAgICAgICAgIDogc3RyaW5nO1xuXHRwdWJsaWMgbmFtZSAgICAgICAgIDogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yKCBuYW1lIDogc3RyaW5nICwgY2xhc3NwYXRoIDogc3RyaW5nICwganMgOiBzdHJpbmcgLCBzcmMgOiBzdHJpbmcgKVxuXHR7XG5cdFx0dGhpcy5qcyAgICAgICAgID0ganM7XG5cdFx0dGhpcy5jbGFzc3BhdGggID0gY2xhc3NwYXRoO1xuXHRcdHRoaXMuc3JjICAgICAgICA9IHNyYztcblx0XHR0aGlzLm5hbWUgICAgICAgPSBuYW1lO1xuXHR9XG59Il19
\ No newline at end of file
diff --git a/tests/AppHarness.ts b/tests/AppHarness.ts
new file mode 100644
index 00000000..dbd1bf03
--- /dev/null
+++ b/tests/AppHarness.ts
@@ -0,0 +1,465 @@
+//---------------------------------------------------
+// Application Harness
+
+class AppHarness
+{
+
+ //------------------------------------------------------------------------------
+
+ private tests : Array = new Array();
+ private dropDown : HTMLSelectElement;
+ private previousBtn : HTMLButtonElement;
+ private nextBtn : HTMLButtonElement;
+ private sourceBtn : HTMLButtonElement;
+ private testIframe : HTMLIFrameElement;
+ private srcIframe : HTMLIFrameElement;
+ private counter : number = 0;
+ private sourceVisible : boolean = false;
+ private loadDefault : boolean = true;
+
+ //------------------------------------------------------------------------------
+
+ constructor()
+ {
+
+ this.initFrameSet();
+ this.initInterface();
+
+
+ this.previousBtn.onclick = () => this.nagigateBy( -1 );
+ this.nextBtn.onclick = () => this.nagigateBy( 1 );
+ this.sourceBtn.onclick = () => this.toggleSource();
+ this.dropDown.onchange = ( e ) => this.dropDownChange( e );
+
+ }
+
+ //------------------------------------------------------------------------------
+
+ /**
+ *
+ * Load a test
+ *
+ * @param classPath - Module and Class path of test
+ * @param js Path to JavaScript file
+ * @param ts Path to Typescript file ( not yet used - reserved for future show source )
+ */
+ public load( classPath : string , js : string , ts : string ) : void
+ {
+
+ this.loadFromURL();
+
+ if ( this.loadDefault )
+ {
+ window.history.pushState(js, js, '?test=' + js);
+ this.testIframe.src = 'frame.html?name=' + classPath + '&js=' + js;
+ this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML( ts );
+
+ }
+ }
+
+ /**
+ *
+ * Add a test to the AppHarness
+ *
+ * @param name Name of test
+ * @param classPath - Module and Class path of test
+ * @param js Path to JavaScript file
+ * @param ts Path to Typescript file ( not yet used - reserved for future show source )
+ */
+ public addTest( name : string , classpath : string , js : string , ts : string ) : void
+ {
+ this.tests.push ( new TestData( name , classpath , js , ts ) );
+ }
+
+ /**
+ *
+ * Add a separator to the menu
+ *
+ * @param name
+ */
+ public addSeperator( name : string = '' ) : void
+ {
+ this.tests.push ( new TestData( '-- ' + name , '' , '' , '') );
+ }
+
+ /**
+ *
+ * Start the application harness
+ *
+ */
+ public start( slideshowMode : boolean = false ) : void
+ {
+ for ( var c : number = 0 ; c < this.tests.length ; c ++ )
+ {
+ var option : HTMLOptionElement = new Option( this.tests[c].name , String( c ) );
+ this.dropDown.add( option );
+ }
+
+ if ( slideshowMode )
+ {
+
+ setInterval( () => this.nagigateBy( 1 ) , 15000);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+
+ private loadFromURL() : void
+ {
+ var queryParams : any = Utils.getQueryParams( document.location.search );
+
+ if ( queryParams.test != null )
+ {
+ var l : number = this.tests.length;
+
+ for ( var c : number = 0 ; c < l ; c ++ )
+ {
+ if ( this.tests[c].js == queryParams.test )
+ {
+ console.log ( '======>>>> LOAD TEST');
+
+ this.navigateToSection( this.tests[c] );
+ this.loadDefault = false;
+ }
+ }
+ }
+ }
+ /**
+ *
+ */
+ private initInterface() : void
+ {
+
+ var testSelector : HTMLDivElement = document.createElement( 'div' );
+ testSelector.style.cssFloat = 'none';
+ testSelector.style.position = 'absolute';
+ testSelector.style.bottom = '15px';
+ testSelector.style.width = '600px';
+ testSelector.style.left = '50%';
+ testSelector.style.marginLeft = '-300px'
+ testSelector.style.textAlign = 'center';
+
+
+ this.dropDown = document.createElement( 'select' );
+ this.dropDown.name = "selectTestDropDown"
+ this.dropDown.id = "selectTest"
+
+ this.sourceBtn = document.createElement( 'button' );
+ this.sourceBtn.innerHTML = 'Show Source';
+ this.sourceBtn.id = 'previous';
+
+ this.previousBtn = document.createElement( 'button' );
+ this.previousBtn.innerHTML = '<<';
+ this.previousBtn.id = 'previous';
+
+ this.nextBtn = document.createElement( 'button' );
+ this.nextBtn.innerHTML = '>>';
+ this.nextBtn.id = 'next';
+
+
+ testSelector.appendChild( this.sourceBtn );
+ testSelector.appendChild( this.previousBtn );
+ testSelector.appendChild( this.dropDown );
+ testSelector.appendChild( this.nextBtn );
+ document.body.appendChild( testSelector );
+ }
+ /**
+ *
+ */
+ private initFrameSet() : void
+ {
+
+ var iframeContainer : HTMLDivElement = document.createElement( 'div' );
+ iframeContainer.style.width = '100%';
+ iframeContainer.style.height = '100%';
+
+ this.testIframe = document.createElement( 'iframe' );
+ this.testIframe.id = 'testContainer';
+ this.testIframe.style.backgroundColor = '#9e9e9e';
+ this.testIframe.style.cssFloat = 'none';
+ this.testIframe.style.position = 'absolute';
+ this.testIframe.style.top = '0px';
+ this.testIframe.style.left = '0px';
+ this.testIframe.style.border = '0px';
+ this.testIframe.style.width = '100%';
+ this.testIframe.style.height = '100%';
+ //bottom: 120px;
+
+ this.srcIframe = document.createElement( 'iframe' );
+ this.srcIframe.id = 'testSourceContainer';
+ this.srcIframe.style.backgroundColor = '#9e9e9e';
+ this.srcIframe.style.cssFloat = 'none';
+ this.srcIframe.style.position = 'absolute';
+ this.srcIframe.style.right = '0px';
+ this.srcIframe.style.top = '0px';
+ this.srcIframe.style.bottom = '0px';
+ this.srcIframe.style.border = '0px';
+ this.srcIframe.style.width = '0%';
+ this.srcIframe.style.height = '100%';
+
+ iframeContainer.appendChild( this.testIframe );
+ iframeContainer.appendChild( this.srcIframe );
+
+ document.body.appendChild( iframeContainer );
+
+ }
+
+ /**
+ *
+ * Selectnext / previous menu item
+ *
+ * @param direction
+ */
+ private nagigateBy( direction : number = 1 ) : void
+ {
+
+ var l : number = this.tests.length;
+ var nextCounter = this.counter + direction;
+
+ if ( nextCounter < 0 )
+ {
+ nextCounter = this.tests.length - 1;
+ }
+ else if ( nextCounter > this.tests.length - 1 )
+ {
+ nextCounter = 0;
+ }
+
+ var testData : TestData = this.tests[nextCounter];
+
+ if ( testData.name.indexOf ('--') != -1 ) // skip section headers
+ {
+ this.counter = nextCounter;
+ this.nagigateBy( direction );
+ }
+ else
+ {
+ this.navigateToSection( testData );
+ this.dropDown.selectedIndex = nextCounter;
+ this.counter = nextCounter;
+ }
+
+ }
+
+ /**
+ *
+ * Navigate to a section
+ *
+ * @param testData
+ */
+ private navigateToSection ( testData : TestData ) : void
+ {
+ window.history.pushState(testData.js, testData.js, '?test=' + testData.js);
+ this.srcIframe.src = "data:text/html;charset=utf-8," + this.createSourceViewHTML( testData.src );
+ this.testIframe.src = 'frame.html?name=' + testData.classpath + '&js=' + testData.js;
+ }
+
+ private toggleSource() : void
+ {
+
+ if ( this.sourceVisible )
+ {
+ this.testIframe.style.width = '100%';
+ this.srcIframe.style.width = '0%';
+ this.sourceBtn.innerHTML = 'Show Source';
+ }
+ else
+ {
+ this.testIframe.style.width = '20%';
+ this.srcIframe.style.width = '80%';
+ this.sourceBtn.innerHTML = 'Hide Source';
+ }
+
+ this.sourceVisible = !this.sourceVisible;
+
+ }
+
+ private createSourceViewHTML ( url : string ) : string
+ {
+
+ var html : string = '';
+
+ html += '';
+ html += '';
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ html += '';
+ html += '';
+ html += '';
+ html += '';
+
+ return html;
+ }
+
+ //------------------------------------------------------------------------------
+ // Utils
+
+ /**
+ *
+ * Util function - get Element by ID
+ *
+ * @param id
+ * @returns {HTMLElement}
+ */
+ private getId(id : string ) : HTMLElement
+ {
+ return document.getElementById( id );
+ }
+
+ //------------------------------------------------------------------------------
+ // Events
+
+ /**
+ *
+ * Dropbox event handler
+ *
+ * @param e
+ */
+ private dropDownChange( e ) : void
+ {
+ this.dropDown.options[this.dropDown.selectedIndex].value
+ this.counter = this.dropDown.selectedIndex;
+ var dataIndex : number = parseInt( this.dropDown.options[this.dropDown.selectedIndex].value ) ;
+
+ if ( ! isNaN( dataIndex ) )
+ {
+ this.navigateToSection( this.tests[dataIndex] );
+ }
+ }
+
+}
+
+//---------------------------------------------------
+// Application Frame
+
+class AppFrame
+{
+
+ private classPath : string = '';
+ private jsPath : string = '';
+
+ constructor( )
+ {
+
+ var queryParams : any = Utils.getQueryParams( document.location.search );
+
+ if ( queryParams.js != undefined && queryParams.name != undefined )
+ {
+
+ this.jsPath = queryParams.js;
+ this.classPath = queryParams.name;
+ this.loadJS( this.jsPath );
+
+ }
+
+ }
+
+ /**
+ *
+ * Load a JavaScript file
+ *
+ * @param url - URL of JavaScript file
+ */
+ private loadJS(url : string )
+ {
+
+ var head : HTMLElement = document.getElementsByTagName("head")[0];
+ var script : HTMLScriptElement = document.createElement("script");
+ script.type = "text/javascript";
+ script.src = url;
+ script.onload = () => this.jsLoaded();
+
+ head.appendChild(script);
+ }
+
+ /**
+ *
+ * Event Handler for loaded JavaScript files
+ *
+ */
+ private jsLoaded()
+ {
+
+ var createPath : Array = this.classPath.split('.'); // Split the classpath
+ var obj : any;
+
+ for ( var c : number = 0 ; c < createPath.length ; c++ )
+ {
+
+ if ( obj == null )
+ {
+ obj = window[createPath[c]]; // reference base module ( will be a child of the window )
+ }
+ else
+ {
+ obj = obj[createPath[c]]; // reference sub module / Class
+ }
+
+
+ }
+
+ if ( obj != null )
+ {
+ new obj(); // if Class has been found - start the test
+ }
+
+ }
+
+
+
+}
+
+//---------------------------------------------------
+// Common Utilities
+
+class Utils
+{
+ /**
+ *
+ * Utility function - Parse a Query formatted string
+ *
+ * @param qs
+ * @returns {{}}
+ */
+ static getQueryParams( qs ) : Object {
+
+ qs = qs.split("+").join(" ");
+
+ var params = {}, tokens,
+ re = /[?&]?([^=]+)=([^&]*)/g;
+
+ while (tokens = re.exec(qs)) {
+ params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
+ }
+
+ return params;
+ }
+}
+
+//---------------------------------------------------
+// Data
+
+class TestData
+{
+ public js : string;
+ public classpath : string;
+ public src : string;
+ public name : string;
+
+ constructor( name : string , classpath : string , js : string , src : string )
+ {
+ this.js = js;
+ this.classpath = classpath;
+ this.src = src;
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/tests/assets/1.png b/tests/assets/1.png
new file mode 100755
index 00000000..109d8dde
Binary files /dev/null and b/tests/assets/1.png differ
diff --git a/tests/assets/130909wall_big.png b/tests/assets/130909wall_big.png
new file mode 100755
index 00000000..109d8dde
Binary files /dev/null and b/tests/assets/130909wall_big.png differ
diff --git a/tests/assets/256x256.png b/tests/assets/256x256.png
new file mode 100755
index 00000000..109d8dde
Binary files /dev/null and b/tests/assets/256x256.png differ
diff --git a/tests/assets/CubeTextureTest.cube b/tests/assets/CubeTextureTest.cube
new file mode 100644
index 00000000..ddc90681
--- /dev/null
+++ b/tests/assets/CubeTextureTest.cube
@@ -0,0 +1,28 @@
+{
+ "data":[
+ {
+ "id":"posX",
+ "image":"sky_posX.jpg"
+ },
+ {
+ "id":"negX",
+ "image":"sky_negX.jpg"
+ },
+ {
+ "id":"posY",
+ "image":"sky_posY.jpg"
+ },
+ {
+ "id":"negY",
+ "image":"sky_negY.jpg"
+ },
+ {
+ "id":"posZ",
+ "image":"sky_posZ.jpg"
+ },
+ {
+ "id":"negZ",
+ "image":"sky_negZ.jpg"
+ }
+ ]
+}
diff --git a/tests/assets/custom_uv_horizontal.png b/tests/assets/custom_uv_horizontal.png
new file mode 100755
index 00000000..7db084b9
Binary files /dev/null and b/tests/assets/custom_uv_horizontal.png differ
diff --git a/tests/assets/dots.png b/tests/assets/dots.png
new file mode 100755
index 00000000..ce903166
Binary files /dev/null and b/tests/assets/dots.png differ
diff --git a/tests/assets/sky_negX.jpg b/tests/assets/sky_negX.jpg
new file mode 100755
index 00000000..a7cff5ae
Binary files /dev/null and b/tests/assets/sky_negX.jpg differ
diff --git a/tests/assets/sky_negY.jpg b/tests/assets/sky_negY.jpg
new file mode 100755
index 00000000..57f7a532
Binary files /dev/null and b/tests/assets/sky_negY.jpg differ
diff --git a/tests/assets/sky_negZ.jpg b/tests/assets/sky_negZ.jpg
new file mode 100755
index 00000000..8458a09e
Binary files /dev/null and b/tests/assets/sky_negZ.jpg differ
diff --git a/tests/assets/sky_posX.jpg b/tests/assets/sky_posX.jpg
new file mode 100755
index 00000000..511555f7
Binary files /dev/null and b/tests/assets/sky_posX.jpg differ
diff --git a/tests/assets/sky_posY.jpg b/tests/assets/sky_posY.jpg
new file mode 100755
index 00000000..c18ce753
Binary files /dev/null and b/tests/assets/sky_posY.jpg differ
diff --git a/tests/assets/sky_posZ.jpg b/tests/assets/sky_posZ.jpg
new file mode 100755
index 00000000..e8130bca
Binary files /dev/null and b/tests/assets/sky_posZ.jpg differ
diff --git a/tests/containers/View3DTest.js b/tests/containers/View3DTest.js
new file mode 100755
index 00000000..2dbdfa1a
--- /dev/null
+++ b/tests/containers/View3DTest.js
@@ -0,0 +1,53 @@
+var View = require("awayjs-core/lib/containers/View");
+var PointLight = require("awayjs-core/lib/entities/PointLight");
+var PrimitiveTorusPrefab = require("awayjs-core/lib/prefabs/PrimitiveTorusPrefab");
+var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+var Debug = require("awayjs-core/lib/utils/Debug");
+var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+var View3DTest = (function () {
+ function View3DTest() {
+ var _this = this;
+ Debug.THROW_ERRORS = false;
+ Debug.LOG_PI_ERRORS = false;
+ this.meshes = new Array();
+ this.light = new PointLight();
+ this.view = new View(new DefaultRenderer());
+ this.view.camera.z = 0;
+ this.view.backgroundColor = 0x776655;
+ this.torus = new PrimitiveTorusPrefab(150, 50, 32, 32, false);
+ var l = 10;
+ var radius = 1000;
+ var matB = new TriangleMethodMaterial();
+ this.torus.material = matB;
+ for (var c = 0; c < l; c++) {
+ var t = Math.PI * 2 * c / l;
+ var mesh = this.torus.getNewObject();
+ mesh.x = Math.cos(t) * radius;
+ mesh.y = 0;
+ mesh.z = Math.sin(t) * radius;
+ this.view.scene.addChild(mesh);
+ this.meshes.push(mesh);
+ }
+ this.view.scene.addChild(this.light);
+ this.raf = new RequestAnimationFrame(this.tick, this);
+ this.raf.start();
+ this.resize(null);
+ window.onresize = function (e) { return _this.resize(null); };
+ }
+ View3DTest.prototype.tick = function (e) {
+ for (var c = 0; c < this.meshes.length; c++)
+ this.meshes[c].rotationY += 2;
+ this.view.camera.rotationY += .5;
+ this.view.render();
+ };
+ View3DTest.prototype.resize = function (e) {
+ this.view.y = 0;
+ this.view.x = 0;
+ this.view.width = window.innerWidth;
+ this.view.height = window.innerHeight;
+ };
+ return View3DTest;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbnRhaW5lcnMvdmlldzNkdGVzdC50cyJdLCJuYW1lcyI6WyJWaWV3M0RUZXN0IiwiVmlldzNEVGVzdC5jb25zdHJ1Y3RvciIsIlZpZXczRFRlc3QudGljayIsIlZpZXczRFRlc3QucmVzaXplIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUUvRCxJQUFPLFVBQVUsV0FBZSxxQ0FBcUMsQ0FBQyxDQUFDO0FBQ3ZFLElBQU8sb0JBQW9CLFdBQWEsOENBQThDLENBQUMsQ0FBQztBQUN4RixJQUFPLHFCQUFxQixXQUFZLDZDQUE2QyxDQUFDLENBQUM7QUFDdkYsSUFBTyxLQUFLLFdBQWdCLDZCQUE2QixDQUFDLENBQUM7QUFFM0QsSUFBTyxlQUFlLFdBQWMsZ0RBQWdELENBQUMsQ0FBQztBQUN0RixJQUFPLHNCQUFzQixXQUFZLHFEQUFxRCxDQUFDLENBQUM7QUFFaEcsSUFBTSxVQUFVO0lBVWZBLFNBVktBLFVBQVVBO1FBQWhCQyxpQkF1RUNBO1FBMURDQSxLQUFLQSxDQUFDQSxZQUFZQSxHQUFHQSxLQUFLQSxDQUFDQTtRQUMzQkEsS0FBS0EsQ0FBQ0EsYUFBYUEsR0FBR0EsS0FBS0EsQ0FBQ0E7UUFFNUJBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLElBQUlBLEtBQUtBLEVBQVFBLENBQUNBO1FBQ2hDQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxVQUFVQSxFQUFFQSxDQUFDQTtRQUM5QkEsSUFBSUEsQ0FBQ0EsSUFBSUEsR0FBR0EsSUFBSUEsSUFBSUEsQ0FBQ0EsSUFBSUEsZUFBZUEsRUFBRUEsQ0FBQ0EsQ0FBQUE7UUFDM0NBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3ZCQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxlQUFlQSxHQUFHQSxRQUFRQSxDQUFDQTtRQUNyQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsb0JBQW9CQSxDQUFDQSxHQUFHQSxFQUFHQSxFQUFFQSxFQUFHQSxFQUFFQSxFQUFHQSxFQUFFQSxFQUFHQSxLQUFLQSxDQUFDQSxDQUFDQTtRQUVsRUEsSUFBSUEsQ0FBQ0EsR0FBaUJBLEVBQUVBLENBQUNBO1FBQ3pCQSxJQUFJQSxNQUFNQSxHQUFpQkEsSUFBSUEsQ0FBQ0E7UUFDaENBLElBQUlBLElBQUlBLEdBQTBCQSxJQUFJQSxzQkFBc0JBLEVBQUVBLENBQUNBO1FBRS9EQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxHQUFHQSxJQUFJQSxDQUFDQTtRQUUzQkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBVUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsRUFBRUEsRUFBRUEsQ0FBQ0E7WUFFbkNBLElBQUlBLENBQUNBLEdBQVFBLElBQUlBLENBQUNBLEVBQUVBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBRWpDQSxJQUFJQSxJQUFJQSxHQUFlQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQTtZQUNqREEsSUFBSUEsQ0FBQ0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBQ0EsTUFBTUEsQ0FBQ0E7WUFDNUJBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1lBQ1hBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBLENBQUNBLEdBQUNBLE1BQU1BLENBQUNBO1lBRTVCQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxRQUFRQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtZQUMvQkEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFFeEJBLENBQUNBO1FBRURBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBO1FBRXJDQSxJQUFJQSxDQUFDQSxHQUFHQSxHQUFHQSxJQUFJQSxxQkFBcUJBLENBQUNBLElBQUlBLENBQUNBLElBQUlBLEVBQUdBLElBQUlBLENBQUNBLENBQUNBO1FBQ3ZEQSxJQUFJQSxDQUFDQSxHQUFHQSxDQUFDQSxLQUFLQSxFQUFFQSxDQUFDQTtRQUNqQkEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBRUEsSUFBSUEsQ0FBRUEsQ0FBQ0E7UUFFcEJBLE1BQU1BLENBQUNBLFFBQVFBLEdBQUdBLFVBQUNBLENBQUNBLElBQUtBLE9BQUFBLEtBQUlBLENBQUNBLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLEVBQWpCQSxDQUFpQkEsQ0FBQ0E7SUFFNUNBLENBQUNBO0lBRU9ELHlCQUFJQSxHQUFaQSxVQUFhQSxDQUFDQTtRQUdiRSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxHQUFVQSxDQUFDQSxFQUFFQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxNQUFNQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQSxFQUFFQTtZQUNqREEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsU0FBU0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFFL0JBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLENBQUNBLFNBQVNBLElBQUlBLEVBQUVBLENBQUNBO1FBQ2pDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxDQUFDQTtJQUNwQkEsQ0FBQ0E7SUFFTUYsMkJBQU1BLEdBQWJBLFVBQWNBLENBQUNBO1FBRWRHLElBQUlBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ2hCQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUVoQkEsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDcENBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEdBQUdBLE1BQU1BLENBQUNBLFdBQVdBLENBQUNBO0lBQ3ZDQSxDQUFDQTtJQUNGSCxpQkFBQ0E7QUFBREEsQ0F2RUEsQUF1RUNBLElBQUEiLCJmaWxlIjoiY29udGFpbmVycy9WaWV3M0RUZXN0LmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2JiYXRlbWFuL1dlYnN0b3JtUHJvamVjdHMvYXdheWpzLXN0YWdlZ2wvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZpZXdcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250YWluZXJzL1ZpZXdcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgUG9pbnRMaWdodFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvUG9pbnRMaWdodFwiKTtcbmltcG9ydCBQcmltaXRpdmVUb3J1c1ByZWZhYlx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZVRvcnVzUHJlZmFiXCIpO1xuaW1wb3J0IFJlcXVlc3RBbmltYXRpb25GcmFtZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvUmVxdWVzdEFuaW1hdGlvbkZyYW1lXCIpO1xuaW1wb3J0IERlYnVnXHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL0RlYnVnXCIpO1xuXG5pbXBvcnQgRGVmYXVsdFJlbmRlcmVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9yZW5kZXIvRGVmYXVsdFJlbmRlcmVyXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9UcmlhbmdsZU1ldGhvZE1hdGVyaWFsXCIpO1xuXG5jbGFzcyBWaWV3M0RUZXN0XG57XG5cblx0cHJpdmF0ZSB2aWV3OlZpZXc7XG5cdHByaXZhdGUgdG9ydXM6UHJpbWl0aXZlVG9ydXNQcmVmYWI7XG5cblx0cHJpdmF0ZSBsaWdodDpQb2ludExpZ2h0O1xuXHRwcml2YXRlIHJhZjpSZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XG5cdHByaXZhdGUgbWVzaGVzOkFycmF5PE1lc2g+O1xuXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXG5cdFx0RGVidWcuVEhST1dfRVJST1JTID0gZmFsc2U7XG5cdFx0RGVidWcuTE9HX1BJX0VSUk9SUyA9IGZhbHNlO1xuXG5cdFx0dGhpcy5tZXNoZXMgPSBuZXcgQXJyYXk8TWVzaD4oKTtcblx0XHR0aGlzLmxpZ2h0ID0gbmV3IFBvaW50TGlnaHQoKTtcblx0XHR0aGlzLnZpZXcgPSBuZXcgVmlldyhuZXcgRGVmYXVsdFJlbmRlcmVyKCkpXG5cdFx0dGhpcy52aWV3LmNhbWVyYS56ID0gMDtcblx0XHR0aGlzLnZpZXcuYmFja2dyb3VuZENvbG9yID0gMHg3NzY2NTU7XG5cdFx0dGhpcy50b3J1cyA9IG5ldyBQcmltaXRpdmVUb3J1c1ByZWZhYigxNTAgLCA1MCAsIDMyICwgMzIgLCBmYWxzZSk7XG5cblx0XHR2YXIgbDpudW1iZXIgICAgICAgID0gMTA7XG5cdFx0dmFyIHJhZGl1czpudW1iZXIgICAgICAgID0gMTAwMDtcblx0XHR2YXIgbWF0QjpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwoKTtcblxuXHRcdHRoaXMudG9ydXMubWF0ZXJpYWwgPSBtYXRCO1xuXG5cdFx0Zm9yICh2YXIgYzpudW1iZXIgPSAwOyBjIDwgbDsgYysrKSB7XG5cblx0XHRcdHZhciB0Om51bWJlcj1NYXRoLlBJICogMiAqIGMgLyBsO1xuXG5cdFx0XHR2YXIgbWVzaDpNZXNoID0gPE1lc2g+IHRoaXMudG9ydXMuZ2V0TmV3T2JqZWN0KCk7XG5cdFx0XHRtZXNoLnggPSBNYXRoLmNvcyh0KSpyYWRpdXM7XG5cdFx0XHRtZXNoLnkgPSAwO1xuXHRcdFx0bWVzaC56ID0gTWF0aC5zaW4odCkqcmFkaXVzO1xuXG5cdFx0XHR0aGlzLnZpZXcuc2NlbmUuYWRkQ2hpbGQobWVzaCk7XG5cdFx0XHR0aGlzLm1lc2hlcy5wdXNoKG1lc2gpO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy52aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMubGlnaHQpO1xuXG5cdFx0dGhpcy5yYWYgPSBuZXcgUmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMudGljayAsIHRoaXMpO1xuXHRcdHRoaXMucmFmLnN0YXJ0KCk7XG5cdFx0dGhpcy5yZXNpemUoIG51bGwgKTtcblxuXHRcdHdpbmRvdy5vbnJlc2l6ZSA9IChlKSA9PiB0aGlzLnJlc2l6ZShudWxsKTtcblxuXHR9XG5cblx0cHJpdmF0ZSB0aWNrKGUpXG5cdHtcblxuXHRcdGZvciAodmFyIGM6bnVtYmVyID0gMDsgYyA8IHRoaXMubWVzaGVzLmxlbmd0aDsgYysrKVxuXHRcdFx0dGhpcy5tZXNoZXNbY10ucm90YXRpb25ZICs9IDI7XG5cblx0XHR0aGlzLnZpZXcuY2FtZXJhLnJvdGF0aW9uWSArPSAuNTtcblx0XHR0aGlzLnZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgcmVzaXplKGUpXG5cdHtcblx0XHR0aGlzLnZpZXcueSA9IDA7XG5cdFx0dGhpcy52aWV3LnggPSAwO1xuXG5cdFx0dGhpcy52aWV3LndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG5cdFx0dGhpcy52aWV3LmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblx0fVxufSJdfQ==
\ No newline at end of file
diff --git a/tests/containers/View3DTest.ts b/tests/containers/View3DTest.ts
new file mode 100644
index 00000000..87b3b15a
--- /dev/null
+++ b/tests/containers/View3DTest.ts
@@ -0,0 +1,82 @@
+import View = require("awayjs-core/lib/containers/View");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import PointLight = require("awayjs-core/lib/entities/PointLight");
+import PrimitiveTorusPrefab = require("awayjs-core/lib/prefabs/PrimitiveTorusPrefab");
+import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+import Debug = require("awayjs-core/lib/utils/Debug");
+
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+
+class View3DTest
+{
+
+ private view:View;
+ private torus:PrimitiveTorusPrefab;
+
+ private light:PointLight;
+ private raf:RequestAnimationFrame;
+ private meshes:Array;
+
+ constructor()
+ {
+
+ Debug.THROW_ERRORS = false;
+ Debug.LOG_PI_ERRORS = false;
+
+ this.meshes = new Array();
+ this.light = new PointLight();
+ this.view = new View(new DefaultRenderer())
+ this.view.camera.z = 0;
+ this.view.backgroundColor = 0x776655;
+ this.torus = new PrimitiveTorusPrefab(150 , 50 , 32 , 32 , false);
+
+ var l:number = 10;
+ var radius:number = 1000;
+ var matB:TriangleMethodMaterial = new TriangleMethodMaterial();
+
+ this.torus.material = matB;
+
+ for (var c:number = 0; c < l; c++) {
+
+ var t:number=Math.PI * 2 * c / l;
+
+ var mesh:Mesh = this.torus.getNewObject();
+ mesh.x = Math.cos(t)*radius;
+ mesh.y = 0;
+ mesh.z = Math.sin(t)*radius;
+
+ this.view.scene.addChild(mesh);
+ this.meshes.push(mesh);
+
+ }
+
+ this.view.scene.addChild(this.light);
+
+ this.raf = new RequestAnimationFrame(this.tick , this);
+ this.raf.start();
+ this.resize( null );
+
+ window.onresize = (e) => this.resize(null);
+
+ }
+
+ private tick(e)
+ {
+
+ for (var c:number = 0; c < this.meshes.length; c++)
+ this.meshes[c].rotationY += 2;
+
+ this.view.camera.rotationY += .5;
+ this.view.render();
+ }
+
+ public resize(e)
+ {
+ this.view.y = 0;
+ this.view.x = 0;
+
+ this.view.width = window.innerWidth;
+ this.view.height = window.innerHeight;
+ }
+}
\ No newline at end of file
diff --git a/tests/controllers/HoverControllerTest.js b/tests/controllers/HoverControllerTest.js
new file mode 100755
index 00000000..11fc419a
--- /dev/null
+++ b/tests/controllers/HoverControllerTest.js
@@ -0,0 +1,53 @@
+var View = require("awayjs-core/lib/containers/View");
+var HoverController = require("awayjs-core/lib/controllers/HoverController");
+var PrimitiveCubePrefab = require("awayjs-core/lib/prefabs/PrimitiveCubePrefab");
+var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+var HoverControllerTest = (function () {
+ function HoverControllerTest() {
+ var _this = this;
+ this._move = false;
+ this._view = new View(new DefaultRenderer());
+ this._cube = new PrimitiveCubePrefab(400, 400, 400);
+ this._cube.geometryType = "lineSubGeometry";
+ this._mesh = this._cube.getNewObject();
+ this._view.scene.addChild(this._mesh);
+ this._hoverControl = new HoverController(this._view.camera, this._mesh, 150, 10);
+ window.onresize = function (event) { return _this.onResize(event); };
+ document.onmousedown = function (event) { return _this.onMouseDown(event); };
+ document.onmouseup = function (event) { return _this.onMouseUp(event); };
+ document.onmousemove = function (event) { return _this.onMouseMove(event); };
+ this.onResize();
+ this._timer = new RequestAnimationFrame(this.render, this);
+ this._timer.start();
+ }
+ HoverControllerTest.prototype.onResize = function (event) {
+ if (event === void 0) { event = null; }
+ this._view.y = 0;
+ this._view.x = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ };
+ HoverControllerTest.prototype.render = function (dt) {
+ this._view.render();
+ };
+ HoverControllerTest.prototype.onMouseUp = function (event) {
+ this._move = false;
+ };
+ HoverControllerTest.prototype.onMouseMove = function (event) {
+ if (this._move) {
+ this._hoverControl.panAngle = 0.3 * (event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._hoverControl.tiltAngle = 0.3 * (event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ };
+ HoverControllerTest.prototype.onMouseDown = function (event) {
+ this._lastPanAngle = this._hoverControl.panAngle;
+ this._lastTiltAngle = this._hoverControl.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ };
+ return HoverControllerTest;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbnRyb2xsZXJzL2hvdmVyY29udHJvbGxlcnRlc3QudHMiXSwibmFtZXMiOlsiSG92ZXJDb250cm9sbGVyVGVzdCIsIkhvdmVyQ29udHJvbGxlclRlc3QuY29uc3RydWN0b3IiLCJIb3ZlckNvbnRyb2xsZXJUZXN0Lm9uUmVzaXplIiwiSG92ZXJDb250cm9sbGVyVGVzdC5yZW5kZXIiLCJIb3ZlckNvbnRyb2xsZXJUZXN0Lm9uTW91c2VVcCIsIkhvdmVyQ29udHJvbGxlclRlc3Qub25Nb3VzZU1vdmUiLCJIb3ZlckNvbnRyb2xsZXJUZXN0Lm9uTW91c2VEb3duIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUMvRCxJQUFPLGVBQWUsV0FBYyw2Q0FBNkMsQ0FBQyxDQUFDO0FBR25GLElBQU8sbUJBQW1CLFdBQWEsNkNBQTZDLENBQUMsQ0FBQztBQUN0RixJQUFPLHFCQUFxQixXQUFZLDZDQUE2QyxDQUFDLENBQUM7QUFFdkYsSUFBTyxlQUFlLFdBQWMsZ0RBQWdELENBQUMsQ0FBQztBQUV0RixJQUFNLG1CQUFtQjtJQWV4QkEsU0FmS0EsbUJBQW1CQTtRQUF6QkMsaUJBeUVDQTtRQWxFUUEsVUFBS0EsR0FBV0EsS0FBS0EsQ0FBQ0E7UUFVN0JBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLElBQUlBLElBQUlBLENBQUNBLElBQUlBLGVBQWVBLEVBQUVBLENBQUNBLENBQUNBO1FBRTdDQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxtQkFBbUJBLENBQUNBLEdBQUdBLEVBQUVBLEdBQUdBLEVBQUVBLEdBQUdBLENBQUNBLENBQUNBO1FBQ3BEQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxZQUFZQSxHQUFHQSxpQkFBaUJBLENBQUNBO1FBQzVDQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFVQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxZQUFZQSxFQUFFQSxDQUFDQTtRQUM5Q0EsSUFBSUEsQ0FBQ0Es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QWFBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFFBQVFBLENBQUNBO1FBQ2pEQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUNuREEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDakNBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEtBQUtBLENBQUNBLE9BQU9BLENBQUNBO1FBQ2pDQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUNuQkEsQ0FBQ0E7SUFDRk4sMEJBQUNBO0FBQURBLENBekVBLEFBeUVDQSxJQUFBIiwiZmlsZSI6ImNvbnRyb2xsZXJzL0hvdmVyQ29udHJvbGxlclRlc3QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtc3RhZ2VnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBIb3ZlckNvbnRyb2xsZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250cm9sbGVycy9Ib3ZlckNvbnRyb2xsZXJcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBQcmltaXRpdmVDdWJlUHJlZmFiXHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3ByZWZhYnMvUHJpbWl0aXZlQ3ViZVByZWZhYlwiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcblxuY2xhc3MgSG92ZXJDb250cm9sbGVyVGVzdFxue1xuXG5cdHByaXZhdGUgX3ZpZXc6Vmlldztcblx0cHJpdmF0ZSBfdGltZXI6UmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuXHRwcml2YXRlIF9ob3ZlckNvbnRyb2w6SG92ZXJDb250cm9sbGVyO1xuXG5cdHByaXZhdGUgX21vdmU6Ym9vbGVhbiA9IGZhbHNlO1xuXHRwcml2YXRlIF9sYXN0UGFuQW5nbGU6bnVtYmVyO1xuXHRwcml2YXRlIF9sYXN0VGlsdEFuZ2xlOm51bWJlcjtcblx0cHJpdmF0ZSBfbGFzdE1vdXNlWDpudW1iZXI7XG5cdHByaXZhdGUgX2xhc3RNb3VzZVk6bnVtYmVyO1xuXHRwcml2YXRlIF9jdWJlOlByaW1pdGl2ZUN1YmVQcmVmYWI7XG5cdHByaXZhdGUgX21lc2g6TWVzaDtcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHR0aGlzLl92aWV3ID0gbmV3IFZpZXcobmV3IERlZmF1bHRSZW5kZXJlcigpKTtcblxuXHRcdHRoaXMuX2N1YmUgPSBuZXcgUHJpbWl0aXZlQ3ViZVByZWZhYig0MDAsIDQwMCwgNDAwKTtcblx0XHR0aGlzLl9jdWJlLmdlb21ldHJ5VHlwZSA9IFwibGluZVN1Ykdlb21ldHJ5XCI7XG5cdFx0dGhpcy5fbWVzaCA9IDxNZXNoPiB0aGlzLl9jdWJlLmdldE5ld09iamVjdCgpO1xuXHRcdHRoaXMuX3ZpZXcuc2NlbmUuYWRkQ2hpbGQodGhpcy5fbWVzaCk7XG5cblx0XHR0aGlzLl9ob3ZlckNvbnRyb2wgPSBuZXcgSG92ZXJDb250cm9sbGVyKHRoaXMuX3ZpZXcuY2FtZXJhLCB0aGlzLl9tZXNoLCAxNTAsIDEwKTtcblxuXHRcdHdpbmRvdy5vbnJlc2l6ZSAgPSAoZXZlbnQ6VUlFdmVudCkgPT4gdGhpcy5vblJlc2l6ZShldmVudCk7XG5cblx0XHRkb2N1bWVudC5vbm1vdXNlZG93biA9IChldmVudDpNb3VzZUV2ZW50KSA9PiB0aGlzLm9uTW91c2VEb3duKGV2ZW50KTtcblx0XHRkb2N1bWVudC5vbm1vdXNldXAgPSAoZXZlbnQ6TW91c2VFdmVudCkgPT4gdGhpcy5vbk1vdXNlVXAoZXZlbnQpO1xuXHRcdGRvY3VtZW50Lm9ubW91c2Vtb3ZlID0gKGV2ZW50Ok1vdXNlRXZlbnQpID0+IHRoaXMub25Nb3VzZU1vdmUoZXZlbnQpO1xuXG5cblx0XHR0aGlzLm9uUmVzaXplKCk7XG5cblx0XHR0aGlzLl90aW1lciA9IG5ldyBSZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5yZW5kZXIgLCB0aGlzKTtcblx0XHR0aGlzLl90aW1lci5zdGFydCgpO1xuXHR9XG5cblx0cHJpdmF0ZSBvblJlc2l6ZShldmVudDpVSUV2ZW50ID0gbnVsbClcblx0e1xuXHRcdHRoaXMuX3ZpZXcueSA9IDA7XG5cdFx0dGhpcy5fdmlldy54ID0gMDtcblx0XHR0aGlzLl92aWV3LndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG5cdFx0dGhpcy5fdmlldy5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cdH1cblxuXHRwcml2YXRlIHJlbmRlcihkdDpudW1iZXIpXG5cdHtcblx0XHR0aGlzLl92aWV3LnJlbmRlcigpO1xuXHR9XG5cblx0cHJpdmF0ZSBvbk1vdXNlVXAoZXZlbnQ6TW91c2VFdmVudClcblx0e1xuXHRcdHRoaXMuX21vdmUgPSBmYWxzZTtcblx0fVxuXG5cdHByaXZhdGUgb25Nb3VzZU1vdmUoZXZlbnQ6TW91c2VFdmVudClcblx0e1xuXHRcdGlmICh0aGlzLl9tb3ZlKSB7XG5cdFx0XHR0aGlzLl9ob3ZlckNvbnRyb2wucGFuQW5nbGUgPSAwLjMqKGV2ZW50LmNsaWVudFggLSB0aGlzLl9sYXN0TW91c2VYKSArIHRoaXMuX2xhc3RQYW5BbmdsZTtcblx0XHRcdHRoaXMuX2hvdmVyQ29udHJvbC50aWx0QW5nbGUgPSAwLjMqKGV2ZW50LmNsaWVudFkgLSB0aGlzLl9sYXN0TW91c2VZKSArIHRoaXMuX2xhc3RUaWx0QW5nbGU7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBvbk1vdXNlRG93bihldmVudDpNb3VzZUV2ZW50KVxuXHR7XG5cdFx0dGhpcy5fbGFzdFBhbkFuZ2xlID0gdGhpcy5faG92ZXJDb250cm9sLnBhbkFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RUaWx0QW5nbGUgPSB0aGlzLl9ob3ZlckNvbnRyb2wudGlsdEFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVggPSBldmVudC5jbGllbnRYO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVkgPSBldmVudC5jbGllbnRZO1xuXHRcdHRoaXMuX21vdmUgPSB0cnVlO1xuXHR9XG59Il19
\ No newline at end of file
diff --git a/tests/controllers/HoverControllerTest.ts b/tests/controllers/HoverControllerTest.ts
new file mode 100644
index 00000000..502412c5
--- /dev/null
+++ b/tests/controllers/HoverControllerTest.ts
@@ -0,0 +1,83 @@
+import View = require("awayjs-core/lib/containers/View");
+import HoverController = require("awayjs-core/lib/controllers/HoverController");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+import PrimitiveCubePrefab = require("awayjs-core/lib/prefabs/PrimitiveCubePrefab");
+import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+
+class HoverControllerTest
+{
+
+ private _view:View;
+ private _timer:RequestAnimationFrame;
+ private _hoverControl:HoverController;
+
+ private _move:boolean = false;
+ private _lastPanAngle:number;
+ private _lastTiltAngle:number;
+ private _lastMouseX:number;
+ private _lastMouseY:number;
+ private _cube:PrimitiveCubePrefab;
+ private _mesh:Mesh;
+
+ constructor()
+ {
+ this._view = new View(new DefaultRenderer());
+
+ this._cube = new PrimitiveCubePrefab(400, 400, 400);
+ this._cube.geometryType = "lineSubGeometry";
+ this._mesh = this._cube.getNewObject();
+ this._view.scene.addChild(this._mesh);
+
+ this._hoverControl = new HoverController(this._view.camera, this._mesh, 150, 10);
+
+ window.onresize = (event:UIEvent) => this.onResize(event);
+
+ document.onmousedown = (event:MouseEvent) => this.onMouseDown(event);
+ document.onmouseup = (event:MouseEvent) => this.onMouseUp(event);
+ document.onmousemove = (event:MouseEvent) => this.onMouseMove(event);
+
+
+ this.onResize();
+
+ this._timer = new RequestAnimationFrame(this.render , this);
+ this._timer.start();
+ }
+
+ private onResize(event:UIEvent = null)
+ {
+ this._view.y = 0;
+ this._view.x = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ }
+
+ private render(dt:number)
+ {
+ this._view.render();
+ }
+
+ private onMouseUp(event:MouseEvent)
+ {
+ this._move = false;
+ }
+
+ private onMouseMove(event:MouseEvent)
+ {
+ if (this._move) {
+ this._hoverControl.panAngle = 0.3*(event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._hoverControl.tiltAngle = 0.3*(event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ }
+
+ private onMouseDown(event:MouseEvent)
+ {
+ this._lastPanAngle = this._hoverControl.panAngle;
+ this._lastTiltAngle = this._hoverControl.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ }
+}
\ No newline at end of file
diff --git a/tests/display/BitmapDataReflectionTest.js b/tests/display/BitmapDataReflectionTest.js
new file mode 100755
index 00000000..87991553
--- /dev/null
+++ b/tests/display/BitmapDataReflectionTest.js
@@ -0,0 +1,78 @@
+var View = require("awayjs-core/lib/containers/View");
+var BitmapData = require("awayjs-core/lib/core/base/BitmapData");
+var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+var AssetType = require("awayjs-core/lib/core/library/AssetType");
+var URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+var PrimitivePlanePrefab = require("awayjs-core/lib/prefabs/PrimitivePlanePrefab");
+var BitmapTexture = require("awayjs-core/lib/textures/BitmapTexture");
+var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+var BitmapDataReflectionTest = (function () {
+ function BitmapDataReflectionTest() {
+ var _this = this;
+ this.view = new View(new DefaultRenderer());
+ this.raf = new RequestAnimationFrame(this.render, this);
+ var token = AssetLibrary.load(new URLRequest('assets/dots.png'));
+ token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); });
+ window.onresize = function (event) { return _this.onResize(event); };
+ }
+ BitmapDataReflectionTest.prototype.onResourceComplete = function (event) {
+ var loader = event.target;
+ var l = loader.baseDependency.assets.length;
+ for (var c = 0; c < l; c++) {
+ var asset = loader.baseDependency.assets[c];
+ switch (asset.assetType) {
+ case AssetType.TEXTURE:
+ var prefab = new PrimitivePlanePrefab(500, 500, 1, 1, false);
+ var tx = asset;
+ var bitmap = new BitmapData(1024, 1024, true, 0x00000000);
+ bitmap.context.translate(0, 1024);
+ bitmap.context.scale(1, -1);
+ bitmap.context.drawImage(tx.htmlImageElement, 0, 0, 1024, 1024);
+ var gradient = bitmap.context.createLinearGradient(0, 0, 0, 1024);
+ gradient.addColorStop(0.8, "rgba(255, 255, 255, 1.0)");
+ gradient.addColorStop(1, "rgba(255, 255, 255, 0.5)");
+ bitmap.context.fillStyle = gradient;
+ bitmap.context.rect(0, 0, 1024, 1024);
+ bitmap.context.globalCompositeOperation = "destination-out";
+ bitmap.context.fill();
+ var bitmapClone = new BitmapData(1024, 1024, true, 0x00000000);
+ bitmapClone.copyPixels(bitmap, bitmapClone.rect, bitmapClone.rect);
+ document.body.appendChild(bitmap.canvas);
+ var bmpTX = new BitmapTexture(bitmapClone, false);
+ var material = new TriangleMethodMaterial(bmpTX);
+ material.bothSides = true;
+ material.alphaBlending = true;
+ var material2 = new TriangleMethodMaterial(tx);
+ material2.bothSides = true;
+ material2.alphaBlending = true;
+ this.reflectionMesh = prefab.getNewObject();
+ this.reflectionMesh.material = material;
+ this.view.scene.addChild(this.reflectionMesh);
+ this.fullmesh = prefab.getNewObject();
+ this.fullmesh.material = material2;
+ this.fullmesh.rotationY = 90;
+ this.view.scene.addChild(this.fullmesh);
+ break;
+ }
+ }
+ this.raf.start();
+ this.onResize();
+ };
+ BitmapDataReflectionTest.prototype.onResize = function (event) {
+ if (event === void 0) { event = null; }
+ this.view.x = window.innerWidth / 2;
+ this.view.width = window.innerWidth / 2;
+ this.view.height = window.innerHeight;
+ };
+ BitmapDataReflectionTest.prototype.render = function () {
+ this.fullmesh.rotationY += .5;
+ this.reflectionMesh.rotationY += .5;
+ this.view.render();
+ };
+ return BitmapDataReflectionTest;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImRpc3BsYXkvYml0bWFwZGF0YXJlZmxlY3Rpb250ZXN0LnRzIl0sIm5hbWVzIjpbIkJpdG1hcERhdGFSZWZsZWN0aW9uVGVzdCIsIkJpdG1hcERhdGFSZWZsZWN0aW9uVGVzdC5jb25zdHJ1Y3RvciIsIkJpdG1hcERhdGFSZWZsZWN0aW9uVGVzdC5vblJlc291cmNlQ29tcGxldGUiLCJCaXRtYXBEYXRhUmVmbGVjdGlvblRlc3Qub25SZXNpemUiLCJCaXRtYXBEYXRhUmVmbGVjdGlvblRlc3QucmVuZGVyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUMvRCxJQUFPLFVBQVUsV0FBZSxzQ0FBc0MsQ0FBQyxDQUFDO0FBQ3hFLElBQU8sWUFBWSxXQUFlLDJDQUEyQyxDQUFDLENBQUM7QUFHL0UsSUFBTyxTQUFTLFdBQWUsd0NBQXdDLENBQUMsQ0FBQztBQUV6RSxJQUFPLFVBQVUsV0FBZSxxQ0FBcUMsQ0FBQyxDQUFDO0FBRXZFLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxvQkFBb0IsV0FBYSw4Q0FBOEMsQ0FBQyxDQUFDO0FBQ3hGLElBQU8sYUFBYSxXQUFjLHdDQUF3QyxDQUFDLENBQUM7QUFFNUUsSUFBTyxxQkFBcUIsV0FBWSw2Q0FBNkMsQ0FBQyxDQUFDO0FBRXZGLElBQU8sZUFBZSxXQUFjLGdEQUFnRCxDQUFDLENBQUM7QUFDdEYsSUFBTyxzQkFBc0IsV0FBWSxxREFBcUQsQ0FBQyxDQUFDO0FBRWhHLElBQU0sd0JBQXdCO0lBTzdCQSxTQVBLQSx3QkFBd0JBO1FBQTlCQyxpQkE2RkNBO1FBcEZDQSxJQUFJQSxDQUFDQSxJQUFJQSxHQUFHQSxJQUFJQSxJQUFJQSxDQUFDQSxJQUFJQSxlQUFlQSxFQUFFQSxDQUFDQSxDQUFDQTtRQUM1Q0EsSUFBSUEsQ0FBQ0EsR0FBR0EsR0FBR0EsSUFBSUEscUJBQXFCQSxDQUFDQSxJQUFJQSxDQUFDQSxNQUFNQSxFQUFFQSxJ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QSxDQUFDQTtJQUNGSiwrQkFBQ0E7QUFBREEsQ0E3RkEsQUE2RkNBLElBQUEiLCJmaWxlIjoiZGlzcGxheS9CaXRtYXBEYXRhUmVmbGVjdGlvblRlc3QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtc3RhZ2VnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBCaXRtYXBEYXRhXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2Jhc2UvQml0bWFwRGF0YVwiKTtcbmltcG9ydCBBc3NldExpYnJhcnlcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExpYnJhcnlcIik7XG5pbXBvcnQgQXNzZXRMb2FkZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbGlicmFyeS9Bc3NldExvYWRlclwiKTtcbmltcG9ydCBBc3NldExvYWRlclRva2VuXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TG9hZGVyVG9rZW5cIik7XG5pbXBvcnQgQXNzZXRUeXBlXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRUeXBlXCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IFVSTFJlcXVlc3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTFJlcXVlc3RcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBQcmltaXRpdmVQbGFuZVByZWZhYlx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9wcmVmYWJzL1ByaW1pdGl2ZVBsYW5lUHJlZmFiXCIpO1xuaW1wb3J0IEJpdG1hcFRleHR1cmVcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi90ZXh0dXJlcy9CaXRtYXBUZXh0dXJlXCIpO1xuaW1wb3J0IEltYWdlVGV4dHVyZVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvSW1hZ2VUZXh0dXJlXCIpO1xuaW1wb3J0IFJlcXVlc3RBbmltYXRpb25GcmFtZVx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdXRpbHMvUmVxdWVzdEFuaW1hdGlvbkZyYW1lXCIpO1xuXG5pbXBvcnQgRGVmYXVsdFJlbmRlcmVyXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtc3RhZ2VnbC9saWIvY29yZS9yZW5kZXIvRGVmYXVsdFJlbmRlcmVyXCIpO1xuaW1wb3J0IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWxcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL21hdGVyaWFscy9UcmlhbmdsZU1ldGhvZE1hdGVyaWFsXCIpO1xuXG5jbGFzcyBCaXRtYXBEYXRhUmVmbGVjdGlvblRlc3Rcbntcblx0cHJpdmF0ZSB2aWV3OlZpZXc7XG5cdHByaXZhdGUgcmFmOlJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0cHJpdmF0ZSByZWZsZWN0aW9uTWVzaDpNZXNoO1xuXHRwcml2YXRlIGZ1bGxtZXNoOk1lc2g7XG5cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0dGhpcy52aWV3ID0gbmV3IFZpZXcobmV3IERlZmF1bHRSZW5kZXJlcigpKTtcblx0XHR0aGlzLnJhZiA9IG5ldyBSZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5yZW5kZXIsIHRoaXMpO1xuXG5cdFx0dmFyIHRva2VuOkFzc2V0TG9hZGVyVG9rZW4gPSBBc3NldExpYnJhcnkubG9hZCggbmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy9kb3RzLnBuZycpKTtcblx0XHR0b2tlbi5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFLCAoZXZlbnQ6TG9hZGVyRXZlbnQpID0+IHRoaXMub25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50KSk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgPSAoZXZlbnQ6VUlFdmVudCkgPT4gdGhpcy5vblJlc2l6ZShldmVudCk7XG5cdH1cblxuXHRwcml2YXRlIG9uUmVzb3VyY2VDb21wbGV0ZShldmVudDpMb2FkZXJFdmVudClcblx0e1xuXHRcdHZhciBsb2FkZXI6QXNzZXRMb2FkZXIgICA9IDxBc3NldExvYWRlcj4gZXZlbnQudGFyZ2V0O1xuXHRcdHZhciBsOm51bWJlciA9IGxvYWRlci5iYXNlRGVwZW5kZW5jeS5hc3NldHMubGVuZ3RoO1xuXG5cdFx0Zm9yICh2YXIgYzpudW1iZXIgPSAwOyBjIDwgbDsgYysrKSB7XG5cblx0XHRcdHZhciBhc3NldDpJQXNzZXQgPSBsb2FkZXIuYmFzZURlcGVuZGVuY3kuYXNzZXRzW2NdO1xuXG5cdFx0XHRzd2l0Y2ggKGFzc2V0LmFzc2V0VHlwZSkge1xuXHRcdFx0XHRjYXNlIEFzc2V0VHlwZS5URVhUVVJFOlxuXG5cdFx0XHRcdFx0dmFyIHByZWZhYjpQcmltaXRpdmVQbGFuZVByZWZhYiA9IG5ldyBQcmltaXRpdmVQbGFuZVByZWZhYig1MDAgLCA1MDAsIDEsIDEsIGZhbHNlKTtcblx0XHRcdFx0XHR2YXIgdHg6SW1hZ2VUZXh0dXJlID0gPEltYWdlVGV4dHVyZT4gYXNzZXQ7XG5cdFx0XHRcdFx0dmFyIGJpdG1hcDpCaXRtYXBEYXRhID0gbmV3IEJpdG1hcERhdGEoMTAyNCwgMTAyNCwgdHJ1ZSwgMHgwMDAwMDAwMCk7XG5cblx0XHRcdFx0XHRiaXRtYXAuY29udGV4dC50cmFuc2xhdGUoMCwgMTAyNCk7XG5cdFx0XHRcdFx0Yml0bWFwLmNvbnRleHQuc2NhbGUoMSwgLTEpO1xuXHRcdFx0XHRcdGJpdG1hcC5jb250ZXh0LmRyYXdJbWFnZSh0eC5odG1sSW1hZ2VFbGVtZW50LCAwLCAwLCAxMDI0LCAxMDI0KTtcblxuXHRcdFx0XHRcdHZhciBncmFkaWVudCA9IGJpdG1hcC5jb250ZXh0LmNyZWF0ZUxpbmVhckdyYWRpZW50KDAsIDAsIDAsIDEwMjQpO1xuXHRcdFx0XHRcdGdyYWRpZW50LmFkZENvbG9yU3RvcCgwLjgsIFwicmdiYSgyNTUsIDI1NSwgMjU1LCAxLjApXCIpO1xuXHRcdFx0XHRcdGdyYWRpZW50LmFkZENvbG9yU3RvcCgxLCBcInJnYmEoMjU1LCAyNTUsIDI1NSwgMC41KVwiKTtcblxuXHRcdFx0XHRcdGJpdG1hcC5jb250ZXh0LmZpbGxTdHlsZSA9IGdyYWRpZW50O1xuXHRcdFx0XHRcdGJpdG1hcC5jb250ZXh0LnJlY3QoMCwgMCwgMTAyNCwgMTAyNCk7XG5cdFx0XHRcdFx0Yml0bWFwLmNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJkZXN0aW5hdGlvbi1vdXRcIjtcblx0XHRcdFx0XHRiaXRtYXAuY29udGV4dC5maWxsKCk7XG5cblx0XHRcdFx0XHR2YXIgYml0bWFwQ2xvbmU6Qml0bWFwRGF0YSA9IG5ldyBCaXRtYXBEYXRhKDEwMjQsIDEwMjQsIHRydWUsIDB4MDAwMDAwMDApO1xuXHRcdFx0XHRcdGJpdG1hcENsb25lLmNvcHlQaXhlbHMoYml0bWFwLCBiaXRtYXBDbG9uZS5yZWN0LCBiaXRtYXBDbG9uZS5yZWN0KTtcblxuXHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYml0bWFwLmNhbnZhcyk7XG5cblx0XHRcdFx0XHR2YXIgYm1wVFg6Qml0bWFwVGV4dHVyZSA9IG5ldyBCaXRtYXBUZXh0dXJlKGJpdG1hcENsb25lLCBmYWxzZSk7XG5cblx0XHRcdFx0XHR2YXIgbWF0ZXJpYWw6VHJpYW5nbGVNZXRob2RNYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKGJtcFRYKTtcblx0XHRcdFx0XHRtYXRlcmlhbC5ib3RoU2lkZXMgPSB0cnVlO1xuXHRcdFx0XHRcdG1hdGVyaWFsLmFscGhhQmxlbmRpbmcgPSB0cnVlO1xuXG5cdFx0XHRcdFx0dmFyIG1hdGVyaWFsMjpUcmlhbmdsZU1ldGhvZE1hdGVyaWFsID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwodHgpO1xuXHRcdFx0XHRcdG1hdGVyaWFsMi5ib3RoU2lkZXMgPSB0cnVlO1xuXHRcdFx0XHRcdG1hdGVyaWFsMi5hbHBoYUJsZW5kaW5nID0gdHJ1ZTtcblxuXHRcdFx0XHRcdHRoaXMucmVmbGVjdGlvbk1lc2ggPSA8TWVzaD4gcHJlZmFiLmdldE5ld09iamVjdCgpO1xuXHRcdFx0XHRcdHRoaXMucmVmbGVjdGlvbk1lc2gubWF0ZXJpYWwgPSBtYXRlcmlhbDtcblx0XHRcdFx0XHR0aGlzLnZpZXcuc2NlbmUuYWRkQ2hpbGQodGhpcy5yZWZsZWN0aW9uTWVzaCk7XG5cblx0XHRcdFx0XHR0aGlzLmZ1bGxtZXNoID0gPE1lc2g+IHByZWZhYi5nZXROZXdPYmplY3QoKTtcblx0XHRcdFx0XHR0aGlzLmZ1bGxtZXNoLm1hdGVyaWFsID0gbWF0ZXJpYWwyO1xuXHRcdFx0XHRcdHRoaXMuZnVsbG1lc2gucm90YXRpb25ZID0gOTA7XG5cdFx0XHRcdFx0dGhpcy52aWV3LnNjZW5lLmFkZENoaWxkKHRoaXMuZnVsbG1lc2gpO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5yYWYuc3RhcnQoKTtcblx0XHR0aGlzLm9uUmVzaXplKCk7XG5cdH1cblxuXHRwcml2YXRlIG9uUmVzaXplKGV2ZW50OlVJRXZlbnQgPSBudWxsKVxuXHR7XG5cdFx0dGhpcy52aWV3LnggPSB3aW5kb3cuaW5uZXJXaWR0aC8yO1xuXHRcdHRoaXMudmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoLzI7XG5cdFx0dGhpcy52aWV3LmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblx0fVxuXG5cdHByaXZhdGUgcmVuZGVyKClcblx0e1xuXHRcdHRoaXMuZnVsbG1lc2gucm90YXRpb25ZICs9LjU7XG5cdFx0dGhpcy5yZWZsZWN0aW9uTWVzaC5yb3RhdGlvblkgKz0uNTtcblxuXHRcdHRoaXMudmlldy5yZW5kZXIoKTtcblx0fVxufSJdfQ==
\ No newline at end of file
diff --git a/tests/display/BitmapDataReflectionTest.ts b/tests/display/BitmapDataReflectionTest.ts
new file mode 100644
index 00000000..7301fa5b
--- /dev/null
+++ b/tests/display/BitmapDataReflectionTest.ts
@@ -0,0 +1,112 @@
+import View = require("awayjs-core/lib/containers/View");
+import BitmapData = require("awayjs-core/lib/core/base/BitmapData");
+import AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+import AssetLoader = require("awayjs-core/lib/core/library/AssetLoader");
+import AssetLoaderToken = require("awayjs-core/lib/core/library/AssetLoaderToken");
+import AssetType = require("awayjs-core/lib/core/library/AssetType");
+import IAsset = require("awayjs-core/lib/core/library/IAsset");
+import URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+import PrimitivePlanePrefab = require("awayjs-core/lib/prefabs/PrimitivePlanePrefab");
+import BitmapTexture = require("awayjs-core/lib/textures/BitmapTexture");
+import ImageTexture = require("awayjs-core/lib/textures/ImageTexture");
+import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+
+class BitmapDataReflectionTest
+{
+ private view:View;
+ private raf:RequestAnimationFrame;
+ private reflectionMesh:Mesh;
+ private fullmesh:Mesh;
+
+ constructor()
+ {
+ this.view = new View(new DefaultRenderer());
+ this.raf = new RequestAnimationFrame(this.render, this);
+
+ var token:AssetLoaderToken = AssetLibrary.load( new URLRequest('assets/dots.png'));
+ token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (event:LoaderEvent) => this.onResourceComplete(event));
+
+ window.onresize = (event:UIEvent) => this.onResize(event);
+ }
+
+ private onResourceComplete(event:LoaderEvent)
+ {
+ var loader:AssetLoader = event.target;
+ var l:number = loader.baseDependency.assets.length;
+
+ for (var c:number = 0; c < l; c++) {
+
+ var asset:IAsset = loader.baseDependency.assets[c];
+
+ switch (asset.assetType) {
+ case AssetType.TEXTURE:
+
+ var prefab:PrimitivePlanePrefab = new PrimitivePlanePrefab(500 , 500, 1, 1, false);
+ var tx:ImageTexture = asset;
+ var bitmap:BitmapData = new BitmapData(1024, 1024, true, 0x00000000);
+
+ bitmap.context.translate(0, 1024);
+ bitmap.context.scale(1, -1);
+ bitmap.context.drawImage(tx.htmlImageElement, 0, 0, 1024, 1024);
+
+ var gradient = bitmap.context.createLinearGradient(0, 0, 0, 1024);
+ gradient.addColorStop(0.8, "rgba(255, 255, 255, 1.0)");
+ gradient.addColorStop(1, "rgba(255, 255, 255, 0.5)");
+
+ bitmap.context.fillStyle = gradient;
+ bitmap.context.rect(0, 0, 1024, 1024);
+ bitmap.context.globalCompositeOperation = "destination-out";
+ bitmap.context.fill();
+
+ var bitmapClone:BitmapData = new BitmapData(1024, 1024, true, 0x00000000);
+ bitmapClone.copyPixels(bitmap, bitmapClone.rect, bitmapClone.rect);
+
+ document.body.appendChild(bitmap.canvas);
+
+ var bmpTX:BitmapTexture = new BitmapTexture(bitmapClone, false);
+
+ var material:TriangleMethodMaterial = new TriangleMethodMaterial(bmpTX);
+ material.bothSides = true;
+ material.alphaBlending = true;
+
+ var material2:TriangleMethodMaterial = new TriangleMethodMaterial(tx);
+ material2.bothSides = true;
+ material2.alphaBlending = true;
+
+ this.reflectionMesh = prefab.getNewObject();
+ this.reflectionMesh.material = material;
+ this.view.scene.addChild(this.reflectionMesh);
+
+ this.fullmesh = prefab.getNewObject();
+ this.fullmesh.material = material2;
+ this.fullmesh.rotationY = 90;
+ this.view.scene.addChild(this.fullmesh);
+
+ break;
+ }
+ }
+
+ this.raf.start();
+ this.onResize();
+ }
+
+ private onResize(event:UIEvent = null)
+ {
+ this.view.x = window.innerWidth/2;
+ this.view.width = window.innerWidth/2;
+ this.view.height = window.innerHeight;
+ }
+
+ private render()
+ {
+ this.fullmesh.rotationY +=.5;
+ this.reflectionMesh.rotationY +=.5;
+
+ this.view.render();
+ }
+}
\ No newline at end of file
diff --git a/tests/entities/BillboardTest.js b/tests/entities/BillboardTest.js
new file mode 100755
index 00000000..b562918d
--- /dev/null
+++ b/tests/entities/BillboardTest.js
@@ -0,0 +1,152 @@
+var View = require("awayjs-core/lib/containers/View");
+var HoverController = require("awayjs-core/lib/controllers/HoverController");
+var AlignmentMode = require("awayjs-core/lib/core/base/AlignmentMode");
+var OrientationMode = require("awayjs-core/lib/core/base/OrientationMode");
+var Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+var URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+var Billboard = require("awayjs-core/lib/entities/Billboard");
+var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+var BillboardTest = (function () {
+ /**
+ * Constructor
+ */
+ function BillboardTest() {
+ this._time = 0;
+ this._move = false;
+ this.init();
+ }
+ /**
+ * Global initialise function
+ */
+ BillboardTest.prototype.init = function () {
+ this.initEngine();
+ this.initListeners();
+ this.loadTexture();
+ };
+ /**
+ * Initialise the engine
+ */
+ BillboardTest.prototype.initEngine = function () {
+ this._view = new View(new DefaultRenderer());
+ //setup the camera for optimal shadow rendering
+ this._view.camera.projection.far = 2100;
+ //setup controller to be used on the camera
+ this._cameraController = new HoverController(this._view.camera, null, 45, 20, 1000, 10);
+ };
+ /**
+ * Initialise the listeners
+ */
+ BillboardTest.prototype.initListeners = function () {
+ var _this = this;
+ document.onmousedown = function (event) { return _this.onMouseDown(event); };
+ document.onmouseup = function (event) { return _this.onMouseUp(event); };
+ document.onmousemove = function (event) { return _this.onMouseMove(event); };
+ window.onresize = function (event) { return _this.onResize(event); };
+ this.onResize();
+ this._timer = new RequestAnimationFrame(this.onEnterFrame, this);
+ this._timer.start();
+ };
+ /**
+ * start loading our texture
+ */
+ BillboardTest.prototype.loadTexture = function () {
+ var _this = this;
+ AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); });
+ AssetLibrary.load(new URLRequest("assets/130909wall_big.png"));
+ };
+ /**
+ * Navigation and render loop
+ */
+ BillboardTest.prototype.onEnterFrame = function (dt) {
+ this._time += dt;
+ this._view.render();
+ };
+ /**
+ * Listener function for resource complete event on asset library
+ */
+ BillboardTest.prototype.onResourceComplete = function (event) {
+ var assets = event.assets;
+ var length = assets.length;
+ for (var c = 0; c < length; c++) {
+ var asset = assets[c];
+ switch (event.url) {
+ case "assets/130909wall_big.png":
+ var material = new TriangleMethodMaterial();
+ material.texture = AssetLibrary.getAsset(asset.name);
+ var s;
+ s = new Billboard(material);
+ s.pivot = new Vector3D(150, 150, 0);
+ s.width = 300;
+ s.height = 300;
+ //s.rotationX = 45;
+ s.orientationMode = OrientationMode.CAMERA_PLANE;
+ s.alignmentMode = AlignmentMode.PIVOT_POINT;
+ this._view.scene.addChild(s);
+ for (var c = 0; c < 100; c++) {
+ var size = this.getRandom(5, 50);
+ s = new Billboard(material);
+ s.pivot = new Vector3D(size / 2, size / 2, 0);
+ s.width = size;
+ s.height = size;
+ s.orientationMode = OrientationMode.CAMERA_PLANE;
+ s.alignmentMode = AlignmentMode.PIVOT_POINT;
+ s.x = this.getRandom(-400, 400);
+ s.y = this.getRandom(-400, 400);
+ s.z = this.getRandom(-400, 400);
+ this._view.scene.addChild(s);
+ }
+ this._timer.start();
+ break;
+ }
+ }
+ };
+ /**
+ * Mouse down listener for navigation
+ */
+ BillboardTest.prototype.onMouseDown = function (event) {
+ this._lastPanAngle = this._cameraController.panAngle;
+ this._lastTiltAngle = this._cameraController.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ };
+ /**
+ * Mouse up listener for navigation
+ */
+ BillboardTest.prototype.onMouseUp = function (event) {
+ this._move = false;
+ };
+ /**
+ *
+ * @param event
+ */
+ BillboardTest.prototype.onMouseMove = function (event) {
+ if (this._move) {
+ this._cameraController.panAngle = 0.3 * (event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._cameraController.tiltAngle = 0.3 * (event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ };
+ /**
+ * stage listener for resize events
+ */
+ BillboardTest.prototype.onResize = function (event) {
+ if (event === void 0) { event = null; }
+ this._view.y = 0;
+ this._view.x = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ };
+ /**
+ * Util function - getRandom Number
+ */
+ BillboardTest.prototype.getRandom = function (min, max) {
+ return Math.random() * (max - min) + min;
+ };
+ return BillboardTest;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVudGl0aWVzL2JpbGxib2FyZHRlc3QudHMiXSwibmFtZXMiOlsiQmlsbGJvYXJkVGVzdCIsIkJpbGxib2FyZFRlc3QuY29uc3RydWN0b3IiLCJCaWxsYm9hcmRUZXN0LmluaXQiLCJCaWxsYm9hcmRUZXN0LmluaXRFbmdpbmUiLCJCaWxsYm9hcmRUZXN0LmluaXRMaXN0ZW5lcnMiLCJCaWxsYm9hcmRUZXN0LmxvYWRUZXh0dXJlIiwiQmlsbGJvYXJkVGVzdC5vbkVudGVyRnJhbWUiLCJCaWxsYm9hcmRUZXN0Lm9uUmVzb3VyY2VDb21wbGV0ZSIsIkJpbGxib2FyZFRlc3Qub25Nb3VzZURvd24iLCJCaWxsYm9hcmRUZXN0Lm9uTW91c2VVcCIsIkJpbGxib2FyZFRlc3Qub25Nb3VzZU1vdmUiLCJCaWxsYm9hcmRUZXN0Lm9uUmVzaXplIiwiQmlsbGJvYXJkVGVzdC5nZXRSYW5kb20iXSwibWFwcGluZ3MiOiJBQUFBLElBQU8sSUFBSSxXQUFpQixpQ0FBaUMsQ0FBQyxDQUFDO0FBQy9ELElBQU8sZUFBZSxXQUFjLDZDQUE2QyxDQUFDLENBQUM7QUFDbkYsSUFBTyxhQUFhLFdBQWMseUNBQXlDLENBQUMsQ0FBQztBQUM3RSxJQUFPLGVBQWUsV0FBYywyQ0FBMkMsQ0FBQyxDQUFDO0FBQ2pGLElBQU8sUUFBUSxXQUFnQixvQ0FBb0MsQ0FBQyxDQUFDO0FBQ3JFLElBQU8sWUFBWSxXQUFlLDJDQUEyQyxDQUFDLENBQUM7QUFHL0UsSUFBTyxVQUFVLFdBQWUscUNBQXFDLENBQUMsQ0FBQztBQUN2RSxJQUFPLFNBQVMsV0FBZSxvQ0FBb0MsQ0FBQyxDQUFDO0FBRXJFLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFFdkUsSUFBTyxxQkFBcUIsV0FBWSw2Q0FBNkMsQ0FBQyxDQUFDO0FBRXZGLElBQU8sZUFBZSxXQUFjLGdEQUFnRCxDQUFDLENBQUM7QUFDdEYsSUFBTyxzQkFBc0IsV0FBWSxxREFBcUQsQ0FBQyxDQUFDO0FBRWhHLElBQU0sYUFBYTtJ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QSxhQUFhQSxHQUFHQSxhQUFhQSxDQUFDQSxXQUFXQSxDQUFDQTtvQkFFNUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLEtBQUtBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBLENBQUNBLENBQUNBO29CQUU3QkEsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsR0FBVUEsQ0FBQ0EsRUFBRUEsQ0FBQ0EsR0FBR0EsR0FBR0EsRUFBRUEsQ0FBQ0EsRUFBR0EsRUFBRUEsQ0FBQ0E7d0JBQ3RDQSxJQUFJQSxJQUFJQSxHQUFVQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxFQUFHQSxFQUFFQSxDQUFDQSxDQUFDQTt3QkFDekNBLENBQUNBLEdBQUdBLElBQUlBLFNBQVNBLENBQUNBLFFBQVFBLENBQUNBLENBQUNBO3dCQUM1QkEsQ0FBQ0EsQ0FBQ0EsS0FBS0EsR0FBR0EsSUFBSUEsUUFBUUEsQ0FBQ0EsSUFBSUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsSUFBSUEsR0FBQ0EsQ0FBQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7d0JBQzFDQSxDQUFDQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTt3QkFDZkEsQ0FBQ0EsQ0FBQ0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0E7d0JBQ2hCQSxDQUFDQSxDQUFDQSxlQUFlQSxHQUFHQSxlQUFlQSxDQUFDQSxZQUFZQSxDQUFDQTt3QkFDakRBLENBQUNBLENBQUNBLGFBQWFBLEdBQUdBLGFBQWFBLENBQUNBLFdBQVdBLENBQUNBO3dCQUMzQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsR0FBSUEsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsR0FBR0EsRUFBR0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7d0JBQ2xDQSxDQUFDQSxDQUFDQSxDQUFDQSxHQUFJQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxHQUFHQSxFQUFHQSxHQUFHQSxDQUFDQSxDQUFDQTt3QkFDbENBLENBQUNBLENBQUNBLENBQUNBLEdBQUlBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLENBQUNBLEdBQUdBLEVBQUdBLEdBQUdBLENBQUNBLENBQUNBO3dCQUNuQ0EsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsUUFBUUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7b0JBQzlCQSxDQUFDQTtvQkFFREEsSUFBSUEsQ0FBQ0EsTUFBTUEsQ0FBQ0EsS0FBS0EsRUFBRUEsQ0FBQ0E7b0JBQ3BCQSxLQUFLQSxDQUFDQTtZQUNSQSxDQUFDQTtRQUNGQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVEUDs7T0FFR0E7SUFDS0EsbUNBQVdBLEdBQW5CQSxVQUFvQkEsS0FBZ0JBO1FBRW5DUSxJQUFJQSxDQUFDQSxhQUFhQSxHQUFHQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFFBQVFBLENBQUNBO1FBQ3JEQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFNBQVNBLENBQUNBO1FBQ3ZEQSxJQUFJQSxDQUFDQSxXQUFXQSxHQUFHQSxLQUFLQSxDQUFDQSxPQUFPQSxDQUFDQTtRQUNqQ0EsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDakNBLElBQUlBLENBQUNBLEtBQUtBLEdBQUdBLElBQUlBLENBQUNBO0lBQ25CQSxDQUFDQTtJQUVEUjs7T0FFR0E7SUFDS0EsaUNBQVNBLEdBQWpCQSxVQUFrQkEsS0FBZ0JBO1FBRWpDUyxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxLQUFLQSxDQUFDQTtJQUNwQkEsQ0FBQ0E7SUFFRFQ7OztPQUdHQTtJQUNLQSxtQ0FBV0EsR0FBbkJBLFVBQW9CQSxLQUFnQkE7UUFFbkNVLEVBQUVBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLENBQUNBO1lBQ2hCQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFFBQVFBLEdBQUdBLEdBQUdBLEdBQUNBLENBQUNBLEtBQUtBLENBQUNBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBO1lBQzlGQSxJQUFJQSxDQUFDQSxpQkFBaUJBLENBQUNBLFNBQVNBLEdBQUdBLEdBQUdBLEdBQUNBLENBQUNBLEtBQUtBLENBQUNBLE9BQU9BLEdBQUdBLElBQUlBLENBQUNBLFdBQVdBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLGNBQWNBLENBQUNBO1FBQ2pHQSxDQUFDQTtJQUNGQSxDQUFDQTtJQUVEVjs7T0FFR0E7SUFDS0EsZ0NBQVFBLEdBQWhCQSxVQUFpQkEsS0FBb0JBO1FBQXBCVyxxQkFBb0JBLEdBQXBCQSxZQUFvQkE7UUFFcENBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLENBQUNBLEdBQUdBLENBQUNBLENBQUNBO1FBQ2pCQSxJQUFJQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUNqQkEsSUFBSUEsQ0FBQ0EsS0FBS0EsQ0FBQ0EsS0FBS0EsR0FBR0EsTUFBTUEsQ0FBQ0EsVUFBVUEsQ0FBQ0E7UUFDckNBLElBQUlBLENBQUNBLEtBQUtBLENBQUNBLE1BQU1BLEdBQUdBLE1BQU1BLENBQUNBLFdBQVdBLENBQUNBO0lBQ3hDQSxDQUFDQTtJQUVEWDs7T0FFR0E7SUFDS0EsaUNBQVNBLEdBQWpCQSxVQUFrQkEsR0FBVUEsRUFBRUEsR0FBVUE7UUFFdkNZLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLE1BQU1BLEVBQUVBLEdBQUNBLENBQUNBLEdBQUdBLEdBQUdBLEdBQUdBLENBQUNBLEdBQUdBLEdBQUdBLENBQUNBO0lBQ3hDQSxDQUFDQTtJQUNGWixvQkFBQ0E7QUFBREEsQ0F0TEEsQUFzTENBLElBQUEiLCJmaWxlIjoiZW50aXRpZXMvQmlsbGJvYXJkVGVzdC5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9iYmF0ZW1hbi9XZWJzdG9ybVByb2plY3RzL2F3YXlqcy1zdGFnZWdsLyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWaWV3XHRcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29udGFpbmVycy9WaWV3XCIpO1xuaW1wb3J0IEhvdmVyQ29udHJvbGxlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRyb2xsZXJzL0hvdmVyQ29udHJvbGxlclwiKTtcbmltcG9ydCBBbGlnbm1lbnRNb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL0FsaWdubWVudE1vZGVcIik7XG5pbXBvcnQgT3JpZW50YXRpb25Nb2RlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9iYXNlL09yaWVudGF0aW9uTW9kZVwiKTtcbmltcG9ydCBWZWN0b3IzRFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2dlb20vVmVjdG9yM0RcIik7XG5pbXBvcnQgQXNzZXRMaWJyYXJ5XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvQXNzZXRMaWJyYXJ5XCIpO1xuaW1wb3J0IElBc3NldFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL2xpYnJhcnkvSUFzc2V0XCIpO1xuaW1wb3J0IFVSTExvYWRlclx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9uZXQvVVJMTG9hZGVyXCIpO1xuaW1wb3J0IFVSTFJlcXVlc3RcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTFJlcXVlc3RcIik7XG5pbXBvcnQgQmlsbGJvYXJkXHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9CaWxsYm9hcmRcIik7XG5pbXBvcnQgTWVzaFx0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2VudGl0aWVzL01lc2hcIik7XG5pbXBvcnQgTG9hZGVyRXZlbnRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2V2ZW50cy9Mb2FkZXJFdmVudFwiKTtcbmltcG9ydCBUZXh0dXJlMkRCYXNlXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvdGV4dHVyZXMvVGV4dHVyZTJEQmFzZVwiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcbmltcG9ydCBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsXHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvVHJpYW5nbGVNZXRob2RNYXRlcmlhbFwiKTtcblxuY2xhc3MgQmlsbGJvYXJkVGVzdFxue1xuXHQvL2VuZ2luZSB2YXJpYWJsZXNcblx0cHJpdmF0ZSBfdmlldzpWaWV3O1xuXHRwcml2YXRlIF9jYW1lcmFDb250cm9sbGVyOkhvdmVyQ29udHJvbGxlcjtcblxuXHQvL25hdmlnYXRpb24gdmFyaWFibGVzXG5cdHByaXZhdGUgX3RpbWVyOlJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0cHJpdmF0ZSBfdGltZTpudW1iZXIgPSAwO1xuXHRwcml2YXRlIF9tb3ZlOmJvb2xlYW4gPSBmYWxzZTtcblx0cHJpdmF0ZSBfbGFzdFBhbkFuZ2xlOm51bWJlcjtcblx0cHJpdmF0ZSBfbGFzdFRpbHRBbmdsZTpudW1iZXI7XG5cdHByaXZhdGUgX2xhc3RNb3VzZVg6bnVtYmVyO1xuXHRwcml2YXRlIF9sYXN0TW91c2VZOm51bWJlcjtcblxuXHQvKipcblx0ICogQ29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHRoaXMuaW5pdCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdsb2JhbCBpbml0aWFsaXNlIGZ1bmN0aW9uXG5cdCAqL1xuXHRwcml2YXRlIGluaXQoKTp2b2lkXG5cdHtcblx0XHR0aGlzLmluaXRFbmdpbmUoKTtcblx0XHR0aGlzLmluaXRMaXN0ZW5lcnMoKTtcblx0XHR0aGlzLmxvYWRUZXh0dXJlKCk7XG5cdH1cblxuXHQvKipcblx0ICogSW5pdGlhbGlzZSB0aGUgZW5naW5lXG5cdCAqL1xuXHRwcml2YXRlIGluaXRFbmdpbmUoKTp2b2lkXG5cdHtcblx0XHR0aGlzLl92aWV3ID0gbmV3IFZpZXcobmV3IERlZmF1bHRSZW5kZXJlcigpKTtcblxuXHRcdC8vc2V0dXAgdGhlIGNhbWVyYSBmb3Igb3B0aW1hbCBzaGFkb3cgcmVuZGVyaW5nXG5cdFx0dGhpcy5fdmlldy5jYW1lcmEucHJvamVjdGlvbi5mYXIgPSAyMTAwO1xuXG5cdFx0Ly9zZXR1cCBjb250cm9sbGVyIHRvIGJlIHVzZWQgb24gdGhlIGNhbWVyYVxuXHRcdHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIgPSBuZXcgSG92ZXJDb250cm9sbGVyKHRoaXMuX3ZpZXcuY2FtZXJhLCBudWxsLCA0NSwgMjAsIDEwMDAsIDEwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXNlIHRoZSBsaXN0ZW5lcnNcblx0ICovXG5cdHByaXZhdGUgaW5pdExpc3RlbmVycygpOnZvaWRcblx0e1xuXHRcdGRvY3VtZW50Lm9ubW91c2Vkb3duID0gKGV2ZW50Ok1vdXNlRXZlbnQpID0+IHRoaXMub25Nb3VzZURvd24oZXZlbnQpO1xuXHRcdGRvY3VtZW50Lm9ubW91c2V1cCA9IChldmVudDpNb3VzZUV2ZW50KSA9PiB0aGlzLm9uTW91c2VVcChldmVudCk7XG5cdFx0ZG9jdW1lbnQub25tb3VzZW1vdmUgPSAoZXZlbnQ6TW91c2VFdmVudCkgPT4gdGhpcy5vbk1vdXNlTW92ZShldmVudCk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgID0gKGV2ZW50OlVJRXZlbnQpID0+IHRoaXMub25SZXNpemUoZXZlbnQpO1xuXG5cdFx0dGhpcy5vblJlc2l6ZSgpO1xuXG5cdFx0dGhpcy5fdGltZXIgPSBuZXcgUmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMub25FbnRlckZyYW1lLCB0aGlzKTtcblx0XHR0aGlzLl90aW1lci5zdGFydCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIHN0YXJ0IGxvYWRpbmcgb3VyIHRleHR1cmVcblx0ICovXG5cdHByaXZhdGUgbG9hZFRleHR1cmUoKTp2b2lkXG5cdHtcblx0XHRBc3NldExpYnJhcnkuYWRkRXZlbnRMaXN0ZW5lcihMb2FkZXJFdmVudC5SRVNPVVJDRV9DT01QTEVURSwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXHRcdEFzc2V0TGlicmFyeS5sb2FkKG5ldyBVUkxSZXF1ZXN0KFwiYXNzZXRzLzEzMDkwOXdhbGxfYmlnLnBuZ1wiKSk7XG5cdH1cblxuXHQvKipcblx0ICogTmF2aWdhdGlvbiBhbmQgcmVuZGVyIGxvb3Bcblx0ICovXG5cdHByaXZhdGUgb25FbnRlckZyYW1lKGR0Om51bWJlcik6dm9pZFxuXHR7XG5cdFx0dGhpcy5fdGltZSArPSBkdDtcblxuXHRcdHRoaXMuX3ZpZXcucmVuZGVyKCk7XG5cdH1cblxuXHQvKipcblx0ICogTGlzdGVuZXIgZnVuY3Rpb24gZm9yIHJlc291cmNlIGNvbXBsZXRlIGV2ZW50IG9uIGFzc2V0IGxpYnJhcnlcblx0ICovXG5cdHByaXZhdGUgb25SZXNvdXJjZUNvbXBsZXRlKGV2ZW50OkxvYWRlckV2ZW50KVxuXHR7XG5cdFx0dmFyIGFzc2V0czpBcnJheTxJQXNzZXQ+ID0gZXZlbnQuYXNzZXRzO1xuXHRcdHZhciBsZW5ndGg6bnVtYmVyID0gYXNzZXRzLmxlbmd0aDtcblxuXHRcdGZvciAodmFyIGM6bnVtYmVyID0gMDsgYyA8IGxlbmd0aDsgYyArKykge1xuXHRcdFx0dmFyIGFzc2V0OklBc3NldCA9IGFzc2V0c1tjXTtcblxuXHRcdFx0c3dpdGNoKGV2ZW50LnVybCkge1xuXG5cdFx0XHRcdGNhc2UgXCJhc3NldHMvMTMwOTA5d2FsbF9iaWcucG5nXCI6XG5cblx0XHRcdFx0XHR2YXIgbWF0ZXJpYWw6VHJpYW5nbGVNZXRob2RNYXRlcmlhbCA9IG5ldyBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsKCk7XG5cdFx0XHRcdFx0XHRtYXRlcmlhbC50ZXh0dXJlID0gPFRleHR1cmUyREJhc2U+IEFzc2V0TGlicmFyeS5nZXRBc3NldChhc3NldC5uYW1lKTtcblxuXHRcdFx0XHRcdHZhciBzOkJpbGxib2FyZDtcblx0XHRcdFx0XHRcdHMgPSBuZXcgQmlsbGJvYXJkKG1hdGVyaWFsKTtcblx0XHRcdFx0XHRcdHMucGl2b3QgPSBuZXcgVmVjdG9yM0QoMTUwLCAxNTAsIDApO1xuXHRcdFx0XHRcdFx0cy53aWR0aCA9IDMwMDtcblx0XHRcdFx0XHRcdHMuaGVpZ2h0ID0gMzAwO1xuXHRcdFx0XHRcdFx0Ly9zLnJvdGF0aW9uWCA9IDQ1O1xuXHRcdFx0XHRcdHMub3JpZW50YXRpb25Nb2RlID0gT3JpZW50YXRpb25Nb2RlLkNBTUVSQV9QTEFORTtcblx0XHRcdFx0XHRzLmFsaWdubWVudE1vZGUgPSBBbGlnbm1lbnRNb2RlLlBJVk9UX1BPSU5UO1xuXG5cdFx0XHRcdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZChzKTtcblxuXHRcdFx0XHRcdGZvciAodmFyIGM6bnVtYmVyID0gMDsgYyA8IDEwMDsgYyArKykge1xuXHRcdFx0XHRcdFx0dmFyIHNpemU6bnVtYmVyID0gdGhpcy5nZXRSYW5kb20oNSAsIDUwKTtcblx0XHRcdFx0XHRcdHMgPSBuZXcgQmlsbGJvYXJkKG1hdGVyaWFsKTtcblx0XHRcdFx0XHRcdHMucGl2b3QgPSBuZXcgVmVjdG9yM0Qoc2l6ZS8yLCBzaXplLzIsIDApO1xuXHRcdFx0XHRcdFx0cy53aWR0aCA9IHNpemU7XG5cdFx0XHRcdFx0XHRzLmhlaWdodCA9IHNpemU7XG5cdFx0XHRcdFx0XHRzLm9yaWVudGF0aW9uTW9kZSA9IE9yaWVudGF0aW9uTW9kZS5DQU1FUkFfUExBTkU7XG5cdFx0XHRcdFx0XHRzLmFsaWdubWVudE1vZGUgPSBBbGlnbm1lbnRNb2RlLlBJVk9UX1BPSU5UO1xuXHRcdFx0XHRcdFx0XHRzLnggPSAgdGhpcy5nZXRSYW5kb20oLTQwMCAsIDQwMCk7XG5cdFx0XHRcdFx0XHRcdHMueSA9ICB0aGlzLmdldFJhbmRvbSgtNDAwICwgNDAwKTtcblx0XHRcdFx0XHRcdFx0cy56ID0gIHRoaXMuZ2V0UmFuZG9tKC00MDAgLCA0MDApO1xuXHRcdFx0XHRcdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZChzKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR0aGlzLl90aW1lci5zdGFydCgpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNb3VzZSBkb3duIGxpc3RlbmVyIGZvciBuYXZpZ2F0aW9uXG5cdCAqL1xuXHRwcml2YXRlIG9uTW91c2VEb3duKGV2ZW50Ok1vdXNlRXZlbnQpOnZvaWRcblx0e1xuXHRcdHRoaXMuX2xhc3RQYW5BbmdsZSA9IHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIucGFuQW5nbGU7XG5cdFx0dGhpcy5fbGFzdFRpbHRBbmdsZSA9IHRoaXMuX2NhbWVyYUNvbnRyb2xsZXIudGlsdEFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVggPSBldmVudC5jbGllbnRYO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVkgPSBldmVudC5jbGllbnRZO1xuXHRcdHRoaXMuX21vdmUgPSB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1vdXNlIHVwIGxpc3RlbmVyIGZvciBuYXZpZ2F0aW9uXG5cdCAqL1xuXHRwcml2YXRlIG9uTW91c2VVcChldmVudDpNb3VzZUV2ZW50KTp2b2lkXG5cdHtcblx0XHR0aGlzLl9tb3ZlID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICpcblx0ICogQHBhcmFtIGV2ZW50XG5cdCAqL1xuXHRwcml2YXRlIG9uTW91c2VNb3ZlKGV2ZW50Ok1vdXNlRXZlbnQpXG5cdHtcblx0XHRpZiAodGhpcy5fbW92ZSkge1xuXHRcdFx0dGhpcy5fY2FtZXJhQ29udHJvbGxlci5wYW5BbmdsZSA9IDAuMyooZXZlbnQuY2xpZW50WCAtIHRoaXMuX2xhc3RNb3VzZVgpICsgdGhpcy5fbGFzdFBhbkFuZ2xlO1xuXHRcdFx0dGhpcy5fY2FtZXJhQ29udHJvbGxlci50aWx0QW5nbGUgPSAwLjMqKGV2ZW50LmNsaWVudFkgLSB0aGlzLl9sYXN0TW91c2VZKSArIHRoaXMuX2xhc3RUaWx0QW5nbGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIHN0YWdlIGxpc3RlbmVyIGZvciByZXNpemUgZXZlbnRzXG5cdCAqL1xuXHRwcml2YXRlIG9uUmVzaXplKGV2ZW50OlVJRXZlbnQgPSBudWxsKTp2b2lkXG5cdHtcblx0XHR0aGlzLl92aWV3LnkgPSAwO1xuXHRcdHRoaXMuX3ZpZXcueCA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFV0aWwgZnVuY3Rpb24gLSBnZXRSYW5kb20gTnVtYmVyXG5cdCAqL1xuXHRwcml2YXRlIGdldFJhbmRvbShtaW46bnVtYmVyLCBtYXg6bnVtYmVyKTpudW1iZXJcblx0e1xuXHRcdHJldHVybiBNYXRoLnJhbmRvbSgpKihtYXggLSBtaW4pICsgbWluO1xuXHR9XG59Il19
\ No newline at end of file
diff --git a/tests/entities/BillboardTest.ts b/tests/entities/BillboardTest.ts
new file mode 100644
index 00000000..b0e759f6
--- /dev/null
+++ b/tests/entities/BillboardTest.ts
@@ -0,0 +1,201 @@
+import View = require("awayjs-core/lib/containers/View");
+import HoverController = require("awayjs-core/lib/controllers/HoverController");
+import AlignmentMode = require("awayjs-core/lib/core/base/AlignmentMode");
+import OrientationMode = require("awayjs-core/lib/core/base/OrientationMode");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+import IAsset = require("awayjs-core/lib/core/library/IAsset");
+import URLLoader = require("awayjs-core/lib/core/net/URLLoader");
+import URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+import Billboard = require("awayjs-core/lib/entities/Billboard");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+import Texture2DBase = require("awayjs-core/lib/textures/Texture2DBase");
+import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+
+class BillboardTest
+{
+ //engine variables
+ private _view:View;
+ private _cameraController:HoverController;
+
+ //navigation variables
+ private _timer:RequestAnimationFrame;
+ private _time:number = 0;
+ private _move:boolean = false;
+ private _lastPanAngle:number;
+ private _lastTiltAngle:number;
+ private _lastMouseX:number;
+ private _lastMouseY:number;
+
+ /**
+ * Constructor
+ */
+ constructor()
+ {
+ this.init();
+ }
+
+ /**
+ * Global initialise function
+ */
+ private init():void
+ {
+ this.initEngine();
+ this.initListeners();
+ this.loadTexture();
+ }
+
+ /**
+ * Initialise the engine
+ */
+ private initEngine():void
+ {
+ this._view = new View(new DefaultRenderer());
+
+ //setup the camera for optimal shadow rendering
+ this._view.camera.projection.far = 2100;
+
+ //setup controller to be used on the camera
+ this._cameraController = new HoverController(this._view.camera, null, 45, 20, 1000, 10);
+ }
+
+ /**
+ * Initialise the listeners
+ */
+ private initListeners():void
+ {
+ document.onmousedown = (event:MouseEvent) => this.onMouseDown(event);
+ document.onmouseup = (event:MouseEvent) => this.onMouseUp(event);
+ document.onmousemove = (event:MouseEvent) => this.onMouseMove(event);
+
+ window.onresize = (event:UIEvent) => this.onResize(event);
+
+ this.onResize();
+
+ this._timer = new RequestAnimationFrame(this.onEnterFrame, this);
+ this._timer.start();
+ }
+
+ /**
+ * start loading our texture
+ */
+ private loadTexture():void
+ {
+ AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (event:LoaderEvent) => this.onResourceComplete(event));
+ AssetLibrary.load(new URLRequest("assets/130909wall_big.png"));
+ }
+
+ /**
+ * Navigation and render loop
+ */
+ private onEnterFrame(dt:number):void
+ {
+ this._time += dt;
+
+ this._view.render();
+ }
+
+ /**
+ * Listener function for resource complete event on asset library
+ */
+ private onResourceComplete(event:LoaderEvent)
+ {
+ var assets:Array = event.assets;
+ var length:number = assets.length;
+
+ for (var c:number = 0; c < length; c ++) {
+ var asset:IAsset = assets[c];
+
+ switch(event.url) {
+
+ case "assets/130909wall_big.png":
+
+ var material:TriangleMethodMaterial = new TriangleMethodMaterial();
+ material.texture = AssetLibrary.getAsset(asset.name);
+
+ var s:Billboard;
+ s = new Billboard(material);
+ s.pivot = new Vector3D(150, 150, 0);
+ s.width = 300;
+ s.height = 300;
+ //s.rotationX = 45;
+ s.orientationMode = OrientationMode.CAMERA_PLANE;
+ s.alignmentMode = AlignmentMode.PIVOT_POINT;
+
+ this._view.scene.addChild(s);
+
+ for (var c:number = 0; c < 100; c ++) {
+ var size:number = this.getRandom(5 , 50);
+ s = new Billboard(material);
+ s.pivot = new Vector3D(size/2, size/2, 0);
+ s.width = size;
+ s.height = size;
+ s.orientationMode = OrientationMode.CAMERA_PLANE;
+ s.alignmentMode = AlignmentMode.PIVOT_POINT;
+ s.x = this.getRandom(-400 , 400);
+ s.y = this.getRandom(-400 , 400);
+ s.z = this.getRandom(-400 , 400);
+ this._view.scene.addChild(s);
+ }
+
+ this._timer.start();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Mouse down listener for navigation
+ */
+ private onMouseDown(event:MouseEvent):void
+ {
+ this._lastPanAngle = this._cameraController.panAngle;
+ this._lastTiltAngle = this._cameraController.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ }
+
+ /**
+ * Mouse up listener for navigation
+ */
+ private onMouseUp(event:MouseEvent):void
+ {
+ this._move = false;
+ }
+
+ /**
+ *
+ * @param event
+ */
+ private onMouseMove(event:MouseEvent)
+ {
+ if (this._move) {
+ this._cameraController.panAngle = 0.3*(event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._cameraController.tiltAngle = 0.3*(event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ }
+
+ /**
+ * stage listener for resize events
+ */
+ private onResize(event:UIEvent = null):void
+ {
+ this._view.y = 0;
+ this._view.x = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ }
+
+ /**
+ * Util function - getRandom Number
+ */
+ private getRandom(min:number, max:number):number
+ {
+ return Math.random()*(max - min) + min;
+ }
+}
\ No newline at end of file
diff --git a/tests/entities/LayoutTest.js b/tests/entities/LayoutTest.js
new file mode 100755
index 00000000..8add1151
--- /dev/null
+++ b/tests/entities/LayoutTest.js
@@ -0,0 +1,105 @@
+var View = require("awayjs-core/lib/containers/View");
+var HoverController = require("awayjs-core/lib/controllers/HoverController");
+var AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+var URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+var Billboard = require("awayjs-core/lib/entities/Billboard");
+var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+var AwayMouseEvent = require("awayjs-core/lib/events/MouseEvent");
+var CoordinateSystem = require("awayjs-core/lib/projections/CoordinateSystem");
+var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+var DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+var TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+var LayoutTest = (function () {
+ function LayoutTest() {
+ var _this = this;
+ this._move = false;
+ this._billboards = new Array();
+ //listen for a resource complete event
+ AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, function (event) { return _this.onResourceComplete(event); });
+ //load an image
+ AssetLibrary.load(new URLRequest('assets/256x256.png'));
+ }
+ /**
+ * Listener for resource complete event
+ *
+ * @param event
+ */
+ LayoutTest.prototype.onResourceComplete = function (event) {
+ var _this = this;
+ //get the image texture
+ this._imageTexture = event.assets[0];
+ //create the view
+ this._view = new View(new DefaultRenderer());
+ this._projection = this._view.camera.projection;
+ this._projection.coordinateSystem = CoordinateSystem.RIGHT_HANDED;
+ this._projection.focalLength = 1000;
+ this._projection.preserveFocalLength = true;
+ this._projection.originX = 0;
+ this._projection.originY = 0;
+ //create a bitmap material
+ this._bitmapMaterial = new TriangleMethodMaterial(this._imageTexture);
+ var billboard;
+ var numHBillboards = 2;
+ var numVBillboards = 2;
+ for (var i = 0; i < numHBillboards; i++) {
+ for (var j = 0; j < numVBillboards; j++) {
+ billboard = new Billboard(this._bitmapMaterial);
+ //billboard.width = 50;
+ //billboard.height = 50;
+ //billboard.pivot = new Vector3D(billboard.billboardWidth/2, billboard.billboardHeight/2, 0);
+ billboard.x = j * 300;
+ billboard.y = i * 300;
+ billboard.z = 0;
+ billboard.addEventListener(AwayMouseEvent.MOUSE_MOVE, this.onMouseEvent);
+ //billboard.orientationMode = away.base.OrientationMode.CAMERA_PLANE;
+ //billboard.alignmentMode = away.base.AlignmentMode.PIVOT_POINT;
+ this._billboards.push(billboard);
+ //add billboard to the scene
+ this._view.scene.addChild(billboard);
+ }
+ }
+ this._hoverControl = new HoverController(this._view.camera, null, 180, 0, 1000);
+ document.onmousedown = function (event) { return _this.onMouseDownHandler(event); };
+ document.onmouseup = function (event) { return _this.onMouseUpHandler(event); };
+ document.onmousemove = function (event) { return _this.onMouseMove(event); };
+ window.onresize = function (event) { return _this.onResize(event); };
+ //trigger an initial resize for the view
+ this.onResize(null);
+ //setup the RAF for a render listener
+ this._timer = new RequestAnimationFrame(this.render, this);
+ this._timer.start();
+ };
+ LayoutTest.prototype.onMouseEvent = function (event) {
+ console.log(event);
+ };
+ LayoutTest.prototype.onResize = function (event) {
+ this._view.x = 0;
+ this._view.y = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ };
+ LayoutTest.prototype.render = function (dt) {
+ for (var i = 0; i < this._billboards.length; i++) {
+ }
+ this._view.render();
+ };
+ LayoutTest.prototype.onMouseUpHandler = function (event) {
+ this._move = false;
+ };
+ LayoutTest.prototype.onMouseMove = function (event) {
+ if (this._move) {
+ this._hoverControl.panAngle = 0.3 * (event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._hoverControl.tiltAngle = -0.3 * (event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ };
+ LayoutTest.prototype.onMouseDownHandler = function (event) {
+ this._lastPanAngle = this._hoverControl.panAngle;
+ this._lastTiltAngle = this._hoverControl.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ };
+ return LayoutTest;
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVudGl0aWVzL2xheW91dHRlc3QudHMiXSwibmFtZXMiOlsiTGF5b3V0VGVzdCIsIkxheW91dFRlc3QuY29uc3RydWN0b3IiLCJMYXlvdXRUZXN0Lm9uUmVzb3VyY2VDb21wbGV0ZSIsIkxheW91dFRlc3Qub25Nb3VzZUV2ZW50IiwiTGF5b3V0VGVzdC5vblJlc2l6ZSIsIkxheW91dFRlc3QucmVuZGVyIiwiTGF5b3V0VGVzdC5vbk1vdXNlVXBIYW5kbGVyIiwiTGF5b3V0VGVzdC5vbk1vdXNlTW92ZSIsIkxheW91dFRlc3Qub25Nb3VzZURvd25IYW5kbGVyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQUksV0FBaUIsaUNBQWlDLENBQUMsQ0FBQztBQUMvRCxJQUFPLGVBQWUsV0FBYyw2Q0FBNkMsQ0FBQyxDQUFDO0FBRW5GLElBQU8sWUFBWSxXQUFlLDJDQUEyQyxDQUFDLENBQUM7QUFFL0UsSUFBTyxVQUFVLFdBQWUscUNBQXFDLENBQUMsQ0FBQztBQUN2RSxJQUFPLFNBQVMsV0FBZSxvQ0FBb0MsQ0FBQyxDQUFDO0FBRXJFLElBQU8sV0FBVyxXQUFlLG9DQUFvQyxDQUFDLENBQUM7QUFDdkUsSUFBTyxjQUFjLFdBQWMsbUNBQW1DLENBQUMsQ0FBQztBQUN4RSxJQUFPLGdCQUFnQixXQUFjLDhDQUE4QyxDQUFDLENBQUM7QUFHckYsSUFBTyxxQkFBcUIsV0FBWSw2Q0FBNkMsQ0FBQyxDQUFDO0FBRXZGLElBQU8sZUFBZSxXQUFjLGdEQUFnRCxDQUFDLENBQUM7QUFDdEYsSUFBTyxzQkFBc0IsV0FBWSxxREFBcUQsQ0FBQyxDQUFDO0FBRWhHLElBQU0sVUFBVTtJQWlCZkEsU0FqQktBLFVBQVVBO1FBQWhCQyxpQkFvSUNBO1FBN0hRQSxVQUFLQSxHQUFXQSxLQUFLQSxDQUFDQTtRQVF0QkEsZ0JBQVdBLEdBQW9CQSxJQUFJQSxLQUFLQSxFQUFhQSxDQUFDQTtRQUk3REEsQUFDQUEsc0NBRHNDQTtRQUN0Q0EsWUFBWUEsQ0FBQ0EsZ0JBQWdCQSxDQUFD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QUFDQSxXQUFXQSxDQUFDQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQTtZQUMxRkEsSUFBSUEsQ0FBQ0EsYUFBYUEsQ0FBQ0EsU0FBU0EsR0FBR0EsQ0FBQ0EsR0FBR0EsR0FBQ0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsV0FBV0EsQ0FBQ0EsR0FBR0EsSUFBSUEsQ0FBQ0EsY0FBY0EsQ0FBQ0E7UUFDOUZBLENBQUNBO0lBQ0ZBLENBQUNBO0lBRU9QLHVDQUFrQkEsR0FBMUJBLFVBQTJCQSxLQUFnQkE7UUFFMUNRLElBQUlBLENBQUNBLGFBQWFBLEdBQUdBLElBQUlBLENBQUNBLGFBQWFBLENBQUNBLFFBQVFBLENBQUNBO1FBQ2pEQSxJQUFJQSxDQUFDQSxjQUFjQSxHQUFHQSxJQUFJQSxDQUFDQSxhQUFhQSxDQUFDQSxTQUFTQSxDQUFDQTtRQUNuREEsSUFBSUEsQ0FBQ0EsV0FBV0EsR0FBR0EsS0FBS0EsQ0FBQ0EsT0FBT0EsQ0FBQ0E7UUFDakNBLElBQUlBLENBQUNBLFdBQVdBLEdBQUdBLEtBQUtBLENBQUNBLE9BQU9BLENBQUNBO1FBQ2pDQSxJQUFJQSxDQUFDQSxLQUFLQSxHQUFHQSxJQUFJQSxDQUFDQTtJQUNuQkEsQ0FBQ0E7SUFDRlIsaUJBQUNBO0FBQURBLENBcElBLEFBb0lDQSxJQUFBIiwiZmlsZSI6ImVudGl0aWVzL0xheW91dFRlc3QuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvYmJhdGVtYW4vV2Vic3Rvcm1Qcm9qZWN0cy9hd2F5anMtc3RhZ2VnbC8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVmlld1x0XHRcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvbnRhaW5lcnMvVmlld1wiKTtcbmltcG9ydCBIb3ZlckNvbnRyb2xsZXJcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb250cm9sbGVycy9Ib3ZlckNvbnRyb2xsZXJcIik7XG5pbXBvcnQgVmVjdG9yM0RcdFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9nZW9tL1ZlY3RvcjNEXCIpO1xuaW1wb3J0IEFzc2V0TGlicmFyeVx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvY29yZS9saWJyYXJ5L0Fzc2V0TGlicmFyeVwiKTtcbmltcG9ydCBVUkxMb2FkZXJcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL2NvcmUvbmV0L1VSTExvYWRlclwiKTtcbmltcG9ydCBVUkxSZXF1ZXN0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9jb3JlL25ldC9VUkxSZXF1ZXN0XCIpO1xuaW1wb3J0IEJpbGxib2FyZFx0XHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvZW50aXRpZXMvQmlsbGJvYXJkXCIpO1xuaW1wb3J0IE1lc2hcdFx0XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9lbnRpdGllcy9NZXNoXCIpO1xuaW1wb3J0IExvYWRlckV2ZW50XHRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvTG9hZGVyRXZlbnRcIik7XG5pbXBvcnQgQXdheU1vdXNlRXZlbnRcdFx0XHRcdD0gcmVxdWlyZShcImF3YXlqcy1jb3JlL2xpYi9ldmVudHMvTW91c2VFdmVudFwiKTtcbmltcG9ydCBDb29yZGluYXRlU3lzdGVtXHRcdFx0XHQ9IHJlcXVpcmUoXCJhd2F5anMtY29yZS9saWIvcHJvamVjdGlvbnMvQ29vcmRpbmF0ZVN5c3RlbVwiKTtcbmltcG9ydCBQZXJzcGVjdGl2ZVByb2plY3Rpb25cdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3Byb2plY3Rpb25zL1BlcnNwZWN0aXZlUHJvamVjdGlvblwiKTtcbmltcG9ydCBJbWFnZVRleHR1cmVcdFx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3RleHR1cmVzL0ltYWdlVGV4dHVyZVwiKTtcbmltcG9ydCBSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcdFx0PSByZXF1aXJlKFwiYXdheWpzLWNvcmUvbGliL3V0aWxzL1JlcXVlc3RBbmltYXRpb25GcmFtZVwiKTtcblxuaW1wb3J0IERlZmF1bHRSZW5kZXJlclx0XHRcdFx0PSByZXF1aXJlKFwiYXdheWpzLXN0YWdlZ2wvbGliL2NvcmUvcmVuZGVyL0RlZmF1bHRSZW5kZXJlclwiKTtcbmltcG9ydCBUcmlhbmdsZU1ldGhvZE1hdGVyaWFsXHRcdD0gcmVxdWlyZShcImF3YXlqcy1zdGFnZWdsL2xpYi9tYXRlcmlhbHMvVHJpYW5nbGVNZXRob2RNYXRlcmlhbFwiKTtcblxuY2xhc3MgTGF5b3V0VGVzdFxue1xuXHRwcml2YXRlIF92aWV3OlZpZXc7XG5cdHByaXZhdGUgX3Byb2plY3Rpb246UGVyc3BlY3RpdmVQcm9qZWN0aW9uO1xuXHRwcml2YXRlIF90aW1lcjpSZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XG5cdHByaXZhdGUgX2hvdmVyQ29udHJvbDpIb3ZlckNvbnRyb2xsZXI7XG5cblx0cHJpdmF0ZSBfbW92ZTpib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgX2xhc3RQYW5BbmdsZTpudW1iZXI7XG5cdHByaXZhdGUgX2xhc3RUaWx0QW5nbGU6bnVtYmVyO1xuXHRwcml2YXRlIF9sYXN0TW91c2VYOm51bWJlcjtcblx0cHJpdmF0ZSBfbGFzdE1vdXNlWTpudW1iZXI7XG5cblx0cHJpdmF0ZSBfaW1hZ2VUZXh0dXJlOkltYWdlVGV4dHVyZTtcblx0cHJpdmF0ZSBfYml0bWFwTWF0ZXJpYWw6VHJpYW5nbGVNZXRob2RNYXRlcmlhbDtcblx0cHJpdmF0ZSBfYmlsbGJvYXJkczpBcnJheTxCaWxsYm9hcmQ+ID0gbmV3IEFycmF5PEJpbGxib2FyZD4oKTtcblxuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHQvL2xpc3RlbiBmb3IgYSByZXNvdXJjZSBjb21wbGV0ZSBldmVudFxuXHRcdEFzc2V0TGlicmFyeS5hZGRFdmVudExpc3RlbmVyKExvYWRlckV2ZW50LlJFU09VUkNFX0NPTVBMRVRFICwgKGV2ZW50OkxvYWRlckV2ZW50KSA9PiB0aGlzLm9uUmVzb3VyY2VDb21wbGV0ZShldmVudCkpO1xuXG5cdFx0Ly9sb2FkIGFuIGltYWdlXG5cdFx0QXNzZXRMaWJyYXJ5LmxvYWQobmV3IFVSTFJlcXVlc3QoJ2Fzc2V0cy8yNTZ4MjU2LnBuZycpICk7XG5cdH1cblxuXHQvKipcblx0ICogTGlzdGVuZXIgZm9yIHJlc291cmNlIGNvbXBsZXRlIGV2ZW50XG5cdCAqXG5cdCAqIEBwYXJhbSBldmVudFxuXHQgKi9cblx0cHJpdmF0ZSBvblJlc291cmNlQ29tcGxldGUoZXZlbnQ6TG9hZGVyRXZlbnQpXG5cdHtcblx0XHQvL2dldCB0aGUgaW1hZ2UgdGV4dHVyZVxuXHRcdHRoaXMuX2ltYWdlVGV4dHVyZSA9IDxJbWFnZVRleHR1cmU+IGV2ZW50LmFzc2V0c1swXTtcblxuXHRcdC8vY3JlYXRlIHRoZSB2aWV3XG5cdFx0dGhpcy5fdmlldyA9IG5ldyBWaWV3KG5ldyBEZWZhdWx0UmVuZGVyZXIoKSk7XG5cblx0XHR0aGlzLl9wcm9qZWN0aW9uID0gPFBlcnNwZWN0aXZlUHJvamVjdGlvbj4gdGhpcy5fdmlldy5jYW1lcmEucHJvamVjdGlvbjtcblxuXG5cdFx0dGhpcy5fcHJvamVjdGlvbi5jb29yZGluYXRlU3lzdGVtID0gQ29vcmRpbmF0ZVN5c3RlbS5SSUdIVF9IQU5ERUQ7XG5cdFx0dGhpcy5fcHJvamVjdGlvbi5mb2NhbExlbmd0aCA9IDEwMDA7XG5cdFx0dGhpcy5fcHJvamVjdGlvbi5wcmVzZXJ2ZUZvY2FsTGVuZ3RoID0gdHJ1ZTtcblx0XHR0aGlzLl9wcm9qZWN0aW9uLm9yaWdpblggPSAwO1xuXHRcdHRoaXMuX3Byb2plY3Rpb24ub3JpZ2luWSA9IDA7XG5cblx0XHQvL2NyZWF0ZSBhIGJpdG1hcCBtYXRlcmlhbFxuXHRcdHRoaXMuX2JpdG1hcE1hdGVyaWFsID0gbmV3IFRyaWFuZ2xlTWV0aG9kTWF0ZXJpYWwodGhpcy5faW1hZ2VUZXh0dXJlKTtcblxuXHRcdHZhciBiaWxsYm9hcmQ6QmlsbGJvYXJkO1xuXHRcdHZhciBudW1IQmlsbGJvYXJkczpudW1iZXIgPSAyO1xuXHRcdHZhciBudW1WQmlsbGJvYXJkczpudW1iZXIgPSAyO1xuXHRcdGZvciAodmFyIGk6bnVtYmVyID0gMDsgaSA8IG51bUhCaWxsYm9hcmRzOyBpKyspIHtcblx0XHRcdGZvciAodmFyIGo6bnVtYmVyID0gMDsgaiA8IG51bVZCaWxsYm9hcmRzOyBqKyspIHtcblx0XHRcdFx0YmlsbGJvYXJkID0gbmV3IEJpbGxib2FyZCh0aGlzLl9iaXRtYXBNYXRlcmlhbCk7XG5cdFx0XHRcdC8vYmlsbGJvYXJkLndpZHRoID0gNTA7XG5cdFx0XHRcdC8vYmlsbGJvYXJkLmhlaWdodCA9IDUwO1xuXHRcdFx0XHQvL2JpbGxib2FyZC5waXZvdCA9IG5ldyBWZWN0b3IzRChiaWxsYm9hcmQuYmlsbGJvYXJkV2lkdGgvMiwgYmlsbGJvYXJkLmJpbGxib2FyZEhlaWdodC8yLCAwKTtcblx0XHRcdFx0YmlsbGJvYXJkLnggPSBqKjMwMDtcblx0XHRcdFx0YmlsbGJvYXJkLnkgPSBpKjMwMDtcblx0XHRcdFx0YmlsbGJvYXJkLnogPSAwO1xuXHRcdFx0XHRiaWxsYm9hcmQuYWRkRXZlbnRMaXN0ZW5lcihBd2F5TW91c2VFdmVudC5NT1VTRV9NT1ZFLCB0aGlzLm9uTW91c2VFdmVudClcblx0XHRcdFx0Ly9iaWxsYm9hcmQub3JpZW50YXRpb25Nb2RlID0gYXdheS5iYXNlLk9yaWVudGF0aW9uTW9kZS5DQU1FUkFfUExBTkU7XG5cdFx0XHRcdC8vYmlsbGJvYXJkLmFsaWdubWVudE1vZGUgPSBhd2F5LmJhc2UuQWxpZ25tZW50TW9kZS5QSVZPVF9QT0lOVDtcblx0XHRcdFx0dGhpcy5fYmlsbGJvYXJkcy5wdXNoKGJpbGxib2FyZCk7XG5cdFx0XHRcdC8vYWRkIGJpbGxib2FyZCB0byB0aGUgc2NlbmVcblx0XHRcdFx0dGhpcy5fdmlldy5zY2VuZS5hZGRDaGlsZChiaWxsYm9hcmQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuX2hvdmVyQ29udHJvbCA9IG5ldyBIb3ZlckNvbnRyb2xsZXIodGhpcy5fdmlldy5jYW1lcmEsIG51bGwsIDE4MCwgMCwgMTAwMCk7XG5cblx0XHRkb2N1bWVudC5vbm1vdXNlZG93biA9IChldmVudDpNb3VzZUV2ZW50KSA9PiB0aGlzLm9uTW91c2VEb3duSGFuZGxlcihldmVudCk7XG5cdFx0ZG9jdW1lbnQub25tb3VzZXVwID0gKGV2ZW50Ok1vdXNlRXZlbnQpID0+IHRoaXMub25Nb3VzZVVwSGFuZGxlcihldmVudCk7XG5cdFx0ZG9jdW1lbnQub25tb3VzZW1vdmUgPSAoZXZlbnQ6TW91c2VFdmVudCkgPT4gdGhpcy5vbk1vdXNlTW92ZShldmVudCk7XG5cblx0XHR3aW5kb3cub25yZXNpemUgID0gKGV2ZW50OlVJRXZlbnQpID0+IHRoaXMub25SZXNpemUoZXZlbnQpO1xuXG5cdFx0Ly90cmlnZ2VyIGFuIGluaXRpYWwgcmVzaXplIGZvciB0aGUgdmlld1xuXHRcdHRoaXMub25SZXNpemUobnVsbCk7XG5cblx0XHQvL3NldHVwIHRoZSBSQUYgZm9yIGEgcmVuZGVyIGxpc3RlbmVyXG5cdFx0dGhpcy5fdGltZXIgPSBuZXcgUmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyLCB0aGlzKTtcblx0XHR0aGlzLl90aW1lci5zdGFydCgpO1xuXHR9XG5cblx0cHJpdmF0ZSBvbk1vdXNlRXZlbnQoZXZlbnQ6QXdheU1vdXNlRXZlbnQpXG5cdHtcblx0XHRjb25zb2xlLmxvZyhldmVudCk7XG5cdH1cblxuXHRwcml2YXRlIG9uUmVzaXplKGV2ZW50OlVJRXZlbnQpXG5cdHtcblx0XHR0aGlzLl92aWV3LnggPSAwO1xuXHRcdHRoaXMuX3ZpZXcueSA9IDA7XG5cdFx0dGhpcy5fdmlldy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuXHRcdHRoaXMuX3ZpZXcuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXIoZHQ6bnVtYmVyKVxuXHR7XG5cdFx0Zm9yICh2YXIgaTpudW1iZXIgPSAwOyBpIDwgdGhpcy5fYmlsbGJvYXJkcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Ly90aGlzLl9iaWxsYm9hcmRzW2ldLnJvdGF0aW9uWiArPTI7XG5cdFx0fVxuXG5cdFx0dGhpcy5fdmlldy5yZW5kZXIoKTtcblxuXHR9XG5cblx0cHJpdmF0ZSBvbk1vdXNlVXBIYW5kbGVyKGV2ZW50Ok1vdXNlRXZlbnQpXG5cdHtcblx0XHR0aGlzLl9tb3ZlID0gZmFsc2U7XG5cdH1cblxuXHRwcml2YXRlIG9uTW91c2VNb3ZlKGV2ZW50Ok1vdXNlRXZlbnQpXG5cdHtcblx0XHRpZiAodGhpcy5fbW92ZSkge1xuXHRcdFx0dGhpcy5faG92ZXJDb250cm9sLnBhbkFuZ2xlID0gMC4zKihldmVudC5jbGllbnRYIC0gdGhpcy5fbGFzdE1vdXNlWCkgKyB0aGlzLl9sYXN0UGFuQW5nbGU7XG5cdFx0XHR0aGlzLl9ob3ZlckNvbnRyb2wudGlsdEFuZ2xlID0gLTAuMyooZXZlbnQuY2xpZW50WSAtIHRoaXMuX2xhc3RNb3VzZVkpICsgdGhpcy5fbGFzdFRpbHRBbmdsZTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIG9uTW91c2VEb3duSGFuZGxlcihldmVudDpNb3VzZUV2ZW50KVxuXHR7XG5cdFx0dGhpcy5fbGFzdFBhbkFuZ2xlID0gdGhpcy5faG92ZXJDb250cm9sLnBhbkFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RUaWx0QW5nbGUgPSB0aGlzLl9ob3ZlckNvbnRyb2wudGlsdEFuZ2xlO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVggPSBldmVudC5jbGllbnRYO1xuXHRcdHRoaXMuX2xhc3RNb3VzZVkgPSBldmVudC5jbGllbnRZO1xuXHRcdHRoaXMuX21vdmUgPSB0cnVlO1xuXHR9XG59Il19
\ No newline at end of file
diff --git a/tests/entities/LayoutTest.ts b/tests/entities/LayoutTest.ts
new file mode 100644
index 00000000..75ce0790
--- /dev/null
+++ b/tests/entities/LayoutTest.ts
@@ -0,0 +1,151 @@
+import View = require("awayjs-core/lib/containers/View");
+import HoverController = require("awayjs-core/lib/controllers/HoverController");
+import Vector3D = require("awayjs-core/lib/core/geom/Vector3D");
+import AssetLibrary = require("awayjs-core/lib/core/library/AssetLibrary");
+import URLLoader = require("awayjs-core/lib/core/net/URLLoader");
+import URLRequest = require("awayjs-core/lib/core/net/URLRequest");
+import Billboard = require("awayjs-core/lib/entities/Billboard");
+import Mesh = require("awayjs-core/lib/entities/Mesh");
+import LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
+import AwayMouseEvent = require("awayjs-core/lib/events/MouseEvent");
+import CoordinateSystem = require("awayjs-core/lib/projections/CoordinateSystem");
+import PerspectiveProjection = require("awayjs-core/lib/projections/PerspectiveProjection");
+import ImageTexture = require("awayjs-core/lib/textures/ImageTexture");
+import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
+
+import DefaultRenderer = require("awayjs-stagegl/lib/core/render/DefaultRenderer");
+import TriangleMethodMaterial = require("awayjs-stagegl/lib/materials/TriangleMethodMaterial");
+
+class LayoutTest
+{
+ private _view:View;
+ private _projection:PerspectiveProjection;
+ private _timer:RequestAnimationFrame;
+ private _hoverControl:HoverController;
+
+ private _move:boolean = false;
+ private _lastPanAngle:number;
+ private _lastTiltAngle:number;
+ private _lastMouseX:number;
+ private _lastMouseY:number;
+
+ private _imageTexture:ImageTexture;
+ private _bitmapMaterial:TriangleMethodMaterial;
+ private _billboards:Array = new Array();
+
+ constructor()
+ {
+ //listen for a resource complete event
+ AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE , (event:LoaderEvent) => this.onResourceComplete(event));
+
+ //load an image
+ AssetLibrary.load(new URLRequest('assets/256x256.png') );
+ }
+
+ /**
+ * Listener for resource complete event
+ *
+ * @param event
+ */
+ private onResourceComplete(event:LoaderEvent)
+ {
+ //get the image texture
+ this._imageTexture = event.assets[0];
+
+ //create the view
+ this._view = new View(new DefaultRenderer());
+
+ this._projection = this._view.camera.projection;
+
+
+ this._projection.coordinateSystem = CoordinateSystem.RIGHT_HANDED;
+ this._projection.focalLength = 1000;
+ this._projection.preserveFocalLength = true;
+ this._projection.originX = 0;
+ this._projection.originY = 0;
+
+ //create a bitmap material
+ this._bitmapMaterial = new TriangleMethodMaterial(this._imageTexture);
+
+ var billboard:Billboard;
+ var numHBillboards:number = 2;
+ var numVBillboards:number = 2;
+ for (var i:number = 0; i < numHBillboards; i++) {
+ for (var j:number = 0; j < numVBillboards; j++) {
+ billboard = new Billboard(this._bitmapMaterial);
+ //billboard.width = 50;
+ //billboard.height = 50;
+ //billboard.pivot = new Vector3D(billboard.billboardWidth/2, billboard.billboardHeight/2, 0);
+ billboard.x = j*300;
+ billboard.y = i*300;
+ billboard.z = 0;
+ billboard.addEventListener(AwayMouseEvent.MOUSE_MOVE, this.onMouseEvent)
+ //billboard.orientationMode = away.base.OrientationMode.CAMERA_PLANE;
+ //billboard.alignmentMode = away.base.AlignmentMode.PIVOT_POINT;
+ this._billboards.push(billboard);
+ //add billboard to the scene
+ this._view.scene.addChild(billboard);
+ }
+ }
+
+ this._hoverControl = new HoverController(this._view.camera, null, 180, 0, 1000);
+
+ document.onmousedown = (event:MouseEvent) => this.onMouseDownHandler(event);
+ document.onmouseup = (event:MouseEvent) => this.onMouseUpHandler(event);
+ document.onmousemove = (event:MouseEvent) => this.onMouseMove(event);
+
+ window.onresize = (event:UIEvent) => this.onResize(event);
+
+ //trigger an initial resize for the view
+ this.onResize(null);
+
+ //setup the RAF for a render listener
+ this._timer = new RequestAnimationFrame(this.render, this);
+ this._timer.start();
+ }
+
+ private onMouseEvent(event:AwayMouseEvent)
+ {
+ console.log(event);
+ }
+
+ private onResize(event:UIEvent)
+ {
+ this._view.x = 0;
+ this._view.y = 0;
+ this._view.width = window.innerWidth;
+ this._view.height = window.innerHeight;
+ }
+
+ private render(dt:number)
+ {
+ for (var i:number = 0; i < this._billboards.length; i++) {
+ //this._billboards[i].rotationZ +=2;
+ }
+
+ this._view.render();
+
+ }
+
+ private onMouseUpHandler(event:MouseEvent)
+ {
+ this._move = false;
+ }
+
+ private onMouseMove(event:MouseEvent)
+ {
+ if (this._move) {
+ this._hoverControl.panAngle = 0.3*(event.clientX - this._lastMouseX) + this._lastPanAngle;
+ this._hoverControl.tiltAngle = -0.3*(event.clientY - this._lastMouseY) + this._lastTiltAngle;
+ }
+ }
+
+ private onMouseDownHandler(event:MouseEvent)
+ {
+ this._lastPanAngle = this._hoverControl.panAngle;
+ this._lastTiltAngle = this._hoverControl.tiltAngle;
+ this._lastMouseX = event.clientX;
+ this._lastMouseY = event.clientY;
+ this._move = true;
+ }
+}
\ No newline at end of file
diff --git a/tests/frame.html b/tests/frame.html
new file mode 100755
index 00000000..9ba0db00
--- /dev/null
+++ b/tests/frame.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/index.html b/tests/index.html
new file mode 100755
index 00000000..afbcfacb
--- /dev/null
+++ b/tests/index.html
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+